/* * form factor of a spherical Cylinder with radius R, height L and scattering * length density eta */ scalar sasfit_ff_long_cyl(scalar q, sasfit_param * param) { scalar mu, sigma, pi_mu, G1, G2, I_sp, Sum, V, omega; scalar R, L, eta; SASFIT_ASSERT_PTR(param); sasfit_get_param(param, 4, &R, &L, EMPTY, &eta); SASFIT_CHECK_COND1((q < 0.0), param, "q(%lg) < 0",q); SASFIT_CHECK_COND1((R < 0.0), param, "R(%lg) < 0",R); SASFIT_CHECK_COND1((L < 0.0), param, "L(%lg) < 0",L); if (R == 0.0) return 0.0; if (L == 0.0) return 0.0; mu = L*q; sigma = 2.0*R*q; V = M_PI*R*R*L; if (R==0 || L==0) return 0; if (q==0) return V*V*eta*eta; pi_mu = gsl_sf_Si(mu)+cos(mu)/mu+sin(mu)/mu/mu; G1 = 2.0/(0.5*sigma) * gsl_sf_bessel_J1(0.5*sigma); G2 = 8.0/sigma/sigma * gsl_sf_bessel_Jn(2,sigma); // I_sp = 3.0 * (sin(sigma*0.5)-0.5*sigma*cos(0.5*sigma)) / pow(sigma/2.0,3); // I_sp = I_sp*I_sp; omega = 8/gsl_pow_2(sigma)*(3*gsl_sf_bessel_Jn(2,sigma)+gsl_sf_bessel_J0(sigma)-1); // Sum = 2.0/mu * (pi_mu*G1*G1 - 1.0/mu*(2.0*G2-I_sp) - sin(mu)/mu/mu); Sum = 2.0/mu * (pi_mu*G1*G1 - omega/mu - sin(mu)/mu/mu); return eta*eta *V*V* Sum; }
double poisson_finite_cylinder(double kx, double kr, double x0,double r0) { double result; if ((kx>=tol) & (kr>=tol)) { result = 4.0*kr*r0*gsl_sf_bessel_Jn(1, kr*r0)*int_aux(0, kx, kr, x0, r0, PFC_F_0) - 4.0*gsl_sf_bessel_Jn(0, kr*r0)*int_aux(1, kx, kr, x0, r0, PFC_F_0) + 4.0*M_PI/(kx*kx + kr*kr)*(1.0 + exp(-kr*x0)*(kx/kr*sin(kx*x0) - cos(kx*x0))); } else if ((kx < tol) & (kr >= tol)){ result = int_aux(0, kx, kr, x0, r0, PFC_F_KX); } else if ((kx >= tol) & (kr < tol)){ result = int_aux(0, kx, kr, x0, r0, PFC_F_KR); } else result = -2.0*M_PI*( log(r0/(x0 + sqrt(r0*r0 + x0*x0))) *r0*r0 + x0*(x0 - sqrt(r0*r0 + x0*x0))); /* the 1/(4pi) factor is due to the factor on the poissonsolver3d (end)*/ return result/(4.0*M_PI); }
/* input: alpha: k*dx (wavenumber * grid spacing) points: points to evaluate bessles at npoints: number of points in points M: highest order bessel function to use output: return value: matrix A where A[i][j] = J_{j'}(alpha*r_i) / * f(j'*\theta_i) where 0 <= i < npoints 0 <= j <= M j' = j if j <= M j - M if j > M f = 1 if j = 0 sin if 1 <= j <= M cos if j > M */ gsl_matrix *bessel_matrix(double alpha, point *points, int npoints, int M, double r_typical) { gsl_matrix *out = gsl_matrix_alloc(npoints, 2*M+1); int i,j; double x, y, r, theta; double column_scale; for (i = 0 ; i < npoints ; i++) { // loop over rows x = points[i].x; y = points[i].y; r = R(x, y); theta = THETA(x,y); // loops over columns gsl_matrix_set(out, i, 0, gsl_sf_bessel_J0(alpha * r) / gsl_sf_bessel_J0(alpha * r_typical)); for (j = 1 ; j <= M ; j++) { column_scale = gsl_sf_bessel_Jn(j, alpha * r_typical); gsl_matrix_set(out, i, j, gsl_sf_bessel_Jn(j, alpha * r) * sin(j * theta) / column_scale); gsl_matrix_set(out, i, j+M, gsl_sf_bessel_Jn(j, alpha * r) * cos(j * theta) / column_scale); } } return out; }
/** * Compute the fourier decomposition of array to -m:m in angular components and 1:nmax in radial components * * Note that the gridding scheme used here is defined on [-1..1] x [-1..1], the cmx and cmy specified here should * be given in these units. The function "compute_com" defined below can be used to do this. * * @arg mmax - largest angular moment computed * @arg nmax - largest radial moment computed * @arg array - 2d matrix (npts x npts) of energy density in the event * @arg npts - number of points in in the array * @arg AmnReal - 2d matrix ((2*mmax+1) x nmax), filled with Real parts of the coeffs on return * @arg AmnIm - 2d matrix ((2*mmax+1) x nmax), filled with Im parts of the coeffs on return * @arg cmx - x location of the CM of the event * @arg cmy - y location of the CM of the event */ void compute_amn(int mmax, int nmax, gsl_matrix *array, int npts, gsl_matrix* AmnReal, gsl_matrix* AmnIm, double cmx, double cmy) { int i,j,k,l; int nm, nn; int mtemp, ntemp; double dx;// = 2/((double)npts-1); double dxy;// = 4/pow(((double)npts-1),2.0); double xv, yv; double coeff = 0; double phiMod, phiRe, phiIm; double ftemp; double AmnRealAcc, AmnImAcc; // for compensated summation double alphaRe, alphaIm; double epsRe, epsIm; double rzero = fabs(xmin); dx = 2*rzero/((double)npts-1); dxy = 4*pow(rzero,2.0)/pow(((double)npts-1),2.0); //printf("# xmin: %lf dx: %lf dxy: %lf\n", xmin, dx, dxy); gsl_vector *xvec = gsl_vector_alloc(npts); gsl_matrix * rMat = gsl_matrix_alloc(npts, npts); gsl_matrix * thMat = gsl_matrix_alloc(npts, npts); gsl_matrix *lamMat = NULL; gsl_matrix_set_zero(rMat); gsl_matrix_set_zero(thMat); gsl_vector_set_zero(xvec); nm = 2*mmax+1; nn = nmax; lamMat = gsl_matrix_alloc(nm, nn); // fill in r and Theta matrices for(i = 0; i < npts; i++) gsl_vector_set(xvec ,i, xmin + dx*i); for(i = 0; i < npts; i++){ xv = gsl_vector_get(xvec, i); for(j = 0; j < npts;j ++){ yv = gsl_vector_get(xvec, j); gsl_matrix_set(rMat, i, j, sqrt((xv-cmx)*(xv-cmx) + (yv-cmy)*(yv-cmy))); gsl_matrix_set(thMat, i, j, atan2((yv-cmy), (xv-cmx))); } } // fill in lambda matrix for(i=0; i < nm; i++){ for(j = 0; j < nn; j++){ ntemp = j + 1; mtemp = -1.0 * mmax + i; gsl_matrix_set(lamMat, i, j, gsl_sf_bessel_zero_Jnu(fabs(mtemp), ntemp)); } } for(i = 0; i < nm; i++){ for(j = 0; j < nn; j++){ AmnImAcc = 0.0; AmnRealAcc = 0.0; epsRe = 0.0; epsIm = 0.0; ntemp = j + 1; mtemp = -1.0*mmax + i; // note that we have to scale the coeff by rzero, then the system is properly scale invariant coeff = pow(rzero,2)*sqrt(M_PI)*gsl_sf_bessel_Jn(fabs(mtemp)+1, gsl_matrix_get(lamMat, i, j)); // now loop over the grid, a lot for(k = 0; k < npts; k++){ for(l = 0; l < npts; l++){ phiMod = gsl_sf_bessel_Jn(mtemp, gsl_matrix_get(lamMat, i, j)*gsl_matrix_get(rMat, k, l)/rzero) / coeff; phiRe = phiMod * cos(mtemp*gsl_matrix_get(thMat, k, l)); phiIm = phiMod * sin(mtemp*gsl_matrix_get(thMat, k, l)); ftemp = gsl_matrix_get(array, k, l); /* kahan compensated summation (http://en.wikipedia.org/wiki/Kahan_summation_algorithm) * we're adding up a lot of little numbers here * this trick keeps accumulation errors from, well, accumulating */ alphaRe = AmnRealAcc; epsRe += ftemp * phiRe; AmnRealAcc = alphaRe + epsRe; epsRe += (alphaRe - AmnRealAcc); alphaIm = AmnImAcc; epsIm += ftemp * phiIm; AmnImAcc = alphaIm + epsIm; epsIm += (alphaIm - AmnImAcc); } } // and save the coeffs gsl_matrix_set(AmnReal, i, j, AmnRealAcc*dxy); gsl_matrix_set(AmnIm, i, j, -1.0 * AmnImAcc*dxy); } } gsl_matrix_free(rMat); gsl_matrix_free(thMat); gsl_vector_free(xvec); gsl_matrix_free(lamMat); }
double BesselJ (int n, double z) { return gsl_sf_bessel_Jn (n,z); }
double FC_FUNC_(oct_bessel, OCT_BESSEL) (const int *n, const double *x) { return gsl_sf_bessel_Jn(*n, *x); }
static Real _J(UnsignedInteger n, Real z) { return gsl_sf_bessel_Jn(n, z); }
int main() { #include "bessel_j_int_data.ipp" add_data(j0_data); add_data(j0_tricky); add_data(j1_data); add_data(j1_tricky); add_data(jn_data); add_data(bessel_j_int_data); unsigned data_total = data.size(); screen_data([](const std::vector<double>& v){ return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1]); }, [](const std::vector<double>& v){ return v[2]; }); #if defined(TEST_C99) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return ::jn(static_cast<int>(v[0]), v[1]); }, [](const std::vector<double>& v){ return v[2]; }); #endif #if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return std::tr1::cyl_bessel_j(static_cast<int>(v[0]), v[1]); }, [](const std::vector<double>& v){ return v[2]; }); #endif #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return gsl_sf_bessel_Jn(static_cast<int>(v[0]), v[1]); }, [](const std::vector<double>& v){ return v[2]; }); #endif #if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return bessel_j(v[1], static_cast<int>(v[0])); }, [](const std::vector<double>& v){ return v[2]; }); #endif unsigned data_used = data.size(); std::string function = "cyl_bessel_j (integer order)[br](" + boost::lexical_cast<std::string>(data_used) + "/" + boost::lexical_cast<std::string>(data_total) + " tests selected)"; std::string function_short = "cyl_bessel_j (integer order)"; double time; time = exec_timed_test([](const std::vector<double>& v){ return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1]); }); std::cout << time << std::endl; #if defined(COMPILER_COMPARISON_TABLES) report_execution_time(time, std::string("Compiler Option Comparison on ") + platform_name(), "boost::math::cyl_bessel_j (integer orders)", get_compiler_options_name()); #else #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_C99) || defined(TEST_LIBSTDCXX)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name()); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name()); #endif // // Boost again, but with promotion to long double turned off: // #if !defined(COMPILER_COMPARISON_TABLES) if(sizeof(long double) != sizeof(double)) { time = exec_timed_test([](const std::vector<double>& v){ return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1], boost::math::policies::make_policy(boost::math::policies::promote_double<false>())); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_C99) || defined(TEST_LIBSTDCXX)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name() + "[br]promote_double<false>"); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name() + "[br]promote_double<false>"); } #endif #if defined(TEST_C99) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return ::jn(static_cast<int>(v[0]), v[1]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "math.h"); #endif #if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return std::tr1::cyl_bessel_j(static_cast<int>(v[0]), v[1]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "tr1/cmath"); #endif #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return gsl_sf_bessel_Jn(static_cast<int>(v[0]), v[1]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "GSL " GSL_VERSION); #endif #if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return bessel_j(v[1], static_cast<int>(v[0])); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "Rmath " R_VERSION_STRING); #endif return 0; }
static double lenscfm_integrand(double ell, void *p) { lensCorrFunc lcf = (lensCorrFunc) p; return ell/2.0/M_PI*lens_power_spectrum(ell,lcf->lps)*gsl_sf_bessel_Jn(4,ell*lcf->theta/60.0/180.0*M_PI); }
int gsl_sf_mathieu_Ms_array(int kind, int nmin, int nmax, double qq, double zz, gsl_sf_mathieu_workspace *work, double result_array[]) { int even_odd, order, ii, kk, mm, status; double maxerr = 1e-14, amax, pi = M_PI, fn; double coeff[GSL_SF_MATHIEU_COEFF], fc; double j1c, z2c, j1mc, z2mc, j1pc, z2pc; double u1, u2; double *bb = work->bb; /* Initialize the result array to zeroes. */ for (ii=0; ii<nmax-nmin+1; ii++) result_array[ii] = 0.0; /* Check for out of bounds parameters. */ if (qq <= 0.0) { GSL_ERROR("q must be greater than zero", GSL_EINVAL); } if (kind < 1 || kind > 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); /* Compute all eigenvalues up to nmax. */ gsl_sf_mathieu_b_array(0, nmax, qq, work, bb); for (ii=0, order=nmin; order<=nmax; ii++, order++) { even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the series coefficients. */ status = gsl_sf_mathieu_b_coeff(order, qq, bb[order], coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++) { amax = GSL_MAX(amax, fabs(coeff[kk])); if (fabs(coeff[kk])/amax < maxerr) break; j1mc = gsl_sf_bessel_Jn(kk, u1); j1pc = gsl_sf_bessel_Jn(kk+2, u1); if (kind == 1) { z2mc = gsl_sf_bessel_Jn(kk, u2); z2pc = gsl_sf_bessel_Jn(kk+2, u2); } else /* kind = 2 */ { z2mc = gsl_sf_bessel_Yn(kk, u2); z2pc = gsl_sf_bessel_Yn(kk+2, u2); } fc = pow(-1.0, 0.5*order+kk+1)*coeff[kk]; fn += fc*(j1mc*z2pc - j1pc*z2mc); } fn *= sqrt(pi/2.0)/coeff[0]; } else { for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++) { amax = GSL_MAX(amax, fabs(coeff[kk])); if (fabs(coeff[kk])/amax < maxerr) break; j1c = gsl_sf_bessel_Jn(kk, u1); j1pc = gsl_sf_bessel_Jn(kk+1, u1); if (kind == 1) { z2c = gsl_sf_bessel_Jn(kk, u2); z2pc = gsl_sf_bessel_Jn(kk+1, u2); } else /* kind = 2 */ { z2c = gsl_sf_bessel_Yn(kk, u2); z2pc = gsl_sf_bessel_Yn(kk+1, u2); } fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk]; fn += fc*(j1c*z2pc - j1pc*z2c); } fn *= sqrt(pi/2.0)/coeff[0]; } result_array[ii] = fn; } /* order loop */ return GSL_SUCCESS; }
int gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz, gsl_sf_result *result) { int even_odd, kk, mm, status; double maxerr = 1e-14, amax, pi = M_PI, fn, factor; double coeff[GSL_SF_MATHIEU_COEFF], fc; double j1c, z2c, j1pc, z2pc; double u1, u2; gsl_sf_result aa; /* Check for out of bounds parameters. */ if (qq <= 0.0) { GSL_ERROR("q must be greater than zero", GSL_EINVAL); } if (kind < 1 || kind > 2) { GSL_ERROR("kind must be 1 or 2", GSL_EINVAL); } mm = 0; amax = 0.0; fn = 0.0; u1 = sqrt(qq)*exp(-1.0*zz); u2 = sqrt(qq)*exp(zz); even_odd = 0; if (order % 2 != 0) even_odd = 1; /* Compute the characteristic value. */ status = gsl_sf_mathieu_a(order, qq, &aa); if (status != GSL_SUCCESS) { return status; } /* Compute the series coefficients. */ status = gsl_sf_mathieu_a_coeff(order, qq, aa.val, coeff); if (status != GSL_SUCCESS) { return status; } if (even_odd == 0) { for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++) { amax = GSL_MAX(amax, fabs(coeff[kk])); if (fabs(coeff[kk])/amax < maxerr) break; j1c = gsl_sf_bessel_Jn(kk, u1); if (kind == 1) { z2c = gsl_sf_bessel_Jn(kk, u2); } else /* kind = 2 */ { z2c = gsl_sf_bessel_Yn(kk, u2); } fc = pow(-1.0, 0.5*order+kk)*coeff[kk]; fn += fc*j1c*z2c; } fn *= sqrt(pi/2.0)/coeff[0]; } else { for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++) { amax = GSL_MAX(amax, fabs(coeff[kk])); if (fabs(coeff[kk])/amax < maxerr) break; j1c = gsl_sf_bessel_Jn(kk, u1); j1pc = gsl_sf_bessel_Jn(kk+1, u1); if (kind == 1) { z2c = gsl_sf_bessel_Jn(kk, u2); z2pc = gsl_sf_bessel_Jn(kk+1, u2); } else /* kind = 2 */ { z2c = gsl_sf_bessel_Yn(kk, u2); z2pc = gsl_sf_bessel_Yn(kk+1, u2); } fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk]; fn += fc*(j1c*z2pc + j1pc*z2c); } fn *= sqrt(pi/2.0)/coeff[0]; } result->val = fn; result->err = 2.0*GSL_DBL_EPSILON; factor = fabs(fn); if (factor > 1.0) result->err *= factor; return GSL_SUCCESS; }
int main() { double d = gsl_sf_bessel_Jn(2, 1.0); return d != 0 ? 0 : 1; }
const Real GreensFunction2DAbs::p_int_theta_second(const Real r, const Real theta, const Real t) const { const Real r_0(this->getr0()); const Real a(this->geta()); const Real minusDt(-1e0 * this->getD() * t); const Integer num_in_term_use(100); const Integer num_out_term_use(100); const Real threshold(CUTOFF); Real sum(0e0); Real term(0e0); Integer n(1); for(; n < num_out_term_use; ++n) { Real in_sum(0e0); Real in_term(0e0); Real in_term1(0e0); Real in_term2(0e0); Real in_term3(0e0); Real a_alpha_mn(0e0); Real alpha_mn(0e0); Real Jn_r_alpha_mn(0e0); Real Jn_r0_alpha_mn(0e0); Real Jn_d_1_a_alpha_mn(0e0);// J_n-1(a alpha_mn) Real Jn_p_1_a_alpha_mn(0e0);// J_n+1(a alpha_mn) Real n_real(static_cast<double>(n)); int n_int(static_cast<int>(n)); Integer m(1); for(; m < num_in_term_use; ++m) { a_alpha_mn = gsl_sf_bessel_zero_Jnu(n_real, m); alpha_mn = a_alpha_mn / a; Jn_r_alpha_mn = gsl_sf_bessel_Jn(n_int, r * alpha_mn); Jn_r0_alpha_mn = gsl_sf_bessel_Jn(n_int, r_0 * alpha_mn); Jn_d_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int - 1, a_alpha_mn); Jn_p_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int + 1, a_alpha_mn); in_term1 = std::exp(alpha_mn * alpha_mn * minusDt); in_term2 = Jn_r_alpha_mn * Jn_r0_alpha_mn; in_term3 = Jn_d_1_a_alpha_mn - Jn_p_1_a_alpha_mn; in_term = in_term1 * in_term2 / (in_term3 * in_term3); in_sum += in_term; // std::cout << "inner sum " << in_sum << ", term" << in_term << std::endl; if(fabs(in_term/in_sum) < threshold) { // std::cout << "normal exit. m = " << m << " second term" << std::endl; break; } } if(m == num_in_term_use) std::cout << "warning: use term over num_in_term_use" << std::endl; // term = in_sum * std::cos(n_real * theta); term = in_sum * std::sin(n_real * theta) / n_real; sum += term; // std::cout << "outer sum " << sum << ", term" << term << std::endl; if(fabs(in_sum / (n_real * sum)) < threshold) { /* if n * theta is a multiple of \pi, the term may be zero and * * term/sum become also zero. this is a problem. sin is in a * * regeon [-1, 1], so the order of term does not depend on * * value of sin, so this considers only (in_sum / n_real). */ // std::cout << "normal exit. n = " << n << " second term" << std::endl; break; } } if(n == num_out_term_use) std::cout << "warning: use term over num_out_term_use" << std::endl; return (8e0 * sum / (M_PI * a * a)); }