int gsl_sf_bessel_il_scaled_array(const int lmax, const double x, double * result_array) { if(x == 0.0) { int ell; result_array[0] = 1.0; for (ell = lmax; ell >= 1; ell--) { result_array[ell] = 0.0; }; return GSL_SUCCESS; } else { int ell; gsl_sf_result r_iellp1; gsl_sf_result r_iell; int stat_0 = gsl_sf_bessel_il_scaled_e(lmax+1, x, &r_iellp1); int stat_1 = gsl_sf_bessel_il_scaled_e(lmax, x, &r_iell); double iellp1 = r_iellp1.val; double iell = r_iell.val; double iellm1; result_array[lmax] = iell; for(ell = lmax; ell >= 1; ell--) { iellm1 = iellp1 + (2*ell + 1)/x * iell; iellp1 = iell; iell = iellm1; result_array[ell-1] = iellm1; } return GSL_ERROR_SELECT_2(stat_0, stat_1); } }
/// Regular modified spherical bessel functions. double bessel_il(unsigned int n, double x) { gsl_sf_result result; int stat = gsl_sf_bessel_il_scaled_e(n, x, &result); if (stat != GSL_SUCCESS) { std::ostringstream msg("Error in bessel_il:"); msg << " n=" << n << " x=" << x; throw std::runtime_error(msg.str()); } else return std::exp(std::abs(x)) * result.val; }
double hyper_helper_function(double rho, void * params) { hyper_integrand_helper *helper = (hyper_integrand_helper *) params; double u = (*helper->transformed_state)[0]; double v = (*helper->transformed_state)[2]; double w = (*helper->transformed_state)[1]; double h = helper->h; double rsqr = h * h - (helper->eta) * rho * rho; //cout << h << " " << rsqr << " " << rho << endl; if (rsqr < 0) { //cout << h << " " << helper->eta << " " << rho << endl; return 0.0; // in this case there is no point that satisfies the delta function } //double r = sqrt(abs(rsqr)); double r = sqrt(rsqr); //cout << rsqr << endl; double arg = rho * r * abs(w); double temp1 = -0.5 * (u * r * r + v * rho * rho); double temp2 = pow(r, 2*helper->nr + helper->kappa + 1) * pow(rho, 2*helper->nrho + helper->kappa + 2) * h; double res = 0.0; //cout << temp1 << " " << temp2 << " " << arg << endl; if (abs(w/u) < 1E-8) { if (helper->kappa != 0) { return 0.0; } res = exp(temp1) * temp2 / sqrt(Pi / 2.0); } else { gsl_sf_result bes1; int status = gsl_sf_bessel_il_scaled_e(helper->kappa, arg, &bes1); if (status != 0) { bes1.val = 1.0 / arg; } res = bes1.val * exp(abs(arg) + temp1) * temp2 * epsilon(helper->kappa, w) * sqrt(2.0 * helper->kappa + 1.0) / sqrt(Pi / 2.0); } //cout << res << " " ; return res; }
/* [Abramowitz+Stegun, 10.2.4 + 10.2.6] * with lmax=15, precision ~ 15D for x < 3 * * assumes l >= 1 */ static int bessel_kl_scaled_small_x(int l, const double x, gsl_sf_result * result) { gsl_sf_result num_fact; double den = gsl_sf_pow_int(x, l+1); int stat_df = gsl_sf_doublefact_e((unsigned int) (2*l-1), &num_fact); if(stat_df != GSL_SUCCESS || den == 0.0) { OVERFLOW_ERROR(result); } else { const int lmax = 50; gsl_sf_result ipos_term; double ineg_term; double sgn = (GSL_IS_ODD(l) ? -1.0 : 1.0); double ex = exp(x); double t = 0.5*x*x; double sum = 1.0; double t_coeff = 1.0; double t_power = 1.0; double delta; int stat_il; int i; for(i=1; i<lmax; i++) { t_coeff /= i*(2*(i-l) - 1); t_power *= t; delta = t_power*t_coeff; sum += delta; if(fabs(delta/sum) < GSL_DBL_EPSILON) break; } stat_il = gsl_sf_bessel_il_scaled_e(l, x, &ipos_term); ineg_term = sgn * num_fact.val/den * sum; result->val = -sgn * 0.5*M_PI * (ex*ipos_term.val - ineg_term); result->val *= ex; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_il; } }
double gsl_sf_bessel_il_scaled(const int l, const double x) { EVAL_RESULT(gsl_sf_bessel_il_scaled_e(l, x, &result)); }