int gsl_sf_sin_err_e(const double x, const double dx, gsl_sf_result * result) { int stat_s = gsl_sf_sin_e(x, result); result->err += fabs(cos(x) * dx); result->err += GSL_DBL_EPSILON * fabs(result->val); return stat_s; }
int gsl_sf_sinc_e(double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ { const double ax = fabs(x); if(ax < 0.8) { /* Do not go to the limit of the fit since * there is a zero there and the Chebyshev * accuracy will go to zero. */ return cheb_eval_e(&sinc_cs, 2.0*ax-1.0, result); } else if(ax < 100.0) { /* Small arguments are no problem. * We trust the library sin() to * roughly machine precision. */ result->val = sin(M_PI * ax)/(M_PI * ax); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Large arguments must be handled separately. */ const double r = M_PI*ax; gsl_sf_result s; int stat_s = gsl_sf_sin_e(r, &s); result->val = s.val/r; result->err = s.err/r + 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_s; } } }
int gsl_sf_Ci_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x <= 4.0) { const double lx = log(x); const double y = (x*x-8.0)*0.125; gsl_sf_result result_c; cheb_eval_e(&ci_cs, y, &result_c); result->val = lx - 0.5 + result_c.val; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lx) + 0.5) + result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result sin_result; gsl_sf_result cos_result; int stat_sin = gsl_sf_sin_e(x, &sin_result); int stat_cos = gsl_sf_cos_e(x, &cos_result); gsl_sf_result f; gsl_sf_result g; fg_asymp(x, &f, &g); result->val = f.val*sin_result.val - g.val*cos_result.val; result->err = fabs(f.err*sin_result.val); result->err += fabs(g.err*cos_result.val); result->err += fabs(f.val*sin_result.err); result->err += fabs(g.val*cos_result.err); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_sin, stat_cos); } }
int gsl_sf_bessel_j0_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(ax < 0.5) { const double y = x*x; const double c1 = -1.0/6.0; const double c2 = 1.0/120.0; const double c3 = -1.0/5040.0; const double c4 = 1.0/362880.0; const double c5 = -1.0/39916800.0; const double c6 = 1.0/6227020800.0; result->val = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*c6))))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result sin_result; const int stat = gsl_sf_sin_e(x, &sin_result); result->val = sin_result.val/x; result->err = fabs(sin_result.err/x); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat; } }
int gsl_sf_bessel_j2_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 4.0*GSL_SQRT_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 1.3) { const double y = x*x; const double c1 = -1.0/14.0; const double c2 = 1.0/504.0; const double c3 = -1.0/33264.0; const double c4 = 1.0/3459456.0; const double c5 = -1.0/518918400; const double c6 = 1.0/105859353600.0; const double c7 = -1.0/28158588057600.0; const double c8 = 1.0/9461285587353600.0; const double c9 = -1.0/3916972233164390400.0; const double sum = 1.0+y*(c1+y*(c2+y*(c3+y*(c4+y*(c5+y*(c6+y*(c7+y*(c8+y*c9)))))))); result->val = y/15.0 * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cos_x = cos_result.val; const double sin_x = sin_result.val; const double f = (3.0/(x*x) - 1.0); result->val = (f * sin_x - 3.0*cos_x/x)/x; result->err = fabs(f * sin_result.err/x) + fabs((3.0*cos_result.err/x)/x); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(f*sin_x/x) + 3.0*fabs(cos_x/(x*x))); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } }
int gsl_sf_bessel_j1_e(const double x, gsl_sf_result * result) { double ax = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(ax < 3.1*GSL_DBL_MIN) { UNDERFLOW_ERROR(result); } else if(ax < 0.25) { const double y = x*x; const double c1 = -1.0/10.0; const double c2 = 1.0/280.0; const double c3 = -1.0/15120.0; const double c4 = 1.0/1330560.0; const double c5 = -1.0/172972800.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*c5)))); result->val = x/3.0 * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cos_x = cos_result.val; const double sin_x = sin_result.val; result->val = (sin_x/x - cos_x)/x; result->err = (fabs(sin_result.err/x) + fabs(cos_result.err))/fabs(x); result->err += 2.0 * GSL_DBL_EPSILON * (fabs(sin_x/(x*x)) + fabs(cos_x/x)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } }
int gsl_sf_bessel_y2_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 1.0/GSL_ROOT3_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x < 0.5) { const double y = x*x; const double c1 = 1.0/6.0; const double c2 = 1.0/24.0; const double c3 = -1.0/144.0; const double c4 = 1.0/3456.0; const double c5 = -1.0/172800.0; const double c6 = 1.0/14515200.0; const double c7 = -1.0/1828915200.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*(c6 + y*c7)))))); result->val = -3.0/(x*x*x) * sum; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double sx = sin_result.val; const double cx = cos_result.val; const double a = 3.0/(x*x); result->val = (1.0 - a)/x * cx - a * sx; result->err = cos_result.err * fabs((1.0 - a)/x) + sin_result.err * fabs(a); result->err += GSL_DBL_EPSILON * (fabs(cx/x) + fabs(sx/(x*x))); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } }
int gsl_sf_bessel_y1_e(const double x, gsl_sf_result * result) { /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(x < 1.0/GSL_SQRT_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x < 0.25) { const double y = x*x; const double c1 = 1.0/2.0; const double c2 = -1.0/8.0; const double c3 = 1.0/144.0; const double c4 = -1.0/5760.0; const double c5 = 1.0/403200.0; const double c6 = -1.0/43545600.0; const double sum = 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*c6))))); result->val = -sum/y; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { gsl_sf_result cos_result; gsl_sf_result sin_result; const int stat_cos = gsl_sf_cos_e(x, &cos_result); const int stat_sin = gsl_sf_sin_e(x, &sin_result); const double cx = cos_result.val; const double sx = sin_result.val; result->val = -(cx/x + sx)/x; result->err = (fabs(cos_result.err/x) + sin_result.err)/fabs(x); result->err += GSL_DBL_EPSILON * (fabs(sx/x) + fabs(cx/(x*x))); return GSL_ERROR_SELECT_2(stat_cos, stat_sin); } }
double gsl_sf_sin(const double x) { EVAL_RESULT(gsl_sf_sin_e(x, &result)); }
int gsl_sf_legendre_H3d_1_e(const double lambda, const double eta, gsl_sf_result * result) { const double xi = fabs(eta*lambda); const double lsq = lambda*lambda; const double lsqp1 = lsq + 1.0; /* CHECK_POINTER(result) */ if(eta < 0.0) { DOMAIN_ERROR(result); } else if(eta == 0.0 || lambda == 0.0) { result->val = 0.0; result->err = 0.0; return GSL_SUCCESS; } else if(xi < GSL_ROOT5_DBL_EPSILON && eta < GSL_ROOT5_DBL_EPSILON) { double etasq = eta*eta; double xisq = xi*xi; double term1 = (etasq + xisq)/3.0; double term2 = -(2.0*etasq*etasq + 5.0*etasq*xisq + 3.0*xisq*xisq)/90.0; double sinh_term = 1.0 - eta*eta/6.0 * (1.0 - 7.0/60.0*eta*eta); double pre = sinh_term/sqrt(lsqp1) / eta; result->val = pre * (term1 + term2); result->err = pre * GSL_DBL_EPSILON * (fabs(term1) + fabs(term2)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { double sin_term; /* Sin(xi)/xi */ double cos_term; /* Cos(xi) */ double coth_term; /* eta/Tanh(eta) */ double sinh_term; /* eta/Sinh(eta) */ double sin_term_err; double cos_term_err; double t1; double pre_val; double pre_err; double term1; double term2; if(xi < GSL_ROOT5_DBL_EPSILON) { sin_term = 1.0 - xi*xi/6.0 * (1.0 - xi*xi/20.0); cos_term = 1.0 - 0.5*xi*xi * (1.0 - xi*xi/12.0); sin_term_err = GSL_DBL_EPSILON; cos_term_err = GSL_DBL_EPSILON; } else { gsl_sf_result sin_xi_result; gsl_sf_result cos_xi_result; gsl_sf_sin_e(xi, &sin_xi_result); gsl_sf_cos_e(xi, &cos_xi_result); sin_term = sin_xi_result.val/xi; cos_term = cos_xi_result.val; sin_term_err = sin_xi_result.err/fabs(xi); cos_term_err = cos_xi_result.err; } if(eta < GSL_ROOT5_DBL_EPSILON) { coth_term = 1.0 + eta*eta/3.0 * (1.0 - eta*eta/15.0); sinh_term = 1.0 - eta*eta/6.0 * (1.0 - 7.0/60.0*eta*eta); } else { coth_term = eta/tanh(eta); sinh_term = eta/sinh(eta); } t1 = sqrt(lsqp1) * eta; pre_val = sinh_term/t1; pre_err = 2.0 * GSL_DBL_EPSILON * fabs(pre_val); term1 = sin_term*coth_term; term2 = cos_term; result->val = pre_val * (term1 - term2); result->err = pre_err * fabs(term1 - term2); result->err += pre_val * (sin_term_err * coth_term + cos_term_err); result->err += pre_val * fabs(term1-term2) * (fabs(eta) + 1.0) * GSL_DBL_EPSILON; result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } }