SDDSlib
Loading...
Searching...
No Matches
kstests.c
Go to the documentation of this file.
1/**
2 * @file kstests.c
3 * @brief Perform the Kolmogorov-Smirnov test for two sets of samples.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author M. Borland, C. Saunders, R. Soliday
14 */
15
16#include "mdb.h"
17#include "sort.h"
18
19double twoVariableKStest(double *d1, long n1, double *d2, long n2, double *maxCDFerror) {
20 long i1, i2;
21 double CDFerror, xDifference, CDF1, CDF2, sqrtNe;
22
23 qsort((void *)d1, n1, sizeof(*d1), double_cmpasc);
24 qsort((void *)d2, n2, sizeof(*d2), double_cmpasc);
25 i1 = i2 = 0;
26 CDF1 = CDF2 = 0;
27 *maxCDFerror = 0;
28 while (i1 < n1 && i2 < n2) {
29 /* move through the arrays together, keeping value from both arrays as close as possible.
30 xDifference is the distance between the points at which the CDFs are evaluated.
31 */
32 if ((xDifference = d1[i1] - d2[i2]) <= 0)
33 /* d2 is evaluated ahead of d1, so advance d1 */
34 CDF1 = ++i1 / ((double)n1);
35 if (xDifference >= 0)
36 /* d1 is evaluated ahead of d2 */
37 CDF2 = ++i2 / ((double)n2);
38 if ((CDFerror = fabs(CDF1 - CDF2)) > *maxCDFerror)
39 *maxCDFerror = CDFerror;
40 }
41 sqrtNe = sqrt(((double)n1 * n2) / ((double)n1 + n2));
42 return KS_Qfunction((sqrtNe + 0.12 + 0.11 / sqrtNe) * (*maxCDFerror));
43}
44
45#define KS_Q_ACCURACY 1e-8
46#define KS_Q_MAXTERMS 1000
47
48/**
49 * @brief Compute the Q-function for the Kolmogorov-Smirnov test.
50 *
51 * Given a lambda value, this function approximates the complementary
52 * cumulative distribution function needed to determine the KS probability (Q-value).
53 *
54 * @param lambda The computed KS statistic scaled by sqrt(N).
55 * @return The KS Q-value as a probability measure.
56 */
57double KS_Qfunction(double lambda) {
58 long j;
59 double expFactor, factor;
60 double sum, term;
61
62 expFactor = -2 * lambda * lambda;
63 factor = 1;
64 j = 1;
65 sum = 0;
66 do {
67 term = exp(expFactor * j * j);
68 sum += factor * term;
69 factor *= -1;
70 } while (term > KS_Q_ACCURACY && j++ < KS_Q_MAXTERMS);
71 if (j > KS_Q_MAXTERMS)
72 fputs("warning: KS test did not converge\n", stderr);
73 return 2 * sum;
74}
double KS_Qfunction(double lambda)
Compute the Q-function for the Kolmogorov-Smirnov test.
Definition kstests.c:57
int double_cmpasc(const void *a, const void *b)
Compare two doubles in ascending order.