6#include <unordered_map>
16 sincos(theta, &y, &x);
22 for (
int n = 1; n < N; ++n)
24 for (
int m = 0; m <= n - 2; ++m)
26 Pnm[n * (n + 1) / 2 + m] = ((2 * n - 1) * x * Pnm[(n - 1) * n / 2 + m] - (n + m - 1) * Pnm[(n - 2) * (n - 1) / 2 + m]) / (n - m);
28 Pnm[n * (n + 1) / 2 + n - 1] = Pnm[(n - 1) * n / 2 + n - 1] * x * (2 * n - 1);
29 Pnm[n * (n + 1) / 2 + n] = Pnm[(n - 1) * n / 2 + n - 1] * y * (1 - 2 * n);
34[[deprecated(
"Use only when constexpr Knm unavailable")]]
38[[deprecated(
"Use only when constexpr Anm unavailable")]]
46 inline double constexpr sqrtNewton(
double x,
double curr,
double prev)
48 return (prev - curr) / curr < 1.e-16 && (prev - curr) / curr > -1.e-16 ? curr :
sqrtNewton(x, 0.5 * (curr + x / curr), curr);
59 std::array<double, N * (N + 1) / 2>
Knm;
63 for (
int n = 1; n < N; ++n)
65 for (
int m = 0; m <= n - 1; ++m)
66 Knm[n * (n + 1) / 2 + m] =
Knm[n * (n - 1) / 2 + m] * (n - m) / (n + m);
67 Knm[n * (n + 1) / 2 + n] =
Knm[n * (n + 1) / 2 + n - 1] / (2 * n);
69 for (
int n = 1; n < N; ++n)
71 for (
int m = 0; m <= n; ++m)
75 Knm[n * (n + 1) / 2 + m] = sqrt(
Knm[n * (n + 1) / 2 + m]);
81 return Knm[n * (n + 1) / 2 + m];
90 std::array<double, 2 * N * (2 * N + 1) / 2>
Anm;
94 for (
int n = 1; n < 2 * N; ++n)
96 for (
int m = 0; m <= n - 1; ++m)
97 Anm[n * (n + 1) / 2 + m] =
Anm[(n - 1) * n / 2 + m] * (n - m) * (n + m);
98 Anm[n * (n + 1) / 2 + n] =
Anm[n * (n + 1) / 2 + n - 1] * 2 * n;
100 for (
int n = 1; n < 2 * N; ++n)
102 for (
int m = 0; m <= n; ++m)
106 Anm[n * (n + 1) / 2 + m] =
ni(n) / sqrt(
Anm[n * (n + 1) / 2 + m]);
112 return Anm[n * (n + 1) / 2 + m];
121 std::array<double, N * (N + 1) * (N + 2) / 2 + 1>
m2lcoef;
124 for (
int j = 0; j < N; ++j)
126 for (
int k = 0; k <= j; ++k)
128 for (
int n = k; n < N; ++n)
130 int idx = N * (j + 2) * (j + 1) / 2 + N * (k + 1) + n + 1;
140#ifndef FMM_CONSTEXPR_MATH
141 inline double* dev_Knm;
142 inline double* dev_Anm;
143 inline double* dev_m2lcoef;
145 inline std::unordered_map<int, std::vector<double>>
dmatrix;
#define FMM_CONSTEXPR_MATH
constexpr anm_wrapper< _3d_MAX_MULTIPOLE_NUM > Anm
std::unordered_map< int, std::vector< double > > dmatrix
constexpr knm_wrapper< _3d_MAX_MULTIPOLE_NUM > Knm
std::unordered_map< int, std::vector< std::complex< double > > > rotation_exponents
double constexpr sqrtNewton(double x, double curr, double prev)
constexpr m2lcoef_wrapper< _3d_MAX_MULTIPOLE_NUM > m2lcoef
void InitMathConstants(int N)
void cudaCopyMathConstants()
double constexpr constexpr_sqrt(double x)
void cudaClearMathConstants()
void ComputePnm(int N, double theta, double *Pnm)
std::vector< double > ComputeWignerD(int N, double theta)
constexpr double ni(int n)
treevector< double > ComputeKnm(int N)
treevector< double > ComputeAnm(int N)
constexpr double operator()(int n, int m) const
std::array< double, 2 *N *(2 *N+1)/2 > Anm
constexpr double operator()(int n, int m) const
std::array< double, N *(N+1)/2 > Knm
std::array< double, N *(N+1) *(N+2)/2+1 > m2lcoef
constexpr m2lcoef_wrapper()