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); } }
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"); } }
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; }
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'; }
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; }
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"); }
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; } }
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); }
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); }
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); }