⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamma.c

📁 it is regression Algorithm in C/C++.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------  File    : gamma.c  Contents: computation of the (incomplete/regularized) gamma function  Author  : Christian Borgelt  History : 2002.07.04 file created            2003.05.19 incomplete Gamma function added            2008.03.14 more incomplete Gamma functions added            2008.03.15 table of factorials and logarithms added            2008.03.17 gamma distribution functions added----------------------------------------------------------------------*/#ifndef _ISOC99_SOURCE#define _ISOC99_SOURCE#endif                          /* needed for function log1p() */#if defined(GAMMA_MAIN) \ || defined(GAMMAPDF_MAIN) \ || defined(GAMMACDF_MAIN) \ || defined(GAMMAQTL_MAIN)#include <stdio.h>#include <stdlib.h>#endif#if defined(GAMMAQTL_MAIN) && !defined(GAMMAQTL)#define GAMMAQTL#endif#include <assert.h>#include <float.h>#include <math.h>#ifdef GAMMAQTL#include "normal.h"#endif#include "gamma.h"/*----------------------------------------------------------------------  Preprocessor Definitions----------------------------------------------------------------------*/#define LN_BASE      2.71828182845904523536028747135  /* e */#define SQRT_PI      1.77245385090551602729816748334  /* \sqrt(\pi) */#define LN_PI        1.14472988584940017414342735135  /* \ln(\pi) */#define LN_SQRT_2PI  0.918938533204672741780329736406                                                  /* \ln(\sqrt(2\pi)) */#define EPSILON      2.2204460492503131e-16#define EPS_QTL      1.4901161193847656e-08#define MAXFACT      170#define MAXITER      1024#define TINY         (EPSILON *EPSILON *EPSILON)/*----------------------------------------------------------------------  Table of Factorials/Gamma Values----------------------------------------------------------------------*/static double _facts[MAXFACT+1] = { 0 };static double _logfs[MAXFACT+1];static double _halfs[MAXFACT+1];static double _loghs[MAXFACT+1];/*----------------------------------------------------------------------  Functions----------------------------------------------------------------------*/static void _init (void){                               /* --- init. factorial tables */  int    i;                     /* loop variable */  double x = 1;                 /* factorial */  _facts[0] = _facts[1] = 1;    /* store factorials for 0 and 1 */  _logfs[0] = _logfs[1] = 0;    /* and their logarithms */  for (i = 1; ++i <= MAXFACT; ) {    _facts[i] = x *= i;         /* initialize the factorial table */    _logfs[i] = log(x);         /* and the table of their logarithms */  }  _halfs[0] = x = SQRT_PI;      /* store Gamma(0.5) */  _loghs[0] = 0.5*LN_PI;        /* and its logarithm */  for (i = 0; ++i < MAXFACT; ) {    _halfs[i] = x *= i-0.5;     /* initialize the table for */    _loghs[i] = log(x);         /* the Gamma function of half numbers */  }                             /* and the table of their logarithms */}  /* _init() *//*--------------------------------------------------------------------*/#if 0double logGamma (double n){                               /* --- compute ln(Gamma(n))         */  double s;                     /*           = ln((n-1)!), n \in IN */  assert(n > 0);                /* check the function argument */  if (_facts[0] <= 0) _init();  /* initialize the tables */  if (n < MAXFACT +1 +4 *EPSILON) {    if (fabs(  n -floor(  n)) < 4 *EPSILON)      return _logfs[(int)floor(n)-1];    if (fabs(2*n -floor(2*n)) < 4 *EPSILON)      return _loghs[(int)floor(n)];  }                             /* try to get the value from a table */  s =  1.000000000190015        /* otherwise compute it */    + 76.18009172947146      /(n+1)    - 86.50532032941677      /(n+2)    + 24.01409824083091      /(n+3)    -  1.231739572450155     /(n+4)    +  0.1208650972866179e-2 /(n+5)    -  0.5395239384953e-5    /(n+6);  return (n+0.5) *log((n+5.5)/LN_BASE) +(LN_SQRT_2PI +log(s/n) -5.0);}  /* logGamma() */#else /*--------------------------------------------------------------*/double logGamma (double n){                               /* --- compute ln(Gamma(n))         */  double s;                     /*           = ln((n-1)!), n \in IN */  assert(n > 0);                /* check the function argument */  if (_facts[0] <= 0) _init();  /* initialize the tables */  if (n < MAXFACT +1 +4 *EPSILON) {    if (fabs(  n -floor(  n)) < 4 *EPSILON)      return _logfs[(int)floor(n)-1];    if (fabs(2*n -floor(2*n)) < 4 *EPSILON)      return _loghs[(int)floor(n)];  }                             /* try to get the value from a table */  s =    0.99999999999980993227684700473478  /* otherwise compute it */    +  676.520368121885098567009190444019 /(n+1)    - 1259.13921672240287047156078755283  /(n+2)    +  771.3234287776530788486528258894   /(n+3)    -  176.61502916214059906584551354     /(n+4)    +   12.507343278686904814458936853    /(n+5)    -    0.13857109526572011689554707     /(n+6)    +    9.984369578019570859563e-6       /(n+7)    +    1.50563273514931155834e-7        /(n+8);  return (n+0.5) *log((n+7.5)/LN_BASE) +(LN_SQRT_2PI +log(s/n) -7.0);}  /* logGamma() */#endif/*----------------------------------------------------------------------Use Lanczos' approximation\Gamma(n+1) = (n+\gamma+0.5)^(n+0.5)            * e^{-(n+\gamma+0.5)}            * \sqrt{2\pi}            * (c_0 +c_1/(n+1) +c_2/(n+2) +...+c_n/(n+k) +\epsilon)and exploit the recursion \Gamma(n+1) = n *\Gamma(n) once,i.e., compute \Gamma(n) as \Gamma(n+1) /n.For the choices \gamma = 5, k = 6, and c_0 to c_6 as definedin the first version, it is |\epsilon| < 2e-10 for all n > 0.Source: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery        Numerical Recipes in C - The Art of Scientific Computing        Cambridge University Press, Cambridge, United Kingdom 1992        pp. 213-214For the choices gamma = 7, k = 8, and c_0 to c_8 as definedin the second version, the value is slightly more accurate.----------------------------------------------------------------------*/double Gamma (double n){                               /* --- compute Gamma(n) = (n-1)! */  assert(n > 0);                /* check the function argument */  if (_facts[0] <= 0) _init();  /* initialize the tables */  if (n < MAXFACT +1 +4 *EPSILON) {    if (fabs(  n -floor(  n)) < 4 *EPSILON)      return _facts[(int)floor(n)-1];    if (fabs(2*n -floor(2*n)) < 4 *EPSILON)      return _halfs[(int)floor(n)];  }                             /* try to get the value from a table */  return exp(logGamma(n));      /* compute through natural logarithm */}  /* Gamma() *//*--------------------------------------------------------------------*/static double _series (double n, double x){                               /* --- series approximation */  int    i;                     /* loop variable */  double t, sum;                /* buffers */  sum = t = 1/n;                /* compute initial values */  for (i = MAXITER; --i >= 0; ) {    sum += t *= x/++n;          /* add one term of the series */    if (fabs(t) < fabs(sum) *EPSILON) break;  }                             /* if term is small enough, abort */  return sum;                   /* return the computed factor */}  /* _series() *//*----------------------------------------------------------------------series approximation:P(a,x) =    \gamma(a,x)/\Gamma(a)\gamma(a,x) = e^-x x^a \sum_{n=0}^\infty (\Gamma(a)/\Gamma(a+1+n)) x^nSource: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery        Numerical Recipes in C - The Art of Scientific Computing        Cambridge University Press, Cambridge, United Kingdom 1992        formula: pp. 216-219The factor exp(n *log(x) -x) is added in the functions below.----------------------------------------------------------------------*/static double _cfrac (double n, double x){                               /* --- continued fraction approx. */  int    i;                     /* loop variable */  double a, b, c, d, e, f;      /* buffers */  b = x+1-n; c = 1/TINY; f = d = 1/b;  for (i = 1; i < MAXITER; i++) {    a = i*(n-i);                /* use Lentz's algorithm to compute */    d = a *d +(b += 2);         /* consecutive approximations */    if (fabs(d) < TINY) d = TINY;    c = b +a/c;    if (fabs(c) < TINY) c = TINY;    d = 1/d; f *= e = d *c;    if (fabs(e-1) < EPSILON) break;  }                             /* if factor is small enough, abort */  return f;                     /* return the computed factor */}  /* _cfrac() *//*----------------------------------------------------------------------continued fraction approximation:P(a,x) = 1 -\Gamma(a,x)/\Gamma(a)\Gamma(a,x) = e^-x x^a (1/(x+1-a- 1(1-a)/(x+3-a- 2*(2-a)/(x+5-a- ...))))Source: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery        Numerical Recipes in C - The Art of Scientific Computing        Cambridge University Press, Cambridge, United Kingdom 1992        formula:           pp. 216-219        Lentz's algorithm: p.  171The factor exp(n *log(x) -x) is added in the functions below.----------------------------------------------------------------------*/double lowerGamma (double n, double x){                               /* --- lower incomplete Gamma fn. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -