38 #include <boost/math/special_functions/beta.hpp>
51 auto old_handler = gsl_set_error_handler_off();
56 m_coefficients.resize(m_nOrders, m_nOrders);
58 auto binomial_coeff = [&] (
const double n,
const double k) {
60 gsl_sf_result lng_n, lng_k, lng_nmk;
61 double lng_n_sgn, lng_k_sgn, lng_nmk_sgn;
63 int status_n = gsl_sf_lngamma_sgn_e(n+1, &lng_n, &lng_n_sgn);
64 int status_k = gsl_sf_lngamma_sgn_e(k+1, &lng_k, &lng_k_sgn);
65 int status_nmk = gsl_sf_lngamma_sgn_e(n-k+1, &lng_nmk, &lng_nmk_sgn);
67 if(status_n != 0 or status_k != 0 or status_nmk != 0) {
71 return lng_n_sgn/(lng_k_sgn*lng_nmk_sgn)*exp(lng_n.val-lng_k.val-lng_nmk.val);
75 for (
int i=0; i<static_cast<int>(m_nOrders); i++) {
76 double fact = pow(2, i);
77 for (
int j=0; j<static_cast<int>(m_nOrders); j++)
78 m_coefficients(i,j) = fact*binomial_coeff(i, j)*binomial_coeff(
double(i+j-1)*0.5, i);
100 m_set_coefficients (lMax);
109 Eigen::VectorXd m_powers(m_nOrders);
114 for (
size_t i=2; i<m_nOrders; i++)
115 m_powers[i] = m_powers[i-1]*x;
117 return m_coefficients.row(ell).dot(m_powers);
126 Eigen::VectorXd m_powers(m_nOrders);
131 for (
size_t i=2; i<m_nOrders; i++)
132 m_powers[i] = m_powers[i-1]*x;
134 Eigen::VectorXd leg_pols = m_coefficients*m_powers;
136 vector<double> vv(leg_pols.data(), leg_pols.data()+leg_pols.size());
146 Eigen::VectorXd min(m_nOrders);
147 Eigen::VectorXd max(m_nOrders);
148 Eigen::VectorXd norm(m_nOrders);
154 for (
size_t i=1; i<m_nOrders; i++) {
155 min[i] = min[i-1]*x_min;
156 max[i] = max[i-1]*x_max;
157 norm[i] = norm[i-1]+1;
160 return m_coefficients.row(ell).dot( (max-min).cwiseQuotient(norm) )/(x_max-x_min);
169 Eigen::VectorXd min(m_nOrders);
170 Eigen::VectorXd max(m_nOrders);
171 Eigen::VectorXd norm(m_nOrders);
177 for (
size_t i=1; i<m_nOrders; i++) {
178 min[i] = min[i-1]*x_min;
179 max[i] = max[i-1]*x_max;
180 norm[i] = norm[i-1]+1;
183 Eigen::VectorXd leg_pols = m_coefficients*( (max-min).cwiseQuotient(norm) )/(x_max-x_min);
185 vector<double> vv(leg_pols.data(), leg_pols.data()+leg_pols.size());
194 double mu_23 = (r12*r12+r13*r13-r23*r23)/(2*r12*r13);
195 double mu_13 = (r12*r12+r23*r23-r13*r13)/(2*r12*r23);
196 double mu_12 = (r23*r23+r13*r13-r12*r12)/(2*r23*r13);
198 vector<vector<double>> leg_pols;
199 leg_pols.push_back(this->
operator()(mu_23));
200 leg_pols.push_back(this->
operator()(mu_13));
201 leg_pols.push_back(this->
operator()(mu_12));
212 double norm = 2*(pow(r12_max, 3)-pow(r12_min,3))*(pow(r13_max, 3)-pow(r13_min, 3))/9;
214 Eigen::VectorXd m_powers(m_nOrders);
216 for (
int i=0; i<static_cast<int>(m_nOrders); i++) {
218 size_t exponent = i+1;
220 auto r12_integrand = [&] (
const double r12) {
221 auto r13_integrand = [&] (
const double r13) {
222 double x_min = (r12*r12+r13*r13-r23_max*r23_max)/(2*r12*r13);
223 double x_max = (r12*r12+r13*r13-r23_min*r23_min)/(2*r12*r13);
225 if ( x_min>1 or x_max < -1)
230 double low = gsl_pow_uint(max(x_min, -1.), exponent);
231 double up = gsl_pow_uint(min(x_max, 1.), exponent);
232 return r13*r13*(up-low)/exponent;
240 Eigen::VectorXd leg_pols = m_coefficients*m_powers;
242 vector<double> vv(leg_pols.data(), leg_pols.data()+leg_pols.size());
Class to manage Legendre polymials computation.
double operator()(const double x, const int ell)
evaluate the Legendre polynomial of order ell at x
std::vector< double > triangle_integral(const double r12_min, const double r12_max, const double r13_min, const double r13_max, const double r23_min, const double r23_max, const double rel_err=1.e-4, const int nevals=10000)
evaluate the bin-averaged Legendre polynomials over a triangle. Triangle side can vary from a minimum...
double integral(const double x_min, const double x_max, const int ell)
evaluate the bin-averaged Legendre polynomial of order ell
std::vector< std::vector< double > > triangle(const double r12, const double r13, const double r23)
evaluate the Legendre polynomials for triangle angles.
void set(const int lMax)
set maximum order of expansion
void m_set_coefficients(const int lMax)
set internal attribute m_coefficients
LegendrePolynomials()
Default constructor of LegendrePolynomials.
double GSL_integrate_cquad(gsl_function func, const double a, const double b, const double rel_err=1.e-3, const double abs_err=0, const int nevals=100)
integral, using the gsl cquad method
The global namespace of the CosmoBolognaLib