home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
statlib.zip
/
STATIST.C
< prev
Wrap
C/C++ Source or Header
|
1998-02-12
|
4KB
|
147 lines
/***********************************************************
Statistische Verteilungsfunktionen als Bibliotheksroutinen
Neubearbeitung meines Omikron-Basic-Merge-Files SIGNIF.BAS
optimiert für C und Coprozessor
(c) 1998 by Heinz Repp
zuletzt bearbeitet am 12.02.98
***********************************************************/
#include <math.h>
#if ! defined PI
#define PI 3.14159265358979323846
#endif
#if (defined CHIQUADRAT || defined STANDARDNORMAL) && ! defined EPSILON
#define EPSILON 5E-9
#endif
#if defined FTEST || defined TSTUDENT
static double sum_sub (register double f, double a,
register double b, double d)
{ register double s;
if (b < a) return 0.0;
s = 1.0;
for (b -= 2.0; b >= a; b -= 2.0)
{ s *= (b + d) / b * f;
s += 1.0;
} /* endfor */
return s;
} /* sum_sub */
#endif
#if defined FTEST
static double pow_i (register double f, register unsigned int i)
{ register double p;
p = f; /* i >= 1 required */
while (--i) p *= f;
return p;
} /* pow_i */
double distribution_of_F (double f, unsigned int f1, unsigned int f2)
{ double i, p;
if (! (f1 && f2))
return -1;
f *= (double) f1 / (double) f2;
if (f1 & f2 & 1) /* f1 and f2 odd */
{ p = - sum_sub (f / (f + 1.0), 3.0, (double) f1, (double) f2 - 2.0);
for (i = (double) f2 - 2.0; i >= 1.0; i -= 2.0)
p *= (i + 1.0) / i;
p *= sqrt (f) / pow_i (f + 1.0, (f2 + 1) >> 1);
p += sum_sub (1.0 / (f + 1.0), 3.0, (double) f2, -1.0)
* sqrt (f) / (f + 1.0);
p += atan (sqrt (f));
p = (p + p) / PI;
} else
{ if (f1 & 1 || ! (f2 & 1) && f1 > f2)
p = sum_sub (1.0 / (f + 1.0), 2.0, (double) f2, (double) f1 - 2.0)
* pow_i (sqrt (f / (f + 1.0)), f1);
else
p = 1.0 - sum_sub (f / (f + 1.0), 2.0, (double) f1, (double) f2 - 2.0)
/ pow_i (sqrt (f + 1.0), f2);
} /* endif */
return p;
} /* distribution_of_F */
#endif
#if defined TSTUDENT
double distribution_of_t (double t, unsigned int f)
{ double p;
if (! f)
return -1;
t /= sqrt ((double) f);
if (f & 1) /* df odd */
p = (sum_sub (1.0 / (t * t + 1.0), 3.0, (double) f, -1.0)
* t / (t * t + 1.0) + atan (t)) / PI;
else /* df even */
p = sum_sub (1.0 / (t * t + 1.0), 2.0, (double) f, -1.0)
* t / sqrt (t * t + 1.0) / 2.0;
return 0.5 + p;
} /* distribution_of_t */
#endif
#if defined CHIQUADRAT
double distribution_of_Chi2 (double x, unsigned int f)
{ double i, j, p, g;
if (! f)
return -1;
if (x <= 0.0)
return 0;
x /= 2.0;
if (f & 1) /* df odd */
{ p = exp (- x) / sqrt (PI * x);
if (p == 0.0) return 1.0; /* underflow */
j = (double) f / 2;
for (i = 0.5; i <= j; i += 1.0) /* 1/2 to f/2 */
p *= x / i;
for (j = p; i <= x; i += 1.0) /* f/2 to x/2 */
{ j *= x / i;
p += j;
} /* endfor2 */
g = EPSILON / x;
for ( ; j > (i - x) * g; i += 1.0) /* x/2 to accuracy limit */
{ j *= x / i;
p += j;
} /* endfor3 */
return p;
} else /* df even */
{ p = 1.0;
for (f >>= 1; --f; )
p = p * x / (double) f + 1.0;
return 1.0 - p * exp (- x);
} /* endif */
} /* distribution_of_Chi2 */
#endif
#if defined STANDARDNORMAL
double distribution_of_Z (double z)
{ double g, i, j, p;
if (z == 0) return 0.5;
p = z;
g = z < 0 ? - EPSILON : EPSILON;
z = z * z / 2.0;
p *= exp (- z) / sqrt ((PI + PI));
if (p == 0.0) return g < 0 ? 0.0 : 1.0; /* underflow */
for (i = p, j = 1.5; j <= z; j += 1)
{ i *= z / j;
p += i;
} /* endfor1 */
g /= z;
for ( ; i / g > j - z; j += 1)
{ i *= z / j;
p += i;
} /* endfor2 */
return 0.5 + p;
} /* distribution_of_Z */
#endif