#ifndef LAMBDABUILDER_SEEN #define LAMBDABUILDER_SEEN #include #include "ndatablock.h" #include "tvector.h" #include "alm.h" /*! generate Legendre polynomials : use in two steps : a) instanciate Legendre(\f$x\f$, \f$lmax\f$) ; \f$x\f$ is the value for wich Legendre polynomials will be required (usually equal to \f$\cos \theta\f$) and \f$lmax\f$ is the MAXIMUM value of the order of polynomials wich will be required in the following code (all polynomials, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula). b) get the value of Legendre polynomial for a particular value of \f$l\f$ by calling the method getPl. */ class Legendre { public : Legendre(); Legendre(r_8 x, int_4 lmax); inline r_8 getPl(int_4 l) { if (l>lmax_) { throw (" illegal call of Legendre::getPl with index greater than lmax, which Legendre Class was instanciated with : instanciate Legendre with a greater lmax... "); } return Pl_(l); } private : /*! compute all \f$P_l(x,l_{max})\f$ for \f$l=1,l_{max}\f$ */ void array_init(int_4 lmax); r_8 x_; int_4 lmax_; TVector Pl_; }; /*! This class generate the coefficients : \f[ \lambda_l^m=\sqrt{\frac{2l+1}{4\pi}\frac{(l-m)!}{(l+m)!}} P_l^m(\cos{\theta}) \f] where \f$P_l^m\f$ are the associated Legendre polynomials. The above coefficients contain the theta-dependance of spheric harmonics : \f[ Y_{lm}(\cos{\theta})=\lambda_l^m(\cos{\theta}) e^{im\phi}. \f] Each object has a fixed theta (radians), and maximum l and m to be calculated (lmax and mmax). use the class in two steps : a) instanciate LambdaLMBuilder(\f$\theta\f$, \f$lmax\f$, \f$mmax\f$) ; \f$lmax\f$ and \f$mmax\f$ are MAXIMUM values for which \f$\lambda_l^m\f$ will be required in the following code (all coefficients, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula). b) get the values of coefficients for particular values of \f$l\f$ and \f$m\f$ by calling the method lamlm. */ class LambdaLMBuilder { public: LambdaLMBuilder() {} LambdaLMBuilder(r_8 theta,int_4 lmax, int_4 mmax); ~LambdaLMBuilder() {}; /*! return the value of the coefficient \f$ \lambda_l^m \f$ */ inline double lamlm(int l, int m) const { return lambda_(l,m); } private: /*! compute a static array of coefficients independant from theta (common to all instances of the LambdaBuilder Class */ void updateArrayRecurrence(int_4 lmax); void array_init(int lmax, int mmax); static TriangularMatrix* a_recurrence_; TriangularMatrix lambda_; protected : /*! compute static arrays of coefficients independant from theta (common to all instances of the derived classes */ void updateArrayLamNorm(); static TriangularMatrix* lam_fact_; static TVector* normal_l_; int_4 lmax_; int_4 mmax_; r_8 cth_; r_8 sth_; }; /*! This class generates the coefficients : \f[ _{w}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}} G^+_{lm} \f] \f[ _{x}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}G^-_{lm} \f] where \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}) \f] and \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) \f] \f$P_l^m\f$ are the associated Legendre polynomials. The coefficients express the theta-dependance of the \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ functions : \f[W_{lm}(\cos{\theta}) = \sqrt{\frac{(l+2)!}{2(l-2)!}}_w\lambda_l^m(\cos{\theta})e^{im\phi} \f] \f[X_{lm}(\cos{\theta}) = -i\sqrt{\frac{(l+2)!}{2(l-2)!}}_x\lambda_l^m(\cos{\theta})e^{im\phi} \f] where \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ are defined as : \f[ W_{lm}(\cos{\theta})=-\frac{1}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left( _{+2}Y_l^m(\cos{\theta})+_{-2}Y_l^m(\cos{\theta})\right) \f] \f[X_{lm}(\cos{\theta})=-\frac{i}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left( _{+2}Y_l^m(\cos{\theta})-_{-2}Y_l^m(\cos{\theta})\right) \f] */ class LambdaWXBuilder : public LambdaLMBuilder { public: LambdaWXBuilder() {} LambdaWXBuilder(r_8 theta, int_4 lmax, int_4 mmax); /*! return the value of the coefficients \f$ _{w}\lambda_l^m\f$ and \f$_{x}\lambda_l^m\f$ */ inline void lam_wx(int l, int m, r_8& w, r_8& x) const { w=lamWlm_(l,m); x=lamXlm_(l,m); } private: void array_init(); TriangularMatrix lamWlm_; TriangularMatrix lamXlm_; }; /*! This class generates the coefficients \f[ _{\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) \f] where \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}) \f] and \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) \f] and \f$P_l^m\f$ are the associated Legendre polynomials. The coefficients express the theta-dependance of the spin-2 spherical harmonics : \f[_{\pm2}Y_l^m(\cos{\theta})=_\pm\lambda_l^m(\cos{\theta})e^{im\phi} \f] */ class LambdaPMBuilder : public LambdaLMBuilder { public: LambdaPMBuilder() {} LambdaPMBuilder(r_8 theta, int_4 lmax, int_4 mmax); /*! return the value of the coefficients \f$ _{+}\lambda_l^m\f$ and \f$_{-}\lambda_l^m\f$ */ inline void lam_pm(int l, int m, r_8& lambda_plus, r_8& lambda_moins) const { lambda_plus = lamPlm_(l,m); lambda_moins = lamMlm_(l,m); } private: void array_init(); TriangularMatrix lamPlm_; TriangularMatrix lamMlm_; }; #endif