2 /* Re Kolmogorov statistics, here is Birnbaum and Tingey's formula for the
3 distribution of D+, the maximum of all positive deviations between a
4 theoretical distribution function P(x) and an empirical one Sn(x)
14 Pr{D > e} = > C e (e + v/n) (1 - e - v/n)
18 [n(1-e)] is the largest integer not exceeding n(1-e).
19 nCv is the number of combinations of n things taken v at a time. */
24 extern double pow ( double, double );
25 extern double floor ( double );
26 extern double lgam ( double );
27 extern double exp ( double );
28 extern double sqrt ( double );
29 extern double log ( double );
30 extern double fabs ( double );
31 double smirnov ( int, double );
32 double kolmogorov ( double );
34 double pow (), floor (), lgam (), exp (), sqrt (), log (), fabs ();
35 double smirnov (), kolmogorov ();
39 /* Exact Smirnov statistic, for one-sided test. */
46 double evn, omevn, p, t, c, lgamnp1;
48 if (n <= 0 || e < 0.0 || e > 1.0)
50 nn = floor ((double) n * (1.0 - e));
55 for (v = 0; v <= nn; v++)
57 evn = e + ((double) v) / n;
58 p += c * pow (evn, (double) (v - 1))
59 * pow (1.0 - evn, (double) (n - v));
60 /* Next combinatorial term; worst case error = 4e-15. */
61 c *= ((double) (n - v)) / (v + 1);
66 lgamnp1 = lgam ((double) (n + 1));
67 for (v = 0; v <= nn; v++)
69 evn = e + ((double) v) / n;
71 if (fabs (omevn) > 0.0)
74 - lgam ((double) (v + 1))
75 - lgam ((double) (n - v + 1))
77 + (n - v) * log (omevn);
87 /* Kolmogorov's limiting distribution of two-sided test, returns
88 probability that sqrt(n) * max deviation > y,
89 or that max deviation > y/sqrt(n).
90 The approximation is useful for the tail of the distribution
96 double p, t, r, sign, x;
111 while ((t / p) > 1.1e-16);
115 /* Functional inverse of Smirnov distribution
116 finds e such that smirnov(n,e) = p. */
124 if (p <= 0.0 || p > 1.0)
126 mtherr ("smirnovi", DOMAIN);
129 /* Start with approximation p = exp(-2 n e^2). */
130 e = sqrt (-log (p) / (2.0 * n));
133 /* Use approximate derivative in Newton iteration. */
135 dpde = 2.0 * t * exp (t * e);
136 if (fabs (dpde) > 0.0)
137 t = (p - smirnov (n, e)) / dpde;
140 mtherr ("smirnovi", UNDERFLOW);
144 if (e >= 1.0 || e <= 0.0)
146 mtherr ("smirnovi", OVERFLOW);
150 while (fabs (t / e) > 1e-10);
155 /* Functional inverse of Kolmogorov statistic for two-sided test.
156 Finds y such that kolmogorov(y) = p.
157 If e = smirnovi (n,p), then kolmogi(2 * p) / sqrt(n) should
165 if (p <= 0.0 || p > 1.0)
167 mtherr ("kolmogi", DOMAIN);
170 /* Start with approximation p = 2 exp(-2 y^2). */
171 y = sqrt (-0.5 * log (0.5 * p));
174 /* Use approximate derivative in Newton iteration. */
176 dpdy = 4.0 * t * exp (t * y);
177 if (fabs (dpdy) > 0.0)
178 t = (p - kolmogorov (y)) / dpdy;
181 mtherr ("kolmogi", UNDERFLOW);
186 while (fabs (t / y) > 1e-10);
192 /* Type in a number. */
200 printf (" %s (%.15e) ? ", s, *px);
202 if (str[0] == '\0' || str[0] == '\n')
204 sscanf (str, "%lf", px);
205 printf ("%.15e\n", *px);
208 /* Type in values, get answers. */
213 double e, p, ps, pk, ek, y;
224 printf ("? Operator error.\n");
230 y = sqrt ((double) n) * e;
231 printf ("y = %.4e\n", y);
233 printf ("Smirnov = %.15e, Kolmogorov/2 = %.15e\n", ps, pk / 2.0);
237 printf ("Smirnov e = %.15e\n", e);
238 y = kolmogi (2.0 * p);
239 ek = y / sqrt ((double) n);
240 printf ("Kolmogorov e = %.15e\n", ek);