/// Carlson elliptic integrals R_J. double ellint_rj(double x, double y, double z, double p) { if (x == 0.0 && y == 0.0 && z == 0.0) return 0.0; const gsl_mode_t mode = GSL_PREC_DOUBLE; gsl_sf_result result; int stat = gsl_sf_ellint_RJ_e(x, y, z, p, mode, &result); if (stat != GSL_SUCCESS) { std::ostringstream msg("Error in ellint_rj:"); msg << " x=" << x << " y=" << y << " z=" << z << " p=" << p; throw std::runtime_error(msg.str()); } else return result.val; }
/* [Carlson, Numer. Math. 33 (1979) 1, (4.3)] */ int gsl_sf_ellint_P_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result) { const double sin_phi = sin(phi); const double sin2_phi = sin_phi * sin_phi; const double sin3_phi = sin2_phi * sin_phi; const double x = 1.0 - sin2_phi; const double y = 1.0 - k*k*sin2_phi; gsl_sf_result rf; gsl_sf_result rj; const int rfstatus = gsl_sf_ellint_RF_e(x, y, 1.0, mode, &rf); const int rjstatus = gsl_sf_ellint_RJ_e(x, y, 1.0, 1.0 + n*sin2_phi, mode, &rj); result->val = sin_phi * rf.val - n/3.0*sin3_phi * rj.val; result->err = GSL_DBL_EPSILON * fabs(sin_phi * rf.val); result->err += n/3.0 * fabs(sin3_phi*rj.err); return GSL_ERROR_SELECT_2(rfstatus, rjstatus); }
double gsl_sf_ellint_RJ(double x, double y, double z, double p, gsl_mode_t mode) { EVAL_RESULT(gsl_sf_ellint_RJ_e(x, y, z, p, mode, &result)); }
/** * C++ version of gsl_sf_ellint_RJ_e(). * Carlson's symmetric basis of functions * * RJ(x,y,z,p) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1), {t,0,Inf}] * @param x A real number * @param y A real number * @param z A real number * @param p A real number * @param mode The mode * @param result The result as a @c gsl::sf::result object * @return GSL_SUCCESS or GSL_EDOM */ inline int RJ_e( double x, double y, double z, double p, mode_t mode, result& result ){ return gsl_sf_ellint_RJ_e( x, y, z, p, mode, &result ); }