/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { //calculate all psi_squares double psim0 = this.psi2(this.m, this.n); double psim1 = this.psi2(this.m - 1, this.n); double psim2 = this.psi2(this.m - 2, this.n); double del1 = psim0 - psim1; double del2 = psim0 - 2.0 * psim1 + psim2; //calculate p_values double p_value1 = Cephes.igamc(Math.Pow(2, this.m - 1) / 2, del1 / 2.0); double p_value2 = Cephes.igamc(Math.Pow(2, this.m - 2) / 2, del2 / 2.0); if (printResults) { Report report = new Report("11: Serial Test"); report.Write("\t\t\t SERIAL TEST"); report.Write("\t\t---------------------------------------------"); report.Write("\t\t COMPUTATIONAL INFORMATION: "); report.Write("\t\t---------------------------------------------"); report.Write("\t\t(a) Block length (m) = " + this.m); report.Write("\t\t(b) Sequence length (n) = " + this.n); report.Write("\t\t(c) Psi_m = " + psim0); report.Write("\t\t(d) Psi_m-1 = " + psim1); report.Write("\t\t(e) Psi_m-2 = " + psim2); report.Write("\t\t(f) Del_1 = " + del1); report.Write("\t\t(g) Del_2 = " + del2); report.Write("\t\t---------------------------------------------\n"); report.Write(p_value1 < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value1 = " + p_value1); report.Write(p_value2 < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value2 = " + p_value2); this.model.reports.Add(report.title, report); } return(new double[] { p_value1, p_value2 }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { int N = n / M; //number of blocks that can be made from the binary string //for each block calculate the proportion of ones double sum = 0.0; for (int i = 0; i < N; i++) { double pi = (double)model.epsilon.GetRange(i * M, M).Sum() / (double)M; //sum of bits in block / length of the block sum += Math.Pow((pi - 0.5), 2); } //calculate p_value double chi_squared = 4.0 * M * sum; double p_value = Cephes.igamc(N / 2.0, chi_squared / 2.0); if (printResults) { Report report = new Report("2: Frequency Test within a Block"); report.Write("\t\t\tBLOCK FREQUENCY TEST"); report.Write("\t\t---------------------------------------------"); report.Write("\t\tCOMPUTATIONAL INFORMATION:"); report.Write("\t\t---------------------------------------------"); report.Write("\t\t(a) Chi^2 = " + chi_squared); report.Write("\t\t(b) # of substrings = " + N); report.Write("\t\t(c) block length = " + M); report.Write("\t\t(d) Note: " + n % M + " bits were discarded."); report.Write("\t\t---------------------------------------------"); report.Write(p_value < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value = " + p_value); model.reports.Add(report.title, report); } return(new double[] { p_value }); }
private double[] run(int[] B, bool printResults) { if (n > model.epsilon.Count || n <= 0) { throw new ArgumentException("The value of n must be smaller than the size of the input data, and be greater than 0", "Frequency n"); } int[] Wj = new int[N]; for (int i = 0; i < N; i++) //for each start position { for (int j = 0; j < M - B.Length + 1; j++) //is there a match for the template { bool match = true; for (int k = 0; k < B.Length; k++) { if ((int)B[k] != (int)model.epsilon[i * M + j + k]) { match = false; break; } } if (match) { Wj[i]++; //if there was a match, record it } } } //calculate p_value double chi2 = 0.0; for (int i = 0; i < N; i++) { chi2 += Math.Pow(((double)Wj[i] - mu) / Math.Pow(sigma, 0.5), 2); } double p_value = Cephes.igamc(N / 2.0, chi2 / 2.0); if (printResults) { Report report = new Report("7: Non-overlapping Template Matching Test"); report.Write("chi^2 = " + chi2); report.Write("p_value = " + p_value); model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { double[] pi = new double[6]; double lambda = (double)(M - this.B.Length + 1) / Math.Pow(2, this.B.Length); double eta = lambda / 2.0; double total = 0.0; for (int i = 0; i < K; i++) { //compute prior probabilities pi[i] = this.probability(i, eta); total += pi[i]; } pi[K] = 1 - total; int[] v = new int[K + 1]; for (int i = 0; i < N; i++) { //search for a match of the template in each block int count = 0; for (int j = 0; j < M - this.B.Length + 1; j++) { bool match = true; for (int k = 0; k < this.B.Length; k++) { if (this.B[k] != this.model.epsilon[i * M + j + k]) { match = false; } } if (match) { count++; } } if (count < K) { //record the matches found v[count]++; } else { v[K]++; } } //compute p_value double sum = 0.0; double chiSquared = 0.0; for (int i = 0; i < K + 1; i++) { chiSquared += Math.Pow((double)v[i] - (double)N * pi[i], 2) / ((double)N * pi[i]); sum += v[i]; } double p_value = Cephes.igamc(5.0 / 2.0, chiSquared / 2.0); if (printResults) { Report report = new Report("8: Overlapping Template Matching Test"); report.Write("\t\t OVERLAPPING TEMPLATE OF ALL ONES TEST"); report.Write("\t\t-----------------------------------------------"); report.Write("\t\tCOMPUTATIONAL INFORMATION:"); report.Write("\t\t-----------------------------------------------"); report.Write("\t\t(a) n (sequence_length) = " + this.n); report.Write("\t\t(b) m (block length of 1s) = " + this.B.Length); report.Write("\t\t(c) M (length of substring) = " + M); report.Write("\t\t(d) N (number of substrings) = " + N); report.Write("\t\t(e) lambda [(M-m+1)/2^m] = " + lambda); report.Write("\t\t(f) eta = " + eta); report.Write("\t\t(g) Chi^2 = " + chiSquared); report.Write("\t\t(h) P-value = " + p_value); report.Write("\t\t-----------------------------------------------"); report.Write("\t\t F R E Q U E N C Y"); report.Write("\t\t", false); for (int i = 0; i < K; i++) { report.Write(" " + i + " "); } report.Write(" >=" + K); report.Write("\t\t-----------------------------------------------"); report.Write("\t\t", false); for (int i = 0; i < K + 1; i++) { report.Write(" " + v[i] + " "); } if (p_value < 0 || p_value > 1) { report.Write("WARNING: P_VALUE IS OUT OF RANGE."); } report.Write(p_value + " " + (p_value < ALPHA ? "FAILURE" : "SUCCESS")); this.model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { double[] Pm = new double[3]; int r = Math.Min(M, Q); //compute predicted probabilities double product = 1; for (int i = 0; i <= r - 1; i++) { product *= ((1.0 - Math.Pow(2, i - Q)) * (1.0 - Math.Pow(2, i - M))) / (1.0 - Math.Pow(2, i - r)); } Pm[0] = Math.Pow(2, r * (M + Q - r) - M * Q) * product; r--; product = 1; for (int i = 0; i <= r - 1; i++) { product *= ((1.0 - Math.Pow(2, i - Q)) * (1.0 - Math.Pow(2, i - M))) / (1.0 - Math.Pow(2, i - r)); } Pm[1] = Math.Pow(2, r * (M + Q - r) - M * Q) * product; Pm[2] = 1 - (Pm[0] + Pm[1]); int N = n / (M * Q); //number of blocks int[] Fm = new int[3]; for (int k = 0; k < N; k++) { //construct the matrix of MxQ in size int[,] matrix = new int[M, Q]; for (int i = 0; i < M; i++) { for (int j = 0; j < Q; j++) { matrix[i, j] = model.epsilon[k * (M * Q) + j + i * M]; } } int R = computeRank(M, Q, matrix); //get the rank of the matrix if (R == M) { Fm[0]++; //full rank } else if (R == M - 1) { Fm[1]++; //full rank - 1 } } Fm[2] = N - (Fm[0] + Fm[1]); //full rank - 2 //compute p_value double chi_squared = (Math.Pow(Fm[0] - N * Pm[0], 2) / (double)(N * Pm[0]) + Math.Pow(Fm[1] - N * Pm[1], 2) / (double)(N * Pm[1]) + Math.Pow(Fm[2] - N * Pm[2], 2) / (double)(N * Pm[2])); double p_value = Cephes.igamc(1, chi_squared / 2.0); if (printResults) { Report report = new Report("2.5 Binary Matrix Rank Test"); report.Write("\t\t\t\tRANK TEST"); report.Write("\t\t---------------------------------------------"); report.Write("\t\tCOMPUTATIONAL INFORMATION:"); report.Write("\t\t---------------------------------------------"); report.Write("\t\t(a) Probability P_" + M + " = " + Pm[0]); report.Write("\t\t(b) P_" + (M - 1) + " = " + Pm[1]); report.Write("\t\t(c) P_" + (M - 2) + " = " + Pm[2]); report.Write("\t\t(d) Frequency F_" + M + " = " + Fm[0]); report.Write("\t\t(e) F_" + (M - 1) + " = " + Fm[1]); report.Write("\t\t(f) F_" + (M - 2) + " = " + Fm[2]); report.Write("\t\t(g) # of matrices = " + N); report.Write("\t\t(h) Chi^2 = " + chi_squared); report.Write("\t\t(i) NOTE: " + n % (M * Q) + " BITS WERE DISCARDED."); report.Write("\t\t---------------------------------------------"); report.Write(p_value < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value = " + p_value); if (p_value < 0 || p_value > 1) { report.Write("WARNING: P_VALUE IS OUT OF RANGE."); } model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { double[] pi; int K, M, V0; init(out K, out M, out V0, out pi); //initialize variables to sensible values int[] V = new int[pi.Length]; int N = n / M; //number of blocks that can be made from the binary string for (int i = 0; i < N; i++) { //count the longest run of ones in each block int longestRun = 0; int currentRun = 0; for (int j = 0; j < M; j++) { if (model.epsilon[i * M + j] == 1) { longestRun = Math.Max(longestRun, ++currentRun); } else { currentRun = 0; } } //record the longest run of ones found in the correct counter if (longestRun < V0) { V[0]++; } else if (longestRun > V0 + K) { V[K]++; } else { V[longestRun - V0]++; } } //calculate p_value double chi_squared = 0.0; for (int i = 0; i <= K; i++) { chi_squared += ((V[i] - N * pi[i]) * (V[i] - N * pi[i])) / (N * pi[i]); } double p_value = Cephes.igamc((double)(K / 2.0), chi_squared / 2.0); if (printResults) { Report report = new Report("4: Test for the Longest Run of Ones in a Block"); report.Write("\t\t\t LONGEST RUNS OF ONES TEST\n"); report.Write("\t\t---------------------------------------------\n"); report.Write("\t\tCOMPUTATIONAL INFORMATION:\n"); report.Write("\t\t---------------------------------------------\n"); report.Write("\t\t(a) N (# of substrings) = " + N); report.Write("\t\t(b) M (Substring Length) = " + M); report.Write("\t\t(c) Chi^2 = " + chi_squared); report.Write("\t\t---------------------------------------------\n"); report.Write("\t\t F R E Q U E N C Y\n"); report.Write("\t\t---------------------------------------------\n"); if (K == 3) { report.Write("\t\t <=1 2 3 >=4 P-value Assignment"); report.Write("\t\t " + V[0] + " " + V[1] + " " + V[2] + " " + V[3]); } else if (K == 5) { report.Write("\t\t<=4 5 6 7 8 >=9 P-value Assignment"); report.Write("\t\t " + V[0] + " " + V[1] + " " + V[2] + " " + V[3] + " " + V[4] + " " + V[5]); } else { report.Write("\t\t<=10 11 12 13 14 15 >=16 P-value Assignment"); report.Write("\t\t " + V[0] + " " + V[1] + " " + V[2] + " " + V[3] + " " + V[4] + " " + V[5] + " " + V[6]); } if (p_value < 0 || p_value > 1) { report.Write("WARNING: P_VALUE IS OUT OF RANGE.\n"); } report.Write(p_value < ALPHA ? "FAILURE" : "SUCCESS" + "{0}\t\tp_value = " + p_value); model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { double[] pi = { 0.01047, 0.03125, 0.12500, 0.50000, 0.25000, 0.06250, 0.020833 }; int N = n / M; //number of blocks double mu = M / 2.0 + (9.0 + Math.Pow(-1, M + 1)) / 36.0 - 1.0 / Math.Pow(2, M) * (M / 3.0 + 2.0 / 9.0); double[] v = new double[K + 1]; for (int i = 0; i < N; i++) { int[] T = new int[M]; //initialize the work arrays int[] P = new int[M]; int[] C = new int[M]; int[] B = new int[M]; int L = 0; int m = -1; int d = 0; C[0] = 1; B[0] = 1; //calculate the linear complexity of the block int blockPos = 0; while (blockPos < M) { d = (int)model.epsilon[i * M + blockPos]; for (int j = 1; j <= L; j++) { d += C[j] * model.epsilon[i * M + blockPos - j]; } d = d % 2; if (d == 1) { for (int j = 0; j < M; j++) { T[j] = C[j]; P[j] = 0; } for (int j = 0; j < M; j++) { if (B[j] == 1) { P[j + blockPos - m] = 1; } } for (int j = 0; j < M; j++) { C[j] = (C[j] + P[j]) % 2; } if (L <= blockPos / 2) { L = blockPos + 1 - L; m = blockPos; for (int j = 0; j < M; j++) { B[j] = T[j]; } } } blockPos++; } double Ti = Math.Pow(-1, M) * (L - mu) + 2.0 / 9.0; //record result of complexity test if (Ti <= -2.5) { v[0]++; } else if (Ti > -2.5 && Ti <= -1.5) { v[1]++; } else if (Ti > -1.5 && Ti <= -0.5) { v[2]++; } else if (Ti > -0.5 && Ti <= 0.5) { v[3]++; } else if (Ti > 0.5 && Ti <= 1.5) { v[4]++; } else if (Ti > 1.5 && Ti <= 2.5) { v[5]++; } else { v[6]++; } } //calculate p_value double chi_squared = 0; for (int i = 0; i < K + 1; i++) { chi_squared += Math.Pow(v[i] - N * pi[i], 2) / (N * pi[i]); } double p_value = Cephes.igamc(K / 2.0, chi_squared / 2.0); if (printResults) { Report report = new Report("10: Linear Complexity Test"); report.Write("-----------------------------------------------------"); report.Write("\tL I N E A R C O M P L E X I T Y"); report.Write("-----------------------------------------------------"); report.Write("\tM (substring length) = {0}" + M); report.Write("\tN (number of substrings) = {0}" + N); report.Write("-----------------------------------------------------"); report.Write(" F R E Q U E N C Y "); report.Write("-----------------------------------------------------"); report.Write(" C0 C1 C2 C3 C4 C5 C6 CHI2 P-value"); report.Write("-----------------------------------------------------"); report.Write("\tNote: " + n % M + " bits were discarded!"); for (int i = 0; i < K + 1; i++) { report.Write(((int)v[i]).ToString(), false); } report.Write(""); report.Write(p_value < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value = " + p_value); model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { int r = 0; double[] apEn = new double[2]; for (int blockSize = m; blockSize <= m + 1; blockSize++) { if (blockSize == 0) { apEn[0] = 0; r++; } else { int[] P = new int[(int)Math.Pow(2, blockSize + 1) - 1]; for (int i = 1; i < Math.Pow(2, blockSize + 1) - 1; i++) { P[i] = 0; } //calculate frequency of n overlapping blocks for (int i = 0; i < n; i++) { int k = 1; for (int j = 0; j < blockSize; j++) { k *= 2; if ((int)model.epsilon[(i + j) % n] == 1) { k++; } } P[k - 1]++; } //calculate approximate entropy entry from frequency double sum = 0; int index = (int)Math.Pow(2, blockSize) - 1; for (int i = 0; i < (int)Math.Pow(2, blockSize); i++) { if (P[index] > 0) { sum += P[index] * Math.Log(P[index] / (double)n); } index++; } apEn[r] = sum / n; r++; } } double approximateEntropy = apEn[0] - apEn[1]; //calculate p_value double chi_squared = 2.0 * n * (Math.Log(2) - approximateEntropy); double p_value = Cephes.igamc(Math.Pow(2, m - 1), chi_squared / 2.0); if (printResults) { Report report = new Report("12: Approximate Entropy Test"); report.Write("\t\t\tAPPROXIMATE ENTROPY TEST"); report.Write("\t\t--------------------------------------------"); report.Write("\t\tCOMPUTATIONAL INFORMATION:"); report.Write("\t\t--------------------------------------------"); report.Write("\t\t(a) m (block length) = " + m); report.Write("\t\t(b) n (sequence length) = " + n); report.Write("\t\t(c) Chi^2 = " + chi_squared); report.Write("\t\t(d) Phi(m) = "+ apEn[0]); report.Write("\t\t(e) Phi(m+1) = "+ apEn[1]); report.Write("\t\t(f) ApEn = " + approximateEntropy); report.Write("\t\t--------------------------------------------"); if (m > (int)(Math.Log(n) / Math.Log(2) - 5)) { report.Write("\t\tNote: The blockSize = " + m + " exceeds recommended value of " + Math.Max(1, (int)(Math.Log(n) / Math.Log(2) - 5))); report.Write("\t\tResults are inaccurate!"); report.Write("\t\t--------------------------------------------"); } report.Write((p_value < ALPHA ? "FAILURE" : "SUCCESS") + "\t\tp_value = " + p_value); model.reports.Add(report.title, report); } return(new double[] { p_value }); }
/// <summary> /// Runs the test /// </summary> /// <param name="printResults">If true text output will be added to a log, otherwise not</param> /// <returns>The p_value(s) of the test based upon the input data</returns> public override double[] run(bool printResults) { int[] stateX = { -4, -3, -2, -1, 1, 2, 3, 4 }; double[,] pi = { { 0.0000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.00000000000, 0.0000000000 }, { 0.5000000000, 0.25000000000, 0.12500000000, 0.06250000000, 0.03125000000, 0.0312500000 }, { 0.7500000000, 0.06250000000, 0.04687500000, 0.03515625000, 0.02636718750, 0.0791015625 }, { 0.8333333333, 0.02777777778, 0.02314814815, 0.01929012346, 0.01607510288, 0.0803755143 }, { 0.8750000000, 0.01562500000, 0.01367187500, 0.01196289063, 0.01046752930, 0.0732727051 } }; Report report = new Report("14: Random Excursions Test"); //determine cycles int J = 0; int[] S_k = new int[n]; S_k[0] = 2 * (int)model.epsilon[0] - 1; int[] cycle = new int[Math.Max(1000, n / 100)]; for (int i = 1; i < n; i++) { S_k[i] = S_k[i - 1] + 2 * model.epsilon[i] - 1; if (S_k[i] == 0) { J++; if (J > Math.Max(1000, n / 100)) { if (printResults) { report.Write("ERROR IN FUNCTION randomExcursions: EXCEEDING THE MAX NUMBER OF CYCLES EXPECTED."); } return(null); } cycle[J] = i; } } if (S_k[n - 1] != 0) { J++; } cycle[J] = n; if (printResults) { report.Write("\t\t\t RANDOM EXCURSIONS TEST"); report.Write("\t\t--------------------------------------------"); report.Write("\t\tCOMPUTATIONAL INFORMATION:"); report.Write("\t\t--------------------------------------------"); report.Write("\t\t(a) Number Of Cycles (J) = " + J); report.Write("\t\t(b) Sequence Length (n) = " + n); } double constraint = Math.Max(0.005 * Math.Pow(n, 0.5), 500); double[] p_values = new double[8]; if (J < constraint) { if (printResults) { report.Write("\t\t---------------------------------------------"); report.Write("\t\tWARNING: TEST NOT APPLICABLE. THERE ARE AN"); report.Write("\t\t\t INSUFFICIENT NUMBER OF CYCLES."); report.Write("\t\t---------------------------------------------"); for (int i = 0; i < 8; i++) { report.Write(0.0.ToString()); } } } else { if (printResults) { report.Write("\t\t(c) Rejection Constraint = " + constraint); report.Write("\t\t-------------------------------------------"); } double[,] v = new double[6, 8]; int cycleStart = 0; int cycleStop = cycle[1]; for (int k = 0; k < 6; k++) { for (int i = 0; i < 8; i++) { v[k, i] = 0.0; } } int[] counter = new int[8]; //for each cycle compute frequency of x for (int j = 1; j <= J; j++) { for (int i = 0; i < 8; i++) { counter[i] = 0; } for (int i = cycleStart; i < cycleStop; i++) { if ((S_k[i] >= 1 && S_k[i] <= 4) || (S_k[i] >= -4 && S_k[i] <= -1)) { int b = S_k[i] < 0 ? 4 : 3; counter[S_k[i] + b]++; } } cycleStart = cycle[j] + 1; if (j < J) { cycleStop = cycle[j + 1]; } for (int i = 0; i < 8; i++) { if ((counter[i] >= 0) && (counter[i] <= 4)) { v[counter[i], i]++; } else if (counter[i] >= 5) { v[5, i]++; } } } //calculate p_values for (int i = 0; i < 8; i++) { int x = stateX[i]; double sum = 0; for (int k = 0; k < 6; k++) { sum += Math.Pow(v[k, i] - J * pi[(int)Math.Abs(x), k], 2) / (J * pi[(int)Math.Abs(x), k]); } p_values[i] = Cephes.igamc(2.5, sum / 2.0); if (printResults) { if (p_values[i] < 0 || p_values[i] > 1) { report.Write("WARNING: P_VALUE IS OUT OF RANGE."); } report.Write(p_values[i] < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tx = " + x + " chi^2 = " + sum + " p_value = " + p_values[i]); } } } if (printResults) { model.reports.Add(report.title, report); } return(p_values); }