[230f479] | 1 | /* gamma.c |
---|
| 2 | * |
---|
| 3 | * Gamma function |
---|
| 4 | * |
---|
| 5 | * |
---|
| 6 | * |
---|
| 7 | * SYNOPSIS: |
---|
| 8 | * |
---|
| 9 | * double x, y, gamma(); |
---|
| 10 | * extern int sgngam; |
---|
| 11 | * |
---|
| 12 | * y = gamma( x ); |
---|
| 13 | * |
---|
| 14 | * |
---|
| 15 | * |
---|
| 16 | * DESCRIPTION: |
---|
| 17 | * |
---|
| 18 | * Returns gamma function of the argument. The result is |
---|
| 19 | * correctly signed, and the sign (+1 or -1) is also |
---|
| 20 | * returned in a global (extern) variable named sgngam. |
---|
| 21 | * This variable is also filled in by the logarithmic gamma |
---|
| 22 | * function lgam(). |
---|
| 23 | * |
---|
| 24 | * Arguments |x| <= 34 are reduced by recurrence and the function |
---|
| 25 | * approximated by a rational function of degree 6/7 in the |
---|
| 26 | * interval (2,3). Large arguments are handled by Stirling's |
---|
| 27 | * formula. Large negative arguments are made positive using |
---|
| 28 | * a reflection formula. |
---|
| 29 | * |
---|
| 30 | * |
---|
| 31 | * ACCURACY: |
---|
| 32 | * |
---|
| 33 | * Relative error: |
---|
| 34 | * arithmetic domain # trials peak rms |
---|
| 35 | * DEC -34, 34 10000 1.3e-16 2.5e-17 |
---|
| 36 | * IEEE -170,-33 20000 2.3e-15 3.3e-16 |
---|
| 37 | * IEEE -33, 33 20000 9.4e-16 2.2e-16 |
---|
| 38 | * IEEE 33, 171.6 20000 2.3e-15 3.2e-16 |
---|
| 39 | * |
---|
| 40 | * Error for arguments outside the test range will be larger |
---|
| 41 | * owing to error amplification by the exponential function. |
---|
| 42 | * |
---|
| 43 | */ |
---|
| 44 | /* lgam() |
---|
| 45 | * |
---|
| 46 | * Natural logarithm of gamma function |
---|
| 47 | * |
---|
| 48 | * |
---|
| 49 | * |
---|
| 50 | * SYNOPSIS: |
---|
| 51 | * |
---|
| 52 | * double x, y, lgam(); |
---|
| 53 | * extern int sgngam; |
---|
| 54 | * |
---|
| 55 | * y = lgam( x ); |
---|
| 56 | * |
---|
| 57 | * |
---|
| 58 | * |
---|
| 59 | * DESCRIPTION: |
---|
| 60 | * |
---|
| 61 | * Returns the base e (2.718...) logarithm of the absolute |
---|
| 62 | * value of the gamma function of the argument. |
---|
| 63 | * The sign (+1 or -1) of the gamma function is returned in a |
---|
| 64 | * global (extern) variable named sgngam. |
---|
| 65 | * |
---|
| 66 | * For arguments greater than 13, the logarithm of the gamma |
---|
| 67 | * function is approximated by the logarithmic version of |
---|
| 68 | * Stirling's formula using a polynomial approximation of |
---|
| 69 | * degree 4. Arguments between -33 and +33 are reduced by |
---|
| 70 | * recurrence to the interval [2,3] of a rational approximation. |
---|
| 71 | * The cosecant reflection formula is employed for arguments |
---|
| 72 | * less than -33. |
---|
| 73 | * |
---|
| 74 | * Arguments greater than MAXLGM return MAXNUM and an error |
---|
| 75 | * message. MAXLGM = 2.035093e36 for DEC |
---|
| 76 | * arithmetic or 2.556348e305 for IEEE arithmetic. |
---|
| 77 | * |
---|
| 78 | * |
---|
| 79 | * |
---|
| 80 | * ACCURACY: |
---|
| 81 | * |
---|
| 82 | * |
---|
| 83 | * arithmetic domain # trials peak rms |
---|
| 84 | * DEC 0, 3 7000 5.2e-17 1.3e-17 |
---|
| 85 | * DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18 |
---|
| 86 | * IEEE 0, 3 28000 5.4e-16 1.1e-16 |
---|
| 87 | * IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17 |
---|
| 88 | * The error criterion was relative when the function magnitude |
---|
| 89 | * was greater than one but absolute when it was less than one. |
---|
| 90 | * |
---|
| 91 | * The following test used the relative error criterion, though |
---|
| 92 | * at certain points the relative error could be much higher than |
---|
| 93 | * indicated. |
---|
| 94 | * IEEE -200, -4 10000 4.8e-16 1.3e-16 |
---|
| 95 | * |
---|
| 96 | */ |
---|
| 97 | |
---|
| 98 | /* gamma.c */ |
---|
| 99 | /* gamma function */ |
---|
| 100 | |
---|
| 101 | /* |
---|
| 102 | Cephes Math Library Release 2.8: June, 2000 |
---|
| 103 | Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier |
---|
| 104 | */ |
---|
| 105 | |
---|
| 106 | |
---|
| 107 | #include "mconf.h" |
---|
| 108 | |
---|
| 109 | #ifdef UNK |
---|
| 110 | static double P[] = { |
---|
| 111 | 1.60119522476751861407E-4, |
---|
| 112 | 1.19135147006586384913E-3, |
---|
| 113 | 1.04213797561761569935E-2, |
---|
| 114 | 4.76367800457137231464E-2, |
---|
| 115 | 2.07448227648435975150E-1, |
---|
| 116 | 4.94214826801497100753E-1, |
---|
| 117 | 9.99999999999999996796E-1 |
---|
| 118 | }; |
---|
| 119 | static double Q[] = { |
---|
| 120 | -2.31581873324120129819E-5, |
---|
| 121 | 5.39605580493303397842E-4, |
---|
| 122 | -4.45641913851797240494E-3, |
---|
| 123 | 1.18139785222060435552E-2, |
---|
| 124 | 3.58236398605498653373E-2, |
---|
| 125 | -2.34591795718243348568E-1, |
---|
| 126 | 7.14304917030273074085E-2, |
---|
| 127 | 1.00000000000000000320E0 |
---|
| 128 | }; |
---|
| 129 | #define MAXGAM 171.624376956302725 |
---|
| 130 | static double LOGPI = 1.14472988584940017414; |
---|
| 131 | #endif |
---|
| 132 | |
---|
| 133 | #ifdef DEC |
---|
| 134 | static unsigned short P[] = { |
---|
| 135 | 0035047,0162701,0146301,0005234, |
---|
| 136 | 0035634,0023437,0032065,0176530, |
---|
| 137 | 0036452,0137157,0047330,0122574, |
---|
| 138 | 0037103,0017310,0143041,0017232, |
---|
| 139 | 0037524,0066516,0162563,0164605, |
---|
| 140 | 0037775,0004671,0146237,0014222, |
---|
| 141 | 0040200,0000000,0000000,0000000 |
---|
| 142 | }; |
---|
| 143 | static unsigned short Q[] = { |
---|
| 144 | 0134302,0041724,0020006,0116565, |
---|
| 145 | 0035415,0072121,0044251,0025634, |
---|
| 146 | 0136222,0003447,0035205,0121114, |
---|
| 147 | 0036501,0107552,0154335,0104271, |
---|
| 148 | 0037022,0135717,0014776,0171471, |
---|
| 149 | 0137560,0034324,0165024,0037021, |
---|
| 150 | 0037222,0045046,0047151,0161213, |
---|
| 151 | 0040200,0000000,0000000,0000000 |
---|
| 152 | }; |
---|
| 153 | #define MAXGAM 34.84425627277176174 |
---|
| 154 | static unsigned short LPI[4] = { |
---|
| 155 | 0040222,0103202,0043475,0006750, |
---|
| 156 | }; |
---|
| 157 | #define LOGPI *(double *)LPI |
---|
| 158 | #endif |
---|
| 159 | |
---|
| 160 | #ifdef IBMPC |
---|
| 161 | static unsigned short P[] = { |
---|
| 162 | 0x2153,0x3998,0xfcb8,0x3f24, |
---|
| 163 | 0xbfab,0xe686,0x84e3,0x3f53, |
---|
| 164 | 0x14b0,0xe9db,0x57cd,0x3f85, |
---|
| 165 | 0x23d3,0x18c4,0x63d9,0x3fa8, |
---|
| 166 | 0x7d31,0xdcae,0x8da9,0x3fca, |
---|
| 167 | 0xe312,0x3993,0xa137,0x3fdf, |
---|
| 168 | 0x0000,0x0000,0x0000,0x3ff0 |
---|
| 169 | }; |
---|
| 170 | static unsigned short Q[] = { |
---|
| 171 | 0xd3af,0x8400,0x487a,0xbef8, |
---|
| 172 | 0x2573,0x2915,0xae8a,0x3f41, |
---|
| 173 | 0xb44a,0xe750,0x40e4,0xbf72, |
---|
| 174 | 0xb117,0x5b1b,0x31ed,0x3f88, |
---|
| 175 | 0xde67,0xe33f,0x5779,0x3fa2, |
---|
| 176 | 0x87c2,0x9d42,0x071a,0xbfce, |
---|
| 177 | 0x3c51,0xc9cd,0x4944,0x3fb2, |
---|
| 178 | 0x0000,0x0000,0x0000,0x3ff0 |
---|
| 179 | }; |
---|
| 180 | #define MAXGAM 171.624376956302725 |
---|
| 181 | static unsigned short LPI[4] = { |
---|
| 182 | 0xa1bd,0x48e7,0x50d0,0x3ff2, |
---|
| 183 | }; |
---|
| 184 | #define LOGPI *(double *)LPI |
---|
| 185 | #endif |
---|
| 186 | |
---|
| 187 | #ifdef MIEEE |
---|
| 188 | static unsigned short P[] = { |
---|
| 189 | 0x3f24,0xfcb8,0x3998,0x2153, |
---|
| 190 | 0x3f53,0x84e3,0xe686,0xbfab, |
---|
| 191 | 0x3f85,0x57cd,0xe9db,0x14b0, |
---|
| 192 | 0x3fa8,0x63d9,0x18c4,0x23d3, |
---|
| 193 | 0x3fca,0x8da9,0xdcae,0x7d31, |
---|
| 194 | 0x3fdf,0xa137,0x3993,0xe312, |
---|
| 195 | 0x3ff0,0x0000,0x0000,0x0000 |
---|
| 196 | }; |
---|
| 197 | static unsigned short Q[] = { |
---|
| 198 | 0xbef8,0x487a,0x8400,0xd3af, |
---|
| 199 | 0x3f41,0xae8a,0x2915,0x2573, |
---|
| 200 | 0xbf72,0x40e4,0xe750,0xb44a, |
---|
| 201 | 0x3f88,0x31ed,0x5b1b,0xb117, |
---|
| 202 | 0x3fa2,0x5779,0xe33f,0xde67, |
---|
| 203 | 0xbfce,0x071a,0x9d42,0x87c2, |
---|
| 204 | 0x3fb2,0x4944,0xc9cd,0x3c51, |
---|
| 205 | 0x3ff0,0x0000,0x0000,0x0000 |
---|
| 206 | }; |
---|
| 207 | #define MAXGAM 171.624376956302725 |
---|
| 208 | static unsigned short LPI[4] = { |
---|
| 209 | 0x3ff2,0x50d0,0x48e7,0xa1bd, |
---|
| 210 | }; |
---|
| 211 | #define LOGPI *(double *)LPI |
---|
| 212 | #endif |
---|
| 213 | |
---|
| 214 | /* Stirling's formula for the gamma function */ |
---|
| 215 | #if UNK |
---|
| 216 | static double STIR[5] = { |
---|
| 217 | 7.87311395793093628397E-4, |
---|
| 218 | -2.29549961613378126380E-4, |
---|
| 219 | -2.68132617805781232825E-3, |
---|
| 220 | 3.47222221605458667310E-3, |
---|
| 221 | 8.33333333333482257126E-2, |
---|
| 222 | }; |
---|
| 223 | #define MAXSTIR 143.01608 |
---|
| 224 | static double SQTPI = 2.50662827463100050242E0; |
---|
| 225 | #endif |
---|
| 226 | #if DEC |
---|
| 227 | static unsigned short STIR[20] = { |
---|
| 228 | 0035516,0061622,0144553,0112224, |
---|
| 229 | 0135160,0131531,0037460,0165740, |
---|
| 230 | 0136057,0134460,0037242,0077270, |
---|
| 231 | 0036143,0107070,0156306,0027751, |
---|
| 232 | 0037252,0125252,0125252,0146064, |
---|
| 233 | }; |
---|
| 234 | #define MAXSTIR 26.77 |
---|
| 235 | static unsigned short SQT[4] = { |
---|
| 236 | 0040440,0066230,0177661,0034055, |
---|
| 237 | }; |
---|
| 238 | #define SQTPI *(double *)SQT |
---|
| 239 | #endif |
---|
| 240 | #if IBMPC |
---|
| 241 | static unsigned short STIR[20] = { |
---|
| 242 | 0x7293,0x592d,0xcc72,0x3f49, |
---|
| 243 | 0x1d7c,0x27e6,0x166b,0xbf2e, |
---|
| 244 | 0x4fd7,0x07d4,0xf726,0xbf65, |
---|
| 245 | 0xc5fd,0x1b98,0x71c7,0x3f6c, |
---|
| 246 | 0x5986,0x5555,0x5555,0x3fb5, |
---|
| 247 | }; |
---|
| 248 | #define MAXSTIR 143.01608 |
---|
| 249 | static unsigned short SQT[4] = { |
---|
| 250 | 0x2706,0x1ff6,0x0d93,0x4004, |
---|
| 251 | }; |
---|
| 252 | #define SQTPI *(double *)SQT |
---|
| 253 | #endif |
---|
| 254 | #if MIEEE |
---|
| 255 | static unsigned short STIR[20] = { |
---|
| 256 | 0x3f49,0xcc72,0x592d,0x7293, |
---|
| 257 | 0xbf2e,0x166b,0x27e6,0x1d7c, |
---|
| 258 | 0xbf65,0xf726,0x07d4,0x4fd7, |
---|
| 259 | 0x3f6c,0x71c7,0x1b98,0xc5fd, |
---|
| 260 | 0x3fb5,0x5555,0x5555,0x5986, |
---|
| 261 | }; |
---|
| 262 | #define MAXSTIR 143.01608 |
---|
| 263 | static unsigned short SQT[4] = { |
---|
| 264 | 0x4004,0x0d93,0x1ff6,0x2706, |
---|
| 265 | }; |
---|
| 266 | #define SQTPI *(double *)SQT |
---|
| 267 | #endif |
---|
| 268 | |
---|
| 269 | int sgngam = 0; |
---|
| 270 | extern int sgngam; |
---|
| 271 | extern double MAXLOG, MAXNUM, PI; |
---|
| 272 | #ifdef ANSIPROT |
---|
| 273 | extern double pow ( double, double ); |
---|
| 274 | extern double log ( double ); |
---|
| 275 | extern double exp ( double ); |
---|
| 276 | extern double sin ( double ); |
---|
| 277 | extern double polevl ( double, void *, int ); |
---|
| 278 | extern double p1evl ( double, void *, int ); |
---|
| 279 | extern double floor ( double ); |
---|
| 280 | extern double fabs ( double ); |
---|
| 281 | extern int isnan ( double ); |
---|
| 282 | extern int isfinite ( double ); |
---|
| 283 | static double stirf ( double ); |
---|
| 284 | double lgam ( double ); |
---|
| 285 | #else |
---|
| 286 | double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs(); |
---|
| 287 | int isnan(), isfinite(); |
---|
| 288 | static double stirf(); |
---|
| 289 | double lgam(); |
---|
| 290 | #endif |
---|
| 291 | #ifdef INFINITIES |
---|
| 292 | extern double INFINITY; |
---|
| 293 | #endif |
---|
| 294 | #ifdef NANS |
---|
| 295 | extern double NAN; |
---|
| 296 | #endif |
---|
| 297 | |
---|
| 298 | /* Gamma function computed by Stirling's formula. |
---|
| 299 | * The polynomial STIR is valid for 33 <= x <= 172. |
---|
| 300 | */ |
---|
| 301 | static double stirf(x) |
---|
| 302 | double x; |
---|
| 303 | { |
---|
| 304 | double y, w, v; |
---|
| 305 | |
---|
| 306 | w = 1.0/x; |
---|
| 307 | w = 1.0 + w * polevl( w, STIR, 4 ); |
---|
| 308 | y = exp(x); |
---|
| 309 | if( x > MAXSTIR ) |
---|
| 310 | { /* Avoid overflow in pow() */ |
---|
| 311 | v = pow( x, 0.5 * x - 0.25 ); |
---|
| 312 | y = v * (v / y); |
---|
| 313 | } |
---|
| 314 | else |
---|
| 315 | { |
---|
| 316 | y = pow( x, x - 0.5 ) / y; |
---|
| 317 | } |
---|
| 318 | y = SQTPI * y * w; |
---|
| 319 | return( y ); |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | |
---|
| 323 | |
---|
| 324 | double gamma(x) |
---|
| 325 | double x; |
---|
| 326 | { |
---|
| 327 | double p, q, z; |
---|
| 328 | int i; |
---|
| 329 | |
---|
| 330 | sgngam = 1; |
---|
| 331 | #ifdef NANS |
---|
| 332 | if( isnan(x) ) |
---|
| 333 | return(x); |
---|
| 334 | #endif |
---|
| 335 | #ifdef INFINITIES |
---|
| 336 | #ifdef NANS |
---|
| 337 | if( x == INFINITY ) |
---|
| 338 | return(x); |
---|
| 339 | if( x == -INFINITY ) |
---|
| 340 | return(NAN); |
---|
| 341 | #else |
---|
| 342 | if( !isfinite(x) ) |
---|
| 343 | return(x); |
---|
| 344 | #endif |
---|
| 345 | #endif |
---|
| 346 | q = fabs(x); |
---|
| 347 | |
---|
| 348 | if( q > 33.0 ) |
---|
| 349 | { |
---|
| 350 | if( x < 0.0 ) |
---|
| 351 | { |
---|
| 352 | p = floor(q); |
---|
| 353 | if( p == q ) |
---|
| 354 | { |
---|
| 355 | #ifdef NANS |
---|
| 356 | gamnan: |
---|
| 357 | mtherr( "gamma", DOMAIN ); |
---|
| 358 | return (NAN); |
---|
| 359 | #else |
---|
| 360 | goto goverf; |
---|
| 361 | #endif |
---|
| 362 | } |
---|
| 363 | i = p; |
---|
| 364 | if( (i & 1) == 0 ) |
---|
| 365 | sgngam = -1; |
---|
| 366 | z = q - p; |
---|
| 367 | if( z > 0.5 ) |
---|
| 368 | { |
---|
| 369 | p += 1.0; |
---|
| 370 | z = q - p; |
---|
| 371 | } |
---|
| 372 | z = q * sin( PI * z ); |
---|
| 373 | if( z == 0.0 ) |
---|
| 374 | { |
---|
| 375 | #ifdef INFINITIES |
---|
| 376 | return( sgngam * INFINITY); |
---|
| 377 | #else |
---|
| 378 | goverf: |
---|
| 379 | mtherr( "gamma", OVERFLOW ); |
---|
| 380 | return( sgngam * MAXNUM); |
---|
| 381 | #endif |
---|
| 382 | } |
---|
| 383 | z = fabs(z); |
---|
| 384 | z = PI/(z * stirf(q) ); |
---|
| 385 | } |
---|
| 386 | else |
---|
| 387 | { |
---|
| 388 | z = stirf(x); |
---|
| 389 | } |
---|
| 390 | return( sgngam * z ); |
---|
| 391 | } |
---|
| 392 | |
---|
| 393 | z = 1.0; |
---|
| 394 | while( x >= 3.0 ) |
---|
| 395 | { |
---|
| 396 | x -= 1.0; |
---|
| 397 | z *= x; |
---|
| 398 | } |
---|
| 399 | |
---|
| 400 | while( x < 0.0 ) |
---|
| 401 | { |
---|
| 402 | if( x > -1.E-9 ) |
---|
| 403 | goto small; |
---|
| 404 | z /= x; |
---|
| 405 | x += 1.0; |
---|
| 406 | } |
---|
| 407 | |
---|
| 408 | while( x < 2.0 ) |
---|
| 409 | { |
---|
| 410 | if( x < 1.e-9 ) |
---|
| 411 | goto small; |
---|
| 412 | z /= x; |
---|
| 413 | x += 1.0; |
---|
| 414 | } |
---|
| 415 | |
---|
| 416 | if( x == 2.0 ) |
---|
| 417 | return(z); |
---|
| 418 | |
---|
| 419 | x -= 2.0; |
---|
| 420 | p = polevl( x, P, 6 ); |
---|
| 421 | q = polevl( x, Q, 7 ); |
---|
| 422 | return( z * p / q ); |
---|
| 423 | |
---|
| 424 | small: |
---|
| 425 | if( x == 0.0 ) |
---|
| 426 | { |
---|
| 427 | #ifdef INFINITIES |
---|
| 428 | #ifdef NANS |
---|
| 429 | goto gamnan; |
---|
| 430 | #else |
---|
| 431 | return( INFINITY ); |
---|
| 432 | #endif |
---|
| 433 | #else |
---|
| 434 | mtherr( "gamma", SING ); |
---|
| 435 | return( MAXNUM ); |
---|
| 436 | #endif |
---|
| 437 | } |
---|
| 438 | else |
---|
| 439 | return( z/((1.0 + 0.5772156649015329 * x) * x) ); |
---|
| 440 | } |
---|
| 441 | |
---|
| 442 | |
---|
| 443 | |
---|
| 444 | /* A[]: Stirling's formula expansion of log gamma |
---|
| 445 | * B[], C[]: log gamma function between 2 and 3 |
---|
| 446 | */ |
---|
| 447 | #ifdef UNK |
---|
| 448 | static double A[] = { |
---|
| 449 | 8.11614167470508450300E-4, |
---|
| 450 | -5.95061904284301438324E-4, |
---|
| 451 | 7.93650340457716943945E-4, |
---|
| 452 | -2.77777777730099687205E-3, |
---|
| 453 | 8.33333333333331927722E-2 |
---|
| 454 | }; |
---|
| 455 | static double B[] = { |
---|
| 456 | -1.37825152569120859100E3, |
---|
| 457 | -3.88016315134637840924E4, |
---|
| 458 | -3.31612992738871184744E5, |
---|
| 459 | -1.16237097492762307383E6, |
---|
| 460 | -1.72173700820839662146E6, |
---|
| 461 | -8.53555664245765465627E5 |
---|
| 462 | }; |
---|
| 463 | static double C[] = { |
---|
| 464 | /* 1.00000000000000000000E0, */ |
---|
| 465 | -3.51815701436523470549E2, |
---|
| 466 | -1.70642106651881159223E4, |
---|
| 467 | -2.20528590553854454839E5, |
---|
| 468 | -1.13933444367982507207E6, |
---|
| 469 | -2.53252307177582951285E6, |
---|
| 470 | -2.01889141433532773231E6 |
---|
| 471 | }; |
---|
| 472 | /* log( sqrt( 2*pi ) ) */ |
---|
| 473 | static double LS2PI = 0.91893853320467274178; |
---|
| 474 | #define MAXLGM 2.556348e305 |
---|
| 475 | #endif |
---|
| 476 | |
---|
| 477 | #ifdef DEC |
---|
| 478 | static unsigned short A[] = { |
---|
| 479 | 0035524,0141201,0034633,0031405, |
---|
| 480 | 0135433,0176755,0126007,0045030, |
---|
| 481 | 0035520,0006371,0003342,0172730, |
---|
| 482 | 0136066,0005540,0132605,0026407, |
---|
| 483 | 0037252,0125252,0125252,0125132 |
---|
| 484 | }; |
---|
| 485 | static unsigned short B[] = { |
---|
| 486 | 0142654,0044014,0077633,0035410, |
---|
| 487 | 0144027,0110641,0125335,0144760, |
---|
| 488 | 0144641,0165637,0142204,0047447, |
---|
| 489 | 0145215,0162027,0146246,0155211, |
---|
| 490 | 0145322,0026110,0010317,0110130, |
---|
| 491 | 0145120,0061472,0120300,0025363 |
---|
| 492 | }; |
---|
| 493 | static unsigned short C[] = { |
---|
| 494 | /*0040200,0000000,0000000,0000000*/ |
---|
| 495 | 0142257,0164150,0163630,0112622, |
---|
| 496 | 0143605,0050153,0156116,0135272, |
---|
| 497 | 0144527,0056045,0145642,0062332, |
---|
| 498 | 0145213,0012063,0106250,0001025, |
---|
| 499 | 0145432,0111254,0044577,0115142, |
---|
| 500 | 0145366,0071133,0050217,0005122 |
---|
| 501 | }; |
---|
| 502 | /* log( sqrt( 2*pi ) ) */ |
---|
| 503 | static unsigned short LS2P[] = {040153,037616,041445,0172645,}; |
---|
| 504 | #define LS2PI *(double *)LS2P |
---|
| 505 | #define MAXLGM 2.035093e36 |
---|
| 506 | #endif |
---|
| 507 | |
---|
| 508 | #ifdef IBMPC |
---|
| 509 | static unsigned short A[] = { |
---|
| 510 | 0x6661,0x2733,0x9850,0x3f4a, |
---|
| 511 | 0xe943,0xb580,0x7fbd,0xbf43, |
---|
| 512 | 0x5ebb,0x20dc,0x019f,0x3f4a, |
---|
| 513 | 0xa5a1,0x16b0,0xc16c,0xbf66, |
---|
| 514 | 0x554b,0x5555,0x5555,0x3fb5 |
---|
| 515 | }; |
---|
| 516 | static unsigned short B[] = { |
---|
| 517 | 0x6761,0x8ff3,0x8901,0xc095, |
---|
| 518 | 0xb93e,0x355b,0xf234,0xc0e2, |
---|
| 519 | 0x89e5,0xf890,0x3d73,0xc114, |
---|
| 520 | 0xdb51,0xf994,0xbc82,0xc131, |
---|
| 521 | 0xf20b,0x0219,0x4589,0xc13a, |
---|
| 522 | 0x055e,0x5418,0x0c67,0xc12a |
---|
| 523 | }; |
---|
| 524 | static unsigned short C[] = { |
---|
| 525 | /*0x0000,0x0000,0x0000,0x3ff0,*/ |
---|
| 526 | 0x12b2,0x1cf3,0xfd0d,0xc075, |
---|
| 527 | 0xd757,0x7b89,0xaa0d,0xc0d0, |
---|
| 528 | 0x4c9b,0xb974,0xeb84,0xc10a, |
---|
| 529 | 0x0043,0x7195,0x6286,0xc131, |
---|
| 530 | 0xf34c,0x892f,0x5255,0xc143, |
---|
| 531 | 0xe14a,0x6a11,0xce4b,0xc13e |
---|
| 532 | }; |
---|
| 533 | /* log( sqrt( 2*pi ) ) */ |
---|
| 534 | static unsigned short LS2P[] = { |
---|
| 535 | 0xbeb5,0xc864,0x67f1,0x3fed |
---|
| 536 | }; |
---|
| 537 | #define LS2PI *(double *)LS2P |
---|
| 538 | #define MAXLGM 2.556348e305 |
---|
| 539 | #endif |
---|
| 540 | |
---|
| 541 | #ifdef MIEEE |
---|
| 542 | static unsigned short A[] = { |
---|
| 543 | 0x3f4a,0x9850,0x2733,0x6661, |
---|
| 544 | 0xbf43,0x7fbd,0xb580,0xe943, |
---|
| 545 | 0x3f4a,0x019f,0x20dc,0x5ebb, |
---|
| 546 | 0xbf66,0xc16c,0x16b0,0xa5a1, |
---|
| 547 | 0x3fb5,0x5555,0x5555,0x554b |
---|
| 548 | }; |
---|
| 549 | static unsigned short B[] = { |
---|
| 550 | 0xc095,0x8901,0x8ff3,0x6761, |
---|
| 551 | 0xc0e2,0xf234,0x355b,0xb93e, |
---|
| 552 | 0xc114,0x3d73,0xf890,0x89e5, |
---|
| 553 | 0xc131,0xbc82,0xf994,0xdb51, |
---|
| 554 | 0xc13a,0x4589,0x0219,0xf20b, |
---|
| 555 | 0xc12a,0x0c67,0x5418,0x055e |
---|
| 556 | }; |
---|
| 557 | static unsigned short C[] = { |
---|
| 558 | 0xc075,0xfd0d,0x1cf3,0x12b2, |
---|
| 559 | 0xc0d0,0xaa0d,0x7b89,0xd757, |
---|
| 560 | 0xc10a,0xeb84,0xb974,0x4c9b, |
---|
| 561 | 0xc131,0x6286,0x7195,0x0043, |
---|
| 562 | 0xc143,0x5255,0x892f,0xf34c, |
---|
| 563 | 0xc13e,0xce4b,0x6a11,0xe14a |
---|
| 564 | }; |
---|
| 565 | /* log( sqrt( 2*pi ) ) */ |
---|
| 566 | static unsigned short LS2P[] = { |
---|
| 567 | 0x3fed,0x67f1,0xc864,0xbeb5 |
---|
| 568 | }; |
---|
| 569 | #define LS2PI *(double *)LS2P |
---|
| 570 | #define MAXLGM 2.556348e305 |
---|
| 571 | #endif |
---|
| 572 | |
---|
| 573 | |
---|
| 574 | /* Logarithm of gamma function */ |
---|
| 575 | |
---|
| 576 | |
---|
| 577 | double lgam(x) |
---|
| 578 | double x; |
---|
| 579 | { |
---|
| 580 | double p, q, u, w, z; |
---|
| 581 | int i; |
---|
| 582 | |
---|
| 583 | sgngam = 1; |
---|
| 584 | #ifdef NANS |
---|
| 585 | if( isnan(x) ) |
---|
| 586 | return(x); |
---|
| 587 | #endif |
---|
| 588 | |
---|
| 589 | #ifdef INFINITIES |
---|
| 590 | if( !isfinite(x) ) |
---|
| 591 | return(INFINITY); |
---|
| 592 | #endif |
---|
| 593 | |
---|
| 594 | if( x < -34.0 ) |
---|
| 595 | { |
---|
| 596 | q = -x; |
---|
| 597 | w = lgam(q); /* note this modifies sgngam! */ |
---|
| 598 | p = floor(q); |
---|
| 599 | if( p == q ) |
---|
| 600 | { |
---|
| 601 | lgsing: |
---|
| 602 | #ifdef INFINITIES |
---|
| 603 | mtherr( "lgam", SING ); |
---|
| 604 | return (INFINITY); |
---|
| 605 | #else |
---|
| 606 | goto loverf; |
---|
| 607 | #endif |
---|
| 608 | } |
---|
| 609 | i = p; |
---|
| 610 | if( (i & 1) == 0 ) |
---|
| 611 | sgngam = -1; |
---|
| 612 | else |
---|
| 613 | sgngam = 1; |
---|
| 614 | z = q - p; |
---|
| 615 | if( z > 0.5 ) |
---|
| 616 | { |
---|
| 617 | p += 1.0; |
---|
| 618 | z = p - q; |
---|
| 619 | } |
---|
| 620 | z = q * sin( PI * z ); |
---|
| 621 | if( z == 0.0 ) |
---|
| 622 | goto lgsing; |
---|
| 623 | /* z = log(PI) - log( z ) - w;*/ |
---|
| 624 | z = LOGPI - log( z ) - w; |
---|
| 625 | return( z ); |
---|
| 626 | } |
---|
| 627 | |
---|
| 628 | if( x < 13.0 ) |
---|
| 629 | { |
---|
| 630 | z = 1.0; |
---|
| 631 | p = 0.0; |
---|
| 632 | u = x; |
---|
| 633 | while( u >= 3.0 ) |
---|
| 634 | { |
---|
| 635 | p -= 1.0; |
---|
| 636 | u = x + p; |
---|
| 637 | z *= u; |
---|
| 638 | } |
---|
| 639 | while( u < 2.0 ) |
---|
| 640 | { |
---|
| 641 | if( u == 0.0 ) |
---|
| 642 | goto lgsing; |
---|
| 643 | z /= u; |
---|
| 644 | p += 1.0; |
---|
| 645 | u = x + p; |
---|
| 646 | } |
---|
| 647 | if( z < 0.0 ) |
---|
| 648 | { |
---|
| 649 | sgngam = -1; |
---|
| 650 | z = -z; |
---|
| 651 | } |
---|
| 652 | else |
---|
| 653 | sgngam = 1; |
---|
| 654 | if( u == 2.0 ) |
---|
| 655 | return( log(z) ); |
---|
| 656 | p -= 2.0; |
---|
| 657 | x = x + p; |
---|
| 658 | p = x * polevl( x, B, 5 ) / p1evl( x, C, 6); |
---|
| 659 | return( log(z) + p ); |
---|
| 660 | } |
---|
| 661 | |
---|
| 662 | if( x > MAXLGM ) |
---|
| 663 | { |
---|
| 664 | #ifdef INFINITIES |
---|
| 665 | return( sgngam * INFINITY ); |
---|
| 666 | #else |
---|
| 667 | loverf: |
---|
| 668 | mtherr( "lgam", OVERFLOW ); |
---|
| 669 | return( sgngam * MAXNUM ); |
---|
| 670 | #endif |
---|
| 671 | } |
---|
| 672 | |
---|
| 673 | q = ( x - 0.5 ) * log(x) - x + LS2PI; |
---|
| 674 | if( x > 1.0e8 ) |
---|
| 675 | return( q ); |
---|
| 676 | |
---|
| 677 | p = 1.0/(x*x); |
---|
| 678 | if( x >= 1000.0 ) |
---|
| 679 | q += (( 7.9365079365079365079365e-4 * p |
---|
| 680 | - 2.7777777777777777777778e-3) *p |
---|
| 681 | + 0.0833333333333333333333) / x; |
---|
| 682 | else |
---|
| 683 | q += polevl( p, A, 4 ) / x; |
---|
| 684 | return( q ); |
---|
| 685 | } |
---|