📄 exp.c
字号:
} else if(l10_val < INT_MIN+1) { UNDERFLOW_ERROR_E10(result); } else { const double sy = GSL_SIGN(y); const int N = (int) floor(l10_val); const double arg_val = (l10_val - N) * M_LN10; const double arg_err = dy/fabs(y) + dx + 2.0*GSL_DBL_EPSILON*fabs(arg_val); result->val = sy * exp(arg_val); result->err = arg_err * fabs(result->val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->e10 = N; return GSL_SUCCESS; } }}int gsl_sf_expm1_e(const double x, gsl_sf_result * result){ const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -1.0; result->err = GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(x < -cut) { result->val = exp(x) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = x * (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = exp(x) - 1.0; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); }}int gsl_sf_exprel_e(const double x, gsl_sf_result * result){ const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -1.0/x; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -cut) { result->val = (exp(x) - 1.0)/x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = (1.0 + 0.5*x*(1.0 + x/3.0*(1.0 + 0.25*x*(1.0 + 0.2*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = (exp(x) - 1.0)/x; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); }}int gsl_sf_exprel_2_e(double x, gsl_sf_result * result){ const double cut = 0.002; if(x < GSL_LOG_DBL_MIN) { result->val = -2.0/x*(1.0 + 1.0/x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < -cut) { result->val = 2.0*(exp(x) - 1.0 - x)/(x*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < cut) { result->val = (1.0 + 1.0/3.0*x*(1.0 + 0.25*x*(1.0 + 0.2*x*(1.0 + 1.0/6.0*x)))); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < GSL_LOG_DBL_MAX) { result->val = 2.0*(exp(x) - 1.0 - x)/(x*x); result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { OVERFLOW_ERROR(result); }}intgsl_sf_exprel_n_e(const int N, const double x, gsl_sf_result * result){ if(N < 0) { DOMAIN_ERROR(result); } else if(x == 0.0) { result->val = 1.0; result->err = 0.0; return GSL_SUCCESS; } else if(fabs(x) < GSL_ROOT3_DBL_EPSILON * N) { result->val = 1.0 + x/(N+1) * (1.0 + x/(N+2)); result->err = 2.0 * GSL_DBL_EPSILON; return GSL_SUCCESS; } else if(N == 0) { return gsl_sf_exp_e(x, result); } else if(N == 1) { return gsl_sf_exprel_e(x, result); } else if(N == 2) { return gsl_sf_exprel_2_e(x, result); } else { if(x > N && (-x + N*(1.0 + log(x/N)) < GSL_LOG_DBL_EPSILON)) { /* x is much larger than n. * Ignore polynomial part, so * exprel_N(x) ~= e^x N!/x^N */ gsl_sf_result lnf_N; double lnr_val; double lnr_err; double lnterm; gsl_sf_lnfact_e(N, &lnf_N); lnterm = N*log(x); lnr_val = x + lnf_N.val - lnterm; lnr_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(lnterm)); lnr_err += lnf_N.err; return gsl_sf_exp_err_e(lnr_val, lnr_err, result); } else if(x > N) { /* Write the identity * exprel_n(x) = e^x n! / x^n (1 - Gamma[n,x]/Gamma[n]) * then use the asymptotic expansion * Gamma[n,x] ~ x^(n-1) e^(-x) (1 + (n-1)/x + (n-1)(n-2)/x^2 + ...) */ double ln_x = log(x); gsl_sf_result lnf_N; double lg_N; double lnpre_val; double lnpre_err; gsl_sf_lnfact_e(N, &lnf_N); /* log(N!) */ lg_N = lnf_N.val - log(N); /* log(Gamma(N)) */ lnpre_val = x + lnf_N.val - N*ln_x; lnpre_err = GSL_DBL_EPSILON * (fabs(x) + fabs(lnf_N.val) + fabs(N*ln_x)); lnpre_err += lnf_N.err; if(lnpre_val < GSL_LOG_DBL_MAX - 5.0) { int stat_eG; gsl_sf_result bigG_ratio; gsl_sf_result pre; int stat_ex = gsl_sf_exp_err_e(lnpre_val, lnpre_err, &pre); double ln_bigG_ratio_pre = -x + (N-1)*ln_x - lg_N; double bigGsum = 1.0; double term = 1.0; int k; for(k=1; k<N; k++) { term *= (N-k)/x; bigGsum += term; } stat_eG = gsl_sf_exp_mult_e(ln_bigG_ratio_pre, bigGsum, &bigG_ratio); if(stat_eG == GSL_SUCCESS) { result->val = pre.val * (1.0 - bigG_ratio.val); result->err = pre.val * (2.0*GSL_DBL_EPSILON + bigG_ratio.err); result->err += pre.err * fabs(1.0 - bigG_ratio.val); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return stat_ex; } else { result->val = 0.0; result->err = 0.0; return stat_eG; } } else { OVERFLOW_ERROR(result); } } else if(x > -10.0*N) { return exprel_n_CF(N, x, result); } else { /* x -> -Inf asymptotic: * exprel_n(x) ~ e^x n!/x^n - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) * ~ - n/x (1 + (n-1)/x + (n-1)(n-2)/x + ...) */ double sum = 1.0; double term = 1.0; int k; for(k=1; k<N; k++) { term *= (N-k)/x; sum += term; } result->val = -N/x * sum; result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } }}intgsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result){ const double adx = fabs(dx); /* CHECK_POINTER(result) */ if(x + adx > GSL_LOG_DBL_MAX) { OVERFLOW_ERROR(result); } else if(x - adx < GSL_LOG_DBL_MIN) { UNDERFLOW_ERROR(result); } else { const double ex = exp(x); const double edx = exp(adx); result->val = ex; result->err = ex * GSL_MAX_DBL(GSL_DBL_EPSILON, edx - 1.0/edx); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}intgsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result){ const double adx = fabs(dx); /* CHECK_POINTER(result) */ if(x + adx > INT_MAX - 1) { OVERFLOW_ERROR_E10(result); } else if(x - adx < INT_MIN + 1) { UNDERFLOW_ERROR_E10(result); } else { const int N = (int)floor(x/M_LN10); const double ex = exp(x-N*M_LN10); result->val = ex; result->err = ex * (2.0 * GSL_DBL_EPSILON * (fabs(x) + 1.0) + adx); result->e10 = N; return GSL_SUCCESS; }}/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/#include "eval.h"double gsl_sf_exp(const double x){ EVAL_RESULT(gsl_sf_exp_e(x, &result));}double gsl_sf_exp_mult(const double x, const double y){ EVAL_RESULT(gsl_sf_exp_mult_e(x, y, &result));}double gsl_sf_expm1(const double x){ EVAL_RESULT(gsl_sf_expm1_e(x, &result));}double gsl_sf_exprel(const double x){ EVAL_RESULT(gsl_sf_exprel_e(x, &result));}double gsl_sf_exprel_2(const double x){ EVAL_RESULT(gsl_sf_exprel_2_e(x, &result));}double gsl_sf_exprel_n(const int n, const double x){ EVAL_RESULT(gsl_sf_exprel_n_e(n, x, &result));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -