[461] | 1 | #ifndef LAMBUILDER_H_SEEN
|
---|
| 2 | #define LAMBUILDER_H_SEEN
|
---|
| 3 |
|
---|
| 4 | #include <math.h>
|
---|
| 5 |
|
---|
| 6 |
|
---|
| 7 | class LambdaBuilder{
|
---|
| 8 | public:
|
---|
| 9 | LambdaBuilder();
|
---|
| 10 | LambdaBuilder(double theta,int lmax, int mmax);
|
---|
| 11 | LambdaBuilder(const LambdaBuilder& lb);
|
---|
| 12 | void reset();
|
---|
| 13 | double lamlm() const {return lamlm_;}
|
---|
| 14 | double lamlm(int flip);
|
---|
| 15 | double lamlm(int l, int m);
|
---|
| 16 | double lamlm(int l, int m, int flip);
|
---|
| 17 | int l() const {return l_;}
|
---|
| 18 | int m() const {return m_;}
|
---|
| 19 | int lmax() const {return lmax_;}
|
---|
| 20 | int mmax() const {return mmax_;}
|
---|
| 21 | void step();
|
---|
| 22 | protected:
|
---|
| 23 | double par_lm_;
|
---|
| 24 | int lmax_;
|
---|
| 25 | int mmax_;
|
---|
| 26 | int l_;
|
---|
| 27 | int m_;
|
---|
| 28 | double lamlm_;
|
---|
| 29 | double cth_;
|
---|
| 30 | double sth_;
|
---|
| 31 | double lammm_;
|
---|
| 32 | double lam_0_;
|
---|
| 33 | double lam_1_;
|
---|
| 34 | double a_rec_;
|
---|
| 35 | double b_rec_;
|
---|
| 36 | double fm2_;
|
---|
| 37 | // static const double bignorm=1e-20*HUGE_VAL;
|
---|
| 38 | static const double bignorm=1e-20*1.d288;
|
---|
| 39 | };
|
---|
| 40 |
|
---|
| 41 | class Lambda2Builder : public LambdaBuilder {
|
---|
| 42 | public:
|
---|
| 43 | Lambda2Builder();
|
---|
| 44 | Lambda2Builder(double theta,int lmax, int mmax);
|
---|
| 45 | Lambda2Builder(const Lambda2Builder& lb);
|
---|
| 46 | void reset();
|
---|
| 47 | double lam2lmp() const {return -fact_*(w_-ix_);}
|
---|
| 48 | double lam2lmp(int flip);
|
---|
| 49 | double lam2lmp(int l, int m);
|
---|
| 50 | double lam2lmp(int l, int m, int flip);
|
---|
| 51 | double lam2lmm() const {return -fact_*(w_+ix_);}
|
---|
| 52 | double lam2lmm(int flip);
|
---|
| 53 | double lam2lmm(int l, int m);
|
---|
| 54 | double lam2lmm(int l, int m, int flip);
|
---|
| 55 | void step();
|
---|
| 56 | private:
|
---|
| 57 | double fact_;
|
---|
| 58 | double w_;
|
---|
| 59 | double ix_;
|
---|
| 60 | };
|
---|
| 61 | #endif
|
---|
| 62 |
|
---|
| 63 | /*! \class LambdaBuilder
|
---|
| 64 | \brief A lambda building class
|
---|
| 65 |
|
---|
| 66 | Objects in this class generate
|
---|
| 67 | \f[
|
---|
| 68 | \lambda_l^m=\sqrt{\frac{2l+1}{4\pi}\frac{(l-m)!}{(l+m)!}}
|
---|
| 69 | P_l^m(\cos{\theta})
|
---|
| 70 | \f]
|
---|
| 71 | where \f$P_l^m\f$ are the associated Legendre polynomials. The interest
|
---|
| 72 | of course is that
|
---|
| 73 | \f[
|
---|
| 74 | Y_{lm}(\cos{\theta})=\lambda_l^m(\cos{\theta}) e^{im\phi}.
|
---|
| 75 | \f]
|
---|
| 76 |
|
---|
| 77 | Each object has a fixed theta, and maximum l and m to be calculated
|
---|
| 78 | (lmax and mmax).
|
---|
| 79 |
|
---|
| 80 | The algorithm solves the \f$\lambda_l^m\f$'s iteratively so there
|
---|
| 81 | is an optimal sequance of l and m's as follows...
|
---|
| 82 |
|
---|
| 83 | \code
|
---|
| 84 | for (int m = 0; m <= nmmax; m++){
|
---|
| 85 | dum=lb.lamlm(m,m)
|
---|
| 86 | for (int l = m+1; l<= nlmax; l++){
|
---|
| 87 | dum = lb.lamlm(l,m)
|
---|
| 88 | }
|
---|
| 89 | }\endcode
|
---|
| 90 | The function LambdaBuilder::step() automatically shifts the l and
|
---|
| 91 | m's to the next optimal value.
|
---|
| 92 | However, \f$\lambda_l^m\f$ can be calculated for any l and m less than
|
---|
| 93 | or equal to lmax and lmax by going through the loop or restarting the
|
---|
| 94 | loop.
|
---|
| 95 |
|
---|
| 96 | \f$\lambda_l^m(-\cos{\theta})\f$ can be quickly obtained using
|
---|
| 97 | symmetry relations, which can be more efficient that creating a new
|
---|
| 98 | LambdaBuilder object.
|
---|
| 99 |
|
---|
| 100 | The algorithm is based on the HEALPIX code.
|
---|
| 101 | */
|
---|
| 102 |
|
---|
| 103 | /*! \fn LambdaBuilder::LambdaBuilder(double theta,int lmax, int mmax)
|
---|
| 104 | \param theta the desired \f$\theta\f$
|
---|
| 105 | \param lmax the maximum value of l
|
---|
| 106 | \param mmax the maximum value of m
|
---|
| 107 | */
|
---|
| 108 | /*!
|
---|
| 109 | \fn LambdaBuilder::LambdaBuilder(const LambdaBuilder& lb)
|
---|
| 110 | \param lb the LambdaBuilder object to be copied
|
---|
| 111 | */
|
---|
| 112 | /*! \fn void LambdaBuilder::reset()
|
---|
| 113 | \brief Resets the object to l=0, m=0
|
---|
| 114 | */
|
---|
| 115 | /*! \fn double LambdaBuilder::lamlm() const
|
---|
| 116 | \returns \f$\lambda_l^m\f$ for current l and m
|
---|
| 117 | */
|
---|
| 118 | /*!
|
---|
| 119 | \fn double LambdaBuilder::lamlm(int flip)
|
---|
| 120 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 121 | \returns \f$\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the current l and m.
|
---|
| 122 | Uses symmetry relations to get this value.
|
---|
| 123 | */
|
---|
| 124 | /*! \fn double LambdaBuilder::lamlm(int l, int m)
|
---|
| 125 | \param l the desired l
|
---|
| 126 | \param m the desired m
|
---|
| 127 | \returns \f$\lambda_l^m\f$ for l and m
|
---|
| 128 | */
|
---|
| 129 | /*! \fn double LambdaBuilder::lamlm(int l, int m, int flip)
|
---|
| 130 | \param l the desired l
|
---|
| 131 | \param m the desired m
|
---|
| 132 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 133 | \returns \f$\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the given l and m.
|
---|
| 134 | Uses symmetry relations to get this value.
|
---|
| 135 | */
|
---|
| 136 | /*! \fn int LambdaBuilder::l() const
|
---|
| 137 | \returns current value of l
|
---|
| 138 | */
|
---|
| 139 | /*! \fn int LambdaBuilder::m() const
|
---|
| 140 | \returns current value of m
|
---|
| 141 | */
|
---|
| 142 | /*! \fn int LambdaBuilder::lmax() const
|
---|
| 143 | \returns the maximum value of l
|
---|
| 144 | */
|
---|
| 145 | /*! \fn int LambdaBuilder::mmax() const
|
---|
| 146 | \returns the maximum value of m
|
---|
| 147 | */
|
---|
| 148 | /*! \fn void LambdaBuilder::step()
|
---|
| 149 | \brief Steps to the next l and m
|
---|
| 150 | */
|
---|
| 151 |
|
---|
| 152 | /*! \class Lambda2Builder
|
---|
| 153 | \brief A lambda building class
|
---|
| 154 |
|
---|
| 155 | Objects in this class generate
|
---|
| 156 | \f[
|
---|
| 157 | _\pm\lambda_l^m=2\sqrt{\frac{(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}\left( G^+_{lm} \mp G^-_{lm}\right)
|
---|
| 158 | \f]
|
---|
| 159 | where
|
---|
| 160 | \f[G^+_{lm}(\cos{\theta})=-\left( \frac{l-m^2}{\sin^2{\theta}}+\frac{1}{2}l\left(l-1\right)\right)P_l^m(\cos{\theta})+\left(l+m\right)\frac{\cos{\theta}}{\sin^2{\theta}}P^m_{l-1}(\cos{\theta})
|
---|
| 161 | \f]
|
---|
| 162 | and
|
---|
| 163 | \f[G^-_{lm}(\cos{\theta})=\frac{m}{\sin^2{\theta}}\left(\left(l-1\right)\cos{\theta}P^m_l(\cos{\theta})-\left(l+m\right)P^m_{l-1}(\cos{\theta})\right)
|
---|
| 164 | \f]
|
---|
| 165 | and \f$P_l^m\f$ are the associated Legendre polynomials.
|
---|
| 166 | The interest in all this is that
|
---|
| 167 | \f[_{\pm2}Y_l^m(\cos{\theta})=_\pm\lambda_l^m(\cos{\theta})e^{im\phi}
|
---|
| 168 | \f]
|
---|
| 169 | where \f$_{\pm2}Y_l^m\f$ are the spin-2 spherical harmonics.
|
---|
| 170 | */
|
---|
| 171 |
|
---|
| 172 | /*! \fn Lambda2Builder::Lambda2Builder(double theta,int lmax, int mmax)
|
---|
| 173 | \param theta the desired \f$\theta\f$
|
---|
| 174 | \param lmax the maximum value of l
|
---|
| 175 | \param mmax the maximum value of m
|
---|
| 176 | */
|
---|
| 177 | /*! \fn Lambda2Builder::Lambda2Builder(const Lambda2Builder& lb)
|
---|
| 178 | \param lb the Lambda2Builder object to be copied
|
---|
| 179 | */
|
---|
| 180 | /*! \fn double Lambda2Builder::lam2lmp() const
|
---|
| 181 | \returns \f$_+\lambda_l^m\f$ for current l and m
|
---|
| 182 | */
|
---|
| 183 | /*! \fn double Lambda2Builder::lam2lmp(int flip);
|
---|
| 184 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 185 | \returns \f$_+\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the current l and m.
|
---|
| 186 | Uses symmetry relations to get this value.
|
---|
| 187 | */
|
---|
| 188 | /*! \fn double Lambda2Builder::lam2lmp(int l, int m)
|
---|
| 189 | \param l the desired l
|
---|
| 190 | \param m the desired m
|
---|
| 191 | \returns \f$_+\lambda_l^m\f$ for l and m
|
---|
| 192 | */
|
---|
| 193 | /*! \fn double Lambda2Builder::lam2lmp(int l, int m, int flip)
|
---|
| 194 | \param l the desired l
|
---|
| 195 | \param m the desired m
|
---|
| 196 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 197 | \returns \f$_+\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the given l and m.
|
---|
| 198 | Uses symmetry relations to get this value.
|
---|
| 199 | */
|
---|
| 200 | /*! \fn double Lambda2Builder::lam2lmm() const
|
---|
| 201 | \returns \f$_-\lambda_l^m\f$ for current l and m
|
---|
| 202 | */
|
---|
| 203 | /*! \fn double Lambda2Builder::lam2lmm(int flip)
|
---|
| 204 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 205 | \returns \f$_-\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the current l and m.
|
---|
| 206 | Uses symmetry relations to get this value.
|
---|
| 207 | */
|
---|
| 208 | /*! \fn double Lambda2Builder::lam2lmm(int l, int m)
|
---|
| 209 | \param l the desired l
|
---|
| 210 | \param m the desired m
|
---|
| 211 | \returns \f$_-\lambda_l^m\f$ for l and m
|
---|
| 212 | */
|
---|
| 213 | /*! \fn double Lambda2Builder::lam2lmm(int l, int m, int flip)
|
---|
| 214 | \param l the desired l
|
---|
| 215 | \param m the desired m
|
---|
| 216 | \param flip \f$\theta\f$ to be multiplied by sign(flip)
|
---|
| 217 | \returns \f$_-\lambda_l^m(\cos{(sign(flip)\theta}))\f$ for the given l and m.
|
---|
| 218 | Uses symmetry relations to get this value.
|
---|
| 219 | )*/
|
---|