// // mainMPI.cpp // Tests Pohlig-Hellman pseuodrandom number generator randomph() // // Created by Paul Beale on 12/15/14. // Copyright (c) 2014 Paul Beale. All rights reserved. // // Performs multiple processor statistical tests of randomph() using MPI // #include "randomph.h" #include #include #include #include #include #include #define MPI using namespace std; // Return the one-sided p-value from a chi square test for a n-bin histogram // from a uniform distribution with a large number of degreesoffreedom=n-1. // In the large n limit, the distribution approaches a gaussian with // average = degreesoffreedom and variance 2*degreesoffreedom. // Uses complementary error function erfc() to determine p-value. double ChiSquareLargeNPValue(int* histogram,int n) { double degreesoffreedom=n-1; double average=0.0,chisqr=0.0,pvalue,sigma; for (int i=0;i ip) countpvalues[ip]++; pvalue=ChiSquareLargeNPValue(hist2d,1048576); log10pvalue = log10(pvalue); countpvalues[0]++; for (int ip=1;ip<=8;ip++) if (-log10pvalue > ip) countpvalues[ip]++; pvalue = ChiSquareLargeNPValue(hist3d,1000000); log10pvalue = log10(pvalue); countpvalues[0]++; for (int ip=1;ip<=8;ip++) if (-log10pvalue > ip) countpvalues[ip]++; pvalue = ChiSquareLargeNPValue(hist4d,1048576); log10pvalue = log10(pvalue); countpvalues[0]++; for (int ip=1;ip<=8;ip++) if (-log10pvalue > ip) countpvalues[ip]++; pvalue = ChiSquareLargeNPValue(hist5d,1048576); log10pvalue = log10(pvalue); countpvalues[0]++; for (int ip=1;ip<=8;ip++) if (-log10pvalue > ip) countpvalues[ip]++; } // get final state of the generator in each process and // compare to the predicted state given in eqn. (7) in the reference above getparameters_randomph(integerparameters); unsigned long mf, sf, cf, q, r; q=(5*ntests*nrounds)/(p0-1); r=(5*ntests*nrounds)%(p0-1); sf=s0; mf=(p0*(p0-1)/2)%n0; mf= (q*mf)%n0; mf=(mf+m0)%n0; // m_{q (p-1)} = (m_0 + q p(p-1)/2 ) mod n // step forward r steps for (int j=1;j<=r;j++) { sf=(a0*sf)%p0; mf=(mf+sf)%n0; } cf=powermod(mf,e0,n0); cout << "final state of the generator in process " <0 back to processid=0 #ifdef MPI if (processid != 0) MPI_Send(countpvalues, 9, MPI_LONG, 0, 0, MPI_COMM_WORLD); #endif if (processid==0) { long mastercountpvalues[9]; for (int i=0;i<9;i++) mastercountpvalues[i]=countpvalues[i]; #ifdef MPI // Collect p-value counts from all processid>0 for (int event=0;event