home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
math
/
ols
/
f.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-28
|
3KB
|
143 lines
#include <stdio.h>
#include <math.h>
#include "distribs.h"
/* The F distribution. */
#ifdef TESTING
int
main ()
{
double x, p, invp;
int df1, df2;
for (df1 = 1; df1 < 10; df1 += 4)
for (df2 = 1; df2 < 10; df2 += 4)
{
printf ("\nF(%d, %d)\n", df1, df2);
for (x = 0.5; x < 5.0; x += 2.0)
{
p = pF (x, df1, df2);
invp = critF (p, df1, df2);
printf ("x = %2.1f, Prob(>F) = %10.8f, InvF = %10.8f\n",
x, p, invp);
}
}
return 0;
}
#endif
/* Rest of this file essentially cleaned up version of Gary
Perlman's source on StatLib. */
#define I_PI 0.3183098861837906715377675 /* 1/pi */
#define F_EPSILON 1.0e-9 /* accuracy of critF approximation */
#define F_MAX 9999.0 /* maximum F ratio */
/*FUNCTION pF: probability of F.
ALGORITHM Compute probability of F ratio.
Adapted from Collected Algorithms of the CACM
Algorithm 322
Egon Dorrer
*/
double
pF (double F, int df1, int df2)
{
int i, j;
int a, b;
double w, y, z, d, p;
if (F < F_EPSILON || df1 < 1 || df2 < 1)
return (1.0);
a = df1 % 2 ? 1 : 2;
b = df2 % 2 ? 1 : 2;
w = (F * df1) / df2;
z = 1.0 / (1.0 + w);
if (a == 1)
if (b == 1)
{
p = sqrt (w);
y = I_PI;
d = y * z / p;
p = 2.0 * y * atan (p);
}
else
{
p = sqrt (w * z);
d = 0.5 * p * z / w;
}
else if (b == 1)
{
p = sqrt (z);
d = 0.5 * z * p;
p = 1.0 - p;
}
else
{
d = z * z;
p = w * z;
}
y = 2.0 * w / z;
for (j = b + 2; j <= df2; j += 2)
{
d *= (1.0 + a / (j - 2.0)) * z;
p = (a == 1 ? p + d * y / (j - 1.0) : (p + w) * z);
}
y = w * z;
z = 2.0 / z;
b = df2 - 2;
for (i = a + 2; i <= df1; i += 2)
{
j = i + b;
d *= y * j / (i - 2.0);
p -= z * d / j;
}
/* correction for approximation errors suggested in certification */
if (p < 0.0)
p = 0.0;
else if (p > 1.0)
p = 1.0;
return (1.0 - p);
}
/* critF: compute critical F value t produce given probability.
ALGORITHM
Begin with upper and lower limits for F values (maxf and minf)
set to extremes. Choose an f value (fval) between the extremes.
Compute the probability of the f value. Set minf or maxf, based
on whether the probability is less than or greater than the
desired p. Continue adjusting the extremes until they are
within F_EPSILON of each other.
*/
double
critF (double p, int df1, int df2)
{
double fval;
double maxf = F_MAX; /* maximum F ratio */
double minf = 0.0; /* minimum F ratio */
if (p <= 0.0 || p >= 1.0)
return (0.0);
fval = 1.0 / p; /* the smaller the p, the larger the F */
while (fabs (maxf - minf) > F_EPSILON)
{
if (pF (fval, df1, df2) < p) /* F too large */
maxf = fval;
else /* F too small */
minf = fval;
fval = (maxf + minf) * 0.5;
}
return (fval);
}