psi.c

来自「一个C语言写的快速贝叶斯垃圾邮件过滤工具」· C语言 代码 · 共 638 行 · 第 1/2 页

C
638
字号
  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(ay);    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(ay);    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 + =
减小字号Ctrl + -
显示快捷键?