📄 trig.c
字号:
if(fabs(zi) < 1.0) { double ch_m1, sh; sinh_series(zi, &sh); cosh_m1_series(zi, &ch_m1); czr->val = cos(zr)*(ch_m1 + 1.0); czi->val = -sin(zr)*sh; czr->err = 2.0 * GSL_DBL_EPSILON * fabs(czr->val); czi->err = 2.0 * GSL_DBL_EPSILON * fabs(czi->val); return GSL_SUCCESS; } else if(fabs(zi) < GSL_LOG_DBL_MAX) { double ex = exp(zi); double ch = 0.5*(ex+1.0/ex); double sh = 0.5*(ex-1.0/ex); czr->val = cos(zr)*ch; czi->val = -sin(zr)*sh; czr->err = 2.0 * GSL_DBL_EPSILON * fabs(czr->val); czi->err = 2.0 * GSL_DBL_EPSILON * fabs(czi->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR_2(czr,czi); }}intgsl_sf_complex_logsin_e(const double zr, const double zi, gsl_sf_result * lszr, gsl_sf_result * lszi){ /* CHECK_POINTER(lszr) */ /* CHECK_POINTER(lszi) */ if(zi > 60.0) { lszr->val = -M_LN2 + zi; lszi->val = 0.5*M_PI - zr; lszr->err = 2.0 * GSL_DBL_EPSILON * fabs(lszr->val); lszi->err = 2.0 * GSL_DBL_EPSILON * fabs(lszi->val); } else if(zi < -60.0) { lszr->val = -M_LN2 - zi; lszi->val = -0.5*M_PI + zr; lszr->err = 2.0 * GSL_DBL_EPSILON * fabs(lszr->val); lszi->err = 2.0 * GSL_DBL_EPSILON * fabs(lszi->val); } else { gsl_sf_result sin_r, sin_i; int status; gsl_sf_complex_sin_e(zr, zi, &sin_r, &sin_i); /* ok by construction */ status = gsl_sf_complex_log_e(sin_r.val, sin_i.val, lszr, lszi); if(status == GSL_EDOM) { DOMAIN_ERROR_2(lszr, lszi); } } return gsl_sf_angle_restrict_symm_e(&(lszi->val));}intgsl_sf_lnsinh_e(const double x, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(x <= 0.0) { DOMAIN_ERROR(result); } else if(fabs(x) < 1.0) { double eps; sinh_series(x, &eps); result->val = log(eps); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -0.5*GSL_LOG_DBL_EPSILON) { result->val = x + log(0.5*(1.0 - exp(-2.0*x))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = -M_LN2 + x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}int gsl_sf_lncosh_e(const double x, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(fabs(x) < 1.0) { double eps; cosh_m1_series(x, &eps); return gsl_sf_log_1plusx_e(eps, result); } else if(x < -0.5*GSL_LOG_DBL_EPSILON) { result->val = x + log(0.5*(1.0 + exp(-2.0*x))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->val = -M_LN2 + x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}/*inline int gsl_sf_sincos_e(const double theta, double * s, double * c){ double tan_half = tan(0.5 * theta); double den = 1. + tan_half*tan_half; double cos_theta = (1.0 - tan_half*tan_half) / den; double sin_theta = 2.0 * tan_half / den;}*/intgsl_sf_polar_to_rect(const double r, const double theta, gsl_sf_result * x, gsl_sf_result * y){ double t = theta; int status = gsl_sf_angle_restrict_symm_e(&t); double c = cos(t); double s = sin(t); x->val = r * cos(t); y->val = r * sin(t); x->err = r * fabs(s * GSL_DBL_EPSILON * t); x->err += 2.0 * GSL_DBL_EPSILON * fabs(x->val); y->err = r * fabs(c * GSL_DBL_EPSILON * t); y->err += 2.0 * GSL_DBL_EPSILON * fabs(y->val); return status;}intgsl_sf_rect_to_polar(const double x, const double y, gsl_sf_result * r, gsl_sf_result * theta){ int stat_h = gsl_sf_hypot_e(x, y, r); if(r->val > 0.0) { theta->val = atan2(y, x); theta->err = 2.0 * GSL_DBL_EPSILON * fabs(theta->val); return stat_h; } else { DOMAIN_ERROR(theta); }}int gsl_sf_angle_restrict_symm_err_e(const double theta, gsl_sf_result * result){ /* synthetic extended precision constants */ const double P1 = 4 * 7.8539812564849853515625e-01; const double P2 = 4 * 3.7748947079307981766760e-08; const double P3 = 4 * 2.6951514290790594840552e-15; const double TwoPi = 2*(P1 + P2 + P3); const double y = 2*floor(theta/TwoPi); double r = ((theta - y*P1) - y*P2) - y*P3; if(r > M_PI) r -= TwoPi; result->val = r; if(theta > 0.0625/GSL_DBL_EPSILON) { result->err = fabs(result->val); GSL_ERROR ("error", GSL_ELOSS); } else if(theta > 0.0625/GSL_SQRT_DBL_EPSILON) { result->err = GSL_SQRT_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}int gsl_sf_angle_restrict_pos_err_e(const double theta, gsl_sf_result * result){ /* synthetic extended precision constants */ const double P1 = 4 * 7.85398125648498535156e-01; const double P2 = 4 * 3.77489470793079817668e-08; const double P3 = 4 * 2.69515142907905952645e-15; const double TwoPi = 2*(P1 + P2 + P3); const double y = 2*floor(theta/TwoPi); result->val = ((theta - y*P1) - y*P2) - y*P3; if(theta > 0.0625/GSL_DBL_EPSILON) { result->err = fabs(result->val); GSL_ERROR ("error", GSL_ELOSS); } else if(theta > 0.0625/GSL_SQRT_DBL_EPSILON) { result->err = GSL_SQRT_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}int gsl_sf_angle_restrict_symm_e(double * theta){ gsl_sf_result r; int stat = gsl_sf_angle_restrict_symm_err_e(*theta, &r); *theta = r.val; return stat;}int gsl_sf_angle_restrict_pos_e(double * theta){ gsl_sf_result r; int stat = gsl_sf_angle_restrict_pos_err_e(*theta, &r); *theta = r.val; return stat;}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_cos_err_e(const double x, const double dx, gsl_sf_result * result){ int stat_c = gsl_sf_cos_e(x, result); result->err += fabs(sin(x) * dx); result->err += GSL_DBL_EPSILON * fabs(result->val); return stat_c;}#if 0intgsl_sf_sin_pi_x_e(const double x, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(-100.0 < x && x < 100.0) { result->val = sin(M_PI * x) / (M_PI * x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { const double N = floor(x + 0.5); const double f = x - N; if(N < INT_MAX && N > INT_MIN) { /* Make it an integer if we can. Saves another * call to floor(). */ const int intN = (int)N; const double sign = ( GSL_IS_ODD(intN) ? -1.0 : 1.0 ); result->val = sign * sin(M_PI * f); result->err = GSL_DBL_EPSILON * fabs(result->val); } else if(N > 2.0/GSL_DBL_EPSILON || N < -2.0/GSL_DBL_EPSILON) { /* All integer-valued floating point numbers * bigger than 2/eps=2^53 are actually even. */ result->val = 0.0; result->err = 0.0; } else { const double resN = N - 2.0*floor(0.5*N); /* 0 for even N, 1 for odd N */ const double sign = ( fabs(resN) > 0.5 ? -1.0 : 1.0 ); result->val = sign * sin(M_PI*f); result->err = GSL_DBL_EPSILON * fabs(result->val); } return GSL_SUCCESS; }}#endifint 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; } }}/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/#include "eval.h"double gsl_sf_sin(const double x){ EVAL_RESULT(gsl_sf_sin_e(x, &result));}double gsl_sf_cos(const double x){ EVAL_RESULT(gsl_sf_cos_e(x, &result));}double gsl_sf_hypot(const double x, const double y){ EVAL_RESULT(gsl_sf_hypot_e(x, y, &result));}double gsl_sf_lnsinh(const double x){ EVAL_RESULT(gsl_sf_lnsinh_e(x, &result));}double gsl_sf_lncosh(const double x){ EVAL_RESULT(gsl_sf_lncosh_e(x, &result));}double gsl_sf_angle_restrict_symm(const double theta){ double result = theta; EVAL_DOUBLE(gsl_sf_angle_restrict_symm_e(&result));}double gsl_sf_angle_restrict_pos(const double theta){ double result = theta; EVAL_DOUBLE(gsl_sf_angle_restrict_pos_e(&result));}#if 0double gsl_sf_sin_pi_x(const double x){ EVAL_RESULT(gsl_sf_sin_pi_x_e(x, &result));}#endifdouble gsl_sf_sinc(const double x){ EVAL_RESULT(gsl_sf_sinc_e(x, &result));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -