Commit aaea79a7 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

introduce abstract alm_info interface

parent ce3cb52f
...@@ -197,29 +197,29 @@ struct ringhelper ...@@ -197,29 +197,29 @@ struct ringhelper
} }
}; };
sharp_alm_info::sharp_alm_info (size_t lmax_, size_t nm_, ptrdiff_t stride_, sharp_standard_alm_info::sharp_standard_alm_info (size_t lmax__, size_t nm_, ptrdiff_t stride_,
const size_t *mval_, const ptrdiff_t *mstart) const size_t *mval__, const ptrdiff_t *mstart)
: lmax(lmax_), nm(nm_), mval(nm_), mvstart(nm), stride(stride_) : lmax_(lmax__), mval_(nm_), mvstart(nm_), stride(stride_)
{ {
for (size_t mi=0; mi<nm; ++mi) for (size_t mi=0; mi<nm_; ++mi)
{ {
mval[mi] = mval_[mi]; mval_[mi] = mval__[mi];
mvstart[mi] = mstart[mi]; mvstart[mi] = mstart[mi];
} }
} }
sharp_alm_info::sharp_alm_info (size_t lmax_, size_t mmax, ptrdiff_t stride_, sharp_standard_alm_info::sharp_standard_alm_info (size_t lmax__, size_t mmax_, ptrdiff_t stride_,
const ptrdiff_t *mstart) const ptrdiff_t *mstart)
: lmax(lmax_), nm(mmax+1), mval(mmax+1), mvstart(mmax+1), stride(stride_) : lmax_(lmax__), mval_(mmax_+1), mvstart(mmax_+1), stride(stride_)
{ {
for (size_t i=0; i<=mmax; ++i) for (size_t i=0; i<=mmax_; ++i)
{ {
mval[i]=i; mval_[i]=i;
mvstart[i] = mstart[i]; mvstart[i] = mstart[i];
} }
} }
ptrdiff_t sharp_alm_info::index (int l, int mi) ptrdiff_t sharp_standard_alm_info::index (int l, int mi)
{ {
return mvstart[mi]+stride*l; return mvstart[mi]+stride*l;
} }
...@@ -278,18 +278,18 @@ sharp_standard_geom_info::sharp_standard_geom_info(size_t nrings, const size_t * ...@@ -278,18 +278,18 @@ sharp_standard_geom_info::sharp_standard_geom_info(size_t nrings, const size_t *
/* This currently requires all m values from 0 to nm-1 to be present. /* This currently requires all m values from 0 to nm-1 to be present.
It might be worthwhile to relax this criterion such that holes in the m It might be worthwhile to relax this criterion such that holes in the m
distribution are permissible. */ distribution are permissible. */
static size_t sharp_get_mmax (const vector<size_t> &mval) size_t sharp_standard_alm_info::mmax() const
{ {
//FIXME: if gaps are allowed, we have to search the maximum m in the array //FIXME: if gaps are allowed, we have to search the maximum m in the array
auto nm=mval.size(); auto nm_=mval_.size();
vector<bool> mcheck(nm,false); vector<bool> mcheck(nm_,false);
for (auto m_cur : mval) for (auto m_cur : mval_)
{ {
MR_assert(m_cur<nm, "not all m values are present"); MR_assert(m_cur<nm_, "not all m values are present");
MR_assert(mcheck[m_cur]==false, "duplicate m value"); MR_assert(mcheck[m_cur]==false, "duplicate m value");
mcheck[m_cur]=true; mcheck[m_cur]=true;
} }
return nm-1; return nm_-1;
} }
MRUTIL_NOINLINE void sharp_standard_geom_info::clear_map (double *map) const MRUTIL_NOINLINE void sharp_standard_geom_info::clear_map (double *map) const
...@@ -315,21 +315,17 @@ MRUTIL_NOINLINE void sharp_standard_geom_info::clear_map (float *map) const ...@@ -315,21 +315,17 @@ MRUTIL_NOINLINE void sharp_standard_geom_info::clear_map (float *map) const
} }
} }
MRUTIL_NOINLINE static void clear_alm (const sharp_alm_info *ainfo, void *alm, void sharp_standard_alm_info::clear_alm (dcmplx *alm) const
int flags)
{ {
for (size_t mi=0;mi<ainfo->nm;++mi) for (size_t mi=0;mi<mval_.size();++mi)
{ for (size_t l=mval_[mi];l<=lmax_;++l)
auto m=ainfo->mval[mi]; reinterpret_cast<dcmplx *>(alm)[mvstart[mi]+l*stride]=0.;
ptrdiff_t mvstart = ainfo->mvstart[mi]; }
ptrdiff_t stride = ainfo->stride; void sharp_standard_alm_info::clear_alm (fcmplx *alm) const
if (flags&SHARP_DP) {
for (size_t l=m;l<=ainfo->lmax;++l) for (size_t mi=0;mi<mval_.size();++mi)
reinterpret_cast<dcmplx *>(alm)[mvstart+l*stride]=0.; for (size_t l=mval_[mi];l<=lmax_;++l)
else reinterpret_cast<fcmplx *>(alm)[mvstart[mi]+l*stride]=0.;
for (size_t l=m;l<=ainfo->lmax;++l)
reinterpret_cast<fcmplx *>(alm)[mvstart+l*stride]=0.;
}
} }
MRUTIL_NOINLINE void sharp_job::init_output() MRUTIL_NOINLINE void sharp_job::init_output()
...@@ -337,7 +333,8 @@ MRUTIL_NOINLINE void sharp_job::init_output() ...@@ -337,7 +333,8 @@ MRUTIL_NOINLINE void sharp_job::init_output()
if (flags&SHARP_ADD) return; if (flags&SHARP_ADD) return;
if (type == SHARP_MAP2ALM) if (type == SHARP_MAP2ALM)
for (size_t i=0; i<nalm; ++i) for (size_t i=0; i<nalm; ++i)
clear_alm (ainfo,alm[i],flags); (flags&SHARP_DP) ? ainfo->clear_alm (reinterpret_cast<dcmplx *>(alm[i]))
: ainfo->clear_alm (reinterpret_cast<fcmplx *>(alm[i]));
else else
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
(flags&SHARP_DP) ? ginfo->clear_map(reinterpret_cast<double *>(map[i])) (flags&SHARP_DP) ? ginfo->clear_map(reinterpret_cast<double *>(map[i]))
...@@ -368,99 +365,78 @@ void sharp_job::alloc_almtmp (size_t lmax, vector<dcmplx> &data) ...@@ -368,99 +365,78 @@ void sharp_job::alloc_almtmp (size_t lmax, vector<dcmplx> &data)
almtmp=data.data(); almtmp=data.data();
} }
void sharp_standard_alm_info::get_alm(size_t mi, const dcmplx *alm, dcmplx *almtmp, size_t nalm) const
{
for (auto l=mval_[mi]; l<=lmax_; ++l)
almtmp[nalm*l] = alm[mvstart[mi]+l*stride];
}
void sharp_standard_alm_info::get_alm(size_t mi, const fcmplx *alm, dcmplx *almtmp, size_t nalm) const
{
for (auto l=mval_[mi]; l<=lmax_; ++l)
almtmp[nalm*l] = alm[mvstart[mi]+l*stride];
}
void sharp_standard_alm_info::add_alm(size_t mi, const dcmplx *almtmp, dcmplx *alm, size_t nalm) const
{
for (auto l=mval_[mi]; l<=lmax_; ++l)
alm[mvstart[mi]+l*stride] += almtmp[nalm*l];
}
void sharp_standard_alm_info::add_alm(size_t mi, const dcmplx *almtmp, fcmplx *alm, size_t nalm) const
{
for (auto l=mval_[mi]; l<=lmax_; ++l)
alm[mvstart[mi]+l*stride] += fcmplx(almtmp[nalm*l]);
}
MRUTIL_NOINLINE void sharp_job::alm2almtmp (size_t lmax, size_t mi) MRUTIL_NOINLINE void sharp_job::alm2almtmp (size_t lmax, size_t mi)
{ {
if (type!=SHARP_MAP2ALM) if (type!=SHARP_MAP2ALM)
{ {
auto ofs=ainfo->mvstart[mi]; auto m=ainfo->mval(mi);
auto stride=ainfo->stride;
auto m=ainfo->mval[mi];
auto lmin=(m<spin) ? spin : m; auto lmin=(m<spin) ? spin : m;
if (spin==0) if (flags&SHARP_DP)
{ {
if (flags&SHARP_DP) for (size_t i=0; i<nalm; ++i)
{ ainfo->get_alm(mi, reinterpret_cast<dcmplx **>(alm)[i],almtmp+i,nalm);
for (auto l=m; l<lmin; ++l) for (auto l=m; l<lmin; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = 0;
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = reinterpret_cast<dcmplx **>(alm)[i][ofs+l*stride];
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0;
}
else
{
for (auto l=m; l<lmin; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = 0;
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = reinterpret_cast<fcmplx **>(alm)[i][ofs+l*stride];
for (size_t i=0; i<nalm; ++i) for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0; almtmp[nalm*l+i] = 0;
} for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0;
} }
else else
{ {
if (flags&SHARP_DP) for (size_t i=0; i<nalm; ++i)
{ ainfo->get_alm(mi, reinterpret_cast<fcmplx **>(alm)[i],almtmp+i,nalm);
for (auto l=m; l<lmin; ++l) for (auto l=m; l<lmin; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = 0;
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = reinterpret_cast<dcmplx **>(alm)[i][ofs+l*stride]*norm_l[l];
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0;
}
else
{
for (auto l=m; l<lmin; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = 0;
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] = dcmplx(reinterpret_cast<fcmplx **>(alm)[i][ofs+l*stride])*norm_l[l];
for (size_t i=0; i<nalm; ++i) for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0; almtmp[nalm*l+i] = 0;
} for (size_t i=0; i<nalm; ++i)
almtmp[nalm*(lmax+1)+i] = 0;
} }
if (spin>0)
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
almtmp[nalm*l+i] *= norm_l[l];
} }
else else
for (size_t i=nalm*ainfo->mval[mi]; i<nalm*(lmax+2); ++i) for (size_t i=nalm*ainfo->mval(mi); i<nalm*(lmax+2); ++i)
almtmp[i]=0; almtmp[i]=0;
} }
MRUTIL_NOINLINE void sharp_job::almtmp2alm (size_t lmax, size_t mi) MRUTIL_NOINLINE void sharp_job::almtmp2alm (size_t lmax, size_t mi)
{ {
if (type != SHARP_MAP2ALM) return; if (type != SHARP_MAP2ALM) return;
auto ofs=ainfo->mvstart[mi]; auto m=ainfo->mval(mi);
auto stride=ainfo->stride;
auto m=ainfo->mval[mi];
auto lmin=(m<spin) ? spin : m; auto lmin=(m<spin) ? spin : m;
if (spin==0) if (spin>0)
{ for (auto l=lmin; l<=lmax; ++l)
if (flags&SHARP_DP) for (size_t i=0; i<nalm; ++i)
for (auto l=lmin; l<=lmax; ++l) almtmp[nalm*l+i] *= norm_l[l];
for (size_t i=0; i<nalm; ++i) if (flags&SHARP_DP)
((dcmplx **)alm)[i][ofs+l*stride] += almtmp[nalm*l+i]; for (size_t i=0; i<nalm; ++i)
else ainfo->add_alm(mi, almtmp+i, reinterpret_cast<dcmplx **>(alm)[i],nalm);
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
((fcmplx **)alm)[i][ofs+l*stride] += fcmplx(almtmp[nalm*l+i]);
}
else else
{ for (size_t i=0; i<nalm; ++i)
if (flags&SHARP_DP) ainfo->add_alm(mi, almtmp+i, reinterpret_cast<fcmplx **>(alm)[i],nalm);
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
((dcmplx **)alm)[i][ofs+l*stride] += almtmp[nalm*l+i]*norm_l[l];
else
for (auto l=lmin; l<=lmax; ++l)
for (size_t i=0; i<nalm; ++i)
((fcmplx **)alm)[i][ofs+l*stride] += fcmplx(almtmp[nalm*l+i]*norm_l[l]);
}
} }
//virtual //virtual
...@@ -496,26 +472,26 @@ void sharp_standard_geom_info::get_ring(bool weighted, size_t iring, const float ...@@ -496,26 +472,26 @@ void sharp_standard_geom_info::get_ring(bool weighted, size_t iring, const float
ringtmp[m] = p1[m*stride]*wgt; ringtmp[m] = p1[m*stride]*wgt;
} }
MRUTIL_NOINLINE void sharp_job::ringtmp2ring (const sharp_geom_info &ginfo, size_t iring, MRUTIL_NOINLINE void sharp_job::ringtmp2ring (size_t iring,
const vector<double> &ringtmp, ptrdiff_t rstride) const vector<double> &ringtmp, ptrdiff_t rstride)
{ {
if (flags & SHARP_DP) if (flags & SHARP_DP)
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
ginfo.add_ring(flags&SHARP_USE_WEIGHTS, iring, &ringtmp[i*rstride+1], ((double **)map)[i]); ginfo->add_ring(flags&SHARP_USE_WEIGHTS, iring, &ringtmp[i*rstride+1], ((double **)map)[i]);
else else
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
ginfo.add_ring(flags&SHARP_USE_WEIGHTS, iring, &ringtmp[i*rstride+1], ((float **)map)[i]); ginfo->add_ring(flags&SHARP_USE_WEIGHTS, iring, &ringtmp[i*rstride+1], ((float **)map)[i]);
} }
MRUTIL_NOINLINE void sharp_job::ring2ringtmp (const sharp_geom_info &ginfo, size_t iring, MRUTIL_NOINLINE void sharp_job::ring2ringtmp (size_t iring,
vector<double> &ringtmp, ptrdiff_t rstride) vector<double> &ringtmp, ptrdiff_t rstride)
{ {
if (flags & SHARP_DP) if (flags & SHARP_DP)
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
ginfo.get_ring(flags&SHARP_USE_WEIGHTS, iring, ((double **)map)[i], &ringtmp[i*rstride+1]); ginfo->get_ring(flags&SHARP_USE_WEIGHTS, iring, ((double **)map)[i], &ringtmp[i*rstride+1]);
else else
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
ginfo.get_ring(flags&SHARP_USE_WEIGHTS, iring, ((float **)map)[i], &ringtmp[i*rstride+1]); ginfo->get_ring(flags&SHARP_USE_WEIGHTS, iring, ((float **)map)[i], &ringtmp[i*rstride+1]);
} }
//FIXME: set phase to zero if not SHARP_MAP2ALM? //FIXME: set phase to zero if not SHARP_MAP2ALM?
...@@ -532,13 +508,13 @@ MRUTIL_NOINLINE void sharp_job::map2phase (size_t mmax, size_t llim, size_t ulim ...@@ -532,13 +508,13 @@ MRUTIL_NOINLINE void sharp_job::map2phase (size_t mmax, size_t llim, size_t ulim
while (auto rng=sched.getNext()) for(auto ith=rng.lo+llim; ith<rng.hi+llim; ++ith) while (auto rng=sched.getNext()) for(auto ith=rng.lo+llim; ith<rng.hi+llim; ++ith)
{ {
int dim2 = s_th*(ith-llim); int dim2 = s_th*(ith-llim);
ring2ringtmp(*ginfo, ginfo->pair(ith).r1,ringtmp,rstride); ring2ringtmp(ginfo->pair(ith).r1,ringtmp,rstride);
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
helper.ring2phase (*ginfo, ginfo->pair(ith).r1, helper.ring2phase (*ginfo, ginfo->pair(ith).r1,
&ringtmp[i*rstride],mmax,&phase[dim2+2*i],pstride); &ringtmp[i*rstride],mmax,&phase[dim2+2*i],pstride);
if (ginfo->pair(ith).r2!=~size_t(0)) if (ginfo->pair(ith).r2!=~size_t(0))
{ {
ring2ringtmp(*ginfo, ginfo->pair(ith).r2,ringtmp,rstride); ring2ringtmp(ginfo->pair(ith).r2,ringtmp,rstride);
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
helper.ring2phase (*ginfo, ginfo->pair(ith).r2, helper.ring2phase (*ginfo, ginfo->pair(ith).r2,
&ringtmp[i*rstride],mmax,&phase[dim2+2*i+1],pstride); &ringtmp[i*rstride],mmax,&phase[dim2+2*i+1],pstride);
...@@ -563,13 +539,13 @@ MRUTIL_NOINLINE void sharp_job::phase2map (size_t mmax, size_t llim, size_t ulim ...@@ -563,13 +539,13 @@ MRUTIL_NOINLINE void sharp_job::phase2map (size_t mmax, size_t llim, size_t ulim
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
helper.phase2ring (*ginfo, ginfo->pair(ith).r1, helper.phase2ring (*ginfo, ginfo->pair(ith).r1,
&ringtmp[i*rstride],mmax,&phase[dim2+2*i],pstride); &ringtmp[i*rstride],mmax,&phase[dim2+2*i],pstride);
ringtmp2ring(*ginfo, ginfo->pair(ith).r1,ringtmp,rstride); ringtmp2ring(ginfo->pair(ith).r1,ringtmp,rstride);
if (ginfo->pair(ith).r2!=~size_t(0)) if (ginfo->pair(ith).r2!=~size_t(0))
{ {
for (size_t i=0; i<nmaps; ++i) for (size_t i=0; i<nmaps; ++i)
helper.phase2ring (*ginfo, ginfo->pair(ith).r2, helper.phase2ring (*ginfo, ginfo->pair(ith).r2,
&ringtmp[i*rstride],mmax,&phase[dim2+2*i+1],pstride); &ringtmp[i*rstride],mmax,&phase[dim2+2*i+1],pstride);
ringtmp2ring(*ginfo, ginfo->pair(ith).r2,ringtmp,rstride); ringtmp2ring(ginfo->pair(ith).r2,ringtmp,rstride);
} }
} }
}); /* end of parallel region */ }); /* end of parallel region */
...@@ -579,8 +555,8 @@ MRUTIL_NOINLINE void sharp_job::execute() ...@@ -579,8 +555,8 @@ MRUTIL_NOINLINE void sharp_job::execute()
{ {
mr::SimpleTimer timer; mr::SimpleTimer timer;
opcnt=0; opcnt=0;
size_t lmax = ainfo->lmax, size_t lmax = ainfo->lmax(),
mmax = sharp_get_mmax(ainfo->mval); mmax = ainfo->mmax();
norm_l = (type==SHARP_ALM2MAP_DERIV1) ? norm_l = (type==SHARP_ALM2MAP_DERIV1) ?
sharp_Ylmgen::get_d1norm (lmax) : sharp_Ylmgen::get_d1norm (lmax) :
...@@ -615,7 +591,7 @@ MRUTIL_NOINLINE void sharp_job::execute() ...@@ -615,7 +591,7 @@ MRUTIL_NOINLINE void sharp_job::execute()
/* map->phase where necessary */ /* map->phase where necessary */
map2phase(mmax, llim, ulim); map2phase(mmax, llim, ulim);
mr::execDynamic(ainfo->nm, 0, 1, [&](mr::Scheduler &sched) mr::execDynamic(ainfo->nm(), 0, 1, [&](mr::Scheduler &sched)
{ {
sharp_job ljob = *this; sharp_job ljob = *this;
ljob.opcnt=0; ljob.opcnt=0;
...@@ -654,7 +630,7 @@ void sharp_job::build_common (sharp_jobtype type, ...@@ -654,7 +630,7 @@ void sharp_job::build_common (sharp_jobtype type,
if (type==SHARP_Yt) type=SHARP_MAP2ALM; if (type==SHARP_Yt) type=SHARP_MAP2ALM;
if (type==SHARP_WY) { type=SHARP_ALM2MAP; flags|=SHARP_USE_WEIGHTS; } if (type==SHARP_WY) { type=SHARP_ALM2MAP; flags|=SHARP_USE_WEIGHTS; }
MR_assert(spin<=alm_info.lmax, "bad spin"); MR_assert(spin<=alm_info.lmax(), "bad spin");
this->type = type; this->type = type;
this->spin = spin; this->spin = spin;
nmaps = (type==SHARP_ALM2MAP_DERIV1) ? 2 : ((spin>0) ? 2 : 1); nmaps = (type==SHARP_ALM2MAP_DERIV1) ? 2 : ((spin>0) ? 2 : 1);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#ifndef SHARP_SHARP_H #ifndef SHARP_SHARP_H
#define SHARP_SHARP_H #define SHARP_SHARP_H
#include <complex>
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
#include <memory> #include <memory>
...@@ -107,48 +108,74 @@ class sharp_standard_geom_info: public sharp_geom_info ...@@ -107,48 +108,74 @@ class sharp_standard_geom_info: public sharp_geom_info
/*! \defgroup almgroup Helpers for dealing with a_lm */ /*! \defgroup almgroup Helpers for dealing with a_lm */
/*! \{ */ /*! \{ */
class sharp_alm_info
{
public:
~sharp_alm_info() {}
virtual size_t lmax() const = 0;
virtual size_t mmax() const = 0;
virtual size_t nm() const = 0;
virtual size_t mval(size_t i) const = 0;
virtual void clear_alm(std::complex<double> *alm) const = 0;
virtual void clear_alm(std::complex<float> *alm) const = 0;
virtual void get_alm(size_t mi, const std::complex<double> *alm, std::complex<double> *almtmp, size_t nalm) const = 0;
virtual void get_alm(size_t mi, const std::complex<float> *alm, std::complex<double> *almtmp, size_t nalm) const = 0;
virtual void add_alm(size_t mi, const std::complex<double> *almtmp, std::complex<double> *alm, size_t nalm) const = 0;
virtual void add_alm(size_t mi, const std::complex<double> *almtmp, std::complex<float> *alm, size_t nalm) const = 0;
};
/*! \internal /*! \internal
Helper type for index calculation in a_lm arrays. */ Helper type for index calculation in a_lm arrays. */
struct sharp_alm_info class sharp_standard_alm_info: public sharp_alm_info
{ {
/*! Maximum \a l index of the array */ private:
size_t lmax; /*! Maximum \a l index of the array */
/*! Number of different \a m values in this object */ size_t lmax_;
size_t nm; /*! Array with \a nm entries containing the individual m values */
/*! Array with \a nm entries containing the individual m values */ std::vector<size_t> mval_;
std::vector<size_t> mval; /*! Array with \a nm entries containing the (hypothetical) indices of
/*! Array with \a nm entries containing the (hypothetical) indices of the coefficients with quantum numbers 0,\a mval[i] */
the coefficients with quantum numbers 0,\a mval[i] */ std::vector<ptrdiff_t> mvstart;
std::vector<ptrdiff_t> mvstart; /*! Stride between a_lm and a_(l+1),m */
/*! Stride between a_lm and a_(l+1),m */ ptrdiff_t stride;
ptrdiff_t stride;
public:
/*! Creates an a_lm data structure from the following parameters: /*! Creates an a_lm data structure from the following parameters:
\param lmax maximum \a l quantum number (>=0) \param lmax maximum \a l quantum number (>=0)
\param mmax maximum \a m quantum number (0<= \a mmax <= \a lmax) \param mmax maximum \a m quantum number (0<= \a mmax <= \a lmax)
\param stride the stride between entries with identical \a m, and \a l \param stride the stride between entries with identical \a m, and \a l
differing by 1. differing by 1.
\param mstart the index of the (hypothetical) coefficient with the \param mstart the index of the (hypothetical) coefficient with the
quantum numbers 0,\a m. Must have \a mmax+1 entries. quantum numbers 0,\a m. Must have \a mmax+1 entries.
*/ */
sharp_alm_info(size_t lmax_, size_t mmax, ptrdiff_t stride_, const ptrdiff_t *mstart); sharp_standard_alm_info(size_t lmax__, size_t mmax_, ptrdiff_t stride_, const ptrdiff_t *mstart);
/*! Creates an a_lm data structure which from the following parameters: /*! Creates an a_lm data structure which from the following parameters:
\param lmax maximum \a l quantum number (\a >=0) \param lmax maximum \a l quantum number (\a >=0)
\param nm number of different \a m (\a 0<=nm<=lmax+1) \param nm number of different \a m (\a 0<=nm<=lmax+1)
\param stride the stride between entries with identical \a m, and \a l \param stride the stride between entries with identical \a m, and \a l
differing by 1. differing by 1.
\param mval array with \a nm entries containing the individual m values \param mval array with \a nm entries containing the individual m values
\param mvstart array with \a nm entries containing the (hypothetical) \param mvstart array with \a nm entries containing the (hypothetical)
indices of the coefficients with the quantum numbers 0,\a mval[i] indices of the coefficients with the quantum numbers 0,\a mval[i]
*/ */
sharp_alm_info (size_t lmax_, size_t nm_, ptrdiff_t stride_, const size_t *mval_, sharp_standard_alm_info (size_t lmax__, size_t nm__, ptrdiff_t stride_, const size_t *mval__,
const ptrdiff_t *mvstart); const ptrdiff_t *mvstart_);
/*! Returns the index of the coefficient with quantum numbers \a l, /*! Returns the index of the coefficient with quantum numbers \a l,
\a mval_[mi]. \a mval_[mi].
\note for a \a sharp_alm_info generated by sharp_make_alm_info() this is \note for a \a sharp_alm_info generated by sharp_make_alm_info() this is
the index for the coefficient with the quantum numbers \a l, \a mi. */ the index for the coefficient with the quantum numbers \a l, \a mi. */
ptrdiff_t index (int l, int mi); ptrdiff_t index (int l, int mi);
virtual size_t lmax() const { return lmax_; }
virtual size_t mmax() const;
virtual size_t nm() const { return mval_.size(); }
virtual size_t mval(size_t i) const { return mval_[i]; }
virtual void clear_alm(std::complex<double> *alm) const;
virtual void clear_alm(std::complex<float> *alm) const;
virtual void get_alm(size_t mi, const std::complex<double> *alm, std::complex<double> *almtmp, size_t nalm) const;
virtual void get_alm(size_t mi, const std::complex<float> *alm, std::complex<double> *almtmp, size_t nalm) const;
virtual void add_alm(size_t mi, const std::complex<double> *almtmp, std::complex<double> *alm, size_t nalm) const;
virtual void add_alm(size_t mi, const std::complex<double> *almtmp, std::complex<float> *alm, size_t nalm) const;
}; };
/*! \} */ /*! \} */
......
...@@ -29,19 +29,19 @@ ...@@ -29,19 +29,19 @@
using namespace std; using namespace std;
unique_ptr<sharp_alm_info> sharp_make_triangular_alm_info (int lmax, int mmax, int stride) unique_ptr<sharp_standard_alm_info> sharp_make_triangular_alm_info (int lmax, int mmax, int stride)
{ {
vector<ptrdiff_t> mvstart(mmax+1); vector<ptrdiff_t> mvstart(mmax+1);
ptrdiff_t tval = 2*lmax+1; ptrdiff_t tval = 2*lmax+1;
for (ptrdiff_t m=0; m<=mmax; ++m) for (ptrdiff_t m=0; m<=mmax; ++m)
mvstart[m] = stride*((m*(tval-m))>>1); mvstart[m] = stride*((m*(tval-m))>>1);
return make_unique<sharp_alm_info>(lmax, mmax, stride, mvstart.data());