Example #1
0
        /// <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 the sum of all bits in the string after mapping (0->-1, 1->1)
            double S_n = model.epsilon.GetRange(0, n).Sum(delegate(int i) { return(2 * i - 1); });

            //calculate p_value
            double S_obs   = Math.Abs(S_n) / Math.Sqrt(n);
            double p_value = Cephes.erfc(S_obs / Math.Sqrt(2));

            if (printResults)
            {
                Report report = new Report("1: Frequency (Monobit) Test");
                report.Write("\t\t\t      FREQUENCY TEST");
                report.Write("\t\t---------------------------------------------");
                report.Write("\t\tCOMPUTATIONAL INFORMATION:");
                report.Write("\t\t---------------------------------------------");
                report.Write("\t\t(a) The nth partial sum = " + (int)S_n);
                report.Write("\t\t(b) S_n/n               = " + S_n / n);
                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)
        {
            double pi = (double)model.epsilon.GetRange(0, n).Sum() / (double)n;    //number of ones in the binary string / length

            //prerequisite for test, if not passed test is not applicable
            if (Math.Abs(pi - 0.5) > (2.0 / Math.Sqrt(n)))
            {
                if (printResults)
                {
                    Report report = new Report("3: Runs Test");
                    report.Write("\t\t\t\tRUNS TEST");
                    report.Write("\t\t------------------------------------------");
                    report.Write("\t\tPI ESTIMATOR CRITERIA NOT MET! PI = " + pi);
                    model.reports.Add(report.title, report);
                }
                return(new double[] { 0.0 });
            }
            else
            {
                //count number of runs in the binary string (where e(i) = e(i+1) is considered to be a run)
                int V_obs = 1;
                for (int i = 1; i < n; i++)
                {
                    if (model.epsilon[i] != model.epsilon[i - 1])
                    {
                        V_obs++;
                    }
                }

                //calculate p_value
                double p_value = Cephes.erfc(Math.Abs(V_obs - 2.0 * n * pi * (1 - pi)) / (2.0 * pi * (1 - pi) * Math.Sqrt(2 * n)));

                if (printResults)
                {
                    Report report = new Report("3: Runs Test");
                    report.Write("\t\t\t\tRUNS TEST");
                    report.Write("\t\t------------------------------------------");
                    report.Write("\t\tCOMPUTATIONAL INFORMATION:");
                    report.Write("\t\t------------------------------------------");
                    report.Write("\t\t(a) Pi                        = " + pi);
                    report.Write("\t\t(b) V_n_obs (Total # of runs) = " + (int)V_obs);
                    report.Write("\t\t(c) V_n_obs - 2 n pi (1-pi)", false);
                    report.Write("\t\t      2 sqrt(2n) pi (1-pi)");
                    report.Write("\t\t------------------------------------------");
                    if (p_value < 0 || p_value > 1)
                    {
                        report.Write("WARNING:  P_VALUE IS OUT OF RANGE.");
                    }
                    report.Write(p_value < ALPHA ? "FAILURE" : "SUCCESS" + "\t\tp_value = " + p_value);
                    model.reports.Add(report.title, report);
                }
                return(new double[] { p_value });
            }
        }
Example #3
0
        /// <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[] expected_value = { 0,                 0,         0,         0, 0, 0, 5.2177052, 6.1962507, 7.1836656,
                                        8.1764248, 9.1723243, 10.170032, 11.168765,
                                        12.168070, 13.167693, 14.167488, 15.167379 };
            double[] variance = { 0,         0,     0,     0, 0, 0, 2.954, 3.125, 3.238, 3.311, 3.356, 3.384,
                                  3.401, 3.410, 3.416, 3.419, 3.421 };

            int K = (int)(n / L - (double)Q);    //number of test blocks

            int p = (int)Math.Pow(2, L);

            long[] T = new long[p];

            //initialization segment
            for (int i = 1; i <= Q; i++)
            {
                long decValue = 0;
                for (int j = 0; j < L; j++)
                {
                    decValue += model.epsilon[(i - 1) * L + j] * (long)Math.Pow(2, L - 1 - j);  //calculate decimal value of segment
                }
                T[decValue] = i;
            }

            //test segment
            double sum = 0;

            for (int i = Q + 1; i <= Q + K; i++)
            {
                long decValue = 0;
                for (int j = 0; j < L; j++)
                {
                    decValue += model.epsilon[(i - 1) * L + j] * (long)Math.Pow(2, L - 1 - j);  //calculate decimal value of segment
                }
                sum        += Math.Log(i - T[decValue]) / Math.Log(2);
                T[decValue] = i;
            }
            double phi = (double)(sum / (double)K);

            //forumla from 2.9.4(5)
            double c     = 0.7 - 0.8 / (double)L + (4 + 32 / (double)L) * Math.Pow(K, -3 / (double)L) / 15;
            double sigma = c * Math.Sqrt(variance[L] / (double)K);

            //calculate p_value
            double arg     = Math.Abs(phi - expected_value[L]) / (Math.Sqrt(2) * sigma);
            double p_value = Cephes.erfc(arg);

            if (printResults)
            {
                Report report = new Report("9: Maurer’s “Universal Statistical” Test");
                report.Write("\t\tUNIVERSAL STATISTICAL TEST");
                report.Write("\t\t--------------------------------------------");
                report.Write("\t\tCOMPUTATIONAL INFORMATION:");
                report.Write("\t\t--------------------------------------------");
                report.Write("\t\t(a) L         = " + L);
                report.Write("\t\t(b) Q         = " + Q);
                report.Write("\t\t(c) K         = " + K);
                report.Write("\t\t(d) sum       = " + sum);
                report.Write("\t\t(f) variance  = " + variance[L]);
                report.Write("\t\t(g) exp_value = " + expected_value[L]);
                report.Write("\t\t(h) phi       = " + phi);
                report.Write("\t\t(i) WARNING:  " + (n - (Q + K) * L) + " bits were discarded.");
                report.Write("\t\t-----------------------------------------");
                if (p_value < 0 || p_value > 1)
                {
                    report.Write("\t\tWARNING:  P_VALUE IS OUT OF RANGE");
                }
                report.Write((p_value < ALPHA ? "FAILURE" : "SUCCESS") + "\t\tp_value = " + p_value);
                model.reports.Add(report.title, report);
            }

            return(new double[] { p_value });
        }
