📄 psi.c
字号:
0.01904704322899483105816086, 0.01869104465298913508094477, 0.01834810912486842177504628, 0.01801753061247172756017024, 0.01769865306145131939690494, 0.01739086605006319997554452, 0.01709360088954001329302371, 0.01680632711763538818529605, 0.01652854933985761040751827, 0.01625980437882562975715546, 0.01599965869724394401313881, 0.01574770606433893015574400, 0.01550356543933893015574400, 0.01526687904880638577704578, 0.01503731063741979257227076, 0.01481454387422086185273411, 0.01459828089844231513993134, 0.01438824099085987447620523, 0.01418415935820681325171544, 0.01398578601958352422176106, 0.01379288478501562298719316, 0.01360523231738567365335942, 0.01342261726990576130858221, 0.01324483949212798353080444, 0.01307170929822216635628920, 0.01290304679189732236910755, 0.01273868124291638877278934, 0.01257845051066194236996928, 0.01242220051066194236996928, 0.01226978472038606978956995, 0.01212106372098095378719041, 0.01197590477193174490346273, 0.01183418141592267460867815, 0.01169577311142440471248438, 0.01156056489076458859566448, 0.01142844704164317229232189, 0.01129931481023821361463594, 0.01117306812421372175754719, 0.01104961133409026496742374, 0.01092885297157366069257770, 0.01081070552355853781923177, 0.01069508522063334415522437, 0.01058191183901270133041676, 0.01047110851491297833872701, 0.01036260157046853389428257, 0.01025632035036012704977199, /* ... */ 0.01015219706839427948625679, /* psi(1,99) */ 0.01005016666333357139524567 /* psi(1,100) */};/*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/int gsl_sf_psi_int_e(const int n, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(n <= 0) { DOMAIN_ERROR(result); } else if(n <= PSI_TABLE_NMAX) { result->val = psi_table[n]; result->err = GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* Abramowitz+Stegun 6.3.18 */ const double c2 = -1.0/12.0; const double c3 = 1.0/120.0; const double c4 = -1.0/252.0; const double c5 = 1.0/240.0; const double ni2 = (1.0/n)*(1.0/n); const double ser = ni2 * (c2 + ni2 * (c3 + ni2 * (c4 + ni2*c5))); result->val = log(n) - 0.5/n + ser; result->err = GSL_DBL_EPSILON * (fabs(log(n)) + fabs(0.5/n) + fabs(ser)); result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}int gsl_sf_psi_e(const double x, gsl_sf_result * result){ const double y = fabs(x); /* CHECK_POINTER(result) */ if(x == 0.0 || x == -1.0 || x == -2.0) { DOMAIN_ERROR(result); } else if(y >= 2.0) { const double t = 8.0/(y*y)-1.0; gsl_sf_result result_c; cheb_eval_e(&apsi_cs, t, &result_c); if(x < 0.0) { const double s = sin(M_PI*x); const double c = cos(M_PI*x); if(fabs(s) < 2.0*GSL_SQRT_DBL_MIN) { DOMAIN_ERROR(result); } else { result->val = log(y) - 0.5/x + result_c.val - M_PI * c/s; result->err = M_PI*fabs(x)*GSL_DBL_EPSILON/(s*s); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } else { result->val = log(y) - 0.5/x + result_c.val; result->err = result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } } else { /* -2 < x < 2 */ gsl_sf_result result_c; if(x < -1.0) { /* x = -2 + v */ const double v = x + 2.0; const double t1 = 1.0/x; const double t2 = 1.0/(x+1.0); const double t3 = 1.0/v; cheb_eval_e(&psi_cs, 2.0*v-1.0, &result_c); result->val = -(t1 + t2 + t3) + result_c.val; result->err = GSL_DBL_EPSILON * (fabs(t1) + fabs(x/(t2*t2)) + fabs(x/(t3*t3))); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 0.0) { /* x = -1 + v */ const double v = x + 1.0; const double t1 = 1.0/x; const double t2 = 1.0/v; cheb_eval_e(&psi_cs, 2.0*v-1.0, &result_c); result->val = -(t1 + t2) + result_c.val; result->err = GSL_DBL_EPSILON * (fabs(t1) + fabs(x/(t2*t2))); result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else if(x < 1.0) { /* x = v */ const double t1 = 1.0/x; cheb_eval_e(&psi_cs, 2.0*x-1.0, &result_c); result->val = -t1 + result_c.val; result->err = GSL_DBL_EPSILON * t1; result->err += result_c.err; result->err += GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; } else { /* x = 1 + v */ const double v = x - 1.0; return cheb_eval_e(&psi_cs, 2.0*v-1.0, result); } }}intgsl_sf_psi_1piy_e(const double y, gsl_sf_result * result){ const double ay = fabs(y); /* CHECK_POINTER(result) */ if(ay > 1000.0) { /* [Abramowitz+Stegun, 6.3.19] */ const double yi2 = 1.0/(ay*ay); const double lny = log(y); /* FIXME: y < 0 ?? */ const double sum = yi2 * (1.0/12.0 + 1.0/120.0 * yi2 + 1.0/252.0 * yi2*yi2); result->val = lny + sum; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lny) + fabs(sum)); return GSL_SUCCESS; } else if(ay > 10.0) { /* [Abramowitz+Stegun, 6.3.19] */ const double yi2 = 1.0/(ay*ay); const double lny = log(y); const double sum = yi2 * (1.0/12.0 + yi2 * (1.0/120.0 + yi2 * (1.0/252.0 + yi2 * (1.0/240.0 + yi2 * (1.0/132.0 + 691.0/32760.0 * yi2))))); result->val = lny + sum; result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lny) + fabs(sum)); return GSL_SUCCESS; } else if(ay > 1.0){ const double y2 = ay*ay; const double x = (2.0*ay - 11.0)/9.0; const double v = y2*(1.0/(1.0+y2) + 0.5/(4.0+y2)); gsl_sf_result result_c; cheb_eval_e(&r1py_cs, x, &result_c); result->val = result_c.val - M_EULER + v; result->err = result_c.err; result->err += 2.0 * GSL_DBL_EPSILON * (fabs(v) + M_EULER + fabs(result_c.val)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); result->err *= 5.0; /* FIXME: losing a digit somewhere... maybe at x=... ? */ return GSL_SUCCESS; } else { /* [Abramowitz+Stegun, 6.3.17] * * -M_EULER + y^2 Sum[1/n 1/(n^2 + y^2), {n,1,M}] * + Sum[1/n^3, {n,M+1,Infinity}] * - y^2 Sum[1/n^5, {n,M+1,Infinity}] * + y^4 Sum[1/n^7, {n,M+1,Infinity}] * - y^6 Sum[1/n^9, {n,M+1,Infinity}] * + O(y^8) * * We take M=50 for at least 15 digit precision. */ const int M = 50; const double y2 = y*y; const double c0 = 0.00019603999466879846570; const double c2 = 3.8426659205114376860e-08; const double c4 = 1.0041592839497643554e-11; const double c6 = 2.9516743763500191289e-15; const double p = c0 + y2 *(-c2 + y2*(c4 - y2*c6)); double sum = 0.0; double v; int n; for(n=1; n<=M; n++) { sum += 1.0/(n * (n*n + y*y)); } v = y2 * (sum + p); result->val = -M_EULER + v; result->err = GSL_DBL_EPSILON * (M_EULER + fabs(v)); result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val); return GSL_SUCCESS; }}int gsl_sf_psi_1_int_e(const int n, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(n <= 0) { DOMAIN_ERROR(result); } else if(n <= PSI_1_TABLE_NMAX) { result->val = psi_1_table[n]; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; } else { /* Abramowitz+Stegun 6.4.12 * double-precision for n > 100 */ const double c0 = -1.0/30.0; const double c1 = 1.0/42.0; const double c2 = -1.0/30.0; const double ni2 = (1.0/n)*(1.0/n); const double ser = ni2*ni2 * (c0 + ni2*(c1 + c2*ni2)); result->val = (1.0 + 0.5/n + 1.0/(6.0*n*n) + ser) / n; result->err = GSL_DBL_EPSILON * result->val; return GSL_SUCCESS; }}int gsl_sf_psi_n_e(const int n, const double x, gsl_sf_result * result){ /* CHECK_POINTER(result) */ if(n < 0 || x <= 0.0) { DOMAIN_ERROR(result); } else if(n == 0) { return gsl_sf_psi_e(x, result); } else { gsl_sf_result ln_nf; gsl_sf_result hzeta; int stat_hz = gsl_sf_hzeta_e(n+1.0, x, &hzeta); int stat_nf = gsl_sf_lnfact_e((unsigned int) n, &ln_nf); int stat_e = gsl_sf_exp_mult_err_e(ln_nf.val, ln_nf.err, hzeta.val, hzeta.err, result); if(GSL_IS_EVEN(n)) result->val = -result->val; return GSL_ERROR_SELECT_3(stat_e, stat_nf, stat_hz); }}/*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/#include "eval.h"double gsl_sf_psi_int(const int n){ EVAL_RESULT(gsl_sf_psi_int_e(n, &result));}double gsl_sf_psi(const double x){ EVAL_RESULT(gsl_sf_psi_e(x, &result));}double gsl_sf_psi_1piy(const double x){ EVAL_RESULT(gsl_sf_psi_1piy_e(x, &result));}double gsl_sf_psi_1_int(const int n){ EVAL_RESULT(gsl_sf_psi_1_int_e(n, &result));}double gsl_sf_psi_n(const int n, const double x){ EVAL_RESULT(gsl_sf_psi_n_e(n, x, &result));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -