36 #include <boost/math/special_functions/spherical_harmonic.hpp> 
   50   shared_ptr<cbl::glob::STR_closest_probability> pars = static_pointer_cast<cbl::glob::STR_closest_probability>(pp);
 
   61   shared_ptr<cbl::glob::STR_distribution_probability> pars = static_pointer_cast<cbl::glob::STR_distribution_probability>(pp);
 
   62   return pars->func->operator()(xx);
 
   70   shared_ptr<cbl::glob::STR_chainMeshInterpolate> Pars = static_pointer_cast<cbl::glob::STR_chainMeshInterpolate>(pars);
 
   72   int distNum = Pars->DistNum;
 
   81   shared_ptr<cbl::glob::STR_multivariateGaussian> Pars = static_pointer_cast<cbl::glob::STR_multivariateGaussian>(pars);
 
   82   Eigen::VectorXd MeanVec = Pars->MeanVec;
 
   83   Eigen::MatrixXd CovMat = Pars->CovMat;
 
   86   double quadform = (XX-MeanVec).
transpose()*CovMat.inverse()*(XX-MeanVec);
 
   87   double norm = pow(pow(2.*
par::pi,-n)*CovMat.determinant(),-0.5);
 
   88   return norm*exp(-0.5*quadform);
 
   96   double x = pow(r/rc, 3);
 
   97   return pow(2*x*(1.-x), 2)*(0.5-x)*pow(rc, -3);
 
  106   if (inputUnits==CoordinateUnits::_radians_)
 
  109   else if (inputUnits==CoordinateUnits::_arcseconds_)
 
  112   else if (inputUnits==CoordinateUnits::_arcminutes_)
 
  115   else if (inputUnits==CoordinateUnits::_degrees_)
 
  119     return ErrorCBL(
"inputUnits type not allowed!", 
"degrees", 
"Func.cpp");
 
  128   if (inputUnits==CoordinateUnits::_degrees_)
 
  131   else if (inputUnits==CoordinateUnits::_arcseconds_)
 
  132     return angle/180.*
par::pi/3600.;
 
  134   else if (inputUnits==CoordinateUnits::_arcminutes_)
 
  137   else if (inputUnits==CoordinateUnits::_radians_)
 
  141     return ErrorCBL(
"inputUnits type not allowed!", 
"radians", 
"Func.cpp");
 
  150   if (inputUnits==CoordinateUnits::_radians_)
 
  151     return angle*180./
