00001 /* 00002 * This file is part of libsharp. 00003 * 00004 * libsharp is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * libsharp is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with libsharp; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 /* 00020 * libsharp is being developed at the Max-Planck-Institut fuer Astrophysik 00021 * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt 00022 * (DLR). 00023 */ 00024 00025 /*! \file sharp_lowlevel.h 00026 * Low-level, portable interface for the spherical transform library. 00027 * 00028 * Copyright (C) 2012-2013 Max-Planck-Society 00029 * \author Martin Reinecke \author Dag Sverre Seljebotn 00030 */ 00031 00032 #ifndef PLANCK_SHARP_LOWLEVEL_H 00033 #define PLANCK_SHARP_LOWLEVEL_H 00034 00035 #include <stddef.h> 00036 00037 #ifdef __cplusplus 00038 extern "C" { 00039 #endif 00040 00041 /*! \internal 00042 Helper type containing information about a single ring. */ 00043 typedef struct 00044 { 00045 double theta, phi0, weight, cth, sth; 00046 ptrdiff_t ofs; 00047 int nph, stride; 00048 } sharp_ringinfo; 00049 00050 /*! \internal 00051 Helper type containing information about a pair of rings with colatitudes 00052 symmetric around the equator. */ 00053 typedef struct 00054 { 00055 sharp_ringinfo r1,r2; 00056 } sharp_ringpair; 00057 00058 /*! \internal 00059 Type holding all required information about a map geometry. */ 00060 typedef struct 00061 { 00062 sharp_ringpair *pair; 00063 int npairs, nphmax; 00064 } sharp_geom_info; 00065 00066 /*! \defgroup almgroup Helpers for dealing with a_lm */ 00067 /*! \{ */ 00068 00069 /*! \internal 00070 Helper type for index calculation in a_lm arrays. */ 00071 typedef struct 00072 { 00073 /*! Maximum \a l index of the array */ 00074 int lmax; 00075 /*! Number of different \a m values in this object */ 00076 int nm; 00077 /*! Array with \a nm entries containing the individual m values */ 00078 int *mval; 00079 /*! Combination of flags from sharp_almflags */ 00080 int flags; 00081 /*! Array with \a nm entries containing the (hypothetical) indices of 00082 the coefficients with quantum numbers 0,\a mval[i] */ 00083 ptrdiff_t *mvstart; 00084 /*! Stride between a_lm and a_(l+1),m */ 00085 ptrdiff_t stride; 00086 } sharp_alm_info; 00087 00088 /*! alm_info flags */ 00089 typedef enum { SHARP_PACKED = 1 00090 /*< m=0-coefficients are packed so that the (zero) imaginary part is 00091 not present. mvstart is in units of *real* float/double for all 00092 m; stride is in units of reals for m=0 and complex for m!=0 */ 00093 } sharp_almflags; 00094 00095 00096 00097 /*! Creates an a_lm data structure from the following parameters: 00098 \param lmax maximum \a l quantum number (>=0) 00099 \param mmax maximum \a m quantum number (0<= \a mmax <= \a lmax) 00100 \param stride the stride between entries with identical \a m, and \a l 00101 differing by 1. 00102 \param mstart the index of the (hypothetical) coefficient with the 00103 quantum numbers 0,\a m. Must have \a mmax+1 entries. 00104 \param alm_info will hold a pointer to the newly created data structure 00105 */ 00106 void sharp_make_alm_info (int lmax, int mmax, int stride, 00107 const ptrdiff_t *mstart, sharp_alm_info **alm_info); 00108 /*! Creates an a_lm data structure which from the following parameters: 00109 \param lmax maximum \a l quantum number (\a >=0) 00110 \param nm number of different \a m (\a 0<=nm<=lmax+1) 00111 \param stride the stride between entries with identical \a m, and \a l 00112 differing by 1. 00113 \param mval array with \a nm entries containing the individual m values 00114 \param mvstart array with \a nm entries containing the (hypothetical) 00115 indices of the coefficients with the quantum numbers 0,\a mval[i] 00116 \param flags a combination of sharp_almflags (pass 0 unless you know you need this) 00117 \param alm_info will hold a pointer to the newly created data structure 00118 */ 00119 void sharp_make_general_alm_info (int lmax, int nm, int stride, const int *mval, 00120 const ptrdiff_t *mvstart, int flags, sharp_alm_info **alm_info); 00121 /*! Returns the index of the coefficient with quantum numbers \a l, 00122 \a mval[mi]. 00123 \note for a \a sharp_alm_info generated by sharp_make_alm_info() this is 00124 the index for the coefficient with the quantum numbers \a l, \a mi. */ 00125 ptrdiff_t sharp_alm_index (const sharp_alm_info *self, int l, int mi); 00126 /*! Deallocates the a_lm info object. */ 00127 void sharp_destroy_alm_info (sharp_alm_info *info); 00128 00129 /*! \} */ 00130 00131 /*! \defgroup geominfogroup Functions for dealing with geometry information */ 00132 /*! \{ */ 00133 00134 /*! Creates a geometry information from a set of ring descriptions. 00135 All arrays passed to this function must have \a nrings elements. 00136 \param nrings the number of rings in the map 00137 \param nph the number of pixels in each ring 00138 \param ofs the index of the first pixel in each ring in the map array 00139 \param stride the stride between consecutive pixels 00140 \param phi0 the azimuth (in radians) of the first pixel in each ring 00141 \param theta the colatitude (in radians) of each ring 00142 \param wgt the pixel weight to be used for the ring in map2alm 00143 and adjoint map2alm transforms. 00144 Pass NULL to use 1.0 as weight for all rings. 00145 \param geom_info will hold a pointer to the newly created data structure 00146 */ 00147 void sharp_make_geom_info (int nrings, const int *nph, const ptrdiff_t *ofs, 00148 const int *stride, const double *phi0, const double *theta, 00149 const double *wgt, sharp_geom_info **geom_info); 00150 00151 /*! Deallocates the geometry information in \a info. */ 00152 void sharp_destroy_geom_info (sharp_geom_info *info); 00153 00154 /*! \} */ 00155 00156 /*! \defgroup lowlevelgroup Low-level libsharp SHT interface */ 00157 /*! \{ */ 00158 00159 /*! Enumeration of SHARP job types. */ 00160 typedef enum { SHARP_YtW=0, /*!< analysis */ 00161 SHARP_MAP2ALM=SHARP_YtW, /*!< analysis */ 00162 SHARP_Y=1, /*!< synthesis */ 00163 SHARP_ALM2MAP=SHARP_Y, /*!< synthesis */ 00164 SHARP_Yt=2, /*!< adjoint synthesis */ 00165 SHARP_WY=3, /*!< adjoint analysis */ 00166 SHARP_ALM2MAP_DERIV1=4 /*!< synthesis of first derivatives */ 00167 } sharp_jobtype; 00168 00169 /*! Job flags */ 00170 typedef enum { SHARP_DP = 1<<4, 00171 /*!< map and a_lm are in double precision */ 00172 SHARP_ADD = 1<<5, 00173 /*!< results are added to the output arrays, instead of 00174 overwriting them */ 00175 SHARP_REAL_HARMONICS = 1<<6, 00176 /*!< Use the real spherical harmonic convention. For 00177 m==0, the alm are treated exactly the same as in 00178 the complex case. For m!=0, alm[i] represent a 00179 pair (+abs(m), -abs(m)) instead of (real, imag), 00180 and the coefficients are scaled by a factor of 00181 sqrt(2) relative to the complex case. In other 00182 words, (sqrt(.5) * alm[i]) recovers the 00183 corresponding complex coefficient (when accessed 00184 as complex). 00185 */ 00186 SHARP_NO_FFT = 1<<7, 00187 00188 SHARP_USE_WEIGHTS = 1<<20, /* internal use only */ 00189 SHARP_NO_OPENMP = 1<<21, /* internal use only */ 00190 SHARP_NVMAX = (1<<4)-1 /* internal use only */ 00191 } sharp_jobflags; 00192 00193 /*! Performs a libsharp SHT job. The interface deliberately does not use 00194 the C99 "complex" data type, in order to be callable from C89 and C++. 00195 \param type the type of SHT 00196 \param spin the spin of the quantities to be transformed 00197 \param alm contains pointers to the a_lm coefficients. If \a spin==0, 00198 alm[0] points to the a_lm of the first SHT, alm[1] to those of the second 00199 etc. If \a spin>0, alm[0] and alm[1] point to the a_lm of the first SHT, 00200 alm[2] and alm[3] to those of the second, etc. The exact data type of \a alm 00201 depends on whether the SHARP_DP flag is set. 00202 \param map contains pointers to the maps. If \a spin==0, 00203 map[0] points to the map of the first SHT, map[1] to that of the second 00204 etc. If \a spin>0, or \a type is SHARP_ALM2MAP_DERIV1, map[0] and map[1] 00205 point to the maps of the first SHT, map[2] and map[3] to those of the 00206 second, etc. The exact data type of \a map depends on whether the SHARP_DP 00207 flag is set. 00208 \param geom_info A \c sharp_geom_info object compatible with the provided 00209 \a map arrays. 00210 \param alm_info A \c sharp_alm_info object compatible with the provided 00211 \a alm arrays. All \c m values from 0 to some \c mmax<=lmax must be present 00212 exactly once. 00213 \param ntrans the number of simultaneous SHTs 00214 \param flags See sharp_jobflags. In particular, if SHARP_DP is set, then 00215 \a alm is expected to have the type "complex double **" and \a map is 00216 expected to have the type "double **"; otherwise, the expected 00217 types are "complex float **" and "float **", respectively. 00218 \param time If not NULL, the wall clock time required for this SHT 00219 (in seconds) will be written here. 00220 \param opcnt If not NULL, a conservative estimate of the total floating point 00221 operation count for this SHT will be written here. */ 00222 void sharp_execute (sharp_jobtype type, int spin, void *alm, void *map, 00223 const sharp_geom_info *geom_info, const sharp_alm_info *alm_info, int ntrans, 00224 int flags, double *time, unsigned long long *opcnt); 00225 00226 void sharp_set_chunksize_min(int new_chunksize_min); 00227 void sharp_set_nchunks_max(int new_nchunks_max); 00228 00229 /*! \} */ 00230 00231 #ifdef __cplusplus 00232 } 00233 #endif 00234 00235 #endif