/*maxwell_juettner_rho_Q: Fitting formula for Faraday conversion coefficient * rho_Q from Dexter (2016) for a Maxwell-Juettner * distribution. This formula comes from his * equations B4, B6, B8, and B13. * *@params: struct of parameters params *@returns: fitting formula to the Faraday conversion coefficient * for a Maxwell-Juettner distribution of electrons. */ double maxwell_juettner_rho_Q(struct parameters * params) { double omega0 = params->electron_charge*params->magnetic_field / (params->mass_electron*params->speed_light); double wp2 = 4. * params->pi * params->electron_density * pow(params->electron_charge, 2.) / params->mass_electron; /* argument for function f(X) (called jffunc) below */ double x = params->theta_e * sqrt(sqrt(2.) * sin(params->observer_angle) * (1.e3*omega0 / (2. * params->pi * params->nu))); /* this is the definition of the modified factor f(X) from Dexter (2016) */ double extraterm = (.011*exp(-x/47.2) - pow(2., (-1./3.)) / pow(3., (23./6.)) * params->pi * 1.e4 * pow((x + 1.e-16), (-8./3.))) * (0.5 + 0.5 * tanh((log(x) - log(120.)) / 0.1)); double jffunc = 2.011 * exp(-pow(x, 1.035)/4.7) - cos(x/2.) * exp(-pow(x, 1.2)/2.73) - .011 * exp(-x / 47.2) + extraterm; double eps11m22 = jffunc * wp2 * pow(omega0, 2.) / pow(2.*params->pi * params->nu, 4.) * (gsl_sf_bessel_Kn(1, 1./params->theta_e) / gsl_sf_bessel_Kn(2, 1./params->theta_e) + 6. * params->theta_e) * pow(sin(params->observer_angle), 2.); double rhoq = 2. * params->pi * params->nu /(2. * params->speed_light) * eps11m22; return rhoq; }
/*differential_of_f: term in gamma integrand only for absorptivity calculation; *it is the differential Df = 2\pi\nu (1/(mc)*d/dgamma + (beta cos(theta) * -cos(xi))/(p*beta*c) * d/d(cos(xi))) f *this is eq. 41 of [1] *below it is applied for the THERMAL, POWER_LAW, and KAPPA_DIST distributions *@param gamma: Input, Lorentz factor *@param nu: Input, frequency of emission/absorption *@returns: Output, Df term in gamma integrand; depends on distribution function */ double differential_of_f(double gamma, double nu) { #if DISTRIBUTION_FUNCTION == THERMAL double prefactor = (M_PI * nu / (mass_electron*speed_light*speed_light)) * (n_e/(theta_e * gsl_sf_bessel_Kn(2, 1./theta_e))); double body = (-1./theta_e) * exp(-gamma/theta_e); double f = prefactor * body; #elif DISTRIBUTION_FUNCTION == POWER_LAW double pl_norm = 4.* M_PI/(normalize_f()); double prefactor = (M_PI * nu / (mass_electron*speed_light*speed_light)) * (n_e_NT*(power_law_p-1.)) /((pow(gamma_min, 1.-power_law_p) - pow(gamma_max, 1.-power_law_p))); double term1 = ((-power_law_p-1.)*exp(-gamma/gamma_cutoff) *pow(gamma,-power_law_p-2.)/(sqrt(gamma*gamma - 1.))); double term2 = (exp(-gamma/gamma_cutoff) * pow(gamma,(-power_law_p-1.)) /(gamma_cutoff * sqrt(gamma*gamma - 1.))); double term3 = (exp(-gamma/gamma_cutoff) * pow(gamma,-power_law_p)) /pow((gamma*gamma - 1.), (3./2.)); double f = pl_norm * prefactor * (term1 - term2 - term3); #elif DISTRIBUTION_FUNCTION == KAPPA_DIST double prefactor = n_e * (1./normalize_f()) * 4. * M_PI*M_PI * nu * mass_electron*mass_electron * speed_light; double term1 = ((- kappa - 1.) / (kappa * w)) * pow((1. + (gamma - 1.) /(kappa * w)), -kappa-2.); double term2 = pow((1. + (gamma - 1.)/(kappa * w)), (- kappa - 1.)) * (- 1./gamma_cutoff); double f = prefactor * (term1 + term2) * exp(-gamma/gamma_cutoff); #endif return f; }
/*dMJ_dgamma: returns the value of df/d\gamma, where f is the Maxwell-Juettner * (relativistic thermal) distribution function, for the parameters in * the struct p. * *@params: pointer to struct of parameters *params * *@returns: d/dgamma MJ(params->gamma, params->theta_e) */ double dMJ_dgamma(struct parameters * params) { double ans = -exp(-params->gamma/params->theta_e) / (4. * params->pi * params->theta_e*params->theta_e * gsl_sf_bessel_Kn(2, 1./params->theta_e)); return ans; }
/*maxwell_juttner_f: Maxwell-Juttner distribution function in terms of Lorentz * factor gamma; uses eq. 47, 49, 50 of [1] *@param gamma: Input, Lorentz factor *@returns: THERMAL distribution function, which goes into the gamma integrand */ double maxwell_juttner_f(double gamma) { double beta = sqrt(1. - 1./(gamma*gamma)); double d = (n_e * gamma * sqrt(gamma*gamma-1.) * exp(-gamma/theta_e)) /(4. * M_PI * theta_e * gsl_sf_bessel_Kn(2, 1./theta_e)); double ans = 1./(pow(mass_electron, 3.) * pow(speed_light, 3.) * gamma*gamma * beta) * d; return ans; }
static double f(double w, void *p) { struct parameters *params = (struct parameters *)p; const double kx = (params->kx); double kr = (params->kr); double x0 = (params->x0); double r0 = (params->r0); int index = (params->index); double result; if (w == 0) w = zero; if (fabs(kx - w) > tol){ result = sin((kx - w)*x0)/(kx - w)* sqrt(pow(w, 2.0*index)*pow(r0, 2.0*index))/(kr*kr + w*w) *gsl_sf_bessel_Kn(index, r0*fabs(w)); } else{ result = x0*sqrt(pow(w, 2.0*index))/(kr*kr + w*w)*gsl_sf_bessel_Kn(index, r0*fabs(w)); } return result; }
/*maxwell_juettner_rho_V: Fitting formula for Faraday rotation coefficient * rho_V from Dexter (2016) for a Maxwell-Juettner * distribution. This formula comes from his * equations B7, B8, B14, and B15. * *@params: struct of parameters params *@returns: fitting formula to the Faraday rotation coefficient * for a Maxwell-Juettner distribution of electrons. */ double maxwell_juettner_rho_V(struct parameters * params) { double omega0 = params->electron_charge*params->magnetic_field / (params->mass_electron*params->speed_light); double wp2 = 4. * params->pi * params->electron_density * pow(params->electron_charge, 2.) / params->mass_electron; /* argument for function g(X) (called shgmfunc) below */ double x = params->theta_e * sqrt(sqrt(2.) * sin(params->observer_angle) * (1.e3*omega0 / (2. * params->pi * params->nu))); /* this is the definition of the modified factor g(X) from Dexter (2016) */ double shgmfunc = 0.43793091 * log(1. + 0.00185777 * pow(x, 1.50316886)); double eps12 = wp2 * omega0 / pow((2. * params->pi * params->nu), 3.) * (gsl_sf_bessel_Kn(0, 1./params->theta_e) - shgmfunc) / gsl_sf_bessel_Kn(2, 1./params->theta_e) * cos(params->observer_angle); double rhov = 2. * params->pi * params->nu / params->speed_light * eps12; return rhov; }
int main() { #include "bessel_k_int_data.ipp" add_data(k0_data); add_data(k1_data); add_data(kn_data); add_data(bessel_k_int_data); unsigned data_total = data.size(); screen_data([](const std::vector<double>& v){ return boost::math::cyl_bessel_k(static_cast<int>(v[0]), v[1]); }, [](const std::vector<double>& v){ return v[2]; }); #if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return std::tr1::cyl_bessel_k(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_Kn(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_k(v[1], static_cast<int>(v[0]), 1); }, [](const std::vector<double>& v){ return v[2]; }); #endif unsigned data_used = data.size(); std::string function = "cyl_bessel_k (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_k (integer order)"; double time; time = exec_timed_test([](const std::vector<double>& v){ return boost::math::cyl_bessel_k(static_cast<int>(v[0]), v[1]); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || 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()); // // 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_k(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_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_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return std::tr1::cyl_bessel_k(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_Kn(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_k(v[1], static_cast<int>(v[0]), 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, "Rmath " R_VERSION_STRING); #endif return 0; }