void tables_WriteTabD (double V[], int n1, int n2, int k, int p1, int p2, int p3, char Desc[]) { int i; printf ("---------------------------------------\n"); printf ("%s\n", Desc); if (k > 1) { printf ("Elements %d to %d\n\n", n1, n2); for (i = n1; i <= n2; i++) { /* printf ("%*.*G", p1, p2, V[i]); */ num_WriteD (V[i], p1, p2, p3); if (((i + 1 - n1) % k) == 0) printf ("\n"); } printf ("\n"); } else { printf ("\n Index Element\n"); for (i = n1; i <= n2; i++) { printf ("%6d", i); num_WriteD (V[i], p1, p2, p3); printf ("\n"); } } printf ("\n"); }
void gofw_Writep2 (double x, double p) /* Prints the statistic x and its significance level p. */ { if ((x < 1.0e5 && x >= 0.1) || (x > -1.0e4 && x <= -0.1)) num_WriteD (x, 8, 2, 1); else if ((x < 0.1 && x >= 0.01) || (x > -0.1 && x <= -0.01)) num_WriteD (x, 8, 3, 2); else num_WriteD (x, 8, 3, 3); printf ("\n"); gofw_Writep1 (p); }
static void WriteDataDisc (unif01_Gen * gen, char *TestName, long N, long n, int r, int s, int L, double Mu, double Sigma) { swrite_Head (gen, TestName, N, n, r); printf (", s = %1d, L = %1d\n", s, L); if (Sigma > 0.0) { printf (" Mu = "); num_WriteD (Mu, 15, 7, 7); printf ("\n Sigma = "); num_WriteD (Sigma, 15, 7, 7); printf ("\n"); } else { printf (" Mu and Sigma are unknown.\n"); } printf ("\n\n"); }
void gofw_Writep0 (double p) /* Prints the significance level of a test, without a descriptor */ { if ((p >= 0.01) && (p <= 0.99)) num_WriteD (p, 8, 2, 1); else if (p < gofw_Epsilonp) printf (" eps "); else if (p < 0.01) num_WriteD (p, 8, 2, 2); else if (p >= 1.0 - gofw_Epsilonp1) printf (" 1 - eps1"); else if (p < 1.0 - 1.0e-4) printf (" %.4f", p); else { printf (" 1 - "); num_WriteD (1.0 - p, 7, 2, 2); } }
static void PrintVal (ftab_Table * T, double d, ftab_FormType Form) /* * Prints the value d according to format Form. */ { int s; /* All Table tables are initialized to -1; thus the test was not done for this pair (e, f) if d = -1. */ if (d < -0.9) { printf (" --- "); } else if (Form == ftab_String) { printf (" "); s = 0.5 + d; printf ("%s", T->Strings[s]); } else if (Form == ftab_Integer) { printf (" "); if (d <= LONG_MAX) printf ("%8ld", (long) d); else num_WriteD (d, 8, 0, 0); } else if (Form == ftab_Real) { printf (" "); num_WriteD (d, 8, 2, 2); } else if (Form == ftab_pLog2) { PrintLog2 (d); } else if (Form == ftab_pLog10) { PrintLog10 (d); } else if (d < gofw_Epsilonp) { printf (" eps "); } else if (d < ftab_Suspectp) { printf (" "); num_WriteD (d, 8, 2, 2); } else if (d > 1.0 - gofw_Epsilonp1 && Form == ftab_pVal2) { printf (" -eps1 "); } else if (d > 1.0 - ftab_Suspectp && Form == ftab_pVal2) { printf (" "); num_WriteD (d - 1.0, 8, 2, 2); } else if (Form == ftab_NotInit) { util_Error ("ftab_PrintTable: Form is not initialized"); } else { printf (" "); } }
static void PrintValTex (ftab_Table * T, double d, ftab_FormType Form) /* * Similar to PrintVal, but prints in LaTex style. */ { int s; if (d < -0.9) { printf (" & --- "); } else if (Form == ftab_String) { printf (" & "); s = d + 0.5; printf ("%s", T->Strings[s]); } else if (Form == ftab_Integer) { printf (" & "); if (d <= LONG_MAX) printf ("%8ld", (long) d); else num_WriteD (d, 8, 0, 0); } else if (Form == ftab_Real) { printf (" & "); num_WriteD (d, 8, 2, 2); } else if (Form == ftab_pLog10) { PrintLog10Tex (d); } else if (Form == ftab_pLog2) { PrintLog2Tex (d); } else if (d < gofw_Epsilonp) { printf (" & \\eps "); } else if (d < ftab_Suspectp) { printf (" & "); num_WriteD (d, 8, 2, 2); } else if (d > 1.0 - gofw_Epsilonp1 && Form == ftab_pVal2) { printf (" & \\epsm "); } else if (d > 1.0 - ftab_Suspectp && Form == ftab_pVal2) { printf (" & "); num_WriteD (d - 1.0, 8, 2, 2); } else if (Form == ftab_NotInit) { util_Error ("ftab\\_PrintTable: Form is not initialized"); } else { printf (" & "); } }
static void WriteResultsDiscOver (sentrop_Res *res, double NLR, double Sum2, double SumSq, double Mu, double Sigma, double Mean, double Var, double Corr) { printf ("\nEmpirical mean :"); num_WriteD (Mean, 12, 8, 2); printf ("\nEmpirical variance :"); num_WriteD (Var, 12, 8, 2); printf ("\n"); Sum2 = Sum2; SumSq = SumSq; #ifndef STABLE if (swrite_Basic) { printf ("\nInformation on the numerical error in the computation\n" " of the variance and the correlation:\n" " Mean * Mean :"); num_WriteD (Mean * Mean, 20, 16, 2); printf ("\n Sum2 / N :"); num_WriteD (Sum2 / NLR, 20, 16, 2); printf ("\n SumSq / (N-1) :"); num_WriteD (SumSq / (NLR - 1.0), 20, 16, 2); printf ("\n\n"); } #endif if (Sigma > 0.0) { printf ("\nDeviation from the theoretical mean :"); num_WriteD (Mean - Mu, 12, 8, 2); printf ("\nStandardized standard deviation :"); gofw_Writep2 (res->Bas->sVal2[gofw_Mean], res->Bas->pVal2[gofw_Mean]); printf ("\n"); } else { printf ("\n\n"); } printf ("Empirical correlation :"); num_WriteD (Corr, 12, 8, 2); printf ("\nEmpirical correlation * sqrt(N) :"); gofw_Writep2 (res->Bas->sVal2[gofw_Cor], res->Bas->pVal2[gofw_Cor]); printf ("\n"); }
static void EntropyDisc00 (unif01_Gen * gen, sentrop_Res * res, long N, long n, int r, int s, int L) /* * Test based on the discrete entropy, proposed by Compagner and L'Ecuyer */ { long Seq; long j; long i; double EntropyNorm; /* Normalized entropy */ double Entropy; /* Value of entropy S */ double EntropyPrev; /* Previous value of entropy */ double SumSq; /* To compute the covariance */ double Sigma, Mu; /* Parameters of the normal law */ double tem; double nLR = n; long d; /* 2^s */ long C; /* 2^L */ long LSurs; /* L / s */ long sSurL; /* s / L */ long nLSurs; /* nL / s */ double xLgx[NLIM + 1]; /* = -i/n * Lg (i/n) */ unsigned long Block; unsigned long Number; unsigned int LL = L; lebool localRes = FALSE; chrono_Chrono *Timer; char *TestName = "sentrop_EntropyDisc test"; Timer = chrono_Create (); if (s <= L && L % s) { util_Error ("EntropyDisc00: s <= L and L % s != 0"); } if (s > L && s % L) { util_Error ("EntropyDisc00: s > L and s % L != 0"); } d = num_TwoExp[s]; C = num_TwoExp[L]; if (s <= L) LSurs = L / s; else { sSurL = s / L; nLSurs = n / sSurL; if (n % sSurL) ++nLSurs; } util_Assert (n / num_TwoExp[L] < NLIM, "sentrop_EntropyDisc: n/2^L is too large"); smultin_MultinomMuSigma (n, num_TwoExp[L], 0.0, (double) n, FoncMNEntropie, &Mu, &Sigma); if (swrite_Basic) WriteDataDisc (gen, TestName, N, n, r, s, L, Mu, Sigma); if (res == NULL) { localRes = TRUE; res = sentrop_CreateRes (); } InitRes (res, N, C - 1, "sentrop_EntropyDisc"); CalcLgx (xLgx, n); statcoll_SetDesc (res->Bas->sVal1, "EntropyDisc sVal1"); statcoll_SetDesc (res->Bas->pVal1, "EntropyDisc pVal1"); SumSq = EntropyPrev = 0.0; for (Seq = 1; Seq <= N; Seq++) { for (i = 0; i < C; i++) res->Count[i] = 0; if (s <= L) { for (i = 1; i <= n; i++) { Block = unif01_StripB (gen, r, s); for (j = 2; j <= LSurs; j++) Block = Block * d + unif01_StripB (gen, r, s); ++res->Count[Block]; } } else { /* s > L */ for (i = 1; i <= nLSurs; i++) { Number = unif01_StripB (gen, r, s); for (j = 1; j <= sSurL; j++) { Block = Number % C; ++res->Count[Block]; Number >>= LL; } } } /* Compute entropy */ Entropy = 0.0; for (i = 0; i < C; i++) { if (res->Count[i] > NLIM) { tem = res->Count[i] / nLR; tem *= -num_Log2 (tem); Entropy += tem; } else if (res->Count[i] > 0) { Entropy += xLgx[res->Count[i]]; } } EntropyNorm = (Entropy - Mu) / Sigma; statcoll_AddObs (res->Bas->sVal1, EntropyNorm); SumSq += EntropyNorm * EntropyPrev; EntropyPrev = EntropyNorm; 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"); } } gofw_ActiveTests2 (res->Bas->sVal1->V, res->Bas->pVal1->V, N, wdist_Normal, (double *) NULL, res->Bas->sVal2, res->Bas->pVal2); res->Bas->pVal1->NObs = N; sres_GetNormalSumStat (res->Bas); /* We now test the correlation between successive values of the entropy. The next SumSq should have mean 0 and variance 1. */ if (N > 1) { res->Bas->sVal2[gofw_Cor] = SumSq / sqrt ((double) N); res->Bas->pVal2[gofw_Cor] = fbar_Normal1 (res->Bas->sVal2[gofw_Cor]); } if (swrite_Collectors) { statcoll_Write (res->Bas->sVal1, 5, 14, 4, 3); } if (swrite_Basic) { WriteResultsDisc (N, res->Bas->sVal2, res->Bas->pVal2, res->Bas); swrite_Final (gen, Timer); } if (localRes) sentrop_DeleteRes (res); chrono_Delete (Timer); }
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); }
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); }