17#ifndef __math_legendre_h__
18#define __math_legendre_h__
29 template <
typename ValueType>
32 return (n < 2.0 ? 1.0 : n*
factorial (n-1.0));
35 template <
typename ValueType>
41 template <
typename ValueType>
42 inline ValueType
Plm (
const int l,
const int m,
const ValueType x)
44 if (m &&
abs (x) >= 1.0)
return (0.0);
48 if (l == m)
return (v0);
50 ValueType v1 = x * (2*m+1) * v0;
51 if (l == m+1)
return (v1);
53 for (
int n = m+2; n <= l; n++) {
54 ValueType v2 = ( (2.0*n-1.0) *x*v1 - (n+m-1) *v0) / (n-m);
65 template <
typename ValueType>
66 inline ValueType Plm_sph_helper (
const ValueType x,
const ValueType m)
68 return (m < 1.0 ? 1.0 : x * (m-1.0) / m * Plm_sph_helper (x, m-2.0));
72 template <
typename ValueType>
73 inline ValueType
Plm_sph (
const int l,
const int m,
const ValueType x)
75 ValueType x2 =
pow2 (x);
76 if (m && x2 >= 1.0)
return (0.0);
77 ValueType v0 = 0.282094791773878;
78 if (m) v0 *= std::sqrt ((2*m+1) * Plm_sph_helper (1.0-x2, 2.0*m));
80 if (l == m)
return (v0);
82 ValueType f = std::sqrt (ValueType (2*m+3));
83 ValueType v1 = x * f * v0;
85 for (
int n = m+2; n <= l; n++) {
86 ValueType v2 = x*v1 - v0/f;
87 f = std::sqrt (ValueType (4*
pow2 (n)-1) / ValueType (
pow2 (n)-
pow2 (m)));
100 template <
typename VectorType>
101 inline void Plm_sph (VectorType& array,
const int lmax,
const int m,
const typename VectorType::Scalar x)
103 using value_type =
typename VectorType::Scalar;
105 if (m && x2 >= 1.0) {
106 for (
int n = m; n <= lmax; ++n)
110 array[m] = 0.282094791773878;
111 if (m) array[m] *= std::sqrt (
value_type (2*m+1) * Plm_sph_helper (1.0-x2, 2.0*m));
112 if (m & 1) array[m] = -array[m];
113 if (lmax == m)
return;
116 array[m+1] = x * f * array[m];
118 for (
int n = m+2; n <= lmax; n++) {
119 array[n] = x*array[n-1] - array[n-2]/f;
131 template <
typename VectorType>
132 inline void Plm_sph_deriv (VectorType& array,
const int lmax,
const int m,
const typename VectorType::Scalar x)
134 using value_type =
typename VectorType::Scalar;
137 for (
int n = m; n <= lmax; n++)
142 for (
int n = lmax; n > m; n--)
143 array[n] = x2 * (n*x*array[n] - (n+m) * std::sqrt ( (2.0*n+1.0) * (n-m) / ( (2.0*n-1.0) * (n+m))) *array[n-1]);
constexpr T pow2(const T &v)
ValueType double_factorial(const ValueType n)
void Plm_sph_deriv(VectorType &array, const int lmax, const int m, const typename VectorType::Scalar x)
ValueType factorial(const ValueType n)
ValueType Plm(const int l, const int m, const ValueType x)
ValueType Plm_sph(const int l, const int m, const ValueType x)
MR::default_type value_type
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)
constexpr default_type NaN