par::pi*3600.;
 
  153   else if (inputUnits==CoordinateUnits::_degrees_)
 
  156   else if (inputUnits==CoordinateUnits::_arcminutes_)
 
  159   else if (inputUnits==CoordinateUnits::_arcseconds_)
 
  163     return ErrorCBL(
"inputUnits type not allowed!", 
"arcseconds", 
"Func.cpp");
 
  172   if (inputUnits==CoordinateUnits::_radians_)
 
  175   else if (inputUnits==CoordinateUnits::_degrees_)
 
  178   else if (inputUnits==CoordinateUnits::_arcseconds_)
 
  181   else if (inputUnits==CoordinateUnits::_arcminutes_)
 
  185     return ErrorCBL(
"inputUnits type not allowed!", 
"arcminutes", 
"Func.cpp");
 
  194   if (outputUnits==CoordinateUnits::_radians_)
 
  195     return radians(angle, inputUnits);
 
  197   else if (outputUnits==CoordinateUnits::_degrees_)
 
  198     return degrees(angle, inputUnits);
 
  200   else if (outputUnits==CoordinateUnits::_arcseconds_)
 
  203   else if (outputUnits==CoordinateUnits::_arcminutes_)
 
  207     return ErrorCBL(
"outputUnits type not allowed!", 
"converted_angle", 
"Func.cpp");
 
  214 void cbl::polar_coord (
const double XX, 
const double YY, 
const double ZZ, 
double &ra, 
double &dec, 
double &dd)
 
  216   dd = sqrt(XX*XX+YY*YY+ZZ*ZZ);
 
  221 void cbl::cartesian_coord (
const double ra, 
const double dec, 
const double dd, 
double &XX, 
double &YY, 
double &ZZ)
 
  223   XX = dd*cos(dec)*cos(ra);
 
  224   YY = dd*cos(dec)*sin(ra);
 
  228 void cbl::polar_coord (
const std::vector<double> XX, 
const std::vector<double> YY, 
const std::vector<double> ZZ, std::vector<double> &ra, std::vector<double> &dec, std::vector<double> &dd)
 
  230   for (
size_t i=0; i<XX.size(); i++) {
 
  231     dd[i] = sqrt(XX[i]*XX[i]+YY[i]*YY[i]+ZZ[i]*ZZ[i]);
 
  232     ra[i] = atan2(YY[i],XX[i]);
 
  233     dec[i] = asin(ZZ[i]/dd[i]);
 
  237 void cbl::cartesian_coord (
const std::vector<double> ra, 
const std::vector<double> dec, 
const std::vector<double> dd, std::vector<double> &XX, std::vector<double> &YY, std::vector<double> &ZZ)
 
  239   for (
size_t i=0; i<XX.size(); i++) {
 
  240     XX[i] = dd[i]*cos(dec[i])*cos(ra[i]);
 
  241     YY[i] = dd[i]*cos(dec[i])*sin(ra[i]);
 
  242     ZZ[i] = dd[i]*sin(dec[i]);
 
  250 double cbl::Euclidean_distance (
const double x1, 
const double x2, 
const double y1, 
const double y2, 
const double z1, 
const double z2)
 
  252   return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
 
  261   double costheta = sin(dec1)*sin(dec2)+cos(dec1)*cos(dec2)*(cos(ra1)*cos(ra2)+sin(ra1)*sin(ra2));
 
  263   if (fabs(costheta)<1.-1.e-30) theta = acos(costheta);
 
  264   else if (costheta>=1.-1.e-30) theta = 0.;
 
  267   double rp = (d1+d2)*tan(theta*0.5);
 
  268   rp *= 4.*d1*d2/((d1+d2)*(d1+d2));
 
  277 double cbl::angular_distance (
const double x1, 
const double x2, 
const double y1, 
const double y2, 
const double z1, 
const double z2)
 
  288   return 2*asin(sqrt(pow(sin((dec2-dec1)*0.5), 2)+cos(dec1)*cos(dec2)*pow(sin((ra2-ra1)*0.5), 2)));
 
  295 double cbl::MC_Int (
double func(
const double), 
const double x1, 
const double x2, 
const int seed)
 
  298   double delta_x = (x2-x1)/step;
 
  300   vector<double> ff(step+1);
 
  301   for (
int i=0; i<step+1; i++) {ff[i] = func(xx); xx += delta_x;}
 
  303   vector<double>::iterator fmin = min_element (ff.begin(),ff.end()),
 
  304     fmax = max_element (ff.begin(),ff.end());
 
  308   f1 = (f1>0) ? f1*0.5 : -fabs(f1)*2.;
 
  314   int sub = 0, subn = 0, numTOT = 10000000;
 
  317     for (
int i=0; i<numTOT; i++) {
 
  318       xt = ran()*(x2-x1)+x1;
 
  320       if (yt<func(xt)) sub ++;
 
  322     INT = double(sub)/double(numTOT)*(x2-x1)*(f2-f1);
 
  325     for (
int i=0; i<numTOT; i++) {
 
  326       xt = ran()*(x2-x1)+x1;
 
  328       if (yt<func(xt)) sub ++;
 
  330     for (
int i=0; i<numTOT; i++) {
 
  331       xt = ran()*(x2-x1)+x1;
 
  333       if (yt>func(xt)) subn ++;
 
  335     INT = (double(sub)/double(numTOT)*(x2-x1)*f2)-(double(subn)/double(numTOT)*(x2-x1)*fabs(f1));
 
  345 double cbl::MC_Int (
double func(
const double, 
const double AA), 
const double AA, 
const double x1, 
const double x2, 
const int seed)
 
  348   double delta_x = (x2-x1)/step;
 
  350   vector<double> ff(step+1);
 
  351   for (
int i=0; i<step+1; i++) {ff[i] = func(xx,AA); xx += delta_x;}
 
  353   vector<double>::iterator fmin = min_element (ff.begin(),ff.end()),
 
  354     fmax = max_element (ff.begin(),ff.end());
 
  358   f1 = (f1>0) ? f1*0.5 : -fabs(f1)*2.;
 
  364   int sub = 0, subn = 0, numTOT = 10;
 
  367     for (
int i=0; i<numTOT; i++) {
 
  368       xt = ran()*(x2-x1)+x1;
 
  370       if (yt<func(xt, AA)) sub ++;
 
  372     INT = double(sub)/double(numTOT)*(x2-x1)*(f2-f1);
 
  375     for (
int i=0; i<numTOT; i++) {
 
  376       xt = ran()*(x2-x1)+x1;
 
  378       if (yt<func(xt,AA)) sub ++;
 
  380     for (
int i=0; i<numTOT; i++) {
 
  381       xt = ran()*(x2-x1)+x1;
 
  383       if (yt>func(xt,AA)) subn ++;
 
  385     INT = (double(sub)/double(numTOT)*(x2-x1)*f2)-(double(subn)/double(numTOT)*(x2-x1)*fabs(f1));
 
  395 double cbl::MC_Int (
double func(
const double, 
const double AA, 
const double BB, 
const double CC, 
const double DD, 
const double EE), 
const double AA, 
const double BB, 
const double CC, 
const double DD, 
const double EE, 
const double x1, 
const double x2, 
const int seed)
 
  398   double delta_x = (x2-x1)/step;
 
  400   vector<double> ff(step+1);
 
  401   for (
int i=0; i<step+1; i++) {ff[i] = func(xx,AA,BB,CC,DD,EE); xx += delta_x;}
 
  403   vector<double>::iterator fmin = min_element (ff.begin(),ff.end()),
 
  404     fmax = max_element (ff.begin(),ff.end());
 
  408   f1 = (f1>0) ? f1*0.5 : -fabs(f1)*2.;
 
  414   int sub = 0, subn = 0, numTOT = 100000;
 
  417     for (
int i=0; i<numTOT; i++) {
 
  418       xt = ran()*(x2-x1)+x1;
 
  420       if (yt<func(xt,AA,BB,CC,DD,EE)) sub ++;
 
  422     INT = double(sub)/double(numTOT)*(x2-x1)*(f2-f1);
 
  425     for (
int i=0; i<numTOT; i++) {
 
  426       xt = ran()*(x2-x1)+x1;
 
  428       if (yt<func(xt,AA,BB,CC,DD,EE)) sub ++;
 
  430     for (
int i=0; i<numTOT; i++) {
 
  431       xt = ran()*(x2-x1)+x1;
 
  433       if (yt>func(xt,AA,BB,CC,DD,EE)) subn ++;
 
  435     INT = (double(sub)/double(numTOT)*(x2-x1)*f2)-(double(subn)/double(numTOT)*(x2-x1)*fabs(f1));
 
  445 double cbl::interpolated (
const double _xx, 
const std::vector<double> xx, 
const std::vector<double> yy, 
const std::string type)
 
  447   if (xx.size()!=yy.size() || xx.size()<2)
 
  450   size_t size = xx.size();
 
  453     return yy[0]+(_xx-xx[0])/(xx[1]-xx[0])*(yy[1]-yy[0]);
 
  455   else if (_xx>xx[size-1])
 
  456     return yy[size-2]+(_xx-xx[size-2])/(xx[size-1]-xx[size-2])*(yy[size-1]-yy[size-2]);
 
  459   gsl_interp_accel *acc = gsl_interp_accel_alloc();
 
  460   const gsl_interp_type *TT;
 
  463     TT = gsl_interp_linear;
 
  465   else if (type==
"Poly")
 
  466     TT = gsl_interp_polynomial;
 
  468   else if (type==
"Spline")
 
  469     TT = gsl_interp_cspline;
 
  471   else if (type==
"Spline_periodic")
 
  472     TT = gsl_interp_cspline_periodic;
 
  474   else if (type==
"Akima")
 
  475     TT = gsl_interp_akima;
 
  477   else if (type==
"Akima_periodic")
 
  478     TT = gsl_interp_akima_periodic;
 
  480   else if (type==
"Steffen")
 
  481     TT = gsl_interp_steffen;
 
  484     ErrorCBL(
"the value of string 'type' is not permitted!", 
"interpolated", 
"Func.cpp");
 
  486   gsl_interp *interp = gsl_interp_alloc(TT, size);
 
  487   gsl_interp_init(interp, xx.data(), yy.data(), size);
 
  490   interp->type->eval(interp->state, xx.data(), yy.data(), interp->size, _xx, acc, &_yy);
 
  492   gsl_interp_free(interp);
 
  493   gsl_interp_accel_free(acc);
 
  502 double cbl::interpolated_2D (
const double _x1, 
const double _x2, 
const std::vector<double> x1, 
const std::vector<double> x2, 
const std::vector<std::vector<double>> yy, 
const std::string type)
 
  506   const size_t size_x1 = x1.size();
 
  507   const size_t size_x2 = x2.size();
 
  508   double *ydata = 
new double[size_x1*size_x2];
 
  510   if ((_x1>
Max(x1) || 
Min(x1)>_x1) ||(_x2>
Max(x2) || 
Min(x2)>_x2))
 
  513   gsl_interp_accel *x1acc = gsl_interp_accel_alloc();
 
  514   gsl_interp_accel *x2acc = gsl_interp_accel_alloc();
 
  515   const gsl_interp2d_type *TT = gsl_interp2d_bilinear;
 
  518     TT = gsl_interp2d_bilinear;
 
  520   else if (type==
"Cubic")
 
  521     TT = gsl_interp2d_bicubic;
 
  523   for (
size_t i=0; i<size_x1; i++)
 
  524     for (
size_t j=0; j<size_x2; j++)
 
  525       ydata[i+j*size_x1] = yy[i][j];
 
  527   gsl_interp2d *interp = gsl_interp2d_alloc(TT, size_x1, size_x2);
 
  528   gsl_interp2d_init(interp, x1.data(), x2.data(), ydata, size_x1, size_x2);
 
  532     val= gsl_interp2d_eval_extrap(interp, x1.data(), x2.data(), ydata, _x1, _x2, x1acc, x2acc);
 
  534     val= gsl_interp2d_eval(interp, x1.data(), x2.data(), ydata, _x1, _x2, x1acc, x2acc);
 
  536   gsl_interp2d_free(interp);
 
  537   gsl_interp_accel_free(x1acc);
 
  538   gsl_interp_accel_free(x2acc);
 
  546 std::vector<double> 
cbl::linear_interpolation_3D (
const std::vector<double> min, std::vector<double> max, std::vector<int> steps, std::vector<std::vector<std::vector<double>>> func, 
const std::vector<std::vector<double>> pos) 
 
  548   if (min.size()!= 3 || max.size()!=3 || steps.size() !=3)
 
  549     ErrorCBL(
"the input grid have a wrong dimension", 
"linear_interpolation_nD", 
"Func.cpp");
 
  551   vector<double> output(pos.size());
 
  552   vector<double> step_dim(3);
 
  553   for (
auto i=0; i<3; i++) step_dim[i] = (max[i]-min[i])/steps[i];
 
  555   for (
size_t i=0; i<pos.size(); i++) {
 
  558     for (
int dim=0; dim<3; dim++) {
 
  559       inds[dim] = (pos[i][dim]-min[dim])/step_dim[dim];
 
  560       if (inds[dim]<0 || (inds[dim]+1)*step_dim[dim]+min[dim] > max[dim])
 
  561     ErrorCBL(
"Point out of grid", 
"linear_interpolation_3D", 
"Func.cpp");
 
  563     double tempX1 = ((pos[i][0]-(min[0]+inds[0]*step_dim[0]))*func[inds[2]][inds[1]][inds[0]+1] - 
 
  564              (pos[i][0]-(min[0]+(inds[0]+1)*step_dim[0]))*func[inds[2]][inds[1]][inds[0]])/step_dim[0];
 
  565     double tempX2 = ((pos[i][0]-(min[0]+inds[0]*step_dim[0]))*func[inds[2]][inds[1]+1][inds[0]+1] - 
 
  566              (pos[i][0]-(min[0]+(inds[0]+1)*step_dim[0]))*func[inds[2]][inds[1]+1][inds[0]])/step_dim[0];
 
  567     double tempX3 = ((pos[i][0]-(min[0]+inds[0]*step_dim[0]))*func[inds[2]+1][inds[1]][inds[0]+1] - 
 
  568              (pos[i][0]-(min[0]+(inds[0]+1)*step_dim[0]))*func[inds[2]+1][inds[1]][inds[0]])/step_dim[0];
 
  569     double tempX4 = ((pos[i][0]-(min[0]+inds[0]*step_dim[0]))*func[inds[2]+1][inds[1]+1][inds[0]+1] - 
 
  570              (pos[i][0]-(min[0]+(inds[0]+1)*step_dim[0]))*func[inds[2]+1][inds[1]+1][inds[0]])/step_dim[0];
 
  571     double tempY1 = ((pos[i][1]-(min[1]+inds[1]*step_dim[1]))*tempX2 - (pos[i][1]-(min[1]+(inds[1]+1)*step_dim[1]))*tempX1)/step_dim[1];
 
  572     double tempY2 = ((pos[i][1]-(min[1]+inds[1]*step_dim[1]))*tempX4 - (pos[i][1]-(min[1]+(inds[1]+1)*step_dim[1]))*tempX3)/step_dim[1];
 
  573     output[i] = ((pos[i][2]-(min[2]+inds[2]*step_dim[2]))*tempY2 - (pos[i][2]-(min[2]+(inds[2]+1)*step_dim[2]))*tempY1)/step_dim[2];
 
  582 void cbl::read_vector (
const std::string file_vector, std::vector<double> &xx, std::vector<double> &vec, 
const std::vector<int> col)
 
  584   vector<int> cols = {0, 1};
 
  585   cols = (col.size() != 2) ? cols : col;
 
  586   const size_t max_col = 
Max(cols);
 
  588   xx.erase(xx.begin(), xx.end());
 
  589   vec.erase(vec.begin(), vec.end());
 
  591   ifstream fin(file_vector.c_str()); 
checkIO(fin, file_vector);
 
  595   while (getline(fin, line)) {
 
  596     stringstream ss(line);
 
  597     vector<double> num; 
double NN = -1.e30;
 
  598     while (ss>>NN) num.push_back(NN);
 
  599     if (num.size()>=max_col) {
 
  600       xx.push_back(num[cols[0]]);
 
  601       vec.push_back(num[cols[1]]);
 
  605   fin.clear(); fin.close();
 
  612 void cbl::read_matrix (
const std::string file_matrix, std::vector<double> &xx, std::vector<double> &yy, std::vector<std::vector<double>> &matrix, 
const std::vector<int> col)
 
  614   vector<int> cols = {0, 1, 2};
 
  615   cols = (col.size() != 3) ? cols : col;
 
  616   const size_t max_col = 
Max(cols);
 
  618   matrix.erase(matrix.begin(), matrix.end());
 
  620   ifstream fin(file_matrix.c_str()); 
checkIO(fin, file_matrix);
 
  623   matrix.push_back(vv);
 
  624   string line; 
size_t i = 0;
 
  626   vector<double> _xx, _yy;
 
  627   while (getline(fin, line)) {
 
  628     stringstream ss(line);
 
  629     vector<double> num; 
double NN = -1.e30;
 
  630     while (ss>>NN) num.push_back(NN);
 
  631     if (num.size()>=max_col) {
 
  632       _xx.push_back(num[cols[0]]);
 
  633       _yy.push_back(num[cols[1]]);
 
  634       matrix[i].push_back(num[cols[2]]);
 
  636     else {i++; matrix.push_back(vv);}
 
  642   fin.clear(); fin.close();
 
  652   gsl_matrix *mm = gsl_matrix_alloc(n, n);
 
  653   gsl_permutation *perm = gsl_permutation_alloc(n);
 
  655   for (
int i=0; i<n; i++)
 
  656     for (
int j=0; j<n; j++)
 
  657       gsl_matrix_set(mm, i, j, mat[i][j]);
 
  660   gsl_linalg_LU_decomp(mm, perm, &s);
 
  661   double det = gsl_linalg_LU_det(mm, s);
 
  664   gsl_permutation_free(perm);
 
  673 void cbl::invert_matrix (
const std::vector<std::vector<double>> mat, std::vector<std::vector<double>> &mat_inv, 
const double prec, 
const int Nres)
 
  675   int size = mat.size();
 
  678   Eigen::MatrixXd inverse = matrix.inverse();
 
  680   Eigen::MatrixXd unity = matrix * inverse;
 
  682   for (
int i=0; i<size; i++) {
 
  683     for (
int j=0; j<size; j++) {
 
  684       const double fact = (i==j) ? 1 : 0;
 
  685       double prod = unity(i, j);
 
  686       if (fabs(fact-prod)>prec)
 
  692     const double fact = 1.-(size+1.)/(Nres-1.); 
 
  705 void cbl::invert_matrix (
const std::vector<std::vector<double>> mat, std::vector<std::vector<double>> &mat_inv, 
const int i1, 
const int i2, 
const double prec, 
const int Nres)
 
  710     ErrorCBL(
"the input matrix has null size", 
"invert_matrix", 
"Func.cpp");
 
  712   mat_inv.erase(mat_inv.begin(), mat_inv.end());
 
  715   gsl_matrix *mm = gsl_matrix_alloc(n, n);
 
  716   gsl_matrix *im = gsl_matrix_alloc(n, n);
 
  717   gsl_permutation * perm = gsl_permutation_alloc(n);
 
  719   for (
int i=i1; i<i2; i++)
 
  720     for (
int j=i1; j<i2; j++)
 
  721       gsl_matrix_set(mm, i-i1, j-i1, mat[i][j]);
 
  724   gsl_linalg_LU_decomp(mm, perm, &s);
 
  727   gsl_linalg_LU_invert(mm, perm, im);
 
  729   for (
int i=0; i<n; i++) {
 
  730     for (
int j=0; j<n; j++) {
 
  731       double fact = (i==j) ? 1 : 0;
 
  733       for (
int el=0; 
el<n; 
el++)
 
  734     prod += mat[i+i1][
el+i1]*gsl_matrix_get(im, 
el, j);
 
  736       if (fabs(fact-prod)>prec)
 
  741   const double fact = (Nres>0) ? 1.-(mat[0].size()+1.)/(Nres-1.) : 1.; 
 
  743   for (
size_t i=0; i<mat.size(); i++) {
 
  744     for (
size_t j=0; j<mat[i].size(); j++) {
 
  745       if (
int(i)<i2 && int(i)>=i1 && int(j)<i2 && int(j)>=i1)
 
  746     mat_inv[i][j] = gsl_matrix_get(im, i-i1, j-i1)*fact;
 
  754   gsl_permutation_free(perm);
 
  761 void cbl::covariance_matrix (
const std::vector<std::vector<double>> mat, std::vector<std::vector<double>> &cov, 
const bool JK)
 
  763   cov.erase(cov.begin(), cov.end());
 
  764   vector<double> vv (mat[0].size(), 0.);
 
  765   for (
size_t i=0; i<mat[0].size(); i++) cov.push_back(vv);
 
  772   for (
size_t i=0; i<mat[0].size(); i++) { 
 
  774     vector<double> vect_temp;
 
  775     for (
size_t j=0; j<mat.size(); j++) 
 
  776       vect_temp.push_back(mat[j][i]);
 
  778     if (vect_temp.size()>2)
 
  779       mean.push_back(
Average(vect_temp));
 
  781       mean.push_back(-1.e30);
 
  788   for (
size_t i=0; i<cov.size(); i++)
 
  789     for (
size_t j=0; j<cov.size(); j++) {
 
  791       for (
size_t k=0; k<mat.size(); k++) {
 
  792     if (mean[i]>-1.e30) {
 
  793       cov[i][j] += (mean[i]-mat[k][i])*(mean[j]-mat[k][j]);
 
  798       if (nm>1) cov[i][j] = (JK) ? 
double(nm-1)/(nm)*cov[i][j] : cov[i][j]/(nm-1);
 
  807 void cbl::covariance_matrix (
const std::vector<std::string> file, std::vector<double> &rad, std::vector<double> &mean, std::vector<std::vector<double>> &cov, 
const bool JK)
 
  809   vector<vector<double>> xi_mocks;
 
  811   string line; 
double r,xi;
 
  812   for (
size_t i=0; i<file.size(); i++) {
 
  813     rad.erase(rad.begin(),rad.end());
 
  815     ifstream fin(file[i].c_str()); 
checkIO(fin, file[i]);
 
  819     while (getline(fin,line)) {
 
  820       stringstream ss(line);
 
  825     fin.clear(); fin.close();
 
  827     xi_mocks.push_back(vv);
 
  832   mean.erase(mean.begin(),mean.end());
 
  834   for (
size_t i=0; i<rad.size(); i++) {
 
  837     for (
size_t j=0; j<xi_mocks.size(); j++)
 
  838       if (xi_mocks[j][i]>-1.e30)
 
  839     vv.push_back(xi_mocks[j][i]);
 
  849 void cbl::covariance_matrix (
const std::vector<std::string> file, 
const std::string covariance_matrix_file, 
const bool JK)
 
  851   vector<double> rad, mean;
 
  852   vector<vector<double>> cov;
 
  855   ofstream fout(covariance_matrix_file.c_str()); 
checkIO(fout, covariance_matrix_file);
 
  857   for (
size_t i=0; i<rad.size(); i++) {
 
  858     for (
size_t j=0; j<rad.size(); j++)
 
  859       fout << rad[i] << 
" " << rad[j] << 
" " << cov[i][j] << 
" " <<  cov[i][j]/sqrt(cov[i][i]*cov[j][j]) << endl;
 
  863   fout.clear(); fout.close();
 
  872   if (vect.size()==0) 
ErrorCBL(
"the input vector has null size", 
"Average", 
"Func.cpp");
 
  874   double aver = 0., NT = 0.;
 
  876 #pragma omp parallel num_threads(omp_get_max_threads()) 
  879     double averT = 0., nT = 0.;
 
  881 #pragma omp for schedule(static, 2) 
  882     for (
size_t i=0; i<vect.size(); ++i)
 
  883       averT += 1./(++nT)*(vect[i]-averT);
 
  886     aver += ((NT+=nT)>0) ? nT/NT*(averT-aver) : 0.;
 
  897 double cbl::Average (
const std::vector<double> vect, 
const std::vector<double> weight)
 
  899   if (vect.size()==0 || vect.size()!=weight.size())
 
  900     ErrorCBL(
"the input vector has null size, or vect.size()!=weight.size()!", 
"Average", 
"Func.cpp");
 
  902   double aver = 0., WeightTOT = 0.;
 
  904 #pragma omp parallel num_threads(omp_get_max_threads()) 
  907     double averT = 0., WeightT = 0.;
 
  909 #pragma omp for schedule(static, 2) 
  910     for (
size_t i=0; i<vect.size(); ++i)
 
  911       averT += weight[i]/(WeightT+=weight[i])*(vect[i]-averT);
 
  914     aver += ((WeightTOT+=WeightT)>0) ? WeightT/WeightTOT*(averT-aver) : 0.;
 
  927   if (vect.size()==0) 
ErrorCBL(
"the input vector has null size", 
"Sigma", 
"Func.cpp");
 
  929   double aver_n1 = 0., aver_n = 0., Sn = 0., sigma = 0., NT = 0.;
 
  931 #pragma omp parallel num_threads(omp_get_max_threads()) 
  934     double aver_n1T = 0., aver_nT = 0., SnT = 0., nT = 0.;
 
  936 #pragma omp for schedule(static, 2) 
  937     for (
size_t i=0; i<vect.size(); ++i) {
 
  939       aver_nT += 1./(++nT)*(vect[i]-aver_nT);
 
  940       SnT += (vect[i]-aver_n1T)*(vect[i]-aver_nT);
 
  948     aver_n += nT/NT*(aver_nT-aver_n);
 
  949     Sn += SnT+pow((aver_nT-aver_n1), 2)*nT*(NT-nT)/NT;
 
  963 double cbl::Sigma (
const std::vector<double> vect, 
const std::vector<double> weight)
 
  965   if (vect.size()==0 || vect.size()!=weight.size())
 
  966     ErrorCBL(
"the input vector has null size, or vect.size()!=weight.size()!", 
"Sigma", 
"Func.cpp");
 
  968   double aver_n1 = 0., aver_n = 0., Sn = 0., sigma = 0., WeightTOT = 0.;
 
  970 #pragma omp parallel num_threads(omp_get_max_threads()) 
  973     double aver_n1T = 0., aver_nT = 0., SnT = 0., WeightT = 0.;
 
  975 #pragma omp for schedule(static, 2) 
  976     for (
size_t i=0; i<vect.size(); ++i) {
 
  978       aver_nT += weight[i]/(WeightT+=weight[i])*(vect[i]-aver_nT);
 
  979       SnT += weight[i]*(vect[i]-aver_n1T)*(vect[i]-aver_nT);
 
  984       WeightTOT += WeightT;
 
  987     aver_n += WeightT/WeightTOT*(aver_nT-aver_n);
 
  988     Sn += SnT+pow((aver_nT-aver_n1), 2)*WeightT*(WeightTOT-WeightT)/WeightTOT;
 
  989     sigma = sqrt(Sn/WeightTOT);
 
 1004   vector<double> vect = Vect;
 
 1005   sort(vect.begin(), vect.end());
 
 1006   vector<double> vect1, vect2;
 
 1008   int start, n = vect.size();
 
 1009   double first = 0., second = 0., third = 0.;
 
 1019     start = int(vect.size()*0.5);
 
 1021     start = int(vect.size()*0.5)+1;
 
 1023       for (
size_t i=0; i<vect.size()*0.5; i++)
 
 1024     vect1.push_back(vect[i]);
 
 1025       for (
size_t i=start; i<vect.size(); i++)
 
 1026     vect2.push_back(vect[i]);
 
 1031     first = (vect1[n*0.5-1]+vect1[(n*0.5)])*0.5;
 
 1033     first = vect1[(n+1)*0.5-1];
 
 1038     second = (vect[n*0.5-1]+vect[(n*0.5)])*0.5;
 
 1040     second = vect[(n+1)*0.5-1];
 
 1045     third = (vect2[n*0.5-1]+vect2[(n*0.5)])*0.5;
 
 1047     third = vect2[(n+1)*0.5-1];
 
 1051   return {first, second, third};
 
 1058 void cbl::Moment (
const std::vector<double> data, 
double &ave, 
double &adev, 
double &sdev, 
double &var, 
double &skew, 
double &curt)
 
 1060   ave = gsl_stats_mean(data.data(), 1, data.size());
 
 1061   adev = gsl_stats_absdev_m(data.data(), 1, data.size(), ave);
 
 1062   var = gsl_stats_variance_m(data.data(), 1, data.size(), ave);
 
 1064   skew = gsl_stats_skew_m_sd(data.data(), 1, data.size(), ave, sdev);
 
 1065   curt = gsl_stats_kurtosis_m_sd(data.data(), 1, data.size(), ave, sdev);
 
 1077   return CC*pow(
bias,0.7)/sqrt(Volume)*exp(n0/(
bias*
bias*density))*100.;
 
 1084 void cbl::measure_var_function (
const std::vector<double> var, 
const int bin, 
const double V_min, 
const double V_max, 
const double Volume, std::vector<double> &
Var, std::vector<double> &Phi, std::vector<double> &err)
 
 1086   if (var.size()==0) 
ErrorCBL(
"there are no objectes in the sample!", 
"measure_var_function", 
"Func.cpp");
 
 1089   Phi.erase(Phi.begin(),Phi.end());
 
 1090   err.erase(err.begin(),err.end());
 
 1092   double delta_logV = (log10(V_max)-log10(V_min))/bin;
 
 1094   double V2 = V_min*pow(10.,delta_logV);
 
 1096   for (
int y=0; y<bin; y++) {
 
 1099     for (
size_t k=0; k<var.size(); k++)
 
 1100       if (V1<var[k] && var[k]<=V2) nHalo ++;
 
 1102     double PHI = nHalo/(V2-V1)/Volume;
 
 1103     double ERR = sqrt(nHalo)/(V2-V1)/Volume;
 
 1105     Var.push_back(pow(10.,(log10(V1)+log10(V2))*0.5));
 
 1110     V2 = V1*pow(10.,delta_logV);
 
 1118 void cbl::bin_function (
const std::string file_grid, 
double func(
double, 
void *), 
void *par, 
const int bin, 
const double x_min, 
const double x_max, 
const std::string binning, std::vector<double> &xx, std::vector<double> &yy)
 
 1120   if (binning != 
"lin" && binning != 
"loglin" && binning != 
"log")
 
 1121     ErrorCBL(
"binning can only be: lin, loglin or log!", 
"bin_function", 
"Func.cpp");
 
 1123   xx.resize(bin), yy.resize(bin);
 
 1125   ifstream fin (file_grid.c_str());
 
 1131     for (
int i=0; i<bin; i++) {
 
 1136     fin.clear(); fin.close();
 
 1138     if (
int(xx.size())!=bin)
 
 1144     coutCBL <<
"I'm creating the grid file: "<<file_grid<<
"..."<<endl;
 
 1146     fin.clear(); fin.close();
 
 1148     double X_min = x_min;
 
 1149     double X_max = x_max;
 
 1151     if (binning != 
"lin") {
 
 1152       if (x_min<0 || x_max<0)
 
 1155       X_min = log10(x_min);
 
 1156       X_max = log10(x_max);
 
 1161     ofstream fout(file_grid.c_str()); 
checkIO(fout, file_grid);
 
 1163     for (
size_t i=0; i<xx.size(); i++) {
 
 1164       yy[i] = (binning==
"lin") ? func(xx[i], par) : func(pow(10., xx[i]), par);
 
 1166       if (binning==
"log") {
 
 1167     if (yy[i]<0) 
ErrorCBL(
"yy[i]<0!", 
"bin_function", 
"Func.cpp");
 
 1168     else yy[i] = log10(yy[i]);
 
 1171       fout <<xx[i]<<
"   "<<yy[i]<<endl;
 
 1172       coutCBL <<xx[i]<<
"   "<<yy[i]<<endl;
 
 1174     fout.clear(); fout.close(); 
coutCBL <<
"I wrote the file: "<<file_grid<<endl;
 
 1183 void cbl::bin_function_2D (
const std::string file_grid, 
double func(
double *, 
size_t, 
void *), 
void *par, 
const int bin, 
const double x1_min, 
const double x1_max, 
const double x2_min, 
const double x2_max, 
const std::string binning, std::vector<double> &xx1, std::vector<double> &xx2, std::vector<std::vector<double>> &yy)
 
 1185   if (binning != 
"lin" && binning != 
"loglin" && binning != 
"log")
 
 1186     ErrorCBL(
"binning can only be: lin, loglin or log !", 
"bin_function_2D", 
"Func.cpp");
 
 1188   xx1.resize(bin), xx2.resize(bin); yy.resize(bin);
 
 1190   ifstream fin (file_grid.c_str());
 
 1194     double XX1, XX2, YY;
 
 1196     for (
int i=0; i<bin; i++) {
 
 1197       for (
int j=0; j<bin; j++) {
 
 1200     if (j==0) xx1[i] = XX1;
 
 1201     if (i==0) xx2[j] = XX2;
 
 1202     yy[i].push_back(YY);
 
 1205     fin.clear(); fin.close();
 
 1207     if (
int(xx1.size())!=bin || 
int(xx2.size())!=bin)
 
 1214     coutCBL <<
"I'm creating the grid file: "<<file_grid<<
"..."<<endl;
 
 1216     fin.clear(); fin.close();
 
 1218     double X1_min = x1_min;
 
 1219     double X1_max = x1_max;
 
 1220     double X2_min = x2_min;
 
 1221     double X2_max = x2_max;
 
 1223     if (binning != 
"lin") {
 
 1224       if (x1_min<0 || x1_max<0 || x2_min<0 || x2_max<0)
 
 1227       X1_min = log10(x1_min);
 
 1228       X1_max = log10(x1_max);
 
 1229       X2_min = log10(x2_min);
 
 1230       X2_max = log10(x2_max);
 
 1236     ofstream fout(file_grid.c_str()); 
checkIO(fout, file_grid);
 
 1239     for (
int i=0; i<bin; i++) {
 
 1240       for (
int j=0; j<bin; j++) {
 
 1242     if (binning==
"lin") {vec[0] = xx1[i]; vec[1] = xx2[j];}
 
 1243     else {vec[0] = pow(10.,xx1[i]); vec[1] = pow(10.,xx2[j]);}
 
 1245     double ff = (binning==
"log") ? log10(func(vec, 2, par)) : func(vec, 2, par);
 
 1246     yy[i].push_back(ff);
 
 1248     fout <<xx1[i]<<
"   "<<xx2[j]<<
"   "<<yy[i][j]<<endl;
 
 1249     coutCBL <<
"--> "<<xx1[i]<<
"   "<<xx2[j]<<
"   "<<yy[i][j]<<endl;
 
 1254     fout.clear(); fout.close(); 
coutCBL <<
"I wrote the file: "<<file_grid<<endl;
 
 1264 double cbl::func_grid_lin (
double xx, 
void *params)
 
 1266   struct cbl::glob::STR_grid *pp = (
struct cbl::glob::STR_grid *) params;
 
 1275 double cbl::func_grid_loglin (
double xx, 
void *params)
 
 1277   struct cbl::glob::STR_grid *pp = (
struct cbl::glob::STR_grid *) params;
 
 1279   double lgx = log10(xx);
 
 1288 double cbl::func_grid_log (
double xx, 
void *params)
 
 1290   struct cbl::glob::STR_grid *pp = (
struct cbl::glob::STR_grid *) params;
 
 1292   double lgx = log10(xx);
 
 1294   return pow(10., 
interpolated(lgx, pp->_xx, pp->_yy, 
"Linear"));
 
 1301 double cbl::func_grid_lin_2D (
double *xx, 
size_t dim, 
void *params)
 
 1305   struct cbl::glob::STR_grid_2D *pp = (
struct cbl::glob::STR_grid_2D *) params;
 
 1307   return interpolated_2D(xx[0], xx[1], pp->_xx1, pp->_xx2, pp->_yy, 
"Linear");
 
 1314 double cbl::func_grid_loglin_2D (
double *xx, 
size_t dim, 
void *params)
 
 1318   struct cbl::glob::STR_grid_2D *pp = (
struct cbl::glob::STR_grid_2D *) params;
 
 1320   double lgx1 = log10(xx[0]);
 
 1321   double lgx2 = log10(xx[1]);
 
 1323   return interpolated_2D(lgx1, lgx2, pp->_xx1, pp->_xx2, pp->_yy, 
"Linear");
 
 1330 double cbl::func_grid_log_2D (
double *xx, 
size_t dim, 
void *params)
 
 1334   struct cbl::glob::STR_grid_2D *pp = (
struct cbl::glob::STR_grid_2D *) params;
 
 1336   double lgx1 = log10(xx[0]);
 
 1337   double lgx2 = log10(xx[1]);
 
 1339   return pow(10., 
interpolated_2D(lgx1, lgx2, pp->_xx1, pp->_xx2, pp->_yy, 
"Linear"));
 
 1349   while (angle < minval)
 
 1352   while (angle > maxval)
 
 1360   if (fabs(theta)>90) {
 
 1361     theta = 180.0 - theta;
 
 1368   if (fabs(theta)==90.)
 
 1373 void cbl::eq2sdss (
const std::vector<double> ra, 
const std::vector<double> dec, std::vector<double> &lambda, std::vector<double> &eta)
 
 1375   lambda.resize(ra.size());
 
 1376   eta.resize(ra.size());
 
 1378   double SurveyCenterRa = 185.-90, SurveyCenterDec = 32.5;
 
 1381   for (
size_t i=0; i<ra.size(); i++) {
 
 1382     double x = cos((ra[i]-SurveyCenterRa*d2r))*cos(dec[i]);
 
 1383     double y = sin((ra[i]-SurveyCenterRa*d2r))*cos(dec[i]);
 
 1384     double z = sin(dec[i]);
 
 1386     lambda[i] = -asin(x)/d2r;
 
 1387     eta[i] = atan2(z, y)/d2r - SurveyCenterDec;
 
 1397 void cbl::sdss2eq (
const std::vector<double> lambda, 
const std::vector<double> eta, std::vector<double> &ra, std::vector<double> &dec)
 
 1399   ra.resize(lambda.size());
 
 1400   dec.resize(lambda.size());
 
 1402   double SurveyCenterRa = 185., SurveyCenterDec = 32.5;
 
 1405   for (
size_t i=0; i<ra.size(); i++) {
 
 1406     double x =  -1.0*sin(lambda[i]*d2r);
 
 1407     double y = cos(lambda[i]*d2r)*cos(eta[i]*d2r+SurveyCenterDec*d2r);
 
 1408     double z = cos(lambda[i]*d2r)*sin(eta[i]*d2r+SurveyCenterDec*d2r);
 
 1410     ra[i] = atan2(y,x)/d2r+SurveyCenterRa-90;
 
 1411     dec[i] = asin(z)/d2r;
 
 1420 void cbl::sdss_stripe (
const std::vector<double> eta, 
const std::vector<double> lambda, std::vector<int> &stripe, std::vector<int> &str_u)
 
 1422   stripe.resize(eta.size());
 
 1423   str_u.resize(eta.size());
 
 1425   double stripe_sep=2.5;
 
 1428   for (
size_t i=0; i<eta.size(); i++) {
 
 1430     if (lambda[i]<90.0) stripe[i] = (eta[i]+cen)/stripe_sep;
 
 1431     if (lambda[i]>90.0) stripe[i] = (eta[i]+cen+180.)/stripe_sep;
 
 1433     str_u[i] = stripe[i];
 
 1436   sort(str_u.begin(), str_u.end());
 
 1437   vector<int>::iterator it = unique(str_u.begin(), str_u.end());
 
 1438   str_u.resize(distance(str_u.begin(), it));
 
 1455 std::vector<double> 
cbl::vector_from_distribution (
const int nRan, 
const std::vector<double> xx, 
const std::vector<double> fx, 
const double xmin, 
const double xmax, 
const int seed)
 
 1462   vector<double> Fx, new_x;
 
 1466     vector<double> Fx_test(sz, 0.);
 
 1472     for (
int i=1; i<sz; ++i)
 
 1475     if (is_sorted(Fx_test.begin(), Fx_test.end())) {
 
 1482     if (sz<30) 
ErrorCBL(
"the input distribution cannot be integrated properly!", 
"vector_from_distribution", 
"Func.cpp");
 
 1488   vector<double> varRandom;
 
 1490   while (varRandom.size()<
unsigned(nRan)) {
 
 1491     double xx = ff(ran());
 
 1492     if (xmin<=xx && xx<=xmax)
 
 1493       varRandom.emplace_back(xx);
 
 1505   size_t ind1 = xx.size(), ind2 = 0;
 
 1507   for (
size_t i=0; i<xx.size(); i++)
 
 1508     if (x_min<xx[i] && xx[i]<x_max) {
 
 1509       ind1 = min(i, ind1);
 
 1510       ind2 = max(i, ind2);
 
 1515   return {ind1, ind2};
 
 1522 void cbl::read_invert_covariance (
const std::string filecov, std::vector< std::vector<double>> &cov, std::vector<std::vector<double>> &cov_inv, 
const size_t i1, 
const size_t i2, 
const double prec, 
const int Nres)
 
 1524   size_t size = i2-i1+1;
 
 1526   cov.erase(cov.begin(), cov.end());
 
 1527   cov_inv.erase(cov_inv.begin(), cov_inv.end());
 
 1529   ifstream fin(filecov.c_str()); 
checkIO(fin, filecov);
 
 1531   cov.erase(cov.begin(), cov.end());
 
 1535   string line; 
size_t i = 0;
 
 1537   while (getline(fin, line)) {
 
 1538     stringstream ss(line);
 
 1539     vector<double> num; 
double NN = -1.e30;
 
 1540     while (ss>>NN) num.push_back(NN);
 
 1541     if (num.size()==3 && num[2]>-1.e29)
 
 1542       cov[i].push_back(num[2]);
 
 1543     else {i++; cov.push_back(vv);}
 
 1546   cov.erase(cov.end()-1, cov.end());
 
 1547   fin.clear(); fin.close();
 
 1550   vector<vector<double>> cov_lim(size,vector<double>(size, 0)), cov_lim_inv;
 
 1552   size_t tot_size = cov.size();
 
 1554   for (
size_t i=0; i<tot_size; i++) {
 
 1555     for (
size_t j=0; j<tot_size; j++) {
 
 1556       if (i>i2 || i<i1 || j>i2 || j<i1) {
 
 1559     cov_lim[i-i1][j-i1] = cov[i][j];
 
 1565   for (
size_t i=0; i<tot_size; i++) {
 
 1566     for (
size_t j=0; j<tot_size; j++) {
 
 1567       if (i>i2 || i<i1 || j>i2 || j<i1)
 
 1570     cov_inv[i][j] = cov_lim_inv[i-i1][j-i1];
 
 1580 void cbl::convolution (
const std::vector<double> f1, 
const std::vector<double> f2, std::vector<double> &res, 
const double deltaX)
 
 1582   size_t nn = f1.size();
 
 1583   if (nn!=f2.size()) 
ErrorCBL(
"the two functions have to have equal sizes!", 
"convolution", 
"Func.cpp");
 
 1585   double *ff1 = 
new double[nn];
 
 1586   double *ff2 = 
new double[nn];
 
 1587   double *rr = 
new double[nn];
 
 1589   for (
size_t i=0; i<nn; i++) {
 
 1595   gsl_fft_real_wavetable *real;
 
 1596   gsl_fft_halfcomplex_wavetable *hc;
 
 1597   gsl_fft_real_workspace *work;
 
 1599   work = gsl_fft_real_workspace_alloc(nn);
 
 1600   real = gsl_fft_real_wavetable_alloc(nn);
 
 1602   gsl_fft_real_transform(ff1, 1., nn, real, work);
 
 1603   gsl_fft_real_transform(ff2, 1., nn, real, work);
 
 1605   gsl_fft_real_wavetable_free(real);
 
 1610   rr[0] = ff1[0]*ff2[0];
 
 1613     for (
unsigned int i=1; i<nn; i+=2) {
 
 1614       rr[i] = ff1[i]*ff2[i]-ff1[i+1]*ff2[i+1];
 
 1615       rr[i+1] = ff1[i]*ff2[i+1]+ff2[i]*ff1[i+1];
 
 1619     for (
unsigned int i=1; i<nn-1; i+=2) {
 
 1620       rr[i] = ff1[i]*ff2[i]-ff1[i+1]*ff2[i+1];
 
 1621       rr[i+1] = ff1[i]*ff2[i+1]+ff2[i]*ff1[i+1];
 
 1623     rr[nn-1] = ff1[nn-1]*ff2[nn-1];
 
 1629   hc = gsl_fft_halfcomplex_wavetable_alloc(nn);
 
 1631   gsl_fft_halfcomplex_inverse(rr, 1., nn, hc, work);
 
 1633   gsl_fft_halfcomplex_wavetable_free(hc);
 
 1640   for (
unsigned int i=0; i<=nn/2; i++)
 
 1641     res[i] = deltaX*rr[i+nn/2];
 
 1643   for (
unsigned int i=nn/2+1; i<nn; i++)
 
 1644     res[i] = deltaX*rr[i-nn/2-1];
 
 1646   if (nn%2==0) res[nn/2] = res[nn/2-1];
 
 1654 void cbl::distribution (std::vector<double> &xx, std::vector<double> &fx, std::vector<double> &err, 
const std::vector<double> FF, 
const std::vector<double> WW, 
const int nbin, 
const bool linear, 
const std::string file_out, 
const double fact, 
const double V1, 
const double V2, 
const std::string bin_type, 
const bool conv, 
const double sigma)
 
 1656   if (xx.size()>0 || fx.size()>0 || FF.size()<=0 || nbin<=0)
 
 1657     ErrorCBL(
"the following conditions have to be satisfied: xx.size()<=0, fx.size()<=0, FF.size()>0 and nbin>0. The values recived are instead: xx.size() = "+
cbl::conv(xx.size(), 
par::fINT)+
", fx.size() = "+
cbl::conv(fx.size(), 
par::fINT)+
", FF.size() = "+
cbl::conv(FF.size(), 
par::fINT)+
"and nbin = "+
cbl::conv(nbin, 
par::fINT)+
"!", 
"distribution", 
"Func.cpp");
 
 1665   gsl_histogram *histo = gsl_histogram_alloc(nbin);
 
 1667   if (linear) gsl_histogram_set_ranges_uniform(histo, minFF, maxFF);
 
 1671     double *vvv = 
new double[nbin+1]; 
for (
int i=0; i<nbin+1; i++) vvv[i] = vv[i];
 
 1672     gsl_histogram_set_ranges(histo, vvv, nbin+1);
 
 1675   vector<double> Weight = WW;
 
 1676   if (Weight.size()==0) Weight.resize(FF.size(), 1.);
 
 1679   for (
size_t i=0; i<FF.size(); i++)
 
 1680     gsl_histogram_accumulate(histo, FF[i], Weight[i]);
 
 1684   for (
int i=0; i<nbin; i++) {
 
 1686     gsl_histogram_get_range(histo, i, &x1, &x2);
 
 1687     double val = gsl_histogram_get(histo, i);
 
 1689     if (linear) xx.push_back(0.5*(x1+x2));
 
 1690     else xx.push_back(pow(10., 0.5*(log10(x1)+log10(x2))));
 
 1692     if (bin_type == 
"Linear") {
 
 1693       fx.push_back(val/((x2-x1)*fact));
 
 1694       err.push_back(sqrt(val)/((x2-x1)*fact));
 
 1697     else if (bin_type == 
"Log") {
 
 1698       fx.push_back(val/((log(x2)-log(x1))*fact));
 
 1699       err.push_back(sqrt(val)/((log(x2)-log(x1))*fact));
 
 1702     else if (bin_type == 
"Log10") {
 
 1703       fx.push_back(val/((log10(x2)-log10(x1))*fact));
 
 1704       err.push_back(sqrt(val)/((log10(x2)-log10(x1))*fact));
 
 1708       ErrorCBL(
"the value of string 'bin_type' is not permitted, possible selections are 'Linear', 'Log', 'Log10'!", 
"distribution", 
"Func.cpp");
 
 1718     coutCBL << 
"The distribution is smoothed with a Gaussian filter" << endl;
 
 1720     fftw_complex *func_tr;
 
 1724     int i1 = nbin*0.5, i2 = 1.5*nbin;
 
 1726     int nbinK = 0.5*nbinN+1;
 
 1728     func = fftw_alloc_real(nbinN);
 
 1729     func_tr = fftw_alloc_complex(nbinK);
 
 1731     for (
int i=0; i<nbinN; i++)
 
 1734     for (
int i=i1; i<i2; i++)
 
 1737     for (
int i=0; i<nbinK; i++) {
 
 1742     fftw_plan real2complex;
 
 1743     real2complex = fftw_plan_dft_r2c_1d(nbinN, func, func_tr, FFTW_ESTIMATE);
 
 1744     fftw_execute(real2complex);
 
 1745     fftw_destroy_plan(real2complex);
 
 1747     double delta = (maxFF-minFF)/nbin;
 
 1748     double SS = pow(sigma,2);
 
 1750     double fact = 2*
par::pi/(nbinN*delta);
 
 1751     for (
int i=0; i<nbinK; i++) {
 
 1753       func_tr[i][0] = func_tr[i][0]*exp(-0.5*kk*kk*SS);
 
 1754       func_tr[i][1] = func_tr[i][1]*exp(-0.5*kk*kk*SS);
 
 1757     fftw_plan complex2real;
 
 1758     complex2real = fftw_plan_dft_c2r_1d(nbinN, func_tr, func, FFTW_ESTIMATE);
 
 1759     fftw_execute(complex2real);
 
 1760     fftw_destroy_plan(complex2real);
 
 1762     for (
int i=i1; i<i2; i++)
 
 1763       fx[i-i1] = func[i]/nbinN;
 
 1769     ofstream fout(file_out.c_str()); 
checkIO(fout, file_out);
 
 1771     for (
size_t i=0; i<xx.size(); i++)
 
 1772       fout << xx[i] << 
"   " << fx[i] << 
"   " << err[i] << endl;
 
 1774     fout.clear(); fout.close(); 
coutCBL << 
"I wrote the file: " << file_out << endl;
 
 1777   gsl_histogram_free(histo);
 
 1788   return gsl_sf_legendre_Pl(l,mu);
 
 1798   int *l = (
int *)(params);
 
 1820   return integral/(2*ll+1);
 
 1836 double cbl::Legendre_polynomial_triangles_average (
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 int ll, 
const double rel_err, 
const double abs_err, 
const int nevals)
 
 1838   double norm = 2*(pow(r12_max, 3)-pow(r12_min,3))*(pow(r13_max, 3)-pow(r13_min, 3))/9;
 
 1840   auto r12_integrand = [&] (
const double r12) {
 
 1842     auto r13_integrand = [&] (
const double r13) {
 
 1843       double mu_min = (r12*r12+r13*r13-r23_max*r23_max)/(2*r12*r13);
 
 1844       double mu_max = (r12*r12+r13*r13-r23_min*r23_min)/(2*r12*r13);
 
 1846       if ((mu_min<=1) & (mu_max>=-1)) {
 
 1847     double low = max(mu_min, -1.);
 
 1848     double up = min(1., mu_max);
 
 1869   const int nBins = int((rMax-rMin)/deltaR);
 
 1871   vector<double> r12, r13, r23;
 
 1874   for (
int i=0; i<nBins; i++)
 
 1875     for (
int j=i; j<nBins; j++) {
 
 1877       double r12_min = rMin+i*deltaR;
 
 1878       double r12_max = r12_min+deltaR;
 
 1880       double r13_min = rMin+j*deltaR;
 
 1881       double r13_max = r13_min+deltaR;
 
 1883       double r23_min = max(0., r13_min-r12_max);
 
 1884       double r23_max = r13_max+r12_max;
 
 1886       int nBins_R23 = int(( r23_max-r23_min)/deltaR);
 
 1888       for ( 
int k=0; k<nBins_R23; k++) {
 
 1889     r12.push_back(0.5*(r12_min+r12_max));
 
 1890     r13.push_back(0.5*(r13_min+r13_max));
 
 1891     r23.push_back(r23_min+(k+0.5)*deltaR);
 
 1895   int nTriangles = 
static_cast<int>(r12.size());
 
 1896   int nOrders = lMax+1;
 
 1898   vector<vector<double>> leg_pols(nTriangles, vector<double>(nOrders+3, 0.));
 
 1900 #pragma omp parallel num_threads(omp_get_max_threads()) 
 1905 #pragma omp for schedule(dynamic) 
 1906     for (
int i=0; i<nTriangles; i++) {
 
 1908       double r12_min = r12[i]-0.5*deltaR;
 
 1909       double r12_max = r12[i]+0.5*deltaR;
 
 1911       double r13_min = r13[i]-0.5*deltaR;
 
 1912       double r13_max = r13[i]+0.5*deltaR;
 
 1914       double r23_min = r23[i]-0.5*deltaR;
 
 1915       double r23_max = r23[i]+0.5*deltaR;
 
 1917       leg_pols[i][0] = r12[i];
 
 1918       leg_pols[i][1] = r13[i];
 
 1919       leg_pols[i][2] = r23[i];
 
 1921       vector<double> integral = legendre.
triangle_integral(r12_min, r12_max, r13_min, r13_max, r23_min, r23_max, rel_err, nevals);
 
 1923       for (
int ell=0; ell<nOrders; ell++)
 
 1924     leg_pols[i][ell+3] = integral[ell];
 
 1943     double xx=coord1, yy=coord2, zz=coord3;
 
 1944     const double sintheta = sin(acos(zz));
 
 1945     complex<double> exp_iphi(xx/(sintheta), yy/(sintheta));
 
 1948       complex<double> pow_exp = pow(exp_iphi, -m);
 
 1949       double fact = gsl_sf_legendre_sphPlm (l, -m, zz);
 
 1950       return conj(fact*pow_exp);
 
 1953       complex<double> pow_exp = pow(exp_iphi, m);
 
 1954       double fact = pow(-1.,m)*gsl_sf_legendre_sphPlm(l, m, zz);
 
 1955       return fact*pow_exp;
 
 1963     return pow(-1.,m)*boost::math::spherical_harmonic(l, m, 
colatitude, RA);
 
 1975   const int nl = lmax+1;
 
 1977   const double sintheta = sin(acos(zz));
 
 1978   complex<double> exp_iphi(xx/(sintheta), yy/(sintheta));
 
 1980   vector<complex<double>> pow_exp(nl+1);
 
 1981   vector<double> norm(nl+1);
 
 1983   for (
int mm=0; mm<nl+1; mm++){
 
 1984     norm[mm] = pow(-1., mm);
 
 1985     pow_exp[mm] = pow(exp_iphi, mm);
 
 1988   vector<vector<complex<double>>> coeff(nl);
 
 1990   for(
int ll=0; ll< nl; ll++){
 
 1992     vector<complex<double>> ylm(ll+1);
 
 1994     for (
int mm=0; mm<ll+1; mm++){
 
 1995       double fact = norm[mm]*gsl_sf_legendre_sphPlm (ll, mm, zz);
 
 1996       ylm[mm] = fact*pow_exp[mm];
 
 2011   const int n_sph = gsl_sf_legendre_array_n(lmax);
 
 2013   vector<double> Plm(n_sph, 0);
 
 2014   vector<complex<double>> sph(n_sph);
 
 2016   double phi = atan2(yy, xx);
 
 2018   vector<complex<double>> pow_exp(lmax+2, complex<double>(cos(phi), sin(phi)));
 
 2020   for (
int mm=0; mm<lmax+2; mm++)
 
 2021     pow_exp[mm] = pow(pow_exp[mm], mm);
 
 2023   gsl_sf_legendre_array_e(GSL_SF_LEGENDRE_SPHARM, lmax, zz, 1., Plm.data());
 
 2027   for(
int l=0; l<lmax+1; l++)
 
 2028     for (
int m=0; m<l+1; m++){
 
 2029       sph[n] = pow_exp[m]*Plm[n];
 
 2041   return gsl_sf_bessel_jl(0, xx);
 
 2050   return gsl_sf_bessel_jl(2, xx);
 
 2059   return gsl_sf_bessel_jl(4, xx);
 
 2068   return gsl_sf_bessel_jl(order, xx);
 
 2077   double volume = (pow(r_up,3)-pow(r_down,3))/3;
 
 2078   double up = (sin(kk*r_up)-kk*r_up*cos(kk*r_up))*pow(kk,-3);
 
 2079   double down = (sin(kk*r_down)-kk*r_down*cos(kk*r_down))*pow(kk,-3);
 
 2089   double volume = (pow(r_up,3)-pow(r_down,3))/3;
 
 2090   double up = (3*gsl_sf_Si(kk*r_up)-4*sin(kk*r_up)+kk*r_up*cos(kk*r_up))*pow(kk,-3);
 
 2091   double down = (3*gsl_sf_Si(kk*r_down)-4*sin(kk*r_down)+kk*r_down*cos(kk*r_down))*pow(kk,-3);
 
 2101   cbl::glob::STR_jl_distance_average *par = (cbl::glob::STR_jl_distance_average *)(params);
 
 2102   return rr*rr*gsl_sf_bessel_jl(par->order, par->k*rr);
 
 2111   double volume = (pow(r_up,3)-pow(r_down,3))/3;
 
 2113   auto integrand = [&] (
const double rr) {
 
 2114     return rr * rr * gsl_sf_bessel_jl(order, kk*rr);
 
 2146   size_t sample_size = mean.size();
 
 2147   vector<double> sample;
 
 2150   gsl_matrix *correlation = gsl_matrix_alloc(sample_size, sample_size);
 
 2152   for (
size_t i=0; i<sample_size; i++) {
 
 2153     std.push_back(sqrt(covariance[i][i]));
 
 2154     sample.push_back(ran());
 
 2155     for (
size_t j=0; j<sample_size; j++) {
 
 2156       double corr = covariance[i][j]/sqrt(covariance[i][i]*covariance[j][j]);
 
 2158         ErrorCBL(
"negative value on the covariance diagonal!", 
"generate_correlated_data", 
"Func.cpp");
 
 2159       gsl_matrix_set(correlation,i,j, corr);
 
 2166   gsl_vector *eigenvalues = gsl_vector_alloc(sample_size);
 
 2167   gsl_matrix *VV = gsl_matrix_alloc(sample_size, sample_size);
 
 2168   gsl_matrix_set_zero(VV);
 
 2170   gsl_matrix *eigenvectors = gsl_matrix_alloc(sample_size, sample_size);
 
 2172   gsl_eigen_symmv_workspace *ww = gsl_eigen_symmv_alloc(sample_size);
 
 2173   gsl_eigen_symmv (correlation, eigenvalues, eigenvectors, ww);
 
 2174   gsl_eigen_symmv_free(ww);
 
 2176   for (
size_t j = 0; j<sample_size; j++) {
 
 2177     for (
size_t i = 0; i<sample_size; i++) {
 
 2178       if (gsl_vector_get(eigenvalues, j)<0)
 
 2179         ErrorCBL(
"covariance matrix must be positive (semi-)definite but has at least one negative eigenvalue!", 
"generate_correlated_data", 
"Func.cpp");
 
 2180       double v1 = gsl_matrix_get(eigenvectors, i, j);
 
 2181       double v2 = sqrt(gsl_vector_get(eigenvalues, j));
 
 2182       gsl_matrix_set(VV, i, j, v1*v2);
 
 2186   vector<double> cov_sample;
 
 2187   for (
size_t i=0; i<sample_size; i++) {
 
 2188     gsl_vector *row = gsl_vector_alloc(sample_size);
 
 2189     gsl_matrix_get_row(row, VV, i);
 
 2190     cov_sample.push_back(0);
 
 2191     for (
size_t j=0; j<sample_size; j++)
 
 2192       cov_sample[i] += gsl_vector_get(row, j)*sample[j];
 
 2193     cov_sample[i] = std[i]*cov_sample[i]+mean[i];
 
 2207   for (
size_t i=0; i<xx.size()-1; i++)
 
 2208     Int += 0.5*(yy[i+1]+yy[i])*(xx[i+1]-xx[i]);
 
 2219   return double(gsl_sf_fact(n))/double(gsl_sf_fact(m)*gsl_sf_fact(n-m));
 
 2226 template <
typename T>        
 
 2229   int sgn = (T(0) < val) - (val < T(0));
 
 2242   double T1 = l1*l1-pow(l2-l3,2.0);
 
 2243   double T2 = pow(l2+l3+1.0,2.0)-l1*l1;
 
 2244   double T3 = l1*l1-m1*m1;
 
 2246   return sqrt(T1*T2*T3);
 
 2255   double T1 = -(2.0*l1+1.0);
 
 2256   double T2 = l2*(l2+1.0)*m1;
 
 2257   double T3 = l3*(l3+1.0)*m1;
 
 2258   double T4 = l1*(l1+1.0)*(m3-m2);
 
 2260   return T1*(T2-T3-T4);
 
 2267 std::vector<double> 
cbl::wigner3j(
double l2, 
double l3, 
double m1, 
double m2, 
double m3)
 
 2271   double huge = sqrt(std::numeric_limits<double>::max()/20.0);
 
 2272   double srhuge = sqrt(huge);
 
 2273   double tiny = std::numeric_limits<double>::min();
 
 2274   double srtiny = sqrt(tiny);
 
 2275   double eps = std::numeric_limits<double>::epsilon();
 
 2280         std::fabs(m1+m2+m3)<eps
 
 2281         && std::fabs(m2) <= l2+eps
 
 2282         && std::fabs(m3) <= l3+eps
 
 2285   if (!select) 
return std::vector<double>(1,0.0);
 
 2288   double l1min = std::max(std::fabs(l2-l3),std::fabs(m1));
 
 2289   double l1max = l2+l3;
 
 2292   int size = (int)std::floor(l1max-l1min+1.0+eps);
 
 2293   std::vector<double> thrcof(size,0.0);
 
 2298       thrcof[0] = pow(-1.0,std::floor(std::fabs(l2+m2-l3+m3)))/sqrt(l1min+l2+l3+1.0);
 
 2308       double alphaNew, l1(l1min);
 
 2310     alphaNew = -(m3-m2+2.0*
wigner3j_auxB(l1,l2,l3,m1,m2,m3))/
wigner3j_auxA(1.0,l2,l3,m1,m2,m3);
 
 2316       thrcof[1] = alphaNew*thrcof[0];
 
 2325       double alphaOld, alphaNew, beta, l1(l1min);
 
 2327         alphaNew = -(m3-m2+2.0*
wigner3j_auxB(l1,l2,l3,m1,m2,m3))/
wigner3j_auxA(1.0,l2,l3,m1,m2,m3);
 
 2333       thrcof[1] = alphaNew*thrcof[0];
 
 2337       bool alphaVar = 
false;
 
 2342           alphaOld = alphaNew;  
 
 2353           thrcof[i] = alphaNew*thrcof[i-1]+beta*thrcof[i-2];
 
 2356           if (std::fabs(thrcof[i])>srhuge)
 
 2358           std::cout << 
"We renormalized the forward recursion." << std::endl;
 
 2359           for (std::vector<double>::iterator it = thrcof.begin(); it != thrcof.begin()+i; ++it)
 
 2372           if (alphaVar) 
break;
 
 2374           if (std::fabs(alphaNew)-std::fabs(alphaOld)>0.0)
 
 2377         }   
while (i<(size-1)); 
 
 2384           double l1midm1(thrcof[i-2]),l1mid(thrcof[i-1]),l1midp1(thrcof[i]);
 
 2388           thrcof[size-1] = srtiny;
 
 2394           thrcof[size-2] = alphaNew*thrcof[size-1];
 
 2411           thrcof[j] = alphaNew*thrcof[j+1]+beta*thrcof[j+2];
 
 2414           if (std::fabs(thrcof[j]>srhuge))
 
 2416               std::cout << 
"We renormalized the backward recursion." << std::endl;
 
 2417               for (std::vector<double>::iterator it = thrcof.begin()+j; it != thrcof.end(); ++it)
 
 2428           double lambda = (l1midp1*thrcof[j+2]+l1mid*thrcof[j+1]+l1midm1*thrcof[j])
 
 2429         /(l1midp1*l1midp1+l1mid*l1mid+l1midm1*l1midm1);
 
 2432           for (std::vector<double>::iterator it = thrcof.begin(); it != thrcof.begin()+j; ++it)
 
 2442   for (
int k=0;k<size;k++)
 
 2444       sum += (2.0*(l1min+k)+1.0)*thrcof[k]*thrcof[k];
 
 2449   double c1 = pow(-1.0,l2-l3-m1)*
sgn(thrcof[size-1]);
 
 2451   for (std::vector<double>::iterator it = thrcof.begin(); it != thrcof.end(); ++it)
 
 2454       *it *= c1/sqrt(sum);
 
 2464 double cbl::wigner3j(
double l1, 
double l2, 
double l3,
double m1, 
double m2, 
double m3)
 
 2469         std::fabs(m1+m2+m3)<1.0e-10
 
 2470         && std::floor(l1+l2+l3)==(l1+l2+l3)
 
 2471         && l3 >= std::fabs(l1-l2)
 
 2473         && std::fabs(m1) <= l1
 
 2474         && std::fabs(m2) <= l2
 
 2475         && std::fabs(m3) <= l3
 
 2478   if (!select) 
return 0.0;
 
 2481   double l1min = std::max(std::fabs(l2-l3),std::fabs(m1));
 
 2484   int index = (int)(l1-l1min);
 
 2486   return wigner3j(l2,l3,m1,m2,m3)[index];
 
 2493 double cbl::wigner_3j(
const int j1, 
const int j2, 
const int j3, 
const int m1, 
const int m2, 
const int m3)
 
 2495   return gsl_sf_coupling_3j(2*j1, 2*
j2, 2*j3, 2*m1, 2*m2, 2*m3);
 
 2502 double cbl::wigner_6j(
const int j1, 
const int j2, 
const int j3, 
const int j4, 
const int j5, 
const int j6)
 
 2504   return gsl_sf_coupling_6j(2*j1, 2*
j2, 2*j3, 2*
j4, 2*j5, 2*j6);
 
 2511 double cbl::clebsh_gordan(
const int l1, 
const int l2, 
const int m1, 
const int m2, 
const int l3, 
const int m3)
 
 2513   return pow(-1, l1-l2+m3)*sqrt(2*l3+1)*gsl_sf_coupling_3j(2*l1, 2*l2, 2*l3, 2*m1, 2*m2, 2*m3);
 
 2522   return  gsl_sf_coupling_3j(2*l, 2*l_prime, 2*l2, 0, 0, 0);
 
 2529 double cbl::get_mu (
const double r1, 
const double r2, 
const double r3)
 
 2531   return ( (r1*r1+r2*r2-r3*r3)/(2*r1*r2));
 
 2540   if ((x>min) && (x<max))
 
 2542   else if ((x<min) or (x>max))
 
 2556   double fact = pow(-1, (L1+L2+L3)*0.5);
 
 2557   double mu = 
get_mu(r1, r2, r3);
 
 2560   if ((fact!=fact) or (beta==0))
 
 2563   double term1 = fact*beta*(2*L3+1)/(8*
cbl::par::pi*r1*r2*r3)*pow(r1/r3, L3);
 
 2566   for (
int L=0; L<L3+1; L++) {
 
 2569     int min_ell = std::max(fabs(L1-(L3-L)), fabs(L2-L));
 
 2570     int max_ell = std::min(L1+(L3-L), L2+L);
 
 2571     for (
int ell=min_ell; ell<max_ell+1; ell++){ 
 
 2572       term2 += 
clebsh_gordan(L1, L3-L, 0, 0, ell, 0)*
clebsh_gordan(L2, L, 0, 0, ell, 0)*
wigner_6j(L1, L2, L3, L, (L3-L), ell)*
cbl::legendre_polynomial(mu, ell);
 
 2589   std::vector<std::vector<double>> integration_limits(ndim);
 
 2590   integration_limits[0] = {pow(r1_min, 3), pow(r1_max, 3)};
 
 2591   integration_limits[1] = {pow(r2_min, 3), pow(r2_max, 3)};
 
 2593   double V1 = pow(r1_max, 3)-pow(r1_min, 3);
 
 2594   double V2 = pow(r2_max, 3)-pow(r2_min, 3);
 
 2598   auto integrand = [&] (
const vector<double> xx) 
 
 2613 std::vector<std::vector<double>> 
cbl::generate_correlated_data (
const int nExtractions, 
const std::vector<double> mean, 
const std::vector<std::vector<double>> covariance, 
const int seed)
 
 2617   size_t sample_size = mean.size();
 
 2620   gsl_matrix *correlation = gsl_matrix_alloc(sample_size,sample_size);
 
 2622   for (
size_t i=0; i<sample_size; i++) {
 
 2623     std.push_back(sqrt(covariance[i][i]));
 
 2624     for (
size_t j=0; j<sample_size; j++) {
 
 2625       double corr = covariance[i][j]/sqrt(covariance[i][i]*covariance[j][j]);
 
 2627         ErrorCBL(
"negative value on the covariance diagonal!", 
"generate_correlated_data", 
"Func.cpp");
 
 2628       gsl_matrix_set(correlation,i,j, corr);
 
 2632   vector<vector<double>> sample;
 
 2633   for (
int j=0; j<nExtractions; j++) {
 
 2634     vector<double> subS(sample_size, 0);
 
 2635     for (
size_t i=0; i<sample_size; i++)
 
 2637     sample.push_back(subS);
 
 2643   gsl_vector *eigenvalues = gsl_vector_alloc(sample_size);
 
 2644   gsl_matrix *VV = gsl_matrix_alloc(sample_size,sample_size);
 
 2645   gsl_matrix_set_zero(VV);
 
 2647   gsl_matrix *eigenvectors = gsl_matrix_alloc(sample_size,sample_size);
 
 2649   gsl_eigen_symmv_workspace *ww = gsl_eigen_symmv_alloc (sample_size);
 
 2650   gsl_eigen_symmv (correlation, eigenvalues, eigenvectors, ww);
 
 2651   gsl_eigen_symmv_free(ww);
 
 2653   for (
size_t j=0; j<sample_size; j++) {
 
 2654     for (
size_t i=0; i<sample_size; i++) {
 
 2655       if (gsl_vector_get(eigenvalues, j)<0)
 
 2656         ErrorCBL(
"covariance matrix must be positive (semi-)definite but has at least one negative eigenvalue!", 
"generate_correlated_data", 
"Func.cpp");
 
 2658       double v1 = gsl_matrix_get(eigenvectors, i, j);
 
 2659       double v2 = sqrt(gsl_vector_get(eigenvalues, j));
 
 2660       gsl_matrix_set(VV, i, j, v1*v2);
 
 2664   vector<vector<double>> cov_sample;
 
 2666   for (
int k=0; k<nExtractions; k++) {
 
 2667     vector<double> cov_SSample(sample_size, 0);
 
 2668     for (
size_t i=0; i<sample_size; i++) {
 
 2670       gsl_vector *row = gsl_vector_alloc(sample_size);
 
 2671       gsl_matrix_get_row(row,VV,i);
 
 2673       for (
size_t j=0; j<sample_size; j++)
 
 2674     cov_SSample[i] += gsl_vector_get(row, j)*sample[k][j];
 
 2676       cov_SSample[i] = std[i]*cov_SSample[i]+mean[i];
 
 2678     cov_sample.push_back(cov_SSample);
 
 2693 void cbl::gauleg (
const double x1, 
const double x2, 
double *x, 
double *w, 
const int n)
 
 2695   const double eps = 3.0e-11;
 
 2697   double xm = 0.5*(x2+x1);
 
 2698   double xl = 0.5*(x2-x1);
 
 2699   for (
int i=1; i<=m; i++) {
 
 2701     double z = cos(
par::pi*(i-0.25)/(n+0.5));
 
 2705       for (
int j=1; j<=n; j++) {
 
 2708     p1 = ((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
 
 2710       pp = n*(z*p1-p2)/(z*z-1.0);
 
 2714     while (fabs(z-z1)>eps);
 
 2717     w[i-1] = 2.0*xl/((1.0-z*z)*pp*pp);
 
Useful generic functions.
 
#define coutCBL
CBL print message.
 
Class to manage Legendre polymials computation.
 
double interpolate(std::vector< double > xi, const int distNum)
N-dim interpolation of a set of N coordinates on a normalised grid (see normalize)
 
ChainMesh()=default
default constructor
 
double integrate_qag(const double a, const double b, const double rel_err=1.e-2, const double abs_err=1.e-6, const int limit_size=1000, const int rule=6)
compute the definite integral with GSL qag method
 
The class LegendrePolynomials.
 
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...
 
The class NormalRandomNumbers.
 
STR_CUBA_inputs & inputs()
return reference to integration parameters
 
double IntegrateCuhre(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Cuhre routine
 
static const char fDP4[]
conversion symbol for: double -> std::string
 
static const char fDP3[]
conversion symbol for: double -> std::string
 
static const char fINT[]
conversion symbol for: int -> std::string
 
static const std::string defaultString
default std::string value
 
static const double defaultDouble
default double value
 
static const double pi
: the ratio of a circle's circumference to its diameter
 
static const double el
: the electrical charge of the electron [C]
 
Var
the catalogue variables
 
@ _workInProgress_
error due to work in progress
 
double bias(const double Mmin, const double sigmalgM, const double M0, const double M1, const double alpha, const std::shared_ptr< void > inputs)
the mean galaxy bias
 
Eigen::MatrixXd MatrixToEigen(const std::vector< std::vector< double >> mat)
convert a std::vector<std::vector<double>> to an Eigen::MatrixXd object
 
Eigen::MatrixXd VectorToEigen(const std::vector< double > vec)
convert a std::vector<double> to an Eigen::MatrixXd object
 
std::vector< std::vector< double > > EigenToMatrix(const Eigen::MatrixXd mat)
convert an Eigen::MatrixXd to a std::vector<std::vector<double>>
 
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
 
double GSL_integrate_qag(gsl_function Func, const double a, const double b, const double rel_err=1.e-3, const double abs_err=0, const int limit_size=1000, const int rule=6)
integral, computed using the GSL qag method
 
The global namespace of the  CosmoBolognaLib
 
void distribution(std::vector< double > &xx, std::vector< double > &fx, std::vector< double > &err, const std::vector< double > FF, const std::vector< double > WW, const int nbin, const bool linear=true, const std::string file_out=par::defaultString, const double fact=1., const double V1=par::defaultDouble, const double V2=par::defaultDouble, const std::string bin_type="Linear", const bool conv=false, const double sigma=0.)
derive and store the number distribution of a given std::vector
 
void sdss_atbound(double &angle, const double minval, const double maxval)
check if ra coordinate is inside the boundaries
 
double MC_Int(double func(const double), const double x1, const double x2, const int seed=3213)
simple Monte Carlo integration of f(x)
 
T Min(const std::vector< T > vect)
minimum element of a std::vector
 
std::string conv(const T val, const char *fact)
convert a number to a std::string
 
double legendre_polynomial_integral(double mu, void *params)
the order l Legendre polynomial integrand
 
double Euclidean_distance(const double x1, const double x2, const double y1, const double y2, const double z1, const double z2)
the Euclidean distance in 3D relative to the origin (0,0,0), i.e. the Euclidean norm
 
void read_matrix(const std::string file_matrix, std::vector< double > &xx, std::vector< double > &yy, std::vector< std::vector< double >> &matrix, const std::vector< int > col={})
read a matrix from file
 
double Legendre_polynomial_mu_average(const int ll, const double mu, const double delta_mu)
the average of the Legendre polynomial of the l-th order over the mu range
 
double multivariateGaussian(std::vector< double > xx, std::shared_ptr< void > pars)
the multivariate Gaussian function
 
double Average(const std::vector< double > vect)
the average of a std::vector
 
CoordinateType
the coordinate type
 
@ _comoving_
comoving coordinates (x, y, z)
 
std::vector< T > different_elements(const std::vector< T > vect_input)
get the unique elements of a std::vector
 
T index_closest(T x, std::vector< T > vv)
given a number x, return the index of the closest element to x in vv
 
double j2(const double xx)
the l=2 spherical Bessel function
 
double j2_distance_average(const double kk, const double r_down, const double r_up)
the distance average l=2 spherical Bessel function this function is used to obtain the analytic twop ...
 
double chainMeshInterpolate(std::vector< double > xx, std::shared_ptr< void > pars)
a multidimension interpolator
 
std::vector< std::complex< double > > spherical_harmonics_array(const int lmax, const double xx, const double yy, const double zz)
the spherical harmonics up to
 
std::vector< T > logarithmic_bin_vector(const size_t nn, const T min, const T max)
fill a std::vector with logarithmically spaced values
 
std::vector< T > linear_bin_vector(const size_t nn, const T min, const T max)
fill a std::vector with linearly spaced values
 
double haversine_distance(const double ra1, const double ra2, const double dec1, const double dec2)
the haversine angular separation
 
double converted_angle(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_radians_, const CoordinateUnits outputUnits=CoordinateUnits::_degrees_)
conversion to angle units
 
void checkDim(const std::vector< T > vect, const int val, const std::string vector, bool equal=true)
check if the dimension of a std::vector is equal/lower than an input value
 
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
 
double Legendre_polynomial_triangles_average(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 int ll, const double rel_err=1.e-5, const double abs_err=1.e-8, const int nevals=100)
the average of the Legendre polynomial of the l-th order over the
 
double jl_spherical_integrand(double rr, void *params)
the generic integrand to obtain the distance average spherical Bessel function of order l
 
double angular_distance(const double x1, const double x2, const double y1, const double y2, const double z1, const double z2)
the angular separation in 3D
 
double interpolated_2D(const double _x1, const double _x2, const std::vector< double > x1, const std::vector< double > x2, const std::vector< std::vector< double >> yy, const std::string type)
2D interpolation
 
double Legendre_polynomial_theta_average(const double theta_min, const double theta_max, const int ll)
the average of the Legendre polynomial of the l-th order over the  range
 
double relative_error_beta(const double bias, const double Volume, const double density)
estimated relative error on
 
void cartesian_coord(const double ra, const double dec, const double dd, double &XX, double &YY, double &ZZ)
conversion from polar coordinates to Cartesian coordinates
 
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
 
std::vector< double > colatitude(std::vector< double > latitude)
convert to colatitude
 
void invert_matrix(const std::vector< std::vector< double >> mat, std::vector< std::vector< double >> &mat_inv, const double prec=1.e-10, const int Nres=-1)
function to invert a matrix
 
double three_spherical_bessel_integral(const double r1, const double r2, const double r3, const int L1, const int L2, const int L3)
compute the integral of three spherical bessel function, from Mehrem (2011)
 
T Max(const std::vector< T > vect)
maximum element of a std::vector
 
double j0(const double xx)
the l=0 spherical Bessel function
 
double trapezoid_integration(const std::vector< double > xx, const std::vector< double > yy)
integral, computed with the trapezoid rule, using ordered data
 
std::vector< double > wigner3j(double l2, double l3, double m1, double m2, double m3)
Wigner  symbol.
 
std::vector< double > linear_interpolation_3D(const std::vector< double > min, std::vector< double > max, std::vector< int > steps, std::vector< std::vector< std::vector< double >>> func, const std::vector< std::vector< double >> pos)
3D interpolation on a 3D regular grid
 
std::vector< std::vector< T > > transpose(std::vector< std::vector< T >> matrix)
transpose a matrix
 
double coupling_3j(const int l, const int l_prime, const int l2)
compute the Wigner 3-j symbol
 
std::complex< double > spherical_harmonics(cbl::CoordinateType coordinate_type, const int l, const int m, const double coord1, const double coord2, const double coord3)
the order l, degree m spherical harmonics
 
double Filter(const double r, const double rc)
filter W(r/rc), used e.g. for filtering the correlation function
 
double radians(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_degrees_)
conversion to radians
 
double interpolated(const double _xx, const std::vector< double > xx, const std::vector< double > yy, const std::string type)
1D interpolation
 
double clebsh_gordan(const int j1, const int j2, const int m1, const int m2, const int j3, const int m3)
get the Clebsh-Gordan coefficient in the notation
 
double average_three_spherical_bessel_integral(const double r1_min, const double r1_max, const double r2_min, const double r2_max, const double r3, const int L1, const int L2, const int L3)
compute the integral of three spherical bessel function, from Mehrem (2011), averaged on r1-r2 shells
 
double binomial_coefficient(const int n, const int m)
get the binomial coefficient
 
double Sigma(const std::vector< double > vect)
the standard deviation of a std::vector
 
double j0_distance_average(const double kk, const double r_down, const double r_up)
the distance average l=0 spherical Bessel function this function is used to obtain the analytic twop ...
 
double wigner_3j(int j1, int j2, int j3, int m1, int m2, int m3)
Wigner  symbol, use it for l<100.
 
std::vector< double > Quartile(const std::vector< double > Vect)
the first, second and third quartiles of a std::vector
 
void Moment(const std::vector< double > data, double &ave, double &adev, double &sdev, double &var, double &skew, double &curt)
compute the moments of a set of data
 
void sdss2eq(const std::vector< double > lambda, const std::vector< double > eta, std::vector< double > &ra, std::vector< double > &dec)
convert sdss coordinates  to R.A., Dec.
 
double sgn(T val)
sgn the sign function
 
std::vector< double > generate_correlated_data(const std::vector< double > mean, const std::vector< std::vector< double >> covariance, const int idum=213123)
generate a covariant sample of n points using a covariance matrix
 
void sdss_stripe(const std::vector< double > eta, const std::vector< double > lambda, std::vector< int > &stripe, std::vector< int > &str_u)
compute the SDSS stripe given SDSS coordinates
 
double volume(const double boxSize, const int frac, const double Bord, const double mean_redshift, cosmology::Cosmology &real_cosm)
get the volume of a simulation box
 
double closest_probability(double xx, std::shared_ptr< void > pp, std::vector< double > par)
probability of the closest element to x from a list with weights
 
void covariance_matrix(const std::vector< std::vector< double >> mat, std::vector< std::vector< double >> &cov, const bool JK=false)
compute the covariance matrix from an input dataset
 
void read_invert_covariance(const std::string filecov, std::vector< std::vector< double >> &cov, std::vector< std::vector< double >> &cov_inv, const size_t i1, const size_t i2, const double prec=1.e-10, const int Nres=-1)
read and invert the covariance matrix
 
double wigner3j_auxA(double l1, double l2, double l3, double m1, double m2, double m3)
Wigner  auxiliar function A.
 
double degrees(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_radians_)
conversion to degrees
 
double j4(const double xx)
the l=4 spherical Bessel function
 
void bin_function_2D(const std::string file_grid, double func(double *, size_t, void *), void *par, const int bin, const double x1_min, const double x1_max, const double x2_min, const double x2_max, const std::string binning, std::vector< double > &xx1, std::vector< double > &xx2, std::vector< std::vector< double >> &yy)
create a 2D grid given an input function
 
double jl_distance_average(const double kk, const int order, const double r_down, const double r_up)
the distance average for the order l-th spherical Bessel function
 
CoordinateUnits
the coordinate units
 
std::vector< double > vector_from_distribution(const int nRan, const std::vector< double > xx, const std::vector< double > fx, const double xmin, const double xmax, const int seed)
return a std::vector of numbers sampled from a given distribution
 
void sdss_atbound2(double &theta, double &phi)
set the angular coordinates in the SDSS boundaries
 
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
 
double perpendicular_distance(const double ra1, const double ra2, const double dec1, const double dec2, const double d1, const double d2)
the perpendicular separation, rp
 
double get_mu(const double r1, const double r2, const double r3)
get the cosine of the angle between two sides of a triangle
 
double determinant_matrix(const std::vector< std::vector< double >> mat)
compute the determinant of a matrix
 
double legendre_polynomial(const double mu, const int l)
the order l Legendre polynomial
 
void measure_var_function(const std::vector< double > var, const int bin, const double V_min, const double V_max, const double Volume, std::vector< double > &Var, std::vector< double > &Phi, std::vector< double > &err)
measure the var function (where "var" could be the mass, the luminosity, the radius,...
 
double jl(const double xx, const int order)
the order l spherical Bessel function
 
void convolution(const std::vector< double > f1, const std::vector< double > f2, std::vector< double > &res, const double deltaX)
convolution of two functions
 
void eq2sdss(const std::vector< double > ra, const std::vector< double > dec, std::vector< double > &lambda, std::vector< double > &eta)
convert from equatorial coordinates R.A., Dec to sdss coordinates
 
double arcseconds(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_radians_)
conversion to arcseconds
 
void bin_function(const std::string file_grid, double func(double, void *), void *par, const int bin, const double x_min, const double x_max, const std::string binning, std::vector< double > &xx, std::vector< double > &yy)
create a 1D grid given an input function
 
double distribution_probability(double xx, std::shared_ptr< void > pp, std::vector< double > par)
probability of an interpolated distribution
 
void read_vector(const std::string file_vector, std::vector< double > &xx, std::vector< double > &vector, const std::vector< int > col={})
read a vector from file
 
double window_function(const double x, const double min=-1, const double max=1)
the unnormalized window function
 
double wigner3j_auxB(double l1, double l2, double l3, double m1, double m2, double m3)
Wigner  auxiliar function B.
 
double number_from_distribution(const std::vector< double > xx, const std::vector< double > fx, const double xmin, const double xmax, const int seed)
return a number sampled from a given distribution
 
double wigner_6j(const int j1, const int j2, const int j3, const int j4, const int j5, const int j6)
Wigner  symbol.
 
void polar_coord(const double XX, const double YY, const double ZZ, double &ra, double &dec, double &dd)
conversion from Cartesian coordinates to polar coordinates
 
double arcminutes(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_radians_)
conversion to arcminutes
 
std::vector< size_t > minimum_maximum_indexes(const std::vector< double > xx, const double x_min, const double x_max)
return the std::vector indexes corresponding to a given interval