mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-08 01:01:11 +00:00
Imported healpix tree
This commit is contained in:
parent
4182c30485
commit
4bfb62f177
136 changed files with 26534 additions and 0 deletions
103
external/healpix/libpsht/libpsht.dox
vendored
Normal file
103
external/healpix/libpsht/libpsht.dox
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*! \mainpage libpsht documentation
|
||||
<ul>
|
||||
<li>\ref introduction "Introduction"
|
||||
<li><a href="modules.html">Programming interface</a>
|
||||
</ul>
|
||||
*/
|
||||
|
||||
/*! \page introduction Introduction to libpsht
|
||||
|
||||
"PSHT" is an acronym for <i>Performant Spherical Harmonic Transforms</i>.
|
||||
All user-visible data types and functions in this library start with
|
||||
the prefix "psht_", or with "pshts_" and "pshtd_" for single- and
|
||||
double precision variants, respectively.
|
||||
|
||||
<i>libpsht</i>'s main functionality is the conversion between <i>maps</i>
|
||||
on the sphere and <i>spherical harmonic coefficients</i> (or <i>a_lm</i>).
|
||||
A map is defined as a set of <i>rings</i>, which in turn consist of
|
||||
individual pixels that
|
||||
<ul>
|
||||
<li>all have the same colatitude and</li>
|
||||
<li>are uniformly spaced in azimuthal direction.</li>
|
||||
</ul>
|
||||
Consequently, a ring is completely defined by
|
||||
<ul>
|
||||
<li>its colatitute (in radians)</li>
|
||||
<li>the number of pixels it contains</li>
|
||||
<li>the azimuth (in radians) of the first pixel in the ring</li>
|
||||
<li>the weight that must be multiplied to every pixel during a map
|
||||
analysis (typically the solid angle of a pixel in the ring) </li>
|
||||
<li>the offset of the first ring pixel in the <i>map array</i></li>
|
||||
<li>the stride between consecutive pixels in the ring.</li>
|
||||
</ul>
|
||||
The map array is a one-dimensional array of type <i>float</i> or
|
||||
<i>double</i>, which contains the values of all map pixels. It is assumed
|
||||
that the pixels of every ring are stored inside this array in order of
|
||||
increasing azimuth and with the specified stride. Note however that the rings
|
||||
themselves can be stored in any order inside the array.
|
||||
|
||||
The a_lm array is a one-dimensional array of type <i>pshts_cmplx</i> or
|
||||
<i>pshtd_cmplx</i>, which contains all spherical harmonic coefficients
|
||||
for 0<=m<=mmax and m<=l<=lmax. There is only one constraint on the
|
||||
internal structure of the array, which is:
|
||||
|
||||
<code>Index[a_l+1,m] = Index[a_l,m] + stride</code>
|
||||
|
||||
That means that coefficients with identical <i>m</i> but different <i>l</i>
|
||||
can be interpreted as a one-dimensional array in <i>l</i> with a unique
|
||||
stride.
|
||||
|
||||
Several functions are provided for efficient index computation in this array;
|
||||
they are documented \ref almgroup "here".
|
||||
|
||||
Information about a pixelisation of the sphere is stored in objects of
|
||||
type psht_geom_info. It is possible to create such an object for any
|
||||
supported pixelisation by using the function psht_make_geometry_info();
|
||||
however, several easier-to-use functions are \ref geominfogroup "supplied"
|
||||
for generating often-used pixelisations like ECP grids, Gaussian grids,
|
||||
and Healpix grids.
|
||||
|
||||
A distinctive feature of PSHT is the ability to execute several transforms
|
||||
simultaneously (as long as they have the same geometry information and
|
||||
a_lm structure); this has the advantage that the spherical
|
||||
harmonics only have to be evaluated once for all of the transforms, saving
|
||||
a substantial amount of CPU time. The set of functions dealing with such
|
||||
<i>job lists</i> is implemented twice, both for \ref sjoblistgroup "single"
|
||||
and \ref djoblistgroup "double" precision transforms.
|
||||
|
||||
Currently, PSHT supports the following kinds of transforms:
|
||||
<ul>
|
||||
<li>scalar a_lm to map</li>
|
||||
<li>scalar map to a_lm</li>
|
||||
<li>polarised a_lm to map</li>
|
||||
<li>polarised map to a_lm</li>
|
||||
<li>spin(1-100) a_lm to map</li>
|
||||
<li>spin(1-100) map to a_lm</li>
|
||||
<li>scalar a_lm to maps of first derivatives</li>
|
||||
</ul>
|
||||
|
||||
All these different kinds can be mixed freely within a job list; i.e., it is
|
||||
possible to perform an a_lm->map and a map->a_lm transform simultaneously.
|
||||
|
||||
PSHT supports shared-memory parallelisation via OpenMP; this feature will
|
||||
be automatically enabled if the compiler supports it.
|
||||
|
||||
PSHT will also make use of SSE2 instructions when compiled for a platform
|
||||
known to support them (basically all Intel/AMD processors running a 64bit
|
||||
operating system).
|
||||
|
||||
The spherical harmonic transforms can ce executed on double-precision and
|
||||
single-precision maps and a_lm, but for accuracy reasons the computations
|
||||
will always be performed in double precision. As a consequence,
|
||||
single-precision transforms will most likely not be faster than their
|
||||
double-precision counterparts, but they will require significantly less
|
||||
memory.
|
||||
|
||||
Two example and benchmark programs are distributed with PSHT:
|
||||
<ul>
|
||||
<li>psht_test.c checks the accuracy of the (iterative) map analysis
|
||||
algorithm</li>
|
||||
<li>psht_perftest.c checks the performance of single or multiple
|
||||
transforms</li>
|
||||
</ul>
|
||||
*/
|
27
external/healpix/libpsht/planck.make
vendored
Normal file
27
external/healpix/libpsht/planck.make
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
PKG:=libpsht
|
||||
|
||||
SD:=$(SRCROOT)/$(PKG)
|
||||
OD:=$(BLDROOT)/$(PKG)
|
||||
|
||||
FULL_INCLUDE+= -I$(SD)
|
||||
|
||||
HDR_$(PKG):=$(SD)/*.h
|
||||
LIB_$(PKG):=$(LIBDIR)/libpsht.a
|
||||
BIN:=psht_test psht_perftest
|
||||
LIBOBJ:=ylmgen_c.o psht.o psht_geomhelpers.o psht_almhelpers.o
|
||||
ALLOBJ:=$(LIBOBJ) psht_test.o psht_perftest.o
|
||||
LIBOBJ:=$(LIBOBJ:%=$(OD)/%)
|
||||
ALLOBJ:=$(ALLOBJ:%=$(OD)/%)
|
||||
|
||||
ODEP:=$(HDR_$(PKG)) $(HDR_libfftpack) $(HDR_c_utils) $(SD)/psht_inc.c
|
||||
BDEP:=$(LIB_$(PKG)) $(LIB_libfftpack) $(LIB_c_utils)
|
||||
|
||||
$(LIB_$(PKG)): $(LIBOBJ)
|
||||
|
||||
$(ALLOBJ): $(ODEP) | $(OD)_mkdir
|
||||
BIN:=$(BIN:%=$(BINDIR)/%)
|
||||
$(BIN): $(BINDIR)/% : $(OD)/%.o $(BDEP)
|
||||
|
||||
all_hdr+=$(HDR_$(PKG))
|
||||
all_lib+=$(LIB_$(PKG))
|
||||
all_cbin+=$(BIN)
|
216
external/healpix/libpsht/psht.c
vendored
Normal file
216
external/healpix/libpsht/psht.c
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht.c
|
||||
* Spherical transform library
|
||||
*
|
||||
* Copyright (C) 2006-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "ls_fft.h"
|
||||
#include "sse_utils.h"
|
||||
#include "ylmgen_c.h"
|
||||
#include "psht.h"
|
||||
#include "c_utils.h"
|
||||
|
||||
const pshts_cmplx pshts_cmplx_null={0,0};
|
||||
const pshtd_cmplx pshtd_cmplx_null={0,0};
|
||||
|
||||
static void get_chunk_info (int ndata, int *nchunks, int *chunksize)
|
||||
{
|
||||
static const int chunksize_min=100;
|
||||
static const int nchunks_max=10;
|
||||
*chunksize = IMAX(chunksize_min,(ndata+nchunks_max-1)/nchunks_max);
|
||||
if ((*chunksize)&1) ++(*chunksize);
|
||||
*nchunks = (ndata+*chunksize-1) / *chunksize;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double phi0_;
|
||||
pshtd_cmplx *shiftarr, *work;
|
||||
int s_shift, s_work;
|
||||
real_plan plan;
|
||||
int norot;
|
||||
} ringhelper;
|
||||
|
||||
static void ringhelper_init (ringhelper *self)
|
||||
{
|
||||
static ringhelper rh_null = { 0, NULL, NULL, 0, 0, NULL, 0 };
|
||||
*self = rh_null;
|
||||
}
|
||||
|
||||
static void ringhelper_destroy (ringhelper *self)
|
||||
{
|
||||
if (self->plan) kill_real_plan(self->plan);
|
||||
DEALLOC(self->shiftarr);
|
||||
DEALLOC(self->work);
|
||||
ringhelper_init(self);
|
||||
}
|
||||
|
||||
static void ringhelper_update (ringhelper *self, int nph, int mmax, double phi0)
|
||||
{
|
||||
int m;
|
||||
self->norot = (fabs(phi0)<1e-14);
|
||||
if (!(self->norot))
|
||||
if ((mmax!=self->s_shift-1) || (!FAPPROX(phi0,self->phi0_,1e-12)))
|
||||
{
|
||||
RESIZE (self->shiftarr,pshtd_cmplx,mmax+1);
|
||||
self->s_shift = mmax+1;
|
||||
self->phi0_ = phi0;
|
||||
for (m=0; m<=mmax; ++m)
|
||||
{
|
||||
self->shiftarr[m].re = cos(m*phi0);
|
||||
self->shiftarr[m].im = sin(m*phi0);
|
||||
}
|
||||
}
|
||||
if (!self->plan) self->plan=make_real_plan(nph);
|
||||
if (nph!=(int)self->plan->length)
|
||||
{
|
||||
kill_real_plan(self->plan);
|
||||
self->plan=make_real_plan(nph);
|
||||
}
|
||||
GROW(self->work,pshtd_cmplx,self->s_work,nph);
|
||||
}
|
||||
|
||||
static int ringinfo_compare (const void *xa, const void *xb)
|
||||
{
|
||||
const psht_ringinfo *a = xa, *b=xb;
|
||||
if (a->sth < b->sth) return -1;
|
||||
if (a->sth > b->sth) return 1;
|
||||
return 0;
|
||||
}
|
||||
static int ringpair_compare (const void *xa, const void *xb)
|
||||
{
|
||||
const psht_ringpair *a = xa, *b=xb;
|
||||
if (a->r1.nph==b->r1.nph)
|
||||
{
|
||||
if (a->r1.phi0<b->r1.phi0) return -1;
|
||||
if (a->r1.phi0>b->r1.phi0) return 1;
|
||||
return 0;
|
||||
}
|
||||
if (a->r1.nph<b->r1.nph) return -1;
|
||||
if (a->r1.nph>b->r1.nph) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void assert_jobspace (int njobs_now)
|
||||
{
|
||||
UTIL_ASSERT (njobs_now<psht_maxjobs,
|
||||
"Too many jobs added to a libpsht joblist. Exiting ...");
|
||||
}
|
||||
|
||||
void psht_make_alm_info (int lmax, int mmax, int stride,
|
||||
const ptrdiff_t *mstart, psht_alm_info **alm_info)
|
||||
{
|
||||
int m;
|
||||
psht_alm_info *info = RALLOC(psht_alm_info,1);
|
||||
info->lmax = lmax;
|
||||
info->mmax = mmax;
|
||||
info->mstart = RALLOC(ptrdiff_t,mmax+1);
|
||||
info->stride = stride;
|
||||
for (m=0; m<=mmax; ++m)
|
||||
info->mstart[m] = mstart[m];
|
||||
*alm_info = info;
|
||||
}
|
||||
|
||||
ptrdiff_t psht_alm_index (const psht_alm_info *self, int l, int m)
|
||||
{ return self->mstart[m]+self->stride*l; }
|
||||
|
||||
void psht_destroy_alm_info (psht_alm_info *info)
|
||||
{
|
||||
DEALLOC (info->mstart);
|
||||
DEALLOC (info);
|
||||
}
|
||||
|
||||
void psht_make_geom_info (int nrings, const int *nph, const ptrdiff_t *ofs,
|
||||
const int *stride, const double *phi0, const double *theta,
|
||||
const double *weight, psht_geom_info **geom_info)
|
||||
{
|
||||
psht_geom_info *info = RALLOC(psht_geom_info,1);
|
||||
psht_ringinfo *infos = RALLOC(psht_ringinfo,nrings);
|
||||
|
||||
int pos=0;
|
||||
int m;
|
||||
info->pair=RALLOC(psht_ringpair,nrings);
|
||||
info->npairs=0;
|
||||
*geom_info = info;
|
||||
|
||||
for (m=0; m<nrings; ++m)
|
||||
{
|
||||
infos[m].theta = theta[m];
|
||||
infos[m].cth = cos(theta[m]);
|
||||
infos[m].sth = sin(theta[m]);
|
||||
infos[m].weight = weight[m];
|
||||
infos[m].phi0 = phi0[m];
|
||||
infos[m].ofs = ofs[m];
|
||||
infos[m].stride = stride[m];
|
||||
infos[m].nph = nph[m];
|
||||
}
|
||||
qsort(infos,nrings,sizeof(psht_ringinfo),ringinfo_compare);
|
||||
while (pos<nrings)
|
||||
{
|
||||
if ((pos<nrings-1) && FAPPROX(infos[pos].cth,-infos[pos+1].cth,1e-12))
|
||||
{
|
||||
info->pair[info->npairs].r1=infos[pos];
|
||||
info->pair[info->npairs].r2=infos[pos+1];
|
||||
pos+=2;
|
||||
++info->npairs;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->pair[info->npairs].r1=infos[pos];
|
||||
info->pair[info->npairs].r2.nph=-1;
|
||||
++pos;
|
||||
++info->npairs;
|
||||
}
|
||||
}
|
||||
DEALLOC(infos);
|
||||
|
||||
qsort(info->pair,info->npairs,sizeof(psht_ringpair),ringpair_compare);
|
||||
}
|
||||
|
||||
void psht_destroy_geom_info (psht_geom_info *geom_info)
|
||||
{
|
||||
DEALLOC (geom_info->pair);
|
||||
DEALLOC (geom_info);
|
||||
}
|
||||
|
||||
#define CONCAT(a,b) a ## b
|
||||
|
||||
#define FLT double
|
||||
#define X(arg) CONCAT(pshtd_,arg)
|
||||
#include "psht_inc.c"
|
||||
#undef FLT
|
||||
#undef X
|
||||
|
||||
#define FLT float
|
||||
#define X(arg) CONCAT(pshts_,arg)
|
||||
#include "psht_inc.c"
|
||||
#undef FLT
|
||||
#undef X
|
||||
|
||||
#undef CONCAT
|
363
external/healpix/libpsht/psht.h
vendored
Normal file
363
external/healpix/libpsht/psht.h
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht.h
|
||||
* Interface for the spherical transform library.
|
||||
*
|
||||
* Copyright (C) 2006-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_PSHT_H
|
||||
#define PLANCK_PSHT_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sse_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! PSHT type for storing single-precision complex values */
|
||||
typedef struct
|
||||
{
|
||||
float re,im;
|
||||
} pshts_cmplx;
|
||||
|
||||
/*! PSHT type for storing double-precision complex values */
|
||||
typedef struct
|
||||
{
|
||||
double re,im;
|
||||
} pshtd_cmplx;
|
||||
|
||||
extern const pshts_cmplx pshts_cmplx_null;
|
||||
extern const pshtd_cmplx pshtd_cmplx_null;
|
||||
|
||||
/*! Helper type containing information about a single ring.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
double theta, phi0, weight, cth, sth;
|
||||
ptrdiff_t ofs;
|
||||
int nph, stride;
|
||||
} psht_ringinfo;
|
||||
|
||||
/*! Helper type containing information about a pair of rings with colatitudes
|
||||
symmetric around the equator.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
psht_ringinfo r1,r2;
|
||||
} psht_ringpair;
|
||||
|
||||
/*! Enumeration of PSHT job types.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef enum { MAP2ALM, ALM2MAP, ALM2MAP_DERIV1 } psht_jobtype;
|
||||
|
||||
/*! Type holding all required information about a map geometry.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
psht_ringpair *pair;
|
||||
int npairs;
|
||||
} psht_geom_info;
|
||||
|
||||
/*! Type holding all required information about a double precision SHT.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
psht_jobtype type;
|
||||
int spin;
|
||||
int add_output;
|
||||
int nmaps, nalm;
|
||||
double *map[3];
|
||||
pshtd_cmplx *alm[3];
|
||||
pshtd_cmplx *phas1[3], *phas2[3];
|
||||
double *norm_l;
|
||||
union {
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
v2df *v[3];
|
||||
v2df2 *v2[3];
|
||||
#else
|
||||
pshtd_cmplx *c[3];
|
||||
#endif
|
||||
} alm_tmp;
|
||||
} pshtd_job;
|
||||
|
||||
enum { psht_maxjobs=10 };
|
||||
|
||||
/*! Type holding a list of simultaneous double precision SHT jobs.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
pshtd_job job[psht_maxjobs];
|
||||
int njobs;
|
||||
} pshtd_joblist;
|
||||
|
||||
/*! Type holding all required information about a single precision SHT.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
psht_jobtype type;
|
||||
int spin;
|
||||
int add_output;
|
||||
int nmaps, nalm;
|
||||
float *map[3];
|
||||
pshts_cmplx *alm[3];
|
||||
pshtd_cmplx *phas1[3], *phas2[3];
|
||||
double *norm_l;
|
||||
union {
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
v2df *v[3];
|
||||
v2df2 *v2[3];
|
||||
#else
|
||||
pshtd_cmplx *c[3];
|
||||
#endif
|
||||
} alm_tmp;
|
||||
} pshts_job;
|
||||
|
||||
/*! Type holding a list of simultaneous single precision SHT jobs.
|
||||
\note No user serviceable parts inside! */
|
||||
typedef struct
|
||||
{
|
||||
pshts_job job[psht_maxjobs];
|
||||
int njobs;
|
||||
} pshts_joblist;
|
||||
|
||||
/*! \defgroup almgroup Helpers for calculation of a_lm indices */
|
||||
/*! \{ */
|
||||
|
||||
/*! Helper type for index calculation in a_lm arrays. */
|
||||
typedef struct
|
||||
{
|
||||
/*! Maximum \a l index of the array */
|
||||
int lmax;
|
||||
/*! Maximum \a m index of the array */
|
||||
int mmax;
|
||||
/*! Array containing the (hypothetical) indices of the coefficient
|
||||
with quantum numbers 0,\a m */
|
||||
ptrdiff_t *mstart;
|
||||
/*! Stride between a_lm and a_(l+1),m */
|
||||
ptrdiff_t stride;
|
||||
} psht_alm_info;
|
||||
|
||||
/*! Creates an Alm data structure information from the following parameters:
|
||||
\param lmax maximum \a l quantum number (>=0)
|
||||
\param mmax maximum \a m quantum number (0<= \a mmax <= \a lmax)
|
||||
\param stride the stride between consecutive a_lm entries
|
||||
\param mstart the index of the (hypothetical) coefficient with the
|
||||
quantum numbers 0,\a m. Must have \a mmax+1 entries.
|
||||
\param alm_info will hold a pointer to the newly created data structure
|
||||
*/
|
||||
void psht_make_alm_info (int lmax, int mmax, int stride,
|
||||
const ptrdiff_t *mstart, psht_alm_info **alm_info);
|
||||
/*! Returns the index of the coefficient with quantum numbers \a l,\a m. */
|
||||
ptrdiff_t psht_alm_index (const psht_alm_info *self, int l, int m);
|
||||
/*! Deallocates the a_lm info object. */
|
||||
void psht_destroy_alm_info (psht_alm_info *info);
|
||||
|
||||
/* \} */
|
||||
|
||||
/*! \defgroup geominfogroup Functions for dealing with geometry information */
|
||||
/*! \{ */
|
||||
|
||||
/*! Creates a geometry information from a set of ring descriptions.
|
||||
All arrays passed to this function must have \a nrings elements.
|
||||
\param nrings the number of rings in the map
|
||||
\param nph the number of pixels in each ring
|
||||
\param ofs the index of the first pixel in each ring in the map array
|
||||
\param stride the stride between consecutive pixels
|
||||
\param phi0 the azimuth (in radians) of the first pixel in each ring
|
||||
\param theta the colatitude (in radians) of each ring
|
||||
\param weight the pixel weight to be used for the ring
|
||||
\param geom_info will hold a pointer to the newly created data structure
|
||||
*/
|
||||
void psht_make_geom_info (int nrings, const int *nph, const ptrdiff_t *ofs,
|
||||
const int *stride, const double *phi0, const double *theta,
|
||||
const double *weight, psht_geom_info **geom_info);
|
||||
|
||||
/*! Deallocates the geometry information in \a info. */
|
||||
void psht_destroy_geom_info (psht_geom_info *info);
|
||||
|
||||
/* \} */
|
||||
|
||||
/*! \defgroup sjoblistgroup Functions for dealing with single precision job lists
|
||||
\note All pointers to maps or a_lm that are passed to the job-adding functions
|
||||
must not be de-allocated until after the last call of execute_jobs() for
|
||||
a particular job list! This is because PSHT does not copy the input data,
|
||||
but only stores the pointers to the supplied maps and a_lm.
|
||||
*/
|
||||
/*! \{ */
|
||||
|
||||
/*! Creates a new joblist object. */
|
||||
void pshts_make_joblist (pshts_joblist **joblist);
|
||||
/*! Removes all jobs in \a joblist. */
|
||||
void pshts_clear_joblist (pshts_joblist *joblist);
|
||||
/*! Deallocates the given joblist object. */
|
||||
void pshts_destroy_joblist (pshts_joblist *joblist);
|
||||
|
||||
/*! Adds a new scalar alm2map job to \a joblist, which reads data from \a alm
|
||||
and writes data to \a map. If \a add_output is 0, \a map will be
|
||||
overwritten, else the result will be added to \a map. */
|
||||
void pshts_add_job_alm2map (pshts_joblist *joblist, const pshts_cmplx *alm,
|
||||
float *map, int add_output);
|
||||
/*! Adds a new scalar map2alm job to \a joblist, which reads data from \a map
|
||||
and writes data to \a alm. If \a add_output is 0, \a alm will be
|
||||
overwritten, else the result will be added to \a alm. */
|
||||
void pshts_add_job_map2alm (pshts_joblist *joblist, const float *map,
|
||||
pshts_cmplx *alm, int add_output);
|
||||
/*! Adds a new polarised alm2map job to \a joblist, which reads data from
|
||||
\a almT, \a almG and \a almC and writes data to \a mapT, \a mapQ and
|
||||
\a mapU. If \a add_output is 0, the output maps will be
|
||||
overwritten, else the result will be added to the output maps. */
|
||||
void pshts_add_job_alm2map_pol (pshts_joblist *joblist,
|
||||
const pshts_cmplx *almT, const pshts_cmplx *almG, const pshts_cmplx *almC,
|
||||
float *mapT, float *mapQ, float *mapU, int add_output);
|
||||
/*! Adds a new polarised map2alm job to \a joblist, which reads data from
|
||||
\a mapT, \a mapQ and \a mapU and writes data to \a almT, \a almG and
|
||||
\a almC. If \a add_output is 0, the output a_lm will be
|
||||
overwritten, else the result will be added to the output a_lm. */
|
||||
void pshts_add_job_map2alm_pol (pshts_joblist *joblist,
|
||||
const float *mapT, const float *mapQ, const float *mapU,
|
||||
pshts_cmplx *almT, pshts_cmplx *almG, pshts_cmplx *almC, int add_output);
|
||||
/*! Adds a new spin alm2map job to \a joblist, which reads data from
|
||||
\a alm1 and \a alm2 and writes data to \a map1 and map2.
|
||||
\a spin must be 1, 2, or 3. If \a add_output is 0,
|
||||
the output maps will be overwritten, else the result will be
|
||||
added to the output maps. */
|
||||
void pshts_add_job_alm2map_spin (pshts_joblist *joblist,
|
||||
const pshts_cmplx *alm1, const pshts_cmplx *alm2, float *map1, float *map2,
|
||||
int spin, int add_output);
|
||||
/*! Adds a new spin map2alm job to \a joblist, which reads data from
|
||||
\a map1 and \a map2 and writes data to \a alm1 and \a alm2.
|
||||
\a spin must be 1, 2, or 3. If \a add_output is 0,
|
||||
the output a_lm will be overwritten, else the result will be added
|
||||
to the output a_lm. */
|
||||
void pshts_add_job_map2alm_spin (pshts_joblist *joblist, const float *map1,
|
||||
const float *map2, pshts_cmplx *alm1, pshts_cmplx *alm2, int spin,
|
||||
int add_output);
|
||||
/*! Adds a new job to \a joblist, which reads data from
|
||||
\a alm and writes maps of the first derivatives to \a mapdtheta and
|
||||
\a mapdphi, respectively. If \a add_output is 0,
|
||||
the output maps will be overwritten, else the result will be added
|
||||
to the output maps. */
|
||||
void pshts_add_job_alm2map_deriv1 (pshts_joblist *joblist,
|
||||
const pshts_cmplx *alm, float *mapdtheta, float *mapdphi, int add_output);
|
||||
|
||||
/*! Executes the jobs in \a joblist, using \a geom_info as map geometry
|
||||
and \a alm_info as structure of the a_lm coefficients.
|
||||
\note The map geometry and the a_lm structure have to be supplied to this
|
||||
function only, since this information is not needed by PSHT anywhere else.
|
||||
However, it is the user's responsibility to ensure that the input arrays
|
||||
(specified by calls to the job-adding functions) are consistent with the
|
||||
specified geometry and a_lm structure, and that the output arrays are
|
||||
large enough to hold the produced results.
|
||||
*/
|
||||
void pshts_execute_jobs (pshts_joblist *joblist,
|
||||
const psht_geom_info *geom_info, const psht_alm_info *alm_info);
|
||||
|
||||
/* \} */
|
||||
|
||||
/*! \defgroup djoblistgroup Functions for dealing with double precision job lists
|
||||
\note All pointers to maps or a_lm that are passed to the job-adding functions
|
||||
must not be de-allocated until after the last call of execute_jobs() for
|
||||
a particular job list! This is because PSHT does not copy the input data,
|
||||
but only stores the pointers to the supplied maps and a_lm.
|
||||
*/
|
||||
/*! \{ */
|
||||
|
||||
/*! Creates a new joblist object. */
|
||||
void pshtd_make_joblist (pshtd_joblist **joblist);
|
||||
/*! Removes all jobs in \a joblist. */
|
||||
void pshtd_clear_joblist (pshtd_joblist *joblist);
|
||||
/*! Deallocates the given joblist object. */
|
||||
void pshtd_destroy_joblist (pshtd_joblist *joblist);
|
||||
|
||||
/*! Adds a new scalar alm2map job to \a joblist, which reads data from \a alm
|
||||
and writes data to \a map. If \a add_output is 0, \a map will be
|
||||
overwritten, else the result will be added to \a map. */
|
||||
void pshtd_add_job_alm2map (pshtd_joblist *joblist, const pshtd_cmplx *alm,
|
||||
double *map, int add_output);
|
||||
/*! Adds a new scalar map2alm job to \a joblist, which reads data from \a map
|
||||
and writes data to \a alm. If \a add_output is 0, \a alm will be
|
||||
overwritten, else the result will be added to \a alm. */
|
||||
void pshtd_add_job_map2alm (pshtd_joblist *joblist, const double *map,
|
||||
pshtd_cmplx *alm, int add_output);
|
||||
/*! Adds a new polarised alm2map job to \a joblist, which reads data from
|
||||
\a almT, \a almG and \a almC and writes data to \a mapT, \a mapQ and
|
||||
\a mapU. If \a add_output is 0, the output maps will be
|
||||
overwritten, else the result will be added to the output maps. */
|
||||
void pshtd_add_job_alm2map_pol (pshtd_joblist *joblist,
|
||||
const pshtd_cmplx *almT, const pshtd_cmplx *almG, const pshtd_cmplx *almC,
|
||||
double *mapT, double *mapQ, double *mapU, int add_output);
|
||||
/*! Adds a new polarised map2alm job to \a joblist, which reads data from
|
||||
\a mapT, \a mapQ and \a mapU and writes data to \a almT, \a almG and
|
||||
\a almC. If \a add_output is 0, the output a_lm will be
|
||||
overwritten, else the result will be added to the output a_lm. */
|
||||
void pshtd_add_job_map2alm_pol (pshtd_joblist *joblist,
|
||||
const double *mapT, const double *mapQ, const double *mapU,
|
||||
pshtd_cmplx *almT, pshtd_cmplx *almG, pshtd_cmplx *almC, int add_output);
|
||||
/*! Adds a new spin alm2map job to \a joblist, which reads data from
|
||||
\a alm1 and \a alm2 and writes data to \a map1 and map2.
|
||||
\a spin must be 1, 2, or 3. If \a add_output is 0,
|
||||
the output maps will be overwritten, else the result will be
|
||||
added to the output maps. */
|
||||
void pshtd_add_job_alm2map_spin (pshtd_joblist *joblist,
|
||||
const pshtd_cmplx *alm1, const pshtd_cmplx *alm2, double *map1, double *map2,
|
||||
int spin, int add_output);
|
||||
/*! Adds a new spin map2alm job to \a joblist, which reads data from
|
||||
\a map1 and \a map2 and writes data to \a alm1 and \a alm2.
|
||||
\a spin must be 1, 2, or 3. If \a add_output is 0,
|
||||
the output a_lm will be overwritten, else the result will be added
|
||||
to the output a_lm. */
|
||||
void pshtd_add_job_map2alm_spin (pshtd_joblist *joblist, const double *map1,
|
||||
const double *map2, pshtd_cmplx *alm1, pshtd_cmplx *alm2, int spin,
|
||||
int add_output);
|
||||
/*! Adds a new job to \a joblist, which reads data from
|
||||
\a alm and writes maps of the first derivatives to \a mapdtheta and
|
||||
\a mapdphi, respectively. If \a add_output is 0,
|
||||
the output maps will be overwritten, else the result will be added
|
||||
to the output maps. */
|
||||
void pshtd_add_job_alm2map_deriv1 (pshtd_joblist *joblist,
|
||||
const pshtd_cmplx *alm, double *mapdtheta, double *mapdphi, int add_output);
|
||||
|
||||
/*! Executes the jobs in \a joblist, using \a geom_info as map geometry
|
||||
and \a alm_info as structure of the a_lm coefficients.
|
||||
\note The map geometry and the a_lm structure have to be supplied to this
|
||||
function only, since this information is not needed by PSHT anywhere else.
|
||||
However, it is the user's responsibility to ensure that the input arrays
|
||||
(specified by calls to the job-adding functions) are consistent with the
|
||||
specified geometry and a_lm structure, and that the output arrays are
|
||||
large enough to hold the produced results.
|
||||
*/
|
||||
void pshtd_execute_jobs (pshtd_joblist *joblist,
|
||||
const psht_geom_info *geom_info, const psht_alm_info *alm_info);
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
63
external/healpix/libpsht/psht_almhelpers.c
vendored
Normal file
63
external/healpix/libpsht/psht_almhelpers.c
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_almhelpers.c
|
||||
* Spherical transform library
|
||||
*
|
||||
* Copyright (C) 2008, 2009, 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include "psht_almhelpers.h"
|
||||
#include "c_utils.h"
|
||||
|
||||
void psht_make_triangular_alm_info (int lmax, int mmax, int stride,
|
||||
psht_alm_info **alm_info)
|
||||
{
|
||||
ptrdiff_t m;
|
||||
int tval;
|
||||
psht_alm_info *info = RALLOC(psht_alm_info,1);
|
||||
info->lmax = lmax;
|
||||
info->mmax = mmax;
|
||||
info->mstart = RALLOC(ptrdiff_t,mmax+1);
|
||||
info->stride = stride;
|
||||
tval = 2*lmax+1;
|
||||
for (m=0; m<=mmax; ++m)
|
||||
info->mstart[m] = stride*((m*(tval-m))>>1);
|
||||
*alm_info = info;
|
||||
}
|
||||
|
||||
void psht_make_rectangular_alm_info (int lmax, int mmax, int stride,
|
||||
psht_alm_info **alm_info)
|
||||
{
|
||||
ptrdiff_t m;
|
||||
psht_alm_info *info = RALLOC(psht_alm_info,1);
|
||||
info->lmax = lmax;
|
||||
info->mmax = mmax;
|
||||
info->mstart = RALLOC(ptrdiff_t,mmax+1);
|
||||
info->stride = stride;
|
||||
for (m=0; m<=mmax; ++m)
|
||||
info->mstart[m] = stride*m*(lmax+1);
|
||||
*alm_info = info;
|
||||
}
|
57
external/healpix/libpsht/psht_almhelpers.h
vendored
Normal file
57
external/healpix/libpsht/psht_almhelpers.h
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_almhelpers.h
|
||||
* PSHT helper function for the creation of a_lm data structures
|
||||
*
|
||||
* Copyright (C) 2008 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_PSHT_ALMHELPERS_H
|
||||
#define PLANCK_PSHT_ALMHELPERS_H
|
||||
|
||||
#include "psht.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! Initialises an a_lm data structure according to the scheme used by
|
||||
Healpix_cxx.
|
||||
\ingroup almgroup */
|
||||
void psht_make_triangular_alm_info (int lmax, int mmax, int stride,
|
||||
psht_alm_info **alm_info);
|
||||
|
||||
/*! Initialises an a_lm data structure according to the scheme used by
|
||||
Fortran Healpix
|
||||
\ingroup almgroup */
|
||||
void psht_make_rectangular_alm_info (int lmax, int mmax, int stride,
|
||||
psht_alm_info **alm_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
198
external/healpix/libpsht/psht_cxx.h
vendored
Normal file
198
external/healpix/libpsht/psht_cxx.h
vendored
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_cxx.h
|
||||
* Spherical transform library
|
||||
*
|
||||
* Copyright (C) 2008, 2009 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_PSHT_CXX_H
|
||||
#define PLANCK_PSHT_CXX_H
|
||||
|
||||
#include "psht.h"
|
||||
#include "psht_geomhelpers.h"
|
||||
#include "psht_almhelpers.h"
|
||||
#include "xcomplex.h"
|
||||
|
||||
class psht_base
|
||||
{
|
||||
protected:
|
||||
psht_geom_info *ginfo;
|
||||
psht_alm_info *ainfo;
|
||||
|
||||
public:
|
||||
psht_base()
|
||||
: ginfo(0), ainfo(0) {}
|
||||
~psht_base()
|
||||
{
|
||||
psht_destroy_geom_info(ginfo);
|
||||
psht_destroy_alm_info(ainfo);
|
||||
}
|
||||
|
||||
void set_general_geometry (int nrings, const int *nph, const ptrdiff_t *ofs,
|
||||
const int *stride, const double *phi0, const double *theta,
|
||||
const double *weight)
|
||||
{
|
||||
psht_make_geom_info (nrings, nph, ofs, stride, phi0, theta, weight,
|
||||
&ginfo);
|
||||
}
|
||||
|
||||
void set_ECP_geometry (int nrings, int nphi)
|
||||
{ psht_make_ecp_geom_info (nrings, nphi, 0., 1, &ginfo); }
|
||||
|
||||
void set_Healpix_geometry (int nside)
|
||||
{ psht_make_healpix_geom_info (nside, 1, &ginfo); }
|
||||
|
||||
void set_weighted_Healpix_geometry (int nside, const double *weight)
|
||||
{ psht_make_weighted_healpix_geom_info (nside, 1, weight, &ginfo); }
|
||||
|
||||
void set_triangular_alm_info (int lmax, int mmax)
|
||||
{ psht_make_triangular_alm_info (lmax, mmax, 1, &ainfo); }
|
||||
};
|
||||
|
||||
template<typename T> class psht_joblist
|
||||
{};
|
||||
|
||||
template<> class psht_joblist<float>: public psht_base
|
||||
{
|
||||
private:
|
||||
pshts_joblist *jobs;
|
||||
|
||||
static pshts_cmplx *conv (xcomplex<float> *ptr)
|
||||
{ return reinterpret_cast<pshts_cmplx *>(ptr); }
|
||||
static const pshts_cmplx *conv (const xcomplex<float> *ptr)
|
||||
{ return reinterpret_cast<const pshts_cmplx *>(ptr); }
|
||||
|
||||
public:
|
||||
psht_joblist()
|
||||
{ pshts_make_joblist (&jobs); }
|
||||
~psht_joblist()
|
||||
{ pshts_destroy_joblist (jobs); }
|
||||
|
||||
void clear_jobs()
|
||||
{ pshts_clear_joblist (jobs); }
|
||||
|
||||
void add_alm2map (const xcomplex<float> *alm, float *map, bool add)
|
||||
{ pshts_add_job_alm2map (jobs, conv(alm), map, add); }
|
||||
void add_map2alm (const float *map, xcomplex<float> *alm, bool add)
|
||||
{ pshts_add_job_map2alm (jobs, map, conv(alm), add); }
|
||||
void add_alm2map_pol (const xcomplex<float> *almT,
|
||||
const xcomplex<float> *almG, const xcomplex<float> *almC,
|
||||
float *mapT, float *mapQ, float *mapU, bool add)
|
||||
{
|
||||
pshts_add_job_alm2map_pol (jobs, conv(almT), conv(almG), conv(almC),
|
||||
mapT, mapQ, mapU, add);
|
||||
}
|
||||
void add_map2alm_pol (const float *mapT, const float *mapQ,
|
||||
const float *mapU, xcomplex<float> *almT, xcomplex<float> *almG,
|
||||
xcomplex<float> *almC, bool add)
|
||||
{
|
||||
pshts_add_job_map2alm_pol (jobs, mapT, mapQ, mapU, conv(almT),
|
||||
conv(almG), conv(almC), add);
|
||||
}
|
||||
void add_alm2map_spin (const xcomplex<float> *alm1,
|
||||
const xcomplex<float> *alm2, float *map1, float *map2, int spin, bool add)
|
||||
{
|
||||
pshts_add_job_alm2map_spin (jobs, conv(alm1), conv(alm2), map1, map2,
|
||||
spin, add);
|
||||
}
|
||||
void add_map2alm_spin (const float *map1, const float *map2,
|
||||
xcomplex<float> *alm1, xcomplex<float> *alm2, int spin, bool add)
|
||||
{
|
||||
pshts_add_job_map2alm_spin (jobs, map1, map2, conv(alm1), conv(alm2),
|
||||
spin, add);
|
||||
}
|
||||
void add_alm2map_der1 (const xcomplex<float> *alm, float *mapdth,
|
||||
float *mapdph, bool add)
|
||||
{
|
||||
pshts_add_job_alm2map_deriv1 (jobs, conv(alm), mapdth, mapdph, add);
|
||||
}
|
||||
|
||||
void execute()
|
||||
{ pshts_execute_jobs (jobs,ginfo,ainfo); }
|
||||
};
|
||||
|
||||
template<> class psht_joblist<double>: public psht_base
|
||||
{
|
||||
private:
|
||||
pshtd_joblist *jobs;
|
||||
|
||||
static pshtd_cmplx *conv (xcomplex<double> *ptr)
|
||||
{ return reinterpret_cast<pshtd_cmplx *>(ptr); }
|
||||
static const pshtd_cmplx *conv (const xcomplex<double> *ptr)
|
||||
{ return reinterpret_cast<const pshtd_cmplx *>(ptr); }
|
||||
|
||||
public:
|
||||
psht_joblist()
|
||||
{ pshtd_make_joblist (&jobs); }
|
||||
~psht_joblist()
|
||||
{ pshtd_destroy_joblist (jobs); }
|
||||
|
||||
void clear_jobs()
|
||||
{ pshtd_clear_joblist (jobs); }
|
||||
|
||||
void add_alm2map (const xcomplex<double> *alm, double *map, bool add)
|
||||
{ pshtd_add_job_alm2map (jobs, conv(alm), map, add); }
|
||||
void add_map2alm (const double *map, xcomplex<double> *alm, bool add)
|
||||
{ pshtd_add_job_map2alm (jobs, map, conv(alm), add); }
|
||||
void add_alm2map_pol (const xcomplex<double> *almT,
|
||||
const xcomplex<double> *almG, const xcomplex<double> *almC,
|
||||
double *mapT, double *mapQ, double *mapU, bool add)
|
||||
{
|
||||
pshtd_add_job_alm2map_pol (jobs, conv(almT), conv(almG), conv(almC),
|
||||
mapT, mapQ, mapU, add);
|
||||
}
|
||||
void add_map2alm_pol (const double *mapT, const double *mapQ,
|
||||
const double *mapU, xcomplex<double> *almT, xcomplex<double> *almG,
|
||||
xcomplex<double> *almC, bool add)
|
||||
{
|
||||
pshtd_add_job_map2alm_pol (jobs, mapT, mapQ, mapU, conv(almT),
|
||||
conv(almG), conv(almC), add);
|
||||
}
|
||||
void add_alm2map_spin (const xcomplex<double> *alm1,
|
||||
const xcomplex<double> *alm2, double *map1, double *map2, int spin,
|
||||
bool add)
|
||||
{
|
||||
pshtd_add_job_alm2map_spin (jobs, conv(alm1), conv(alm2), map1, map2,
|
||||
spin, add);
|
||||
}
|
||||
void add_map2alm_spin (const double *map1, const double *map2,
|
||||
xcomplex<double> *alm1, xcomplex<double> *alm2, int spin, bool add)
|
||||
{
|
||||
pshtd_add_job_map2alm_spin (jobs, map1, map2, conv(alm1), conv(alm2),
|
||||
spin, add);
|
||||
}
|
||||
void add_alm2map_der1 (const xcomplex<double> *alm, double *mapdth,
|
||||
double *mapdph, bool add)
|
||||
{
|
||||
pshtd_add_job_alm2map_deriv1 (jobs, conv(alm), mapdth, mapdph, add);
|
||||
}
|
||||
|
||||
void execute()
|
||||
{ pshtd_execute_jobs (jobs,ginfo,ainfo); }
|
||||
};
|
||||
|
||||
#endif
|
229
external/healpix/libpsht/psht_geomhelpers.c
vendored
Normal file
229
external/healpix/libpsht/psht_geomhelpers.c
vendored
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_geomhelpers.c
|
||||
* Spherical transform library
|
||||
*
|
||||
* Copyright (C) 2006-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "psht_geomhelpers.h"
|
||||
#include "c_utils.h"
|
||||
|
||||
void psht_make_healpix_geom_info (int nside, int stride,
|
||||
psht_geom_info **geom_info)
|
||||
{
|
||||
double *weight=RALLOC(double,2*nside);
|
||||
SET_ARRAY(weight,0,2*nside,1);
|
||||
psht_make_weighted_healpix_geom_info (nside, stride, weight, geom_info);
|
||||
DEALLOC(weight);
|
||||
}
|
||||
|
||||
void psht_make_weighted_healpix_geom_info (int nside, int stride,
|
||||
const double *weight, psht_geom_info **geom_info)
|
||||
{
|
||||
const double pi=3.141592653589793238462643383279502884197;
|
||||
ptrdiff_t npix=(ptrdiff_t)nside*nside*12;
|
||||
ptrdiff_t ncap=2*(ptrdiff_t)nside*(nside-1);
|
||||
int nrings=4*nside-1;
|
||||
|
||||
double *theta=RALLOC(double,nrings);
|
||||
double *weight_=RALLOC(double,nrings);
|
||||
int *nph=RALLOC(int,nrings);
|
||||
double *phi0=RALLOC(double,nrings);
|
||||
ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings);
|
||||
int *stride_=RALLOC(int,nrings);
|
||||
int m;
|
||||
for (m=0; m<nrings; ++m)
|
||||
{
|
||||
int ring=m+1;
|
||||
ptrdiff_t northring = (ring>2*nside) ? 4*nside-ring : ring;
|
||||
stride_[m] = stride;
|
||||
if (northring < nside)
|
||||
{
|
||||
theta[m] = 2*asin(northring/(sqrt(6.)*nside));
|
||||
nph[m] = 4*northring;
|
||||
phi0[m] = pi/nph[m];
|
||||
ofs[m] = 2*northring*(northring-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
double fact1 = (8.*nside)/npix;
|
||||
double costheta = (2*nside-northring)*fact1;
|
||||
theta[m] = acos(costheta);
|
||||
nph[m] = 4*nside;
|
||||
if ((northring-nside) & 1)
|
||||
phi0[m] = 0;
|
||||
else
|
||||
phi0[m] = pi/nph[m];
|
||||
ofs[m] = ncap + (northring-nside)*nph[m];
|
||||
}
|
||||
if (northring != ring) /* southern hemisphere */
|
||||
{
|
||||
theta[m] = pi-theta[m];
|
||||
ofs[m] = npix - nph[m] - ofs[m];
|
||||
}
|
||||
weight_[m]=4.*pi/npix*weight[northring-1];
|
||||
}
|
||||
|
||||
psht_make_geom_info (nrings, nph, ofs, stride_, phi0, theta, weight_,
|
||||
geom_info);
|
||||
|
||||
DEALLOC(theta);
|
||||
DEALLOC(weight_);
|
||||
DEALLOC(nph);
|
||||
DEALLOC(phi0);
|
||||
DEALLOC(ofs);
|
||||
DEALLOC(stride_);
|
||||
}
|
||||
|
||||
static void gauleg (double x1, double x2, double *x, double *w, int n)
|
||||
{
|
||||
const double pi = 3.141592653589793238462643383279502884197;
|
||||
const double eps = 3.0E-14;
|
||||
|
||||
int m = (n+1)/2;
|
||||
double xm = 0.5*(x2+x1);
|
||||
double xl = 0.5*(x2-x1);
|
||||
int i;
|
||||
for(i=1; i<=m; ++i)
|
||||
{
|
||||
double z = cos(pi*(i-0.25)/(n+0.5));
|
||||
double pp;
|
||||
int dobreak=0;
|
||||
while(1)
|
||||
{
|
||||
double p1 = 1.0, p2 = 0.0;
|
||||
double z1 = z;
|
||||
int j;
|
||||
for(j=1; j<=n; ++j)
|
||||
{
|
||||
double p3 = p2;
|
||||
p2 = p1;
|
||||
p1 = ((2*j-1)*z*p2-(j-1)*p3)/j;
|
||||
}
|
||||
pp = n*(z*p1-p2)/(z*z-1);
|
||||
z = z1 - p1/pp;
|
||||
if (dobreak) break;
|
||||
if (fabs(z-z1) <= eps) dobreak=1;
|
||||
}
|
||||
x[i-1] = xm - xl*z;
|
||||
x[n-i] = xm + xl*z;
|
||||
w[i-1] = w[n-i] = 2*xl/((1-z*z)*pp*pp);
|
||||
}
|
||||
}
|
||||
|
||||
static void makeweights (int bw, double *weights)
|
||||
{
|
||||
const double pi = 3.141592653589793238462643383279502884197;
|
||||
const double fudge = pi/(4*bw);
|
||||
int j;
|
||||
for (j=0; j<2*bw; ++j)
|
||||
{
|
||||
double tmpsum = 0;
|
||||
int k;
|
||||
for (k=0; k<bw; ++k)
|
||||
tmpsum += 1./(2*k+1) * sin((2*j+1)*(2*k+1)*fudge);
|
||||
tmpsum *= sin((2*j+1)*fudge);
|
||||
tmpsum *= 2./bw;
|
||||
weights[j] = tmpsum ;
|
||||
/* weights[j + 2*bw] = tmpsum * sin((2*j+1)*fudge); */
|
||||
}
|
||||
}
|
||||
|
||||
void psht_make_gauss_geom_info (int nrings, int nphi, int stride,
|
||||
psht_geom_info **geom_info)
|
||||
{
|
||||
const double pi=3.141592653589793238462643383279502884197;
|
||||
|
||||
double *theta=RALLOC(double,nrings);
|
||||
double *weight=RALLOC(double,nrings);
|
||||
int *nph=RALLOC(int,nrings);
|
||||
double *phi0=RALLOC(double,nrings);
|
||||
ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings);
|
||||
int *stride_=RALLOC(int,nrings);
|
||||
int m;
|
||||
|
||||
gauleg(-1,1,theta,weight,nrings);
|
||||
|
||||
for (m=0; m<nrings; ++m)
|
||||
{
|
||||
theta[m] = acos(theta[m]);
|
||||
nph[m]=nphi;
|
||||
phi0[m]=0;
|
||||
ofs[m]=(ptrdiff_t)m*nphi;
|
||||
stride_[m]=stride;
|
||||
weight[m]*=2*pi/nphi;
|
||||
}
|
||||
|
||||
psht_make_geom_info (nrings, nph, ofs, stride_, phi0, theta, weight,
|
||||
geom_info);
|
||||
|
||||
DEALLOC(theta);
|
||||
DEALLOC(weight);
|
||||
DEALLOC(nph);
|
||||
DEALLOC(phi0);
|
||||
DEALLOC(ofs);
|
||||
DEALLOC(stride_);
|
||||
}
|
||||
|
||||
void psht_make_ecp_geom_info (int nrings, int nphi, double phi0, int stride,
|
||||
psht_geom_info **geom_info)
|
||||
{
|
||||
const double pi=3.141592653589793238462643383279502884197;
|
||||
|
||||
double *theta=RALLOC(double,nrings);
|
||||
double *weight=RALLOC(double,nrings);
|
||||
int *nph=RALLOC(int,nrings);
|
||||
double *phi0_=RALLOC(double,nrings);
|
||||
ptrdiff_t *ofs=RALLOC(ptrdiff_t,nrings);
|
||||
int *stride_=RALLOC(int,nrings);
|
||||
|
||||
int m;
|
||||
|
||||
UTIL_ASSERT((nrings&1)==0,
|
||||
"Even number of rings needed for equidistant grid!");
|
||||
makeweights(nrings/2,weight);
|
||||
for (m=0; m<nrings; ++m)
|
||||
{
|
||||
theta[m] = (m+0.5)*pi/nrings;
|
||||
nph[m]=nphi;
|
||||
phi0_[m]=phi0;
|
||||
ofs[m]=(ptrdiff_t)m*nphi;
|
||||
stride_[m]=stride;
|
||||
weight[m]*=2*pi/nphi;
|
||||
}
|
||||
|
||||
psht_make_geom_info (nrings, nph, ofs, stride_, phi0_, theta, weight,
|
||||
geom_info);
|
||||
|
||||
DEALLOC(theta);
|
||||
DEALLOC(weight);
|
||||
DEALLOC(nph);
|
||||
DEALLOC(phi0_);
|
||||
DEALLOC(ofs);
|
||||
DEALLOC(stride_);
|
||||
}
|
72
external/healpix/libpsht/psht_geomhelpers.h
vendored
Normal file
72
external/healpix/libpsht/psht_geomhelpers.h
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_geomhelpers.h
|
||||
* PSHT helper function for the creation of grid geometries
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_PSHT_GEOMHELPERS_H
|
||||
#define PLANCK_PSHT_GEOMHELPERS_H
|
||||
|
||||
#include "psht.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! Creates a geometry information describing a HEALPix map with an
|
||||
Nside parameter \a nside.
|
||||
\ingroup geominfogroup */
|
||||
void psht_make_healpix_geom_info (int nside, int stride,
|
||||
psht_geom_info **geom_info);
|
||||
|
||||
/*! Creates a geometry information describing a HEALPix map with an
|
||||
Nside parameter \a nside. \a weight contains the relative ring
|
||||
weights and must have \a 2*nside entries.
|
||||
\ingroup geominfogroup */
|
||||
void psht_make_weighted_healpix_geom_info (int nside, int stride,
|
||||
const double *weight, psht_geom_info **geom_info);
|
||||
|
||||
/*! Creates a geometry information describing a Gaussian map with \a nrings
|
||||
iso-latitude rings and \a nphi pixels per ring. The azimuth of the first
|
||||
pixel in each ring is 0.
|
||||
\ingroup geominfogroup */
|
||||
void psht_make_gauss_geom_info (int nrings, int nphi, int stride,
|
||||
psht_geom_info **geom_info);
|
||||
|
||||
/*! Creates a geometry information describing an ECP map with \a nrings
|
||||
iso-latitude rings and \a nphi pixels per ring. The azimuth of the first
|
||||
pixel in each ring is \a phi0 (in radians).
|
||||
\ingroup geominfogroup */
|
||||
void psht_make_ecp_geom_info (int nrings, int nphi, double phi0, int stride,
|
||||
psht_geom_info **geom_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1081
external/healpix/libpsht/psht_inc.c
vendored
Normal file
1081
external/healpix/libpsht/psht_inc.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
223
external/healpix/libpsht/psht_perftest.c
vendored
Normal file
223
external/healpix/libpsht/psht_perftest.c
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_perftest.c
|
||||
Performance test of libpsht's map synthesis and analysis algorithms.
|
||||
|
||||
This program creates a list of transform jobs with a user-specified
|
||||
maximum multipole lmax that operate on a HEALPix, ECP or Gaussian grid.
|
||||
Depending on the geometry type, the user has to specify the Nside parameter
|
||||
(for HEALPix) or the number of pixels per ring.
|
||||
The individual job types are also given by the user
|
||||
and can be "alm2map", "map2alm", "alm2map_pol", "map2alm_pol",
|
||||
"alm2map_spin[1-3]", "map2alm_spin[1-3]", and "alm2map_deriv1".
|
||||
Any combination of job types is allowed.
|
||||
|
||||
All requested jobs are executed simultaneously.
|
||||
|
||||
Copyright (C) 2006-2010 Max-Planck-Society
|
||||
\author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "psht.h"
|
||||
#include "psht_geomhelpers.h"
|
||||
#include "psht_almhelpers.h"
|
||||
#include "c_utils.h"
|
||||
#include "walltime_c.h"
|
||||
|
||||
static void get_map(float **map, ptrdiff_t npix)
|
||||
{
|
||||
*map=RALLOC(float,npix);
|
||||
SET_ARRAY(*map,0,npix,1);
|
||||
}
|
||||
static void get_alm(pshts_cmplx **alm, ptrdiff_t nalm)
|
||||
{
|
||||
static const pshts_cmplx pshts_cmplx_one={1,1};
|
||||
*alm=RALLOC(pshts_cmplx,nalm);
|
||||
SET_ARRAY(*alm,0,nalm,pshts_cmplx_one);
|
||||
}
|
||||
|
||||
static void prepare_job (const char *jobname, float **map,
|
||||
pshts_cmplx **alm, ptrdiff_t npix, ptrdiff_t nalm, int ofs_m, int ofs_a,
|
||||
int num_m, int num_a)
|
||||
{
|
||||
int m;
|
||||
printf("adding job: %s\n", jobname);
|
||||
for (m=0; m<num_m; ++m)
|
||||
get_map (&map[ofs_m+m],npix);
|
||||
for (m=0; m<num_a; ++m)
|
||||
get_alm (&alm[ofs_a+m],nalm);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ptrdiff_t npix=0,lmax,nalm;
|
||||
float *map[100];
|
||||
pshts_cmplx *alm[100];
|
||||
psht_alm_info *alms;
|
||||
psht_geom_info *tinfo;
|
||||
pshts_joblist *joblist;
|
||||
int ofs_m, ofs_a, m;
|
||||
double wtimer;
|
||||
|
||||
UTIL_ASSERT (argc>=5,
|
||||
"usage: psht_perftest <healpix|ecp|gauss> <lmax> <nside|nphi> <type>+\n"
|
||||
" where <type> can be 'alm2map', 'map2alm', 'alm2map_pol',\n"
|
||||
" 'map2alm_pol', 'alm2map_spin[1-3]', 'map2alm_spin[1-3]',\n"
|
||||
" or 'alm2map_deriv1'");
|
||||
lmax=atoi(argv[2]);
|
||||
|
||||
if (strcmp(argv[1],"gauss")==0)
|
||||
{
|
||||
int nrings=lmax+1;
|
||||
int ppring=atoi(argv[3]);
|
||||
npix=(ptrdiff_t)nrings*ppring;
|
||||
printf("\nTesting Gaussian grid (%d rings, %d pixels/ring, %ld pixels)\n",
|
||||
nrings,ppring,(long)npix);
|
||||
psht_make_gauss_geom_info (nrings, ppring, 1, &tinfo);
|
||||
}
|
||||
else if (strcmp(argv[1],"ecp")==0)
|
||||
{
|
||||
int nrings=2*lmax+2;
|
||||
int ppring=atoi(argv[3]);
|
||||
npix=(ptrdiff_t)nrings*ppring;
|
||||
printf("\nTesting ECP grid (%d rings, %d pixels/ring, %ld pixels)\n",
|
||||
nrings,ppring,(long)npix);
|
||||
psht_make_ecp_geom_info (nrings, ppring, 0., 1, &tinfo);
|
||||
}
|
||||
else if (strcmp(argv[1],"healpix")==0)
|
||||
{
|
||||
int nside=atoi(argv[3]);
|
||||
if (nside<1) nside=1;
|
||||
npix=12*(ptrdiff_t)nside*nside;
|
||||
printf("\nTesting Healpix grid (nside=%d, %ld pixels)\n",
|
||||
nside,(long)npix);
|
||||
psht_make_healpix_geom_info (nside, 1, &tinfo);
|
||||
}
|
||||
else
|
||||
UTIL_FAIL("unknown command");
|
||||
|
||||
psht_make_triangular_alm_info(lmax,lmax,1,&alms);
|
||||
nalm = ((ptrdiff_t)(lmax+1)*(lmax+2))/2;
|
||||
pshts_make_joblist (&joblist);
|
||||
|
||||
ofs_m=ofs_a=0;
|
||||
for (m=4; m<argc; ++m)
|
||||
{
|
||||
if (strcmp(argv[m],"alm2map")==0)
|
||||
{
|
||||
prepare_job ("alm2map",map,alm,npix,nalm,ofs_m,ofs_a,1,1);
|
||||
pshts_add_job_alm2map(joblist,alm[ofs_a],map[ofs_m],0);
|
||||
++ofs_m; ++ofs_a;
|
||||
}
|
||||
else if (strcmp(argv[m],"map2alm")==0)
|
||||
{
|
||||
prepare_job ("map2alm",map,alm,npix,nalm,ofs_m,ofs_a,1,1);
|
||||
pshts_add_job_map2alm(joblist,map[ofs_m],alm[ofs_a],0);
|
||||
++ofs_m; ++ofs_a;
|
||||
}
|
||||
else if (strcmp(argv[m],"alm2map_pol")==0)
|
||||
{
|
||||
prepare_job ("alm2map_pol",map,alm,npix,nalm,ofs_m,ofs_a,3,3);
|
||||
pshts_add_job_alm2map_pol(joblist,alm[ofs_a],alm[ofs_a+1],alm[ofs_a+2],
|
||||
map[ofs_m],map[ofs_m+1],map[ofs_m+2],0);
|
||||
ofs_m+=3; ofs_a+=3;
|
||||
}
|
||||
else if (strcmp(argv[m],"map2alm_pol")==0)
|
||||
{
|
||||
prepare_job ("map2alm_pol",map,alm,npix,nalm,ofs_m,ofs_a,3,3);
|
||||
pshts_add_job_map2alm_pol(joblist,map[ofs_m],map[ofs_m+1],map[ofs_m+2],
|
||||
alm[ofs_a],alm[ofs_a+1],alm[ofs_a+2],0);
|
||||
ofs_m+=3; ofs_a+=3;
|
||||
}
|
||||
else if (strcmp(argv[m],"alm2map_spin1")==0)
|
||||
{
|
||||
prepare_job ("alm2map_spin1",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_alm2map_spin(joblist,alm[ofs_a],alm[ofs_a+1],
|
||||
map[ofs_m],map[ofs_m+1],1,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"map2alm_spin1")==0)
|
||||
{
|
||||
prepare_job ("map2alm_spin1",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_map2alm_spin(joblist,map[ofs_m],map[ofs_m+1],
|
||||
alm[ofs_a],alm[ofs_a+1],1,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"alm2map_spin2")==0)
|
||||
{
|
||||
prepare_job ("alm2map_spin2",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_alm2map_spin(joblist,alm[ofs_a],alm[ofs_a+1],
|
||||
map[ofs_m],map[ofs_m+1],2,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"map2alm_spin2")==0)
|
||||
{
|
||||
prepare_job ("map2alm_spin2",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_map2alm_spin(joblist,map[ofs_m],map[ofs_m+1],
|
||||
alm[ofs_a],alm[ofs_a+1],2,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"alm2map_spin3")==0)
|
||||
{
|
||||
prepare_job ("alm2map_spin3",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_map2alm_spin(joblist,map[ofs_m],map[ofs_m+1],
|
||||
alm[ofs_a],alm[ofs_a+1],3,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"map2alm_spin3")==0)
|
||||
{
|
||||
prepare_job ("map2alm_spin3",map,alm,npix,nalm,ofs_m,ofs_a,2,2);
|
||||
pshts_add_job_map2alm_spin(joblist,map[ofs_m],map[ofs_m+1],
|
||||
alm[ofs_a],alm[ofs_a+1],3,0);
|
||||
ofs_m+=2; ofs_a+=2;
|
||||
}
|
||||
else if (strcmp(argv[m],"alm2map_deriv1")==0)
|
||||
{
|
||||
prepare_job ("alm2map_deriv1",map,alm,npix,nalm,ofs_m,ofs_a,2,1);
|
||||
pshts_add_job_alm2map_deriv1(joblist,alm[ofs_a], map[ofs_m],
|
||||
map[ofs_m+1],0);
|
||||
ofs_m+=2; ofs_a+=1;
|
||||
}
|
||||
else
|
||||
UTIL_FAIL("unknown transform type");
|
||||
}
|
||||
|
||||
wtimer=wallTime();
|
||||
pshts_execute_jobs (joblist, tinfo, alms);
|
||||
printf("wall time for transform: %fs\n",wallTime()-wtimer);
|
||||
|
||||
pshts_destroy_joblist(joblist);
|
||||
psht_destroy_geom_info(tinfo);
|
||||
psht_destroy_alm_info(alms);
|
||||
for (m=0; m<ofs_m; ++m)
|
||||
DEALLOC(map[m]);
|
||||
for (m=0; m<ofs_a; ++m)
|
||||
DEALLOC(alm[m]);
|
||||
|
||||
return 0;
|
||||
}
|
260
external/healpix/libpsht/psht_test.c
vendored
Normal file
260
external/healpix/libpsht/psht_test.c
vendored
Normal file
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file psht_test.c
|
||||
Accuracy test for libpsht's map analysis.
|
||||
|
||||
This program first generates a_lm coefficients up to
|
||||
a user-specified lmax (with mmax=lmax); where applicable, the
|
||||
real and imaginary parts of the coefficients are uniform
|
||||
random numbers of the interval [-1;1[.
|
||||
Afterwards, the random a_lm are converted to a map.
|
||||
This map is analyzed (optionally using an iterative scheme
|
||||
with a user-supplied number of steps).
|
||||
After every iteration, the code then outputs the RMS of the residual a_lm
|
||||
(i.e. the difference between the current and original a_lm), divided by
|
||||
the RMS of the original a_lm, as well as the maximum absolute change of any
|
||||
real or imaginary part between the current and original a_lm.
|
||||
|
||||
This operation can be performed for several different pixelisations:
|
||||
- a Gaussian with the minimal number of rings for exact analysis
|
||||
and a user-defined ring resolution
|
||||
- an ECP grid with the minimal number of rings for exact analysis
|
||||
and a user-defined ring resolution
|
||||
- a Healpix grid with a user-defined Nside parameter.
|
||||
|
||||
The user can specify the spin of the desired transform.
|
||||
|
||||
Copyright (C) 2006-2010 Max-Planck-Society
|
||||
\author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "psht.h"
|
||||
#include "psht_geomhelpers.h"
|
||||
#include "psht_almhelpers.h"
|
||||
#include "c_utils.h"
|
||||
#include "walltime_c.h"
|
||||
|
||||
static double drand (double min, double max)
|
||||
{
|
||||
return min + (max-min)*rand()/(RAND_MAX+1.0);
|
||||
}
|
||||
|
||||
static void random_alm (pshtd_cmplx *alm, psht_alm_info *helper, int spin)
|
||||
{
|
||||
int l,m;
|
||||
for (m=0;m<=helper->mmax; ++m)
|
||||
for (l=m;l<=helper->lmax; ++l)
|
||||
{
|
||||
if ((l<spin)&&(m<spin))
|
||||
alm[psht_alm_index(helper,l,m)] = pshtd_cmplx_null;
|
||||
else
|
||||
{
|
||||
alm[psht_alm_index(helper,l,m)].re = drand(-1,1);
|
||||
alm[psht_alm_index(helper,l,m)].im = (m==0) ? 0 : drand(-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void measure_errors (pshtd_cmplx **alm, pshtd_cmplx **alm2,
|
||||
ptrdiff_t nalms, int ncomp)
|
||||
{
|
||||
int i;
|
||||
ptrdiff_t m;
|
||||
|
||||
for (i=0; i<ncomp; ++i)
|
||||
{
|
||||
double sum=0, sum2=0, maxdiff=0;
|
||||
for (m=0; m<nalms; ++m)
|
||||
{
|
||||
double x=alm[i][m].re-alm2[i][m].re, y=alm[i][m].im-alm2[i][m].im;
|
||||
sum+=x*x+y*y;
|
||||
sum2+=alm[i][m].re*alm[i][m].re+alm[i][m].im*alm[i][m].im;
|
||||
if (fabs(x)>maxdiff) maxdiff=fabs(x);
|
||||
if (fabs(y)>maxdiff) maxdiff=fabs(y);
|
||||
}
|
||||
sum=sqrt(sum/nalms);
|
||||
sum2=sqrt(sum2/nalms);
|
||||
printf("component %i: rms %e, maxerr %e\n",i, sum/sum2, maxdiff);
|
||||
}
|
||||
}
|
||||
|
||||
static void map2alm_iter (psht_geom_info *tinfo, double **map,
|
||||
pshtd_cmplx **alm_orig, pshtd_cmplx **alm, int lmax, int mmax,
|
||||
ptrdiff_t npix, ptrdiff_t nalms, int spin, int niter)
|
||||
{
|
||||
psht_alm_info *alms;
|
||||
pshtd_joblist *joblist;
|
||||
int ncomp = (spin==0) ? 1 : 2;
|
||||
int iter,i;
|
||||
ptrdiff_t m;
|
||||
double timer;
|
||||
|
||||
psht_make_triangular_alm_info(lmax,mmax,1,&alms);
|
||||
pshtd_make_joblist (&joblist);
|
||||
|
||||
if (spin==0)
|
||||
pshtd_add_job_map2alm(joblist,map[0],alm[0],0);
|
||||
else
|
||||
pshtd_add_job_map2alm_spin(joblist,map[0],map[1],alm[0],alm[1],spin,0);
|
||||
timer=wallTime();
|
||||
pshtd_execute_jobs (joblist, tinfo, alms);
|
||||
printf("wall time for map2alm: %fs\n",wallTime()-timer);
|
||||
pshtd_clear_joblist (joblist);
|
||||
measure_errors(alm_orig,alm,nalms,ncomp);
|
||||
|
||||
for (iter=0; iter<niter; ++iter)
|
||||
{
|
||||
double **map2;
|
||||
ALLOC2D(map2,double,ncomp,npix);
|
||||
printf ("\niteration %i:\n", iter+1);
|
||||
if (spin==0)
|
||||
pshtd_add_job_alm2map(joblist,alm[0],map2[0],0);
|
||||
else
|
||||
pshtd_add_job_alm2map_spin(joblist,alm[0],alm[1],map2[0],map2[1],spin,0);
|
||||
timer=wallTime();
|
||||
pshtd_execute_jobs (joblist, tinfo, alms);
|
||||
printf("wall time for alm2map: %fs\n",wallTime()-timer);
|
||||
pshtd_clear_joblist (joblist);
|
||||
for (i=0; i<ncomp; ++i)
|
||||
for (m=0; m<npix; ++m)
|
||||
map2[i][m] = map[i][m]-map2[i][m];
|
||||
|
||||
if (spin==0)
|
||||
pshtd_add_job_map2alm(joblist,map2[0],alm[0],1);
|
||||
else
|
||||
pshtd_add_job_map2alm_spin(joblist,map2[0],map2[1],alm[0],alm[1],spin,1);
|
||||
timer=wallTime();
|
||||
pshtd_execute_jobs (joblist, tinfo, alms);
|
||||
printf("wall time for map2alm: %fs\n",wallTime()-timer);
|
||||
pshtd_clear_joblist (joblist);
|
||||
DEALLOC2D(map2);
|
||||
measure_errors(alm_orig,alm,nalms,ncomp);
|
||||
}
|
||||
|
||||
psht_destroy_alm_info(alms);
|
||||
pshtd_destroy_joblist(joblist);
|
||||
}
|
||||
|
||||
static void check_accuracy (psht_geom_info *tinfo, ptrdiff_t lmax,
|
||||
ptrdiff_t mmax, ptrdiff_t npix, int spin, int niter)
|
||||
{
|
||||
psht_alm_info *alms;
|
||||
pshtd_joblist *joblist;
|
||||
double **map;
|
||||
pshtd_cmplx **alm, **alm2;
|
||||
ptrdiff_t nalms = ((mmax+1)*(mmax+2))/2 + (mmax+1)*(lmax-mmax);
|
||||
int ncomp = (spin==0) ? 1 : 2;
|
||||
double timer;
|
||||
|
||||
ALLOC2D(map,double,ncomp,npix);
|
||||
|
||||
psht_make_triangular_alm_info(lmax,mmax,1,&alms);
|
||||
pshtd_make_joblist (&joblist);
|
||||
|
||||
srand(4);
|
||||
ALLOC2D(alm,pshtd_cmplx,ncomp,nalms);
|
||||
random_alm(alm[0],alms,spin);
|
||||
if (spin>0)
|
||||
random_alm(alm[1],alms,spin);
|
||||
|
||||
ALLOC2D(alm2,pshtd_cmplx,ncomp,nalms);
|
||||
|
||||
printf ("\niteration 0:\n");
|
||||
if (spin==0)
|
||||
pshtd_add_job_alm2map(joblist,alm[0],map[0],0);
|
||||
else
|
||||
pshtd_add_job_alm2map_spin(joblist,alm[0],alm[1],map[0],map[1],spin,0);
|
||||
timer=wallTime();
|
||||
pshtd_execute_jobs (joblist, tinfo, alms);
|
||||
printf("wall time for alm2map: %fs\n",wallTime()-timer);
|
||||
pshtd_clear_joblist (joblist);
|
||||
|
||||
map2alm_iter(tinfo, map, alm, alm2, lmax, mmax, npix, nalms, spin, niter);
|
||||
|
||||
DEALLOC2D(map);
|
||||
DEALLOC2D(alm);
|
||||
DEALLOC2D(alm2);
|
||||
|
||||
psht_destroy_alm_info(alms);
|
||||
pshtd_destroy_joblist(joblist);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int lmax;
|
||||
int spin;
|
||||
int niter;
|
||||
psht_geom_info *tinfo;
|
||||
|
||||
UTIL_ASSERT (argc==6,
|
||||
"usage: psht_test <healpix|ecp|gauss> <lmax> <nside|nphi> <niter> <spin>");
|
||||
lmax=atoi(argv[2]);
|
||||
niter=atoi(argv[4]);
|
||||
spin=atoi(argv[5]);
|
||||
|
||||
printf("Testing map analysis accuracy.\n");
|
||||
printf("lmax=%d, %d iterations, spin=%d\n", lmax, niter, spin);
|
||||
|
||||
if (strcmp(argv[1],"gauss")==0)
|
||||
{
|
||||
int nrings=lmax+1;
|
||||
int ppring=atoi(argv[3]);
|
||||
ptrdiff_t npix=(ptrdiff_t)nrings*ppring;
|
||||
printf("\nTesting Gaussian grid (%d rings, %d pixels/ring, %ld pixels)\n",
|
||||
nrings,ppring,(long)npix);
|
||||
psht_make_gauss_geom_info (nrings, ppring, 1, &tinfo);
|
||||
check_accuracy(tinfo,lmax,lmax,npix,spin,niter);
|
||||
psht_destroy_geom_info(tinfo);
|
||||
}
|
||||
else if (strcmp(argv[1],"ecp")==0)
|
||||
{
|
||||
int nrings=2*lmax+2;
|
||||
int ppring=atoi(argv[3]);
|
||||
ptrdiff_t npix=(ptrdiff_t)nrings*ppring;
|
||||
printf("\nTesting ECP grid (%d rings, %d pixels/ring, %ld pixels)\n",
|
||||
nrings,ppring,(long)npix);
|
||||
psht_make_ecp_geom_info (nrings, ppring, 0., 1, &tinfo);
|
||||
check_accuracy(tinfo,lmax,lmax,npix,spin,niter);
|
||||
psht_destroy_geom_info(tinfo);
|
||||
}
|
||||
else if (strcmp(argv[1],"healpix")==0)
|
||||
{
|
||||
int nside=atoi(argv[3]);
|
||||
ptrdiff_t npix;
|
||||
if (nside<1) nside=1;
|
||||
npix=12*(ptrdiff_t)nside*nside;
|
||||
printf("\nTesting Healpix grid (nside=%d, %ld pixels)\n",
|
||||
nside,(long)npix);
|
||||
psht_make_healpix_geom_info (nside, 1, &tinfo);
|
||||
check_accuracy(tinfo,lmax,lmax,npix,spin,niter);
|
||||
psht_destroy_geom_info(tinfo);
|
||||
}
|
||||
else
|
||||
UTIL_FAIL("unknown grid geometry");
|
||||
|
||||
return 0;
|
||||
}
|
1151
external/healpix/libpsht/ylmgen_c.c
vendored
Normal file
1151
external/healpix/libpsht/ylmgen_c.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
141
external/healpix/libpsht/ylmgen_c.h
vendored
Normal file
141
external/healpix/libpsht/ylmgen_c.h
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* This file is part of libpsht.
|
||||
*
|
||||
* libpsht is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libpsht is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libpsht; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libpsht is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file ylmgen_c.h
|
||||
* Code for efficient calculation of Y_lm(phi=0,theta)
|
||||
*
|
||||
* Copyright (C) 2005-2011 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_YLMGEN_C_H
|
||||
#define PLANCK_YLMGEN_C_H
|
||||
|
||||
#include "sse_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef double ylmgen_dbl2[2];
|
||||
typedef double ylmgen_dbl3[3];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double cth_crit;
|
||||
int mdist_crit;
|
||||
/* members depending on m and m' */
|
||||
int s, m, mlo, mhi, cosPow, sinPow;
|
||||
long double prefactor;
|
||||
ylmgen_dbl3 *fx;
|
||||
int preMinus_p, preMinus_m;
|
||||
} sylmgen_d;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double fsmall, fbig, eps, cth_crit;
|
||||
int lmax, mmax, m_cur, ith, nth, m_crit, spinrec;
|
||||
/*! The index of the first non-negligible Y_lm value. */
|
||||
int *firstl;
|
||||
double *cf, *mfac, *t1fac, *t2fac, *th, *cth, *sth, *logsth;
|
||||
ylmgen_dbl2 *recfac;
|
||||
double *lamfact;
|
||||
/*! Points to an array of size [0..lmax] containing the Y_lm values. */
|
||||
double *ylm;
|
||||
/*! Points to an array of size [0..lmax] containing the lambda_w
|
||||
and lambda_x values for spin>0 transforms. */
|
||||
ylmgen_dbl2 **lambda_wx;
|
||||
long double *logsum, *lc05, *ls05;
|
||||
double *flm1, *flm2, *xl;
|
||||
|
||||
sylmgen_d **sylm;
|
||||
|
||||
int *lwx_uptodate;
|
||||
int ylm_uptodate;
|
||||
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
int ith1, ith2;
|
||||
/*! Points to an array of size [0..lmax] containing the Y_lm values. */
|
||||
v2df *ylm_sse2;
|
||||
/*! Points to an array of size [0..lmax] containing the lambda_w
|
||||
and lambda_x values for spin>0 transforms. */
|
||||
v2df2 **lambda_wx_sse2;
|
||||
int *lwx_uptodate_sse2;
|
||||
int ylm_uptodate_sse2;
|
||||
#endif
|
||||
|
||||
int recfac_uptodate, lamfact_uptodate;
|
||||
} Ylmgen_C;
|
||||
|
||||
/*! Creates a generator which will calculate Y_lm(theta,phi=0)
|
||||
up to \a l=l_max and \a m=m_max. It may regard Y_lm whose absolute
|
||||
magnitude is smaller than \a epsilon as zero. If \a spinrec is nonzero,
|
||||
the spin-1 and spin-2 Y_lm will be calculated by recursion from the spin-0
|
||||
ones, otherwise Wigner d matrix elements will be used. */
|
||||
void Ylmgen_init (Ylmgen_C *gen, int l_max, int m_max, int spinrec,
|
||||
double epsilon);
|
||||
|
||||
/*! Passes am array \a theta of \a nth colatitudes that will be used in
|
||||
subsequent calls. The individual angles will be referenced by their
|
||||
index in the array, starting with 0.
|
||||
\note The array can be freed or reused after the call. */
|
||||
void Ylmgen_set_theta (Ylmgen_C *gen, const double *theta, int nth);
|
||||
|
||||
/*! Deallocates a generator previously initialised by Ylmgen_init(). */
|
||||
void Ylmgen_destroy (Ylmgen_C *gen);
|
||||
|
||||
/*! Prepares the object for the calculation at \a theta and \a m. */
|
||||
void Ylmgen_prepare (Ylmgen_C *gen, int ith, int m);
|
||||
|
||||
/*! Recalculates (if necessary) the Y_lm values. */
|
||||
void Ylmgen_recalc_Ylm (Ylmgen_C *gen);
|
||||
/*! Recalculates (if necessary) the lambda_w and lambda_x values for spin >0
|
||||
transforms. */
|
||||
void Ylmgen_recalc_lambda_wx (Ylmgen_C *gen, int spin);
|
||||
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
/*! Prepares the object for the calculation at \a theta, \a theta2 and \a m. */
|
||||
void Ylmgen_prepare_sse2 (Ylmgen_C *gen, int ith1, int ith2, int m);
|
||||
|
||||
/*! Recalculates (if necessary) the Y_lm values. */
|
||||
void Ylmgen_recalc_Ylm_sse2 (Ylmgen_C *gen);
|
||||
/*! Recalculates (if necessary) the lambda_w and lambda_x values for spin >0
|
||||
transforms. */
|
||||
void Ylmgen_recalc_lambda_wx_sse2 (Ylmgen_C *gen, int spin);
|
||||
#endif
|
||||
|
||||
/*! Returns a pointer to an array with lmax+1 entries containing normalisation
|
||||
factors that must be applied to Y_lm values computed for \a spin with the
|
||||
given \a spinrec flag. The array must be deallocated (using free()) by the
|
||||
user. */
|
||||
double *Ylmgen_get_norm (int lmax, int spin, int spinrec);
|
||||
|
||||
/*! Returns the maximum spin quantum number supported by the Ylmgen code. */
|
||||
int Ylmgen_maxspin(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue