Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Cephes/   (Cephes Mathematical Library ©)  Datei vom 9.5.2026 mit Größe 4 kB image not shown  

Quelle  kolmogorov.c

  Sprache: C
 


/* Re Kolmogorov statistics, here is Birnbaum and Tingey's formula for the
   distribution of D+, the maximum of all positive deviations between a
   theoretical distribution function P(x) and an empirical one Sn(x)
   from n samples.

     +
    D  =         sup     [P(x) - S (x)]
     n     -inf < x < inf         n


                  [n(1-e)]
        +            -                    v-1              n-v
    Pr{D   > e} =    >    C    e (e + v/n)    (1 - e - v/n)
        n            -   n v
                    v=0

    [n(1-e)] is the largest integer not exceeding n(1-e).
    nCv is the number of combinations of n things taken v at a time.  */


#include "mconf.h"
#ifdef ANSIPROT
extern double pow(doubledouble);
extern double floor(double);
extern double lgam(double);
extern double exp(double);
extern double sqrt(double);
extern double log(double);
extern double fabs(double);
double smirnov(intdouble);
double kolmogorov(double);
#else
double pow(), floor(), lgam(), exp(), sqrt(), log(), fabs();
double smirnov(), kolmogorov();
#endif
extern double MAXLOG;

/* Exact Smirnov statistic, for one-sided test.  */
double smirnov(n, e) int n;
double e;
{
  int v, nn;
  double evn, omevn, p, t, c, lgamnp1;

  if (n <= 0 || e < 0.0 || e > 1.0)
    return (-1.0);
  nn = floor((double)n * (1.0 - e));
  p = 0.0;
  if (n < 1013) {
    c = 1.0;
    for (v = 0; v <= nn; v++) {
      evn = e + ((double)v) / n;
      p += c * pow(evn, (double)(v - 1)) * pow(1.0 - evn, (double)(n - v));
      /* Next combinatorial term; worst case error = 4e-15.  */
      c *= ((double)(n - v)) / (v + 1);
    }
  } else {
    lgamnp1 = lgam((double)(n + 1));
    for (v = 0; v <= nn; v++) {
      evn = e + ((double)v) / n;
      omevn = 1.0 - evn;
      if (fabs(omevn) > 0.0) {
        t = lgamnp1 - lgam((double)(v + 1)) - lgam((double)(n - v + 1)) +
            (v - 1) * log(evn) + (n - v) * log(omevn);
        if (t > -MAXLOG)
          p += exp(t);
      }
    }
  }
  return (p * e);
}

/* Kolmogorov's limiting distribution of two-sided test, returns
   probability that sqrt(n) * max deviation > y,
   or that max deviation > y/sqrt(n).
   The approximation is useful for the tail of the distribution
   when n is large.  */

double kolmogorov(y) double y;
{
  double p, t, r, sign, x;

  x = -2.0 * y * y;
  sign = 1.0;
  p = 0.0;
  r = 1.0;
  do {
    t = exp(x * r * r);
    p += sign * t;
    if (t == 0.0)
      break;
    r += 1.0;
    sign = -sign;
  } while ((t / p) > 1.1e-16);
  return (p + p);
}

/* Functional inverse of Smirnov distribution
   finds e such that smirnov(n,e) = p.  */

double smirnovi(n, p) int n;
double p;
{
  double e, t, dpde;

  if (p <= 0.0 || p > 1.0) {
    mtherr("smirnovi", DOMAIN);
    return 0.0;
  }
  /* Start with approximation p = exp(-2 n e^2).  */
  e = sqrt(-log(p) / (2.0 * n));
  do {
    /* Use approximate derivative in Newton iteration. */
    t = -2.0 * n * e;
    dpde = 2.0 * t * exp(t * e);
    if (fabs(dpde) > 0.0)
      t = (p - smirnov(n, e)) / dpde;
    else {
      mtherr("smirnovi", UNDERFLOW);
      return 0.0;
    }
    e = e + t;
    if (e >= 1.0 || e <= 0.0) {
      mtherr("smirnovi", OVERFLOW);
      return 0.0;
    }
  } while (fabs(t / e) > 1e-10);
  return (e);
}

/* Functional inverse of Kolmogorov statistic for two-sided test.
   Finds y such that kolmogorov(y) = p.
   If e = smirnovi (n,p), then kolmogi(2 * p) / sqrt(n) should
   be close to e.  */

double kolmogi(p) double p;
{
  double y, t, dpdy;

  if (p <= 0.0 || p > 1.0) {
    mtherr("kolmogi", DOMAIN);
    return 0.0;
  }
  /* Start with approximation p = 2 exp(-2 y^2).  */
  y = sqrt(-0.5 * log(0.5 * p));
  do {
    /* Use approximate derivative in Newton iteration. */
    t = -2.0 * y;
    dpdy = 4.0 * t * exp(t * y);
    if (fabs(dpdy) > 0.0)
      t = (p - kolmogorov(y)) / dpdy;
    else {
      mtherr("kolmogi", UNDERFLOW);
      return 0.0;
    }
    y = y + t;
  } while (fabs(t / y) > 1e-10);
  return (y);
}

#ifdef SALONE
/* Type in a number.  */
void getnum(s, px) char *s;
double *px;
{
  char str[30];

  printf(" %s (%.15e) ? ", s, *px);
  gets(str);
  if (str[0] == '\0' || str[0] == '\n')
    return;
  sscanf(str, "%lf", px);
  printf("%.15e\n", *px);
}

/* Type in values, get answers.  */
void main() {
  int n;
  double e, p, ps, pk, ek, y;

  n = 5;
  e = 0.0;
  p = 0.1;
loop:
  ps = n;
  getnum("n", &ps);
  n = ps;
  if (n <= 0) {
    printf("? Operator error.\n");
    goto loop;
  }
  /*
  getnum ("e", &e);
  ps = smirnov (n, e);
  y = sqrt ((double) n) * e;
  printf ("y = %.4e\n", y);
  pk = kolmogorov (y);
  printf ("Smirnov = %.15e, Kolmogorov/2 = %.15e\n", ps, pk / 2.0);
*/

  getnum("p", &p);
  e = smirnovi(n, p);
  printf("Smirnov e = %.15e\n", e);
  y = kolmogi(2.0 * p);
  ek = y / sqrt((double)n);
  printf("Kolmogorov e = %.15e\n", ek);
  goto loop;
}
#endif

Messung V0.5 in Prozent
C=97 H=81 G=89

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.