NingSun | 0c89b3c | 2018-02-08 08:34:03 -0800 | [diff] [blame^] | 1 | /* This code was taken from http://www.fourmilab.ch/random/ where it states that: |
| 2 | |
| 3 | This software is in the public domain. Permission to use, copy, modify, and distribute |
| 4 | this software and its documentation for any purpose and without fee is hereby granted, |
| 5 | without any conditions or restrictions. This software is provided “as is” without |
| 6 | express or implied warranty. */ |
| 7 | |
| 8 | /* |
| 9 | |
| 10 | Compute probability of measured Chi Square value. |
| 11 | |
| 12 | This code was developed by Gary Perlman of the Wang |
| 13 | Institute (full citation below) and has been minimally |
| 14 | modified for use in this program. |
| 15 | |
| 16 | */ |
| 17 | |
| 18 | #include <math.h> |
| 19 | |
| 20 | /*HEADER |
| 21 | Module: z.c |
| 22 | Purpose: compute approximations to normal z distribution probabilities |
| 23 | Programmer: Gary Perlman |
| 24 | Organization: Wang Institute, Tyngsboro, MA 01879 |
| 25 | Copyright: none |
| 26 | Tabstops: 4 |
| 27 | */ |
| 28 | |
| 29 | #define Z_MAX 6.0 /* maximum meaningful z value */ |
| 30 | |
| 31 | /*FUNCTION poz: probability of normal z value */ |
| 32 | /*ALGORITHM |
| 33 | Adapted from a polynomial approximation in: |
| 34 | Ibbetson D, Algorithm 209 |
| 35 | Collected Algorithms of the CACM 1963 p. 616 |
| 36 | Note: |
| 37 | This routine has six digit accuracy, so it is only useful for absolute |
| 38 | z values < 6. For z values >= to 6.0, poz() returns 0.0. |
| 39 | */ |
| 40 | static double /*VAR returns cumulative probability from -oo to z */ |
| 41 | poz(const double z) /*VAR normal z value */ |
| 42 | { |
| 43 | double y, x, w; |
| 44 | |
| 45 | if (z == 0.0) { |
| 46 | x = 0.0; |
| 47 | } else { |
| 48 | y = 0.5 * fabs(z); |
| 49 | if (y >= (Z_MAX * 0.5)) { |
| 50 | x = 1.0; |
| 51 | } else if (y < 1.0) { |
| 52 | w = y * y; |
| 53 | x = ((((((((0.000124818987 * w |
| 54 | -0.001075204047) * w +0.005198775019) * w |
| 55 | -0.019198292004) * w +0.059054035642) * w |
| 56 | -0.151968751364) * w +0.319152932694) * w |
| 57 | -0.531923007300) * w +0.797884560593) * y * 2.0; |
| 58 | } else { |
| 59 | y -= 2.0; |
| 60 | x = (((((((((((((-0.000045255659 * y |
| 61 | +0.000152529290) * y -0.000019538132) * y |
| 62 | -0.000676904986) * y +0.001390604284) * y |
| 63 | -0.000794620820) * y -0.002034254874) * y |
| 64 | +0.006549791214) * y -0.010557625006) * y |
| 65 | +0.011630447319) * y -0.009279453341) * y |
| 66 | +0.005353579108) * y -0.002141268741) * y |
| 67 | +0.000535310849) * y +0.999936657524; |
| 68 | } |
| 69 | } |
| 70 | return (z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5)); |
| 71 | } |
| 72 | |
| 73 | /* |
| 74 | Module: chisq.c |
| 75 | Purpose: compute approximations to chisquare distribution probabilities |
| 76 | Contents: pochisq() |
| 77 | Uses: poz() in z.c (Algorithm 209) |
| 78 | Programmer: Gary Perlman |
| 79 | Organization: Wang Institute, Tyngsboro, MA 01879 |
| 80 | Copyright: none |
| 81 | Tabstops: 4 |
| 82 | */ |
| 83 | |
| 84 | #define LOG_SQRT_PI 0.5723649429247000870717135 /* log (sqrt (pi)) */ |
| 85 | #define I_SQRT_PI 0.5641895835477562869480795 /* 1 / sqrt (pi) */ |
| 86 | #define BIGX 20.0 /* max value to represent exp (x) */ |
| 87 | #define ex(x) (((x) < -BIGX) ? 0.0 : exp(x)) |
| 88 | |
| 89 | /*FUNCTION pochisq: probability of chi sqaure value */ |
| 90 | /*ALGORITHM Compute probability of chi square value. |
| 91 | Adapted from: |
| 92 | Hill, I. D. and Pike, M. C. Algorithm 299 |
| 93 | Collected Algorithms for the CACM 1967 p. 243 |
| 94 | Updated for rounding errors based on remark in |
| 95 | ACM TOMS June 1985, page 185 |
| 96 | */ |
| 97 | |
| 98 | double pochisq( |
| 99 | const double ax, /* obtained chi-square value */ |
| 100 | const int df /* degrees of freedom */ |
| 101 | ) |
| 102 | { |
| 103 | double x = ax; |
| 104 | double a, y, s; |
| 105 | double e, c, z; |
| 106 | int even; /* true if df is an even number */ |
| 107 | |
| 108 | if (x <= 0.0 || df < 1) { |
| 109 | return 1.0; |
| 110 | } |
| 111 | |
| 112 | a = 0.5 * x; |
| 113 | even = (2 * (df / 2)) == df; |
| 114 | y = 0.0; |
| 115 | if (df > 1) { |
| 116 | y = ex(-a); |
| 117 | } |
| 118 | s = (even ? y : (2.0 * poz(-sqrt(x)))); |
| 119 | if (df > 2) { |
| 120 | x = 0.5 * (df - 1.0); |
| 121 | z = (even ? 1.0 : 0.5); |
| 122 | if (a > BIGX) { |
| 123 | e = (even ? 0.0 : LOG_SQRT_PI); |
| 124 | c = log(a); |
| 125 | while (z <= x) { |
| 126 | e = log(z) + e; |
| 127 | s += ex(c * z - a - e); |
| 128 | z += 1.0; |
| 129 | } |
| 130 | return (s); |
| 131 | } else { |
| 132 | e = (even ? 1.0 : (I_SQRT_PI / sqrt(a))); |
| 133 | c = 0.0; |
| 134 | while (z <= x) { |
| 135 | e = e * (a / z); |
| 136 | c = c + e; |
| 137 | z += 1.0; |
| 138 | } |
| 139 | return (c * y + s); |
| 140 | } |
| 141 | } else { |
| 142 | return s; |
| 143 | } |
| 144 | } |