Example #4
0
        /// <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 unsafe override double[] run(bool printResults)
        {
            double[] X = new double[n];


            for (int i = 0; i < n; i++)
            {
                X[i] = 2 * (int)model.epsilon[i] - 1; //map all bits in binary string (0->-1,1->1)
            }
            double[] m = new double[n / 2 + 1];
            //generate DFT of the binary string, using the unsafe functions implemented in C
            fixed(double *wsavePtr = &(new double[2 * n])[0])
            {
                fixed(int *ifacPtr = &(new int[15])[0])
                {
                    fixed(double *mPtr = &m[0])
                    {
                        fixed(double *XPtr = &X[0])
                        {
                            FFT.__ogg_fdrffti(n, wsavePtr, ifacPtr);        //init stage for work arrays
                            FFT.__ogg_fdrfftf(n, XPtr, wsavePtr, ifacPtr);  //apply FFT on data
                        }
                    }
                }
            }

            //get magnitude of the DFT produced (to convert complex domain to real domain)
            m[0] = Math.Sqrt(X[0] * X[0]);
            for (int i = 0; i < n / 2; i++)
            {
                if (2 * i + 2 >= X.Length)
                {
                    m[i + 1] = Math.Sqrt(Math.Pow(X[2 * i + 1], 2));
                }
                else
                {
                    m[i + 1] = Math.Sqrt(Math.Pow(X[2 * i + 1], 2) + Math.Pow(X[2 * i + 2], 2));
                }
            }

            int    N_l = 0;
            double T   = Math.Sqrt(2.995732274 * n); //calculate upper bound (T) (the 95% peak height threshold)

            for (int i = 0; i < n / 2; i++)
            {
                if (m[i] < T)
                {
                    N_l++;    //count observed number of peaks in |DFT| greater than T
                }
            }
            double N_0 = 0.95 * n / 2.0; //expected number of peaks
            double d   = (N_l - N_0) / Math.Sqrt(n / 4.0 * 0.95 * 0.05);

            //calculate p_value
            double p_value = Cephes.erfc(Math.Abs(d) / Math.Sqrt(2.0));

            if (printResults)
            {
                Report report = new Report("6: Discrete Fourier Transform (Sprectral) Test");
                report.Write("\t\t\t\tFFT TEST");
                report.Write("\t\t-------------------------------------------");
                report.Write("\t\tCOMPUTATIONAL INFORMATION:");
                report.Write("\t\t-------------------------------------------");
                report.Write("\t\t(-) Upper Bound= " + T);
                report.Write("\t\t(b) N_l        = " + N_l);
                report.Write("\t\t(c) N_o        = " + N_0);
                report.Write("\t\t(d) d          = " + d);
                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 = { -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            int J = 0;

            int[] S = new int[this.n];
            //compute partial sums
            S[0] = 2 * (int)this.model.epsilon[0] - 1;
            for (int i = 1; i < this.n; i++)
            {
                S[i] = S[i - 1] + 2 * this.model.epsilon[i] - 1;
                if (S[i] == 0)
                {
                    J++;
                }
            }
            if (S[this.n - 1] != 0)
            {
                J++;
            }

            Report report = new Report("15: Random Excursions Variant Test");

            if (printResults)
            {
                report.Write("\t\t\tRANDOM EXCURSIONS VARIANT 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)  = " + this.n);
            }

            double[] p_values   = new double[18];
            int      constraint = (int)Math.Max(0.005 * Math.Pow(this.n, 0.5), 500);

            if (J < constraint)
            {
                if (printResults)
                {
                    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 < 18; i++)
                {
                    report.Write(0.0.ToString());
                }
            }
            else
            {
                for (int p = 0; p < 18; p++)
                {
                    int x     = stateX[p];
                    int count = 0;
                    //count occurences of state x
                    for (int i = 0; i < this.n; i++)
                    {
                        if (S[i] == x)
                        {
                            count++;
                        }
                    }
                    //compute p_value
                    p_values[p] = Cephes.erfc(Math.Abs(count - J) / (Math.Sqrt(2.0 * J * (4.0 * Math.Abs(x) - 2))));

                    if (printResults)
                    {
                        if (p_values[p] < 0 || p_values[p] > 1)
                        {
                            report.Write("\t\t(b) WARNING: P_VALUE IS OUT OF RANGE.");
                        }
                        report.Write(p_values[p] < ALPHA ? "FAILURE" : "SUCCESS" + "\t\t");
                        report.Write("(x = " + x + ") Total visits = " + count + "; p-value = " + p_values[p]);
                        report.Write(p_values[p].ToString());
                    }
                }
            }
            if (printResults)
            {
                this.model.reports.Add(report.title, report);
            }
            return(p_values);
        }