/* gamma.c
*
* Gamma function
*
*
*
* SYNOPSIS :
*
* double x , y , gamma ( ) ;
* extern int sgngam ;
*
* y = gamma ( x ) ;
*
*
*
* DESCRIPTION :
*
* Returns gamma function of the argument . The result is
* correctly signed , and the sign ( + 1 or - 1 ) is also
* returned in a global ( extern ) variable named sgngam .
* This variable is also filled in by the logarithmic gamma
* function lgam ( ) .
*
* Arguments | x | < = 34 are reduced by recurrence and the function
* approximated by a rational function of degree 6 / 7 in the
* interval ( 2 , 3 ) . Large arguments are handled by Stirling ' s
* formula . Large negative arguments are made positive using
* a reflection formula .
*
*
* ACCURACY :
*
* Relative error :
* arithmetic domain # trials peak rms
* DEC - 34 , 34 10000 1 . 3 e - 16 2 . 5 e - 17
* IEEE - 170 , - 33 20000 2 . 3 e - 15 3 . 3 e - 16
* IEEE - 33 , 33 20000 9 . 4 e - 16 2 . 2 e - 16
* IEEE 33 , 171 . 6 20000 2 . 3 e - 15 3 . 2 e - 16
*
* Error for arguments outside the test range will be larger
* owing to error amplification by the exponential function .
*
*/
/* lgam()
*
* Natural logarithm of gamma function
*
*
*
* SYNOPSIS :
*
* double x , y , lgam ( ) ;
* extern int sgngam ;
*
* y = lgam ( x ) ;
*
*
*
* DESCRIPTION :
*
* Returns the base e ( 2 . 718 . . . ) logarithm of the absolute
* value of the gamma function of the argument .
* The sign ( + 1 or - 1 ) of the gamma function is returned in a
* global ( extern ) variable named sgngam .
*
* For arguments greater than 13 , the logarithm of the gamma
* function is approximated by the logarithmic version of
* Stirling ' s formula using a polynomial approximation of
* degree 4 . Arguments between - 33 and + 33 are reduced by
* recurrence to the interval [ 2 , 3 ] of a rational approximation .
* The cosecant reflection formula is employed for arguments
* less than - 33 .
*
* Arguments greater than MAXLGM return MAXNUM and an error
* message . MAXLGM = 2 . 035093 e36 for DEC
* arithmetic or 2 . 556348 e305 for IEEE arithmetic .
*
*
*
* ACCURACY :
*
*
* arithmetic domain # trials peak rms
* DEC 0 , 3 7000 5 . 2 e - 17 1 . 3 e - 17
* DEC 2 . 718 , 2 . 035 e36 5000 3 . 9 e - 17 9 . 9 e - 18
* IEEE 0 , 3 28000 5 . 4 e - 16 1 . 1 e - 16
* IEEE 2 . 718 , 2 . 556 e305 40000 3 . 5 e - 16 8 . 3 e - 17
* The error criterion was relative when the function magnitude
* was greater than one but absolute when it was less than one .
*
* The following test used the relative error criterion , though
* at certain points the relative error could be much higher than
* indicated .
* IEEE - 200 , - 4 10000 4 . 8 e - 16 1 . 3 e - 16
*
*/
/* gamma.c */
/* gamma function */
/*
Cephes Math Library Release 2 . 8 : June , 2000
Copyright 1984 , 1987 , 1989 , 1992 , 2000 by Stephen L . Moshier
*/
#include "mconf.h"
#ifdef UNK
static double P[] = {1 .60119522476751861407 E-4 , 1 .19135147006586384913 E-3 ,
1 .04213797561761569935 E-2 , 4 .76367800457137231464 E-2 ,
2 .07448227648435975150 E-1 , 4 .94214826801497100753 E-1 ,
9 .99999999999999996796 E-1 };
static double Q[] = {-2 .31581873324120129819 E-5 , 5 .39605580493303397842 E-4 ,
-4 .45641913851797240494 E-3 , 1 .18139785222060435552 E-2 ,
3 .58236398605498653373 E-2 , -2 .34591795718243348568 E-1 ,
7 .14304917030273074085 E-2 , 1 .00000000000000000320 E0};
#define MAXGAM 171 .624376956302725
static double LOGPI = 1 .14472988584940017414 ;
#endif
#ifdef DEC
static unsigned short P[] = {
0035047 , 0162701 , 0146301 , 0005234 , 0035634 , 0023437 , 0032065 ,
0176530 , 0036452 , 0137157 , 0047330 , 0122574 , 0037103 , 0017310 ,
0143041 , 0017232 , 0037524 , 0066516 , 0162563 , 0164605 , 0037775 ,
0004671 , 0146237 , 0014222 , 0040200 , 0000000 , 0000000 , 0000000 };
static unsigned short Q[] = {
0134302 , 0041724 , 0020006 , 0116565 , 0035415 , 0072121 , 0044251 , 0025634 ,
0136222 , 0003447 , 0035205 , 0121114 , 0036501 , 0107552 , 0154335 , 0104271 ,
0037022 , 0135717 , 0014776 , 0171471 , 0137560 , 0034324 , 0165024 , 0037021 ,
0037222 , 0045046 , 0047151 , 0161213 , 0040200 , 0000000 , 0000000 , 0000000 };
#define MAXGAM 34 .84425627277176174
static unsigned short LPI[4 ] = {
0040222 ,
0103202 ,
0043475 ,
0006750 ,
};
#define LOGPI *(double *)LPI
#endif
#ifdef IBMPC
static unsigned short P[] = {0 x2153, 0 x3998, 0 xfcb8, 0 x3f24, 0 xbfab, 0 xe686,
0 x84e3, 0 x3f53, 0 x14b0, 0 xe9db, 0 x57cd, 0 x3f85,
0 x23d3, 0 x18c4, 0 x63d9, 0 x3fa8, 0 x7d31, 0 xdcae,
0 x8da9, 0 x3fca, 0 xe312, 0 x3993, 0 xa137, 0 x3fdf,
0 x0000, 0 x0000, 0 x0000, 0 x3ff0};
static unsigned short Q[] = {
0 xd3af, 0 x8400, 0 x487a, 0 xbef8, 0 x2573, 0 x2915, 0 xae8a, 0 x3f41,
0 xb44a, 0 xe750, 0 x40e4, 0 xbf72, 0 xb117, 0 x5b1b, 0 x31ed, 0 x3f88,
0 xde67, 0 xe33f, 0 x5779, 0 x3fa2, 0 x87c2, 0 x9d42, 0 x071a, 0 xbfce,
0 x3c51, 0 xc9cd, 0 x4944, 0 x3fb2, 0 x0000, 0 x0000, 0 x0000, 0 x3ff0};
#define MAXGAM 171 .624376956302725
static unsigned short LPI[4 ] = {
0 xa1bd,
0 x48e7,
0 x50d0,
0 x3ff2,
};
#define LOGPI *(double *)LPI
#endif
#ifdef MIEEE
static unsigned short P[] = {0 x3f24, 0 xfcb8, 0 x3998, 0 x2153, 0 x3f53, 0 x84e3,
0 xe686, 0 xbfab, 0 x3f85, 0 x57cd, 0 xe9db, 0 x14b0,
0 x3fa8, 0 x63d9, 0 x18c4, 0 x23d3, 0 x3fca, 0 x8da9,
0 xdcae, 0 x7d31, 0 x3fdf, 0 xa137, 0 x3993, 0 xe312,
0 x3ff0, 0 x0000, 0 x0000, 0 x0000};
static unsigned short Q[] = {
0 xbef8, 0 x487a, 0 x8400, 0 xd3af, 0 x3f41, 0 xae8a, 0 x2915, 0 x2573,
0 xbf72, 0 x40e4, 0 xe750, 0 xb44a, 0 x3f88, 0 x31ed, 0 x5b1b, 0 xb117,
0 x3fa2, 0 x5779, 0 xe33f, 0 xde67, 0 xbfce, 0 x071a, 0 x9d42, 0 x87c2,
0 x3fb2, 0 x4944, 0 xc9cd, 0 x3c51, 0 x3ff0, 0 x0000, 0 x0000, 0 x0000};
#define MAXGAM 171 .624376956302725
static unsigned short LPI[4 ] = {
0 x3ff2,
0 x50d0,
0 x48e7,
0 xa1bd,
};
#define LOGPI *(double *)LPI
#endif
/* Stirling's formula for the gamma function */
#if UNK
static double STIR[5 ] = {
7 .87311395793093628397 E-4 , -2 .29549961613378126380 E-4 ,
-2 .68132617805781232825 E-3 , 3 .47222221605458667310 E-3 ,
8 .33333333333482257126 E-2 ,
};
#define MAXSTIR 143 .01608
static double SQTPI = 2 .50662827463100050242 E0;
#endif
#if DEC
static unsigned short STIR[20 ] = {
0035516 , 0061622 , 0144553 , 0112224 , 0135160 , 0131531 , 0037460 ,
0165740 , 0136057 , 0134460 , 0037242 , 0077270 , 0036143 , 0107070 ,
0156306 , 0027751 , 0037252 , 0125252 , 0125252 , 0146064 ,
};
#define MAXSTIR 26 .77
static unsigned short SQT[4 ] = {
0040440 ,
0066230 ,
0177661 ,
0034055 ,
};
#define SQTPI *(double *)SQT
#endif
#if IBMPC
static unsigned short STIR[20 ] = {
0 x7293, 0 x592d, 0 xcc72, 0 x3f49, 0 x1d7c, 0 x27e6, 0 x166b,
0 xbf2e, 0 x4fd7, 0 x07d4, 0 xf726, 0 xbf65, 0 xc5fd, 0 x1b98,
0 x71c7, 0 x3f6c, 0 x5986, 0 x5555, 0 x5555, 0 x3fb5,
};
#define MAXSTIR 143 .01608
static unsigned short SQT[4 ] = {
0 x2706,
0 x1ff6,
0 x0d93,
0 x4004,
};
#define SQTPI *(double *)SQT
#endif
#if MIEEE
static unsigned short STIR[20 ] = {
0 x3f49, 0 xcc72, 0 x592d, 0 x7293, 0 xbf2e, 0 x166b, 0 x27e6,
0 x1d7c, 0 xbf65, 0 xf726, 0 x07d4, 0 x4fd7, 0 x3f6c, 0 x71c7,
0 x1b98, 0 xc5fd, 0 x3fb5, 0 x5555, 0 x5555, 0 x5986,
};
#define MAXSTIR 143 .01608
static unsigned short SQT[4 ] = {
0 x4004,
0 x0d93,
0 x1ff6,
0 x2706,
};
#define SQTPI *(double *)SQT
#endif
int sgngam = 0 ;
extern int sgngam;
extern double MAXLOG, MAXNUM, PI;
#ifdef ANSIPROT
extern double pow(double , double );
extern double log(double );
extern double exp(double );
extern double sin(double );
extern double polevl(double , void *, int );
extern double p1evl(double , void *, int );
extern double floor(double );
extern double fabs(double );
extern int isnan(double );
extern int isfinite(double );
static double stirf(double );
double lgam(double );
#else
double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs();
int isnan(), isfinite();
static double stirf();
double lgam();
#endif
#ifdef INFINITIES
extern double INFINITY;
#endif
#ifdef NANS
extern double NAN;
#endif
/* Gamma function computed by Stirling's formula.
* The polynomial STIR is valid for 33 < = x < = 172 .
*/
static double stirf(x) double x;
{
double y, w, v;
w = 1 .0 / x;
w = 1 .0 + w * polevl(w, STIR, 4 );
y = exp(x);
if (x > MAXSTIR) { /* Avoid overflow in pow() */
v = pow(x, 0 .5 * x - 0 .25 );
y = v * (v / y);
} else {
y = pow(x, x - 0 .5 ) / y;
}
y = SQTPI * y * w;
return (y);
}
double gamma(x) double x;
{
double p, q, z;
int i;
sgngam = 1 ;
#ifdef NANS
if (isnan(x))
return (x);
#endif
#ifdef INFINITIES
#ifdef NANS
if (x == INFINITY)
return (x);
if (x == -INFINITY)
return (NAN);
#else
if (!isfinite(x))
return (x);
#endif
#endif
q = fabs(x);
if (q > 33 .0 ) {
if (x < 0 .0 ) {
p = floor(q);
if (p == q) {
#ifdef NANS
gamnan:
mtherr("gamma" , DOMAIN);
return (NAN);
#else
goto goverf;
#endif
}
i = p;
if ((i & 1 ) == 0 )
sgngam = -1 ;
z = q - p;
if (z > 0 .5 ) {
p += 1 .0 ;
z = q - p;
}
z = q * sin(PI * z);
if (z == 0 .0 ) {
#ifdef INFINITIES
return (sgngam * INFINITY);
#else
goverf:
mtherr("gamma" , OVERFLOW);
return (sgngam * MAXNUM);
#endif
}
z = fabs(z);
z = PI / (z * stirf(q));
} else {
z = stirf(x);
}
return (sgngam * z);
}
z = 1 .0 ;
while (x >= 3 .0 ) {
x -= 1 .0 ;
z *= x;
}
while (x < 0 .0 ) {
if (x > -1 .E-9 )
goto small;
z /= x;
x += 1 .0 ;
}
while (x < 2 .0 ) {
if (x < 1 .e-9 )
goto small;
z /= x;
x += 1 .0 ;
}
if (x == 2 .0 )
return (z);
x -= 2 .0 ;
p = polevl(x, P, 6 );
q = polevl(x, Q, 7 );
return (z * p / q);
small:
if (x == 0 .0 ) {
#ifdef INFINITIES
#ifdef NANS
goto gamnan;
#else
return (INFINITY);
#endif
#else
mtherr("gamma" , SING);
return (MAXNUM);
#endif
} else
return (z / ((1 .0 + 0 .5772156649015329 * x) * x));
}
/* A[]: Stirling's formula expansion of log gamma
* B [ ] , C [ ] : log gamma function between 2 and 3
*/
#ifdef UNK
static double A[] = {8 .11614167470508450300 E-4 , -5 .95061904284301438324 E-4 ,
7 .93650340457716943945 E-4 , -2 .77777777730099687205 E-3 ,
8 .33333333333331927722 E-2 };
static double B[] = {-1 .37825152569120859100 E3, -3 .88016315134637840924 E4,
-3 .31612992738871184744 E5, -1 .16237097492762307383 E6,
-1 .72173700820839662146 E6, -8 .53555664245765465627 E5};
static double C[] = {
/* 1.00000000000000000000E0, */
-3 .51815701436523470549 E2, -1 .70642106651881159223 E4,
-2 .20528590553854454839 E5, -1 .13933444367982507207 E6,
-2 .53252307177582951285 E6, -2 .01889141433532773231 E6};
/* log( sqrt( 2*pi ) ) */
static double LS2PI = 0 .91893853320467274178 ;
#define MAXLGM 2 .556348 e305
#endif
#ifdef DEC
static unsigned short A[] = {0035524 , 0141201 , 0034633 , 0031405 , 0135433 ,
0176755 , 0126007 , 0045030 , 0035520 , 0006371 ,
0003342 , 0172730 , 0136066 , 0005540 , 0132605 ,
0026407 , 0037252 , 0125252 , 0125252 , 0125132 };
static unsigned short B[] = {
0142654 , 0044014 , 0077633 , 0035410 , 0144027 , 0110641 , 0125335 , 0144760 ,
0144641 , 0165637 , 0142204 , 0047447 , 0145215 , 0162027 , 0146246 , 0155211 ,
0145322 , 0026110 , 0010317 , 0110130 , 0145120 , 0061472 , 0120300 , 0025363 };
static unsigned short C[] = {
/*0040200,0000000,0000000,0000000*/
0142257 , 0164150 , 0163630 , 0112622 , 0143605 , 0050153 , 0156116 , 0135272 ,
0144527 , 0056045 , 0145642 , 0062332 , 0145213 , 0012063 , 0106250 , 0001025 ,
0145432 , 0111254 , 0044577 , 0115142 , 0145366 , 0071133 , 0050217 , 0005122 };
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {
040153 ,
037616 ,
041445 ,
0172645 ,
};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .035093 e36
#endif
#ifdef IBMPC
static unsigned short A[] = {0 x6661, 0 x2733, 0 x9850, 0 x3f4a, 0 xe943,
0 xb580, 0 x7fbd, 0 xbf43, 0 x5ebb, 0 x20dc,
0 x019f, 0 x3f4a, 0 xa5a1, 0 x16b0, 0 xc16c,
0 xbf66, 0 x554b, 0 x5555, 0 x5555, 0 x3fb5};
static unsigned short B[] = {0 x6761, 0 x8ff3, 0 x8901, 0 xc095, 0 xb93e, 0 x355b,
0 xf234, 0 xc0e2, 0 x89e5, 0 xf890, 0 x3d73, 0 xc114,
0 xdb51, 0 xf994, 0 xbc82, 0 xc131, 0 xf20b, 0 x0219,
0 x4589, 0 xc13a, 0 x055e, 0 x5418, 0 x0c67, 0 xc12a};
static unsigned short C[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0 x12b2, 0 x1cf3, 0 xfd0d, 0 xc075, 0 xd757, 0 x7b89, 0 xaa0d, 0 xc0d0,
0 x4c9b, 0 xb974, 0 xeb84, 0 xc10a, 0 x0043, 0 x7195, 0 x6286, 0 xc131,
0 xf34c, 0 x892f, 0 x5255, 0 xc143, 0 xe14a, 0 x6a11, 0 xce4b, 0 xc13e};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {0 xbeb5, 0 xc864, 0 x67f1, 0 x3fed};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .556348 e305
#endif
#ifdef MIEEE
static unsigned short A[] = {0 x3f4a, 0 x9850, 0 x2733, 0 x6661, 0 xbf43,
0 x7fbd, 0 xb580, 0 xe943, 0 x3f4a, 0 x019f,
0 x20dc, 0 x5ebb, 0 xbf66, 0 xc16c, 0 x16b0,
0 xa5a1, 0 x3fb5, 0 x5555, 0 x5555, 0 x554b};
static unsigned short B[] = {0 xc095, 0 x8901, 0 x8ff3, 0 x6761, 0 xc0e2, 0 xf234,
0 x355b, 0 xb93e, 0 xc114, 0 x3d73, 0 xf890, 0 x89e5,
0 xc131, 0 xbc82, 0 xf994, 0 xdb51, 0 xc13a, 0 x4589,
0 x0219, 0 xf20b, 0 xc12a, 0 x0c67, 0 x5418, 0 x055e};
static unsigned short C[] = {0 xc075, 0 xfd0d, 0 x1cf3, 0 x12b2, 0 xc0d0, 0 xaa0d,
0 x7b89, 0 xd757, 0 xc10a, 0 xeb84, 0 xb974, 0 x4c9b,
0 xc131, 0 x6286, 0 x7195, 0 x0043, 0 xc143, 0 x5255,
0 x892f, 0 xf34c, 0 xc13e, 0 xce4b, 0 x6a11, 0 xe14a};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {0 x3fed, 0 x67f1, 0 xc864, 0 xbeb5};
#define LS2PI *(double *)LS2P
#define MAXLGM 2 .556348 e305
#endif
/* Logarithm of gamma function */
double lgam(x) double x;
{
double p, q, u, w, z;
int i;
sgngam = 1 ;
#ifdef NANS
if (isnan(x))
return (x);
#endif
#ifdef INFINITIES
if (!isfinite(x))
return (INFINITY);
#endif
if (x < -34 .0 ) {
q = -x;
w = lgam(q); /* note this modifies sgngam! */
p = floor(q);
if (p == q) {
lgsing:
#ifdef INFINITIES
mtherr("lgam" , SING);
return (INFINITY);
#else
goto loverf;
#endif
}
i = p;
if ((i & 1 ) == 0 )
sgngam = -1 ;
else
sgngam = 1 ;
z = q - p;
if (z > 0 .5 ) {
p += 1 .0 ;
z = p - q;
}
z = q * sin(PI * z);
if (z == 0 .0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = LOGPI - log(z) - w;
return (z);
}
if (x < 13 .0 ) {
z = 1 .0 ;
p = 0 .0 ;
u = x;
while (u >= 3 .0 ) {
p -= 1 .0 ;
u = x + p;
z *= u;
}
while (u < 2 .0 ) {
if (u == 0 .0 )
goto lgsing;
z /= u;
p += 1 .0 ;
u = x + p;
}
if (z < 0 .0 ) {
sgngam = -1 ;
z = -z;
} else
sgngam = 1 ;
if (u == 2 .0 )
return (log(z));
p -= 2 .0 ;
x = x + p;
p = x * polevl(x, B, 5 ) / p1evl(x, C, 6 );
return (log(z) + p);
}
if (x > MAXLGM) {
#ifdef INFINITIES
return (sgngam * INFINITY);
#else
loverf:
mtherr("lgam" , OVERFLOW);
return (sgngam * MAXNUM);
#endif
}
q = (x - 0 .5 ) * log(x) - x + LS2PI;
if (x > 1 .0 e8)
return (q);
p = 1 .0 / (x * x);
if (x >= 1000 .0 )
q += ((7 .9365079365079365079365 e-4 * p - 2 .7777777777777777777778 e-3 ) * p +
0 .0833333333333333333333 ) /
x;
else
q += polevl(p, A, 4 ) / x;
return (q);
}
Messung V0.5 in Prozent C=71 H=91 G=81
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.8Bemerkung:
¤
*© Formatika GbR, Deutschland