alm.h

Go to the documentation of this file.
00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.sourceforge.net
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*! \file alm.h
00028  *  Class for storing spherical harmonic coefficients.
00029  *
00030  *  Copyright (C) 2003-2012 Max-Planck-Society
00031  *  \author Martin Reinecke
00032  */
00033 
00034 #ifndef PLANCK_ALM_H
00035 #define PLANCK_ALM_H
00036 
00037 #include "arr.h"
00038 
00039 /*! Base class for calculating the storage layout of spherical harmonic
00040     coefficients. */
00041 class Alm_Base
00042   {
00043   protected:
00044     int lmax, mmax, tval;
00045 
00046   public:
00047     /*! Returns the total number of coefficients for maximum quantum numbers
00048         \a l and \a m. */
00049     static tsize Num_Alms (int l, int m);
00050 
00051     /*! Constructs an Alm_Base object with given \a lmax and \a mmax. */
00052     Alm_Base (int lmax_=0, int mmax_=0)
00053       : lmax(lmax_), mmax(mmax_), tval(2*lmax+1) {}
00054 
00055     /*! Changes the object's maximum quantum numbers to \a lmax and \a mmax. */
00056     void Set (int lmax_, int mmax_)
00057       {
00058       lmax=lmax_;
00059       mmax=mmax_;
00060       tval=2*lmax+1;
00061       }
00062 
00063     /*! Returns the maximum \a l */
00064     int Lmax() const { return lmax; }
00065     /*! Returns the maximum \a m */
00066     int Mmax() const { return mmax; }
00067 
00068     /*! Returns an array index for a given m, from which the index of a_lm
00069         can be obtained by adding l. */
00070     int index_l0 (int m) const
00071       { return ((m*(tval-m))>>1); }
00072 
00073     /*! Returns the array index of the specified coefficient. */
00074     int index (int l, int m) const
00075       { return index_l0(m) + l; }
00076 
00077     /*! Returns \a true, if both objects have the same \a lmax and \a mmax,
00078         else  \a false. */
00079     bool conformable (const Alm_Base &other) const
00080       { return ((lmax==other.lmax) && (mmax==other.mmax)); }
00081 
00082     /*! Swaps the contents of two Alm_Base objects. */
00083     void swap (Alm_Base &other);
00084   };
00085 
00086 /*! Class for storing spherical harmonic coefficients. */
00087 template<typename T> class Alm: public Alm_Base
00088   {
00089   private:
00090     arr<T> alm;
00091 
00092   public:
00093     /*! Constructs an Alm object with given \a lmax and \a mmax. */
00094     Alm (int lmax_=0, int mmax_=0)
00095       : Alm_Base(lmax_,mmax_), alm (Num_Alms(lmax,mmax)) {}
00096 
00097     /*! Deletes the old coefficients and allocates storage according to
00098         \a lmax and \a mmax. */
00099     void Set (int lmax_, int mmax_)
00100       {
00101       Alm_Base::Set(lmax_, mmax_);
00102       alm.alloc(Num_Alms(lmax,mmax));
00103       }
00104 
00105     /*! Deallocates the old coefficients and uses the content of \a data
00106         for storage. \a data is deallocated during the call. */
00107     void Set (arr<T> &data, int lmax_, int mmax_)
00108       {
00109       planck_assert (Num_Alms(lmax_,mmax_)==data.size(),"wrong array size");
00110       Alm_Base::Set(lmax_, mmax_);
00111       alm.transfer(data);
00112       }
00113 
00114     /*! Sets all coefficients to zero. */
00115     void SetToZero ()
00116       { alm.fill (0); }
00117 
00118     /*! Multiplies all coefficients by \a factor. */
00119     template<typename T2> void Scale (const T2 &factor)
00120       { for (tsize m=0; m<alm.size(); ++m) alm[m]*=factor; }
00121     /*! \a a(l,m) *= \a factor[l] for all \a l,m. */
00122     template<typename T2> void ScaleL (const arr<T2> &factor)
00123       {
00124       planck_assert(factor.size()>tsize(lmax),
00125         "alm.ScaleL: factor array too short");
00126       for (int m=0; m<=mmax; ++m)
00127         for (int l=m; l<=lmax; ++l)
00128           operator()(l,m)*=factor[l];
00129       }
00130     /*! \a a(l,m) *= \a factor[m] for all \a l,m. */
00131     template<typename T2> void ScaleM (const arr<T2> &factor)
00132       {
00133       planck_assert(factor.size()>tsize(mmax),
00134         "alm.ScaleM: factor array too short");
00135       for (int m=0; m<=mmax; ++m)
00136         for (int l=m; l<=lmax; ++l)
00137           operator()(l,m)*=factor[m];
00138       }
00139     /*! Adds \a num to a_00. */
00140     template<typename T2> void Add (const T2 &num)
00141       { alm[0]+=num; }
00142 
00143     /*! Returns a reference to the specified coefficient. */
00144     T &operator() (int l, int m)
00145       { return alm[index(l,m)]; }
00146     /*! Returns a constant reference to the specified coefficient. */
00147     const T &operator() (int l, int m) const
00148       { return alm[index(l,m)]; }
00149 
00150     /*! Returns a pointer for a given m, from which the address of a_lm
00151         can be obtained by adding l. */
00152     T *mstart (int m)
00153       { return &alm[index_l0(m)]; }
00154     /*! Returns a pointer for a given m, from which the address of a_lm
00155         can be obtained by adding l. */
00156     const T *mstart (int m) const
00157       { return &alm[index_l0(m)]; }
00158 
00159     /*! Returns a constant reference to the a_lm data. */
00160     const arr<T> &Alms () const { return alm; }
00161 
00162     /*! Swaps the contents of two Alm objects. */
00163     void swap (Alm &other)
00164       {
00165       Alm_Base::swap(other);
00166       alm.swap(other.alm);
00167       }
00168 
00169     /*! Adds all coefficients from \a other to the own coefficients. */
00170     void Add (const Alm &other)
00171       {
00172       planck_assert (conformable(other), "A_lm are not conformable");
00173       for (tsize m=0; m<alm.size(); ++m)
00174         alm[m] += other.alm[m];
00175       }
00176   };
00177 
00178 #endif

Generated on Thu Oct 8 14:48:52 2015 for Healpix C++