Exemplo n.º 1
0
double num2_Combination (int n, int s)
{
   double Res;
   int i;
   int Diff;
   if (s == 0 || s == n)
      return 1.0;
   if (s < 0) {
      util_Warning (1, "num2_Combination:   s < 0");
      return 0.0;
   }
   if (s > n) {
      util_Warning (1, "num2_Combination:   s > n");
      return 0.0;
   }
   if (s > (n / 2))
      s = n - s;
   if (n <= NLIM) {
      Res = 1.0;
      Diff = n - s;
      for (i = 1; i <= s; i++) {
         Res = (Res * (double) (Diff + i)) / (double) (i);
      }
      return Res;
   } else {
      Res = (num2_LnFactorial (n) - num2_LnFactorial (s))
         - num2_LnFactorial (n - s);
      return exp (Res);
   }
}
Exemplo n.º 2
0
void svaria_CollisionArgMax (unif01_Gen * gen, sres_Chi2 * res,
   long N, long n, int r, long k, long m)
{
   if (m > 1) {
      svaria_CollisionArgMax_00 (gen, res, N, n, r, k, m);

   } else if (m == 1) {
      double ValDelta[] = { -1.0 };
      smultin_Param *par;

      if (swrite_Basic) {
         printf (
          "***********************************************************\n"
          "Test svaria_CollisionArgMax calling smultin_Multinomial\n\n");
      }
      par = smultin_CreateParam (1, ValDelta, smultin_GenerCellMax, -3);
      if (NULL == res) {
         smultin_Multinomial (gen, par, NULL, N, n, r, 0, k, TRUE);
      } else {
         smultin_Res *resm;
         resm = smultin_CreateRes (par);
         smultin_Multinomial (gen, par, resm, N, n, r, 0, k, TRUE);
         sres_InitChi2 (res, N, -1, "svaria_CollisionArgMax");
         statcoll_SetDesc (res->sVal1, "CollisionArgMax sVal1");
         res->sVal1->NObs = resm->Collector[0]->NObs;
         tables_CopyTabD (resm->Collector[0]->V, res->sVal1->V, 1, N);
         tables_CopyTabD (resm->sVal2[0], res->sVal2, 0, gofw_NTestTypes - 1);
         tables_CopyTabD (resm->pVal2[0], res->pVal2, 0, gofw_NTestTypes - 1);
         smultin_DeleteRes (resm);
      }
      smultin_DeleteParam (par);
   } else {
     util_Warning (m <= 0, "svaria_CollisionArgMax:   m <= 0");
   }
}
Exemplo n.º 3
0
double num2_Factorial (int n)
{
   util_Assert (n >= 0, "num2_Factorial:   n < 0");
   if (n <= 170)
      return Factorials[n];
   util_Warning (1, "num2_Factorial:   n > 170:   return inf");
   return 1.0 / 0.0;
}
Exemplo n.º 4
0
void ftab_SetDesc (ftab_Table *T, char *Desc)
{
   size_t len;
   util_Assert (T != NULL, "ftab_SetDesc:  ftab_Table is a NULL pointer");
   len = strlen (Desc);
   if (len > MAXLEN) {
      len = MAXLEN;
      util_Warning (1, "ftab_Table->Desc truncated");
   }
   if (T->Desc != NULL)
      T->Desc = util_Free (T->Desc);
   T->Desc = util_Calloc (len + 1, sizeof (char));
   strncpy (T->Desc, Desc, (size_t) len);
   T->Desc[len] = '\0';
}
Exemplo n.º 5
0
double num2_EvalCheby (const double A[], int N, double x)
{
   int j;
   double xx;
   double b0, b1, b2;
   util_Warning (fabs (x) > 1.0,
      "Chebychev polynomial evaluated at x outside [-1, 1]");
   xx = 2.0 * x;
   b0 = 0.0;
   b1 = 0.0;
   for (j = N; j >= 0; j--) {
      b2 = b1;
      b1 = b0;
      b0 = (xx * b1 - b2) + A[j];
   }
   return (b0 - b2) / 2.0;
}
Exemplo n.º 6
0
void ffam_PrintFam (ffam_Fam *fam)
{
    int i;
    if (fam == NULL) {
        util_Warning (TRUE, "ffam_PrintFam:   fam is NULL");
        return;
    }
    printf ("-------------------------------------------------\n");
    printf ("Family:   %s\nNumber of generators:   %d\n\n",
            fam->name, fam->Ng);
    printf ("LSize Resol   Generator\n");
    printf ("-------------------------------------------------\n");
    for (i = 0; i < fam->Ng; i++) {
        printf ("%3d   %3d    %s\n", fam->LSize[i], fam->Resol[i],
                fam->Gen[i]->name);
    }
    printf ("\n\n");
}
Exemplo n.º 7
0
static void InitAppear (int r, int s, int L, long Q, double E[], double KV[])
{
   util_Assert (r >= 0, "svaria_AppearanceSpacings:   r < 0");
   util_Assert (s > 0, "svaria_AppearanceSpacings:   s <= 0");
   /*   if (L >= s && L % s) {
      util_Error ("svaria_AppearanceSpacings:   L mod s != 0");
      }*/
   if (L < s && s % L) {
      util_Error ("svaria_AppearanceSpacings:   s mod L != 0");
   }
   util_Warning (Q < 10.0 * num_TwoExp[L],
      "svaria_AppearanceSpacings:   Q < 10 * 2^L");

   /* Theoretical mean E and variance KV for different L given by Maurer */
   if (L > 16) {
      /* For L > 16 and near 16, the 6-th decimal of E[L] could be
         erroneous. For KV [L], the 4-th decimal. */
      E[L] = L - 8.32746E-1;
      KV[L] = 3.423715;
   } else {
      E [1]  = 0.73264948;      KV[1]  = 0.68977;
      E [2]  = 1.53743829;      KV[2]  = 1.33774;
      E [3]  = 2.40160681;      KV[3]  = 1.90133;
      E [4]  = 3.31122472;      KV[4]  = 2.35774;
      E [5]  = 4.25342659;      KV[5]  = 2.70455;
      E [6]  = 5.21770525;      KV[6]  = 2.95403;
      E [7]  = 6.19625065;      KV[7]  = 3.12539;
      E [8]  = 7.18366555;      KV[8]  = 3.23866;
      E [9]  = 8.17642476;      KV[9]  = 3.31120;
      E [10] = 9.17232431;      KV[10] = 3.35646;
      E [11] = 10.1700323;      KV[11] = 3.38409;
      E [12] = 11.1687649;      KV[12] = 3.40065;
      E [13] = 12.1680703;      KV[13] = 3.41043;
      E [14] = 13.1676926;      KV[14] = 3.41614;
      E [15] = 14.1674884;      KV[15] = 3.41943;
      E [16] = 15.1673788;      KV[16] = 3.42130;
   }
}
Exemplo n.º 8
0
void sknuth_Gap (unif01_Gen *gen, sres_Chi2 *res,
                 long N, long n, int r, double Alpha, double Beta)
{
   int len;
   int t;
   long m;                        /* Number of observed Gaps */
   long Seq;                      /* Current replication number */
   double p;                      /* Probability of U01 in (Alpha, Beta) */
   double X2;
   double U;
   double Mult;
   double V[1];                   /* Number of degrees of freedom for Chi2 */
   char str[LENGTH + 1];
   lebool localRes = FALSE;
   chrono_Chrono *Timer;
   char *TestName = "sknuth_Gap test";

   Timer = chrono_Create ();
   p = Beta - Alpha;
   t = (int)(log (gofs_MinExpected / n) / num2_log1p (-p));
   len = (int)(1 + log (gofs_MinExpected / (n*p)) / num2_log1p (-p));
   t = util_Min(t, len);
   t = util_Max(t, 0);

   Mult = p * n;
   if (swrite_Basic)
      WriteDataGap (gen, TestName, N, n, r, Alpha, Beta);

   util_Assert (Alpha >= 0.0 && Alpha <= 1.0,
                "sknuth_Gap:   Alpha outside interval [0..1]");
   util_Assert (Beta <= 1.0 && Beta > Alpha,
                "sknuth_Gap:   Beta outside interval (Alpha..1]");

   if (res == NULL) {
      localRes = TRUE;
      res = sres_CreateChi2 ();
   }
   sres_InitChi2 (res, N, t, "sknuth_Gap");

   sprintf (str, "The N statistic values (a ChiSquare with %1d degrees"
                 " of freedom):", t);
   statcoll_SetDesc (res->sVal1, str);
   res->degFree = t;
   if (res->degFree < 1) {
      util_Warning (TRUE, "Chi-square with 0 degree of freedom.");
      if (localRes)
         sres_DeleteChi2 (res);
      chrono_Delete (Timer);
      return;
   }

   /* Compute the probabilities for each gap length */
   res->NbExp[0] = Mult;
   res->Loc[0] = 0;
   for (len = 1; len < t; len++) {
      Mult *= 1.0 - p;
      res->NbExp[len] = Mult;
      res->Loc[len] = len;
   }
   res->NbExp[t] = Mult * (1.0 - p) / p;
   res->Loc[t] = t;
   if (swrite_Classes)
      gofs_WriteClasses (res->NbExp, res->Count, 0, t, 0);

   /* Beginning of test */
   for (Seq = 1; Seq <= N; Seq++) {
      for (len = 0; len <= t; len++)
         res->Count[len] = 0;
      for (m = 1; m <= n; m++) {
         /* Process one gap */
         len = 0;
         U = unif01_StripD (gen, r);
         while ((U < Alpha || U >= Beta) && len < n) {
            ++len;
            U = unif01_StripD (gen, r);
         }
         if (len >= n) {
            util_Warning (TRUE,
   "sknuth_Gap:   one gap of length > n\n*********  Interrupting the test\n");
            printf ("\n\n");
            res->pVal2[gofw_Mean] = res->pVal2[gofw_AD]
                   = res->pVal2[gofw_KSM] = res->pVal2[gofw_KSP] = 0.0;
            if (localRes)
               sres_DeleteChi2 (res);
            chrono_Delete (Timer);
            return;
         }
         if (len >= t)
            ++res->Count[t];
         else
            ++res->Count[len];
      }
      if (swrite_Counters)
         tables_WriteTabL (res->Count, 0, t, 5, 10, "Observed numbers:");

      X2 = gofs_Chi2 (res->NbExp, res->Count, 0, t);
      statcoll_AddObs (res->sVal1, X2);
   }

   V[0] = t;
   gofw_ActiveTests2 (res->sVal1->V, res->pVal1->V, N, wdist_ChiSquare, V,
                      res->sVal2, res->pVal2);
   sres_GetChi2SumStat (res);

   if (swrite_Collectors)
      statcoll_Write (res->sVal1, 5, 14, 4, 3);

   if (swrite_Basic) {
      swrite_AddStrChi (str, LENGTH, res->degFree);
      gofw_WriteActiveTests2 (N, res->sVal2, res->pVal2, str);
      swrite_Chi2SumTest (N, res);
      swrite_Final (gen, Timer);
   }
   if (localRes)
      sres_DeleteChi2 (res);
   chrono_Delete (Timer);
}
Exemplo n.º 9
0
void svaria_SumLogs (unif01_Gen * gen, sres_Chi2 * res,
   long N, long n, int r)
{
   const double Eps = DBL_EPSILON / 2.0;      /* To avoid log(0) */
   const double Epsilon = 1.E-100;            /* To avoid underflow */
   long i;
   long Seq;
   double u;
   double Prod;
   double Sum;
   double V[1];
   lebool localRes = FALSE;
   chrono_Chrono *Timer;
   char *TestName = "svaria_SumLogs test";
   char chaine[LEN1 + 1] = "";
   char str[LEN2 + 1];

   Timer = chrono_Create ();
   if (swrite_Basic) {
      swrite_Head (gen, TestName, N, n, r);
      printf ("\n\n");
   }
   util_Assert (n < LONG_MAX/2, "2n > LONG_MAX");
   if (res == NULL) {
      localRes = TRUE;
      res = sres_CreateChi2 ();
   }
   sres_InitChi2 (res, N, -1, "svaria_SumLogs");

   strncpy (chaine, "SumLogs sVal1:   chi2 with ", (size_t) LEN1);
   sprintf (str, "%ld", 2 * n);
   strncat (chaine, str, (size_t) LEN2);
   strncat (chaine, " degrees of freedom", (size_t) LEN1);
   statcoll_SetDesc (res->sVal1, chaine);
   res->degFree = 2 * n;
   if (res->degFree < 1) {
      util_Warning (TRUE, "Chi-square with 0 degree of freedom.");
      if (localRes)
         sres_DeleteChi2 (res);
      return;
   }

   for (Seq = 1; Seq <= N; Seq++) {
      Prod = 1.0;
      Sum = 0.0;
      for (i = 1; i <= n; i++) {
         u = unif01_StripD (gen, r);
         if (u < Eps)
            u = Eps;
         Prod *= u;
         if (Prod < Epsilon) {
            Sum += log (Prod);
            Prod = 1.0;
         }
      }
      statcoll_AddObs (res->sVal1, -2.0 * (Sum + log (Prod)));

   }
   V[0] = 2 * n;
   gofw_ActiveTests2 (res->sVal1->V, res->pVal1->V, N, wdist_ChiSquare, V,
                      res->sVal2, res->pVal2);
   res->pVal1->NObs = N;
   sres_GetChi2SumStat (res);

   if (swrite_Collectors)
      statcoll_Write (res->sVal1, 5, 14, 4, 3);

   if (swrite_Basic) {
      swrite_AddStrChi (str, LEN2, res->degFree);
      gofw_WriteActiveTests2 (N, res->sVal2, res->pVal2, str);
      swrite_Chi2SumTest (N, res);
      swrite_Final (gen, Timer);
   }
   if (localRes)
      sres_DeleteChi2 (res);
   chrono_Delete (Timer);
}
Exemplo n.º 10
0
void sentrop_EntropyDiscOver2 (unif01_Gen * gen, sentrop_Res * res,
   long N, long n, int r, int s, int L)
{
   long i, j;                     /* Indices */
   unsigned long B2, B1, B0;      /* Blocks of bits */
   long Seq;                      /* Replication number */
   double Entropy;                /* Value of the entropy S */
   double tempPrev;               /* Previous value of the entropy */
   double SumSq;                  /* To compute the covariance */
   double Corr;                   /* Empirical correlation */
   double Var;                    /* Empirical variance */
   double Mean;                   /* Empirical mean */
   double Sigma, Mu;              /* Parameters of the normal law */
   double Sum2, Sum;              /* Temporary variables */
   unsigned long d;               /* 2^s */
   long C;                        /* 2^L */
   unsigned long CLC;             /* 2^L */
   long m0;                       /* m0 = ceil (L/s) */
   long m;                        /* m = n/s */
   double xLgx[NLIM + 1];         /* = -i/n * Lg (i/n) */
   double NLR = N;
   double temp, E1;
   lebool localRes = FALSE;
   chrono_Chrono *Timer;
   char *TestName = "sentrop_EntropyDiscOver2 test";

   Timer = chrono_Create ();
   InitExactOver (n, L, &Mu, &Sigma);
   if (swrite_Basic)
      WriteDataDisc (gen, TestName, N, n, r, s, L, Mu, Sigma);

   util_Assert (L <= n, "sentrop_EntropyDiscOver2:   L > n");
   util_Assert (L <= 15, "sentrop_EntropyDiscOver2:   L > 15");
   util_Assert (r <= 31, "sentrop_EntropyDiscOver2:   r > 31");
   util_Assert (s <= 31, "sentrop_EntropyDiscOver2:   s > 31");
   util_Assert (L + s <= 31, "sentrop_EntropyDiscOver2:   L+s > 31");
   util_Assert (n % s == 0, "sentrop_EntropyDiscOver2:   n % s != 0");

   d = num_TwoExp[s];
   m = n / s;
   m0 = L / s;
   if (m0 * s < L)
      ++m0;
   /* B0 must not be larger than LONG_MAX (31 bits) */
   util_Assert (m0 * s <= 31, "sentrop_EntropyDiscOver2:   m0 * s > 31");
   C = num_TwoExp[L];
   CLC = num_TwoExp[L];

   if (res == NULL) {
      localRes = TRUE;
      res = sentrop_CreateRes ();
   }
   InitRes (res, N, C - 1, "sentrop_EntropyDiscOver2");
   tempPrev = SumSq = Sum2 = Sum = 0.0;
   CalcLgx (xLgx, n);

   for (Seq = 1; Seq <= N; Seq++) {
      for (i = 0; i < C; i++)
         res->Count[i] = 0;

      B0 = unif01_StripB (gen, r, s);
      for (j = 2; j <= m0; j++)
         B0 = B0 * d + unif01_StripB (gen, r, s);

      /* B0 now contains the bits 0,...,0,b_1,...,b_{m0*s} */
      B2 = B0;

      /* Count the blocks of L bits in b_1,...,b_{m0*s} */
      for (i = 0; i <= m0 * s - L; i++) {
         ++res->Count[B2 % CLC];
         B2 >>= 1;
      }
      B1 = B0 % CLC;
      B0 = B2 % CLC;
      /* B1 contains 0,...,0,b_{m0*s-L+1},...,b_{m0*s} */
      /* B0 contains 0,...,0,b_1,...,b_{L-1} */
      for (j = 1; j <= m - m0; j++) {
         B1 = B1 * d + unif01_StripB (gen, r, s);
         B2 = B1;
         B1 %= CLC;
         /* B1 and B2 contain L bits and L+s bits, resp. */
         for (i = 1; i <= s; i++) {
            ++res->Count[B2 % CLC];
            B2 >>= 1;
         }
      }

      /* B1 contains 0,...,0,b_{m*s-L+1},...,b_{m*s}. */
      /* Her we must have 2 * L <= 31. */
      B2 = B0 + B1 * (CLC / 2);
      /* B2 contains 0,..,0,b_{m*s-L+1},..,b_{m*s},b_1,...,b_{L-1}. */
      /* Now count blocks with overlap. */
      for (i = 1; i < L; i++) {
         ++res->Count[B2 % CLC];
         B2 >>= 1;
      }

      /* Compute entropy */
      Entropy = 0.0;
      for (i = 0; i < C; i++) {
         util_Assert (res->Count[i] <= NLIM,
            "sentrop_EntropyDiscOver2:   NLIM is too small");
         Entropy += xLgx[res->Count[i]];
      }

#ifdef STABLE
      /* Ideally, we should use the moving average for numerical stability.
         But we shall use the first observed value of instead; it should be
         typical and will prevent loss of precision (unless it is 0). */

      if (1 == Seq)
         E1 = Entropy;
      temp = Entropy - E1;
      Sum += temp;
      Sum2 += temp * temp;
      SumSq += temp * tempPrev;
      tempPrev = temp;

#else
      /* The naive unstable method */
      Sum += Entropy;
      Sum2 += Entropy * Entropy;
      SumSq += Entropy * tempPrev;
      tempPrev = Entropy;
#endif

      if (swrite_Counters)
         tables_WriteTabL (res->Count, 0, C - 1, 5, 10, "Counters:");

      if (swrite_Collectors) {
         printf ("Entropy = ");
         num_WriteD (Entropy, 15, 6, 1);
         printf ("\n");
      }
   }

   /* We now test the correlation between successive values of the */
   /* entropy. Corr should have mean 0 and variance 1. */

#ifdef STABLE
   Mean = Sum / NLR + E1;
   Var = Sum2 / NLR - (E1 - Mean) * (E1 - Mean);
   Var *= NLR / (NLR - 1.0);
   temp = (Entropy + E1 * NLR - 2.0 * NLR * Mean) * E1 / (NLR - 1.0);
   Corr = SumSq / (NLR - 1.0) - temp - Mean * Mean;
   if (Var <= 0.0) {
      Corr = 1.0e100;
      util_Warning (TRUE,
         "Empirical variance <= 0.   Correlation set to 1e100.");
   } else
      Corr /= Var;

#else
   /* Naive calculations. Here, there could be huge losses of precision
      because Mean*Mean, Sum2/NLR, and SumSq/(NLR - 1.0) may be very close. */
   Mean = Sum / NLR;
   Var = (Sum2 / NLR - Mean * Mean) * NLR / (NLR - 1.0);
   Corr = (SumSq / (NLR - 1.0) - Mean * Mean) / Var;
#endif

   if (Sigma > 0.0) {
      /* We know the true values of Mu and Sigma */
      res->Bas->sVal2[gofw_Mean] = (Mean - Mu) * sqrt (NLR) / Sigma;
      res->Bas->pVal2[gofw_Mean] = fbar_Normal1 (res->Bas->sVal2[gofw_Mean]);
   } else
      res->Bas->sVal2[gofw_Mean] = -1.0;

   res->Bas->sVal2[gofw_Cor] = Corr * sqrt (NLR);
   res->Bas->pVal2[gofw_Cor] = fbar_Normal1 (res->Bas->sVal2[gofw_Cor]);

   if (swrite_Basic) {
      WriteResultsDiscOver (res, NLR, Sum2, SumSq, Mu, Sigma, Mean, Var,
         Corr);
      swrite_Final (gen, Timer);
   }
   if (localRes)
      sentrop_DeleteRes (res);
   chrono_Delete (Timer);
}
Exemplo n.º 11
0
void sentrop_EntropyDiscOver (unif01_Gen * gen, sentrop_Res * res,
   long N, long n, int r, int s, int L)
{

   long i;                        /* Index */
   unsigned long Block1, Block0;  /* Blocks of bits */
   long Seq;                      /* Replication number */
   double Entropy;                /* Value of the entropy S */
   double tempPrev;               /* Previous value of entropy */
   double SumSq;                  /* To compute the covariance */
   double Corr;                   /* Empirical correlation */
   double Var;                    /* Empirical variance */
   double Mean;                   /* Empirical mean */
   double Sigma, Mu;              /* Parameters of the normal law */
   double Sum2, Sum;              /* Temporary variables */
   long d;                        /* 2^s */
   long C;                        /* 2^L */
   long nSurs;                    /* n / s */
   double xLgx[NLIM + 1];         /* = -i/n * Lg (i/n) */
   double NLR = N;
   double temp, E1;
   lebool localRes = FALSE;
   chrono_Chrono *Timer;
   char *TestName = "sentrop_EntropyDiscOver test";

   Timer = chrono_Create ();
   InitExactOver (n, L, &Mu, &Sigma);
   if (swrite_Basic)
      WriteDataDisc (gen, TestName, N, n, r, s, L, Mu, Sigma);

   util_Assert (L <= n - L, "sentrop_EntropyDiscOver:   L > n-L");
   util_Assert (n <= 31, "sentrop_EntropyDiscOver:   n > 31");
   util_Assert (r <= 31, "sentrop_EntropyDiscOver:   r > 31");
   util_Assert (s <= 31, "sentrop_EntropyDiscOver:   s > 31");
   util_Assert (n % s == 0, "sentrop_EntropyDiscOver:   n % s != 0");
   util_Assert (N > 1, "sentrop_EntropyDiscOver:   N <= 1");

   d = num_TwoExp[s];
   C = num_TwoExp[L];
   nSurs = n / s;

   if (res == NULL) {
      localRes = TRUE;
      res = sentrop_CreateRes ();
   }
   InitRes (res, N, C - 1, "sentrop_EntropyDiscOver");
   CalcLgx (xLgx, n);
   tempPrev = SumSq = Sum2 = Sum = 0.0;

   for (Seq = 1; Seq <= N; Seq++) {
      for (i = 0; i < C; i++)
         res->Count[i] = 0;

      Block0 = unif01_StripB (gen, r, s);
      for (i = 2; i <= nSurs; i++)
         Block0 = Block0 * d + unif01_StripB (gen, r, s);

      /* Compute entropy of the block of n bits = Block0. */
      /* This block has less than 31 bits. */
      Block1 = Block0;
      for (i = 0; i <= n - L - 1; i++) {
         ++res->Count[Block1 % C];
         Block1 >>= 1;
      }
      Block1 = (Block1 % C) + C * (Block0 % C);
      for (i = n - L; i < n; i++) {
         ++res->Count[Block1 % C];
         Block1 >>= 1;
      }

      Entropy = 0.0;
      for (i = 0; i < C; i++) {
         util_Assert (res->Count[i] <= NLIM,
            "sentrop_EntropyDiscOver:   NLIM is too small");
         Entropy += xLgx[res->Count[i]];
      }

#ifdef STABLE
      /* Ideally, we should use the moving average for numerical stability.
         But we shall use the first observed value instead; it should be
         typical and will prevent loss of precision (unless it is 0). */
      if (1 == Seq)
         E1 = Entropy;
      temp = Entropy - E1;
      Sum += temp;
      Sum2 += temp * temp;
      SumSq += temp * tempPrev;
      tempPrev = temp;

#else
      /* The naive method: it is simple but numerically unstable. It can be
         used for debugging and testing the more stable calculation in the
         case of small samples. */
      Sum += Entropy;
      Sum2 += Entropy * Entropy;
      SumSq += Entropy * tempPrev;
      tempPrev = Entropy;
#endif

      if (swrite_Counters)
         tables_WriteTabL (res->Count, 0, C - 1, 5, 10, "Counters:");

      if (swrite_Collectors) {
         printf ("Entropy = ");
         num_WriteD (Entropy, 15, 6, 1);
         printf ("\n");
      }
   }

   /* We now test the correlation between successive values of the entropy.
      Corr should have mean 0 and variance 1. We use a numerically stable
      calculation. */

#ifdef STABLE
   Mean = Sum / NLR + E1;
   Var = Sum2 / NLR - (E1 - Mean) * (E1 - Mean);
   Var *= NLR / (NLR - 1.0);
   temp = (Entropy + E1 * NLR - 2.0 * NLR * Mean) * E1 / (NLR - 1.0);
   Corr = SumSq / (NLR - 1.0) - temp - Mean * Mean;
   if (Var <= 0.0) {
      Corr = 1.0e100;
      util_Warning (TRUE,
         "Empirical variance <= 0.   Correlation set to 1e100.");
   } else
      Corr /= Var;

#else
   /* Naive calculations. Here, there could be huge losses of precision
      because Mean*Mean, Sum2/NLR, and SumSq/(NLR - 1.0) may be very close. */
   Mean = Sum / NLR;
   Var = (Sum2 / NLR - Mean * Mean) * NLR / (NLR - 1.0);
   Corr = (SumSq / (NLR - 1.0) - Mean * Mean) / Var;

#endif


   if (Sigma > 0.0) {
      /* We know the true values of Mu and Sigma */
      res->Bas->sVal2[gofw_Mean] = (Mean - Mu) * sqrt (NLR) / Sigma;
      res->Bas->pVal2[gofw_Mean] = fbar_Normal1 (res->Bas->sVal2[gofw_Mean]);
   } else
      res->Bas->pVal2[gofw_Mean] = -1.0;

   res->Bas->sVal2[gofw_Cor] = Corr * sqrt (NLR);
   res->Bas->pVal2[gofw_Cor] = fbar_Normal1 (res->Bas->sVal2[gofw_Cor]);

   if (swrite_Basic) {
      WriteResultsDiscOver (res, NLR, Sum2, SumSq, Mu, Sigma, Mean, Var,
         Corr);
      swrite_Final (gen, Timer);
   }
   if (localRes)
      sentrop_DeleteRes (res);
   chrono_Delete (Timer);
}