#include #include #include "nr3.h" #include "quadrature.h" #include "interp_1d.h" #include "romberg.h" #include "gamma.h" #include "gauss_wgts.h" /* * define some parameters that are used in separate routines. * Since the functions called in the integration algorithms can * take only 1 argument, we have to specify the other arguments * globally. */ long int funccalls; // to check how many calculations are needed. /* * try different integration modes: * -1 Gaussian quadrature, integral over z done analytically * 0,1 Gaussian quadrature, 40 or 50 steps in z * 2 Simpsons rule * 3 Romberg integration */ int mode; /* * integrand = 2 - integrate over dr from 0 to 1.6 * integrand = 1 - intergrate over dtheta from 0 to pi/2 (dr/dtheta = 4.8 sin^theta cos theta * integrand =0 - integrate over dx = e^theta from -80 to ln(PI/2), dx/dtheta = theta * */ int integrand; const double PI = acos(-1); // pi to machine accuracy double global_r; // we pass the value r to the function that calculated the inner integral over z int PREC1a = 40; // number of Gaussian-quadrature abscissa for the integration over z int PREC1b = 50; // number of Gaussian-quadrature abscissa for the integration over z double EPS=1e-9; // accuracy outer integral VecDoub x1a(PREC1a),weight1a(PREC1a); // for Gaussian quadrature VecDoub x1b(PREC1b),weight1b(PREC1b); // for Gaussian quadrature //---------------------------------------------------------------------// /* * functions for the integration routines * func3 returns r times f(r,z). z is passed as argument */ Doub func3(Doub z) { funccalls++; if (global_r<1e-100) global_r = 1e-100; // z can be smaller than -1.69 return pow(global_r,z+1); } /* * func_r returns the function used to take a step in the integral over dr */ Doub func_r(Doub r) { if (funccalls>2e10) throw; // less then 20 billion trials, to keep this manageable. global_r = r; double t=pow((r/1.6),1/3.0); if (t>1.0) t=1.0; // catch round-off errors t=asin(t); double result = 2 * PI; double zmax = 1.3*cos(t)-0.5*cos(2*t)-0.2*cos(3*t)-0.1*cos(4*t); double zmin = -1.3*cos(t)-0.5*cos(2*t)+0.2*cos(3*t)-0.1*cos(4*t); if (zmax