ANIMA  4.0
animaSphericalHarmonic.cxx
Go to the documentation of this file.
1 #include <cmath>
2 
4 
5 #include <boost/math/special_functions/legendre.hpp>
7 
8 namespace anima
9 {
10 
12 {
13  m_L = 0;
14  m_M = 0;
15 }
16 
18 {
19  m_L = l;
20  m_M = m;
21 }
22 
23 std::complex <double> SphericalHarmonic::Value(const double &theta, const double &phi)
24 {
25  int absm = abs(m_M);
26  std::complex <double> resVal(0, absm * phi);
27  resVal = std::exp(resVal);
28 
29  double sqrtFactor = sqrt((2*m_L + 1) * std::tgamma(m_L - absm + 1) / (4 * M_PI * std::tgamma(m_L + absm + 1)));
30  resVal *= sqrtFactor * boost::math::legendre_p(m_L,absm,cos(theta));
31 
32  if (m_M < 0)
33  {
34  resVal = std::conj(resVal);
35 
36  if (absm % 2 != 0)
37  resVal *= -1;
38  }
39 
40  return resVal;
41 }
42 
43 std::complex <double> SphericalHarmonic::getThetaFirstDerivative(const double& theta, const double& phi)
44 {
45  if ((m_M == 0)||(m_L < 1))
46  return std::complex<double> (0.0,0.0);
47 
48  int absm = std::abs(m_M);
49  std::complex<double> retval(0.0,(double)(absm*phi));
50  retval = std::exp(retval);
51 
52  double factor = sqrt(((double)(2*m_L+1) / (4.0*M_PI)) * (std::tgamma(m_L - absm + 1) / std::tgamma(m_L + absm + 1)));
53  if ((absm%2 != 0)&&(m_M < 0))
54  factor *= -1;
55 
56  factor *= - sin(theta) * anima::legendre_first_derivative(m_L,absm,cos(theta));
57 
58  return factor * retval;
59 }
60 
61 std::complex <double> SphericalHarmonic::getPhiFirstDerivative(const double& theta, const double& phi)
62 {
63  int absm = std::abs(m_M);
64  std::complex<double> retval(0.0,(double)(absm*phi));
65  retval = std::exp(retval);
66  retval *= std::complex<double> (0.0,absm);
67 
68  double factor = std::sqrt(((double)(2*m_L+1) / (4.0*M_PI)) * (std::tgamma(m_L - absm + 1) / std::tgamma(m_L + absm + 1))) *
69  boost::math::legendre_p (m_L,absm,cos(theta));
70 
71  if ((absm%2 != 0)&&(m_M < 0))
72  factor *= -1;
73 
74  return factor * retval;
75 }
76 
77 std::complex <double> SphericalHarmonic::getThetaSecondDerivative(const double& theta, const double& phi)
78 {
79  if ((m_M == 0)||(m_L < 2))
80  return std::complex<double> (0.0,0.0);
81 
82  int absm = std::abs(m_M);
83  std::complex<double> retval(0.0,(double)(absm*phi));
84  retval = std::exp(retval);
85 
86  double factor = std::sqrt(((double)(2*m_L+1) / (4.0*M_PI)) * (std::tgamma(m_L - absm + 1) / std::tgamma(m_L + absm + 1)));
87  if ((absm%2 != 0)&&(m_M < 0))
88  factor *= -1;
89 
90  factor *= sin(theta) * sin(theta) * anima::legendre_second_derivative(m_L,absm,cos(theta)) -
91  cos(theta) * anima::legendre_first_derivative(m_L,absm,cos(theta));
92 
93  return factor * retval;
94 }
95 
96 std::complex <double> SphericalHarmonic::getPhiSecondDerivative(const double& theta, const double& phi)
97 {
98  double factor = - m_M * m_M;
99 
100  return factor * this->Value(theta,phi);
101 }
102 
103 std::complex <double> SphericalHarmonic::getThetaPhiDerivative(const double& theta, const double& phi)
104 {
105  if ((m_M == 0)||(m_L < 1))
106  return std::complex<double> (0.0,0.0);
107 
108  int absm = std::abs(m_M);
109  std::complex<double> retval(0.0,(double)(absm*phi));
110  retval = std::exp(retval);
111  retval *= std::complex<double> (0.0,absm);
112 
113  double factor = sqrt(((double)(2*m_L+1) / (4.0*M_PI)) * (std::tgamma(m_L - absm + 1) / std::tgamma(m_L + absm + 1)));
114  if ((absm%2 != 0)&&(m_M < 0))
115  factor *= -1;
116 
117  factor *= sin(theta) * anima::legendre_first_derivative(m_L,absm,cos(theta));
118 
119  return factor * retval;
120 }
121 
122 } // end of namespace anima
double legendre_second_derivative(int L, int M, double value)
std::complex< double > getThetaPhiDerivative(const double &theta, const double &phi)
std::complex< double > getPhiSecondDerivative(const double &theta, const double &phi)
std::complex< double > getPhiFirstDerivative(const double &theta, const double &phi)
std::complex< double > getThetaSecondDerivative(const double &theta, const double &phi)
std::complex< double > getThetaFirstDerivative(const double &theta, const double &phi)
double legendre_first_derivative(int L, int M, double value)
std::complex< double > Value(const double &theta, const double &phi)