removed QWQNG, added stdin
This commit is contained in:
commit
0fe369bc5a
39 changed files with 3095 additions and 0 deletions
249
RandTest/KolmogorovSmirnov.cpp
Executable file
249
RandTest/KolmogorovSmirnov.cpp
Executable file
|
|
@ -0,0 +1,249 @@
|
|||
//#include "StdAfx.h"
|
||||
#include "KolmogorovSmirnov.h"
|
||||
#include "memory.h"
|
||||
#include "stdlib.h"
|
||||
#include "math.h"
|
||||
#include <float.h>
|
||||
|
||||
CKolmogorovSmirnov::CKolmogorovSmirnov()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// double CKolmogorovSmirnov::ZtoP
|
||||
//
|
||||
// Returns: cumulative normal distribution value based on input z-score
|
||||
// Accuracy better than 1% for zscore<=±7.5; better than 0.05% for zscore=±4
|
||||
double CKolmogorovSmirnov::ZtoP( double zscore )
|
||||
{
|
||||
double retval;
|
||||
|
||||
// calculation variables
|
||||
double w;
|
||||
double y;
|
||||
double t;
|
||||
double num;
|
||||
double denom;
|
||||
|
||||
// calculation constants
|
||||
double c[8];
|
||||
c[1] = 2.506628275; c[2] = 0.31938153; c[3] = -0.356563782; c[4] = 1.781477937;
|
||||
c[5] = -1.821255978; c[6] = 1.330274429; c[7] = 0.2316419;
|
||||
|
||||
w = (zscore>=0)? 1 : -1;
|
||||
y = 1./( 1. + (c[7]*w*zscore) );
|
||||
t = 1. + (c[7]*w*zscore);
|
||||
|
||||
num = w * ( 0.5 - c[2] + ((c[6] + (c[5]*t) + (c[4]*t*t) + (c[3]*t*t*t))/(t*t*t*t)) );
|
||||
denom = c[1] * pow( 10, pow(0.5*zscore, 2) );
|
||||
|
||||
retval = 0.5 + (num/denom);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// double CKolmogorovSmirnov::PtoZ
|
||||
//
|
||||
// Returns: z-score based on input cumulative normal distribution value
|
||||
// Accuracy better than 0.1% for zscore<=±7.5; 6 digits for zscore=±6
|
||||
double CKolmogorovSmirnov::PtoZ( double p )
|
||||
{
|
||||
double retval = -8.2;
|
||||
if (p <= DBL_EPSILON)
|
||||
return retval;
|
||||
|
||||
// calculation variables
|
||||
double pp;
|
||||
double y;
|
||||
double num;
|
||||
double denom;
|
||||
|
||||
// calculation constants
|
||||
double P[5];
|
||||
P[0] = -0.322232431088; P[1] = -1.0; P[2] = -0.342242088547;
|
||||
P[3] = -0.0204231210245; P[4] = -0.453642210148e-4;
|
||||
double q[5];
|
||||
q[0] = 0.099348462606; q[1] = 0.588581570495; q[2] = 0.531103462366;
|
||||
q[3] = 0.10353775285; q[4] = 0.38560700634e-2;
|
||||
|
||||
pp = (p<0.5)? p : (1.-p);
|
||||
y = sqrt( log(1./(pp*pp)) );
|
||||
num = y*(y*(y*(y*P[4]+P[3]) + P[2]) + P[1]) + P[0];
|
||||
denom = y*(y*(y*(y*q[4]+q[3]) + q[2]) + q[1]) + q[0];
|
||||
|
||||
retval = y + (num/denom);
|
||||
retval = (p<0.5)? -retval : retval;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void CKolmogorovSmirnov::KSUP( double* pKn_pos, double* pKn_neg, double* U, unsigned long n )
|
||||
{
|
||||
unsigned long i; // universal index
|
||||
double val; // calc value
|
||||
double* Us = new double[n];
|
||||
double Kn_pos;
|
||||
double Kn_neg;
|
||||
double* cump1 = new double[n+2];
|
||||
double* cump2 = new double[n+2];
|
||||
double* kn = new double[n+2];
|
||||
double max;
|
||||
double min;
|
||||
|
||||
memcpy( (void*)Us, (void*)U, n * sizeof(double) );
|
||||
qsort( Us, n, sizeof(double), KSUPcompare );
|
||||
|
||||
cump1[1] = Us[0];
|
||||
cump2[1] = 0.;
|
||||
for ( i=1; i<=n; i++ )
|
||||
{
|
||||
cump1[i+1] = Us[i-1];
|
||||
val = (double)i/n;
|
||||
cump2[i+1] = val;
|
||||
}
|
||||
|
||||
min = cump2[2] - cump1[2];
|
||||
max = min;
|
||||
for ( i=2; i<=(n+1); i++ )
|
||||
{
|
||||
kn[i-1] = cump2[i] - cump1[i];
|
||||
if ( kn[i-1] > max )
|
||||
{
|
||||
max = kn[i-1];
|
||||
}
|
||||
if ( kn[i-1] < min )
|
||||
{
|
||||
min = kn[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
Kn_pos = sqrt((double)n) * (double)max;
|
||||
Kn_neg = (-sqrt((double)n)) * ((double)min - (1/(double)n));
|
||||
|
||||
*pKn_pos = KSProb( n, Kn_pos );
|
||||
*pKn_neg = KSProb( n, Kn_neg );
|
||||
|
||||
if (Us!=NULL)
|
||||
{
|
||||
delete Us;
|
||||
Us = NULL;
|
||||
}
|
||||
|
||||
if (kn!=NULL)
|
||||
{
|
||||
delete kn;
|
||||
kn = NULL;
|
||||
}
|
||||
|
||||
if (cump1!=NULL)
|
||||
{
|
||||
delete cump1;
|
||||
cump1 = NULL;
|
||||
}
|
||||
|
||||
if (cump2!=NULL)
|
||||
{
|
||||
delete cump2;
|
||||
cump2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double CKolmogorovSmirnov::KSProb( unsigned long n, double Kn )
|
||||
{
|
||||
double retval;
|
||||
double e;
|
||||
double las;
|
||||
unsigned long j;
|
||||
double cof[7];
|
||||
|
||||
cof[1] = 76.18009172947146; cof[2] = -86.50532032941677; cof[3] = 24.01409824083091;
|
||||
cof[4] = -1.231739572450155; cof[5] = 1.208650973866179e-3; cof[6] = -5.395239384953e-6;
|
||||
|
||||
if ( Kn<=0 )
|
||||
{
|
||||
retval = 0;
|
||||
}
|
||||
else if ( Kn>=sqrt((double)n) )
|
||||
{
|
||||
retval = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = Kn / sqrt((double)n);
|
||||
las = floor( (double)n - ((double)n*e) );
|
||||
|
||||
retval = 0;
|
||||
for ( j=0; j<=las; j++ )
|
||||
{
|
||||
double ee = exp(lnbin(n, j));
|
||||
double p1 = pow((e+(double)j/(double)n),((double)j-1.));
|
||||
double p2 = pow((1.0-e-(double)j/(double)n),(double)(n-j));
|
||||
retval += ee * p1 * p2;
|
||||
}
|
||||
|
||||
retval = 1.-e*retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
double CKolmogorovSmirnov::lnbin( double n, double k )
|
||||
{
|
||||
double retval = 0;
|
||||
if (k==0)
|
||||
retval = 0;
|
||||
else
|
||||
{
|
||||
retval = lnf(n) - lnf(k) - lnf(n-k);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
double CKolmogorovSmirnov::lnf( double xx )
|
||||
{
|
||||
double retval = 0;
|
||||
double x1 = xx + 1.;
|
||||
|
||||
double cof[7];
|
||||
|
||||
cof[1] = 76.18009172947146; cof[2] = -86.50532032941677; cof[3] = 24.01409824083091;
|
||||
cof[4] = -1.231739572450155; cof[5] = 1.208650973866179e-3; cof[6] = -5.395239384953e-6;
|
||||
|
||||
if (x1<=1.)
|
||||
retval = 0;
|
||||
else
|
||||
{
|
||||
double x = x1;
|
||||
double y = x1;
|
||||
|
||||
double tmp = x + 5.5 - (x+.5)*log(x+5.5);
|
||||
double ser = 1.000000000190015;
|
||||
|
||||
for (int j=0; j<=5; j++)
|
||||
{
|
||||
y = y+1.;
|
||||
ser += cof[j+1]/y;
|
||||
}
|
||||
|
||||
retval = log(2.506628274631 * ser/x) - tmp;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int CKolmogorovSmirnov::KSUPcompare( const void* elem1, const void* elem2 )
|
||||
{
|
||||
if ((*(double*)elem1)==(*(double*)elem2))
|
||||
return 0;
|
||||
if ((*(double*)elem1)>(*(double*)elem2))
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue