9 #include <boost/math/special_functions/legendre.hpp>
16 interpolator::interpolator(unit_sphere
const &Sfrom, unit_sphere
const &Sto)
17 : m_Lfrom(Sfrom.get_P())
19 , m_Phi(cmatrix_t::Zero(m_Lfrom, 2 * m_Lfrom))
20 , m_Q(cmatrix_t::Zero(m_Lto, 2 * m_Lto))
21 , m_res(cvector_t::Zero(m_Lto * 2 * m_Lto, 1))
24 cmatrix_t a(m_Lfrom, 2 * m_Lfrom), afft(m_Lfrom, 2 * m_Lfrom);
26 n[0] = int(2 * m_Lfrom);
27 this->dft_plan = fftw_plan_many_dft(1, n,
int(m_Lfrom),
28 (fftw_complex *)a.data(),
nullptr,
int(m_Lfrom), 1,
29 (fftw_complex *)afft.data(),
nullptr,
int(m_Lfrom), 1,
30 FFTW_FORWARD, FFTW_MEASURE);
32 cmatrix_t bfft(m_Lto, 2 * m_Lto), b(m_Lto, 2 * m_Lto);
33 n[0] = int(2 * m_Lto);
34 this->idft_plan = fftw_plan_many_dft(1, n,
int(m_Lto),
35 (fftw_complex *)bfft.data(),
nullptr,
int(m_Lto), 1,
36 (fftw_complex *)b.data(),
nullptr,
int(m_Lto), 1,
37 FFTW_BACKWARD, FFTW_MEASURE);
40 int L = int(std::min(m_Lfrom, m_Lto));
41 for (
int m = -L; m <= L; ++m)
42 m_A.push_back(Amatrix(L, m, Sto.get_theta(), Sfrom.get_theta(), Sfrom.get_wtheta()));
45 interpolator::interpolator(interpolator &&other)
46 : m_Lfrom(other.m_Lfrom)
48 , m_A(std::move(other.m_A))
49 , dft_plan(other.dft_plan)
50 , idft_plan(other.idft_plan)
51 , m_Phi(std::move(other.m_Phi))
52 , m_Q(std::move(other.m_Q))
53 , m_res(std::move(other.m_res))
55 other.dft_plan =
nullptr;
56 other.idft_plan =
nullptr;
61 interpolator::cvector_t
const &
64 using namespace boost::math::double_constants;
66 size_t L = std::min(m_Lfrom, m_Lto);
73 (fftw_complex *)other.data(),
74 (fftw_complex *)m_Phi.data());
75 m_Phi *= pi / m_Lfrom;
80 for (
size_t m = 0; m < L; ++m)
81 m_Q.col(m) = m_A[m + L] * m_Phi.col(m);
82 for (
int m = -
int(L); m < 0; ++m)
83 m_Q.col(2 * m_Lto + m) = m_A[m + L] * m_Phi.col(2 * m_Lfrom + m);
89 (fftw_complex *)m_Q.data(),
90 (fftw_complex *)m_res.data());
102 fftw_destroy_plan(dft_plan);
104 fftw_destroy_plan(idft_plan);
106 if (other.dft_plan ==
nullptr)
113 m_Lfrom = other.m_Lfrom;
121 cmatrix_t a(m_Lfrom, 2 * m_Lfrom), afft(m_Lfrom, 2 * m_Lfrom);
123 n[0] = int(2 * m_Lfrom);
124 this->dft_plan = fftw_plan_many_dft(1, n,
int(m_Lfrom),
125 (fftw_complex *)a.data(),
nullptr,
int(m_Lfrom), 1,
126 (fftw_complex *)afft.data(),
nullptr,
int(m_Lfrom), 1,
127 FFTW_FORWARD, FFTW_MEASURE);
128 cmatrix_t bfft(m_Lto, 2 * m_Lto), b(m_Lto, 2 * m_Lto);
129 n[0] = int(2 * m_Lto);
130 this->idft_plan = fftw_plan_many_dft(1, n,
int(m_Lto),
131 (fftw_complex *)bfft.data(),
nullptr,
int(m_Lto), 1,
132 (fftw_complex *)b.data(),
nullptr,
int(m_Lto), 1,
133 FFTW_BACKWARD, FFTW_MEASURE);
139 interpolator::operator=(interpolator &&other)
144 m_Lfrom = other.m_Lfrom;
146 m_A = std::move(other.m_A);
147 dft_plan = other.dft_plan;
148 idft_plan = other.idft_plan;
149 m_Phi = std::move(other.m_Phi);
150 m_Q = std::move(other.m_Q);
151 m_res = std::move(other.m_res);
153 other.dft_plan =
nullptr;
154 other.idft_plan =
nullptr;
160 interpolator::dmatrix_t interpolator::Amatrix(
int L,
int m,
161 dvector_t
const &theta,
163 dvector_t
const &wxi)
165 using boost::math::legendre_p;
167 dmatrix_t Pi = dmatrix_t::Zero(theta.rows(), Eigen::Index(L + 1));
168 dmatrix_t Pj = dmatrix_t::Zero(xi.rows(), Eigen::Index(L + 1));
169 for (
int l = std::abs(m); l <= L; ++l)
171 for (
int i = 0; i < theta.rows(); ++i)
172 Pi(i, l) = legendre_p(l, m, std::cos(theta(i)));
173 for (
int j = 0; j < xi.rows(); ++j)
174 Pj(j, l) = legendre_p(l, m, std::cos(xi(j)));
176 dmatrix_t A = dmatrix_t::Zero(theta.rows(), xi.rows());
177 for (
int l = std::abs(m); l <= L; ++l)
178 A +=
C(l, m) * Pi.col(l) * Pj.col(l).transpose();
179 return A * wxi.asDiagonal();
182 double interpolator::C(
int l,
int m)
184 double constexpr pi = boost::math::constants::pi<double>();
186 double r = (2.0 * l + 1) / (4.0 * pi);
189 for (
int k = l - m + 1; k <= l + m; ++k)
194 for (
int k = l + m + 1; k <= l - m; ++k)