📄 randtest.c
字号:
/* ---------------------------------------------------------------------------- randtest.C mbwall 9may98 Copyright (c) 1998 Matthew Wall, all rights reserved DESCRIPTION: Program to test the random number generator in GAlib.---------------------------------------------------------------------------- */#include <stdio.h>#include <iostream.h>#include <string.h>#include <math.h>#include <ga/garandom.h>static const int HIST_SIZE=501;static const int NFLIPS=10000;static const long int NUM_CHECKS=1000000L;static const int RCHI=100;intmain(int argc, char **argv){ cerr << "This program checks the random number generators in GAlib.\n"; cerr << "These are not rigorous statistical tests, but they should\n"; cerr << "give you a quick indication of whether or not the library is\n"; cerr << "working properly. Command-line options include:\n\n"; cerr << " [+-]chi - do the chi square test (default)\n"; cerr << " [+-]hist - do the histogram tests. Histograms should be\n"; cerr << " nearlyflat, i.e. each number has an equal chance\n"; cerr << " of beingchosen.\n"; cerr << " [+-]bnds - do the bounds tests. All numbers generated\n"; cerr << " should be within the limits specified in the\n"; cerr << " test.\n"; cerr << " [+-]means - do the means tests. A few thousand invocations\n"; cerr << " of each random number function are made, and the\n"; cerr << " averages of these calls are displayed with the\n"; cerr << " number that should have been found.\n"; cerr << " seed n - specify the seed number to use for the RNG. You\n"; cerr << " should get the same results every time if you\n"; cerr << " specify the same seed every time. A seed of 0\n"; cerr << " tells the lib to pick its own seed based upon the\n"; cerr << " current time.\n"; cerr << "\n"; cerr.flush(); int dohist = 0; int dobnds = 0; int domeans = 0; int dochisq = 1; int seed = 0; int i; for(i=1; i<argc; i++){ if(strcmp("seed", argv[i]) == 0){ if(++i >= argc) { cerr << "You must enter a number when specifying a random seed.\n"; exit(1); } else { seed = atoi(argv[i]); } } else if(strcmp("+chi", argv[i]) == 0){ dochisq = 1; } else if(strcmp("-chi", argv[i]) == 0){ dochisq = 0; } else if(strcmp("+hist", argv[i]) == 0){ dohist = 1; } else if(strcmp("-hist", argv[i]) == 0){ dohist = 0; } else if(strcmp("+bnds", argv[i]) == 0){ dobnds = 1; } else if(strcmp("-bnds", argv[i]) == 0){ dobnds = 0; } else if(strcmp("+means", argv[i]) == 0){ domeans = 1; } else if(strcmp("-means", argv[i]) == 0){ domeans = 0; } }// Tell us which RNG we're using... cout << argv[0] << ": Random Number Test\n"; cout << "Using the " << GAGetRNG() << " random number generator (RNG).\n"; // initialize the RNG by calling the seed routine with our seed if(seed) cout << "Using specified random seed " << seed << "\n"; GARandomSeed(seed); cout << "Library thinks the random seed is " << GAGetRandomSeed() << "\n"; // the basic chi square test for randomness of a RNG // must do it more than once since it might be wrong about one in ten // times. The error is r*t/N - N and should be within 2*sqrt(r) of r. if(dochisq) { cout << "\n"; cerr << "chi-square test...\n"; cout << "running the chi-square test for randomness of the RNG...\n"; cout << " (there will be some failures of the chi-square test)\n"; int ii; double elimit = 2*sqrt((double)RCHI); double chisq = 0.0; long int NCHI=1000; // NCHI should be >= 10 * RCHI long int f[RCHI]; cerr << " integer test (" << NCHI << ")...\n"; cout << " integer test (" << NCHI << "): chi-squared should be within "; cout << elimit << " of " << RCHI << "\n"; cout.flush(); for(ii=0; ii<10; ii++) { memset(f, 0, RCHI * sizeof(long int)); for(i=0; i<NCHI; i++) f[GARandomInt(0,RCHI-1)]++; for(i=0; i<RCHI; i++) chisq += ((double)f[i] - (double)NCHI / (double)RCHI) * ((double)f[i] - (double)NCHI / (double)RCHI); chisq *= (double)RCHI / (double)NCHI; cout << " run #" << ii << "\t" << chisq << "\t"; if(fabs(chisq - RCHI) > elimit) cout << "***failed***"; cout << "\n"; } cout.flush(); NCHI = 10000; cerr << " integer test (" << NCHI << ")...\n"; cout << " integer test (" << NCHI << "): chi-squared should be within "; cout << elimit << " of " << RCHI << "\n"; cout.flush(); for(ii=0; ii<10; ii++) { memset(f, 0, RCHI * sizeof(long int)); long int i; long int t; for(i=0; i<NCHI; i++) f[GARandomInt(0,RCHI-1)]++; for(i=0, t=0; i<RCHI; i++) t += f[i] * f[i]; chisq = (double)RCHI*(double)t/(double)NCHI - (double)NCHI; cout << " run #" << ii << "\t" << chisq << "\t"; if(fabs(chisq - RCHI) > elimit) cout << "***failed***"; cout << "\n"; } cout.flush(); NCHI = 10000; cerr << " integer test (" << NCHI << ")...\n"; cout << " integer test (" << NCHI << "): chi-squared should be within "; cout << elimit << " of " << RCHI << "\n"; cout.flush(); for(ii=0; ii<10; ii++) { memset(f, 0, RCHI * sizeof(long int)); long int i; long int t; for(i=0; i<NCHI; i++) f[GARandomInt(0,RCHI-1)]++; for(i=0, t=0; i<RCHI; i++) t += f[i] * f[i]; chisq = (double)RCHI*(double)t/(double)NCHI - (double)NCHI; cout << " run #" << ii << "\t" << chisq << "\t"; if(fabs(chisq - RCHI) > elimit) cout << "***failed***"; cout << "\n"; } cout.flush(); NCHI = 100000; cerr << " integer test (" << NCHI << ")...\n"; cout << " integer test (" << NCHI << "): chi-squared should be within "; cout << elimit << " of " << RCHI << "\n"; cout.flush(); for(ii=0; ii<10; ii++) { memset(f, 0, RCHI * sizeof(long int)); long int i; long int t; for(i=0; i<NCHI; i++) f[GARandomInt(0,RCHI-1)]++; for(i=0, t=0; i<RCHI; i++) t += f[i] * f[i]; chisq = (double)RCHI*(double)t/(double)NCHI - (double)NCHI; cout << " run #" << ii << "\t" << chisq << "\t"; if(fabs(chisq - RCHI) > elimit) cout << "***failed***"; cout << "\n"; } cout.flush(); } // histograms of the tests if(dohist) { cout << "\n"; cerr << "histograms...\n"; cout << "plotting histograms of calls to random number functions...\n"; int i, j, histogram[HIST_SIZE]; memset(histogram, 0, HIST_SIZE*sizeof(int)); cout << "\n100 random integers in [0, 1] with GARandomInt():\n"; for(i=0; i<100; i++) histogram[GARandomInt()]++; for(i=0; i<=1; i++){ cout << i << "\t"; for(j=0; j<histogram[i]; j++) cout << "."; cout << "\n"; } cout.flush(); memset(histogram, 0, HIST_SIZE*sizeof(int)); cout << "\n100 random integers in [0, 1] with GARandomInt(0,1):\n"; for(i=0; i<100; i++) histogram[GARandomInt(0,1)]++; for(i=0; i<=1; i++){ cout << i << "\t"; for(j=0; j<histogram[i]; j++) cout << "."; cout << "\n"; } cout.flush(); memset(histogram, 0, HIST_SIZE*sizeof(int)); cout<<"\n10000 random integers in [-20, -10] with GARandomInt(-20,-10):\n"; for(i=0; i<10000; i++) histogram[GARandomInt(-20,-10)+20]++; for(i=0; i<=10; i++){ cout << (i-20) << "\t"; for(j=0; j<histogram[i]; j++) if(j%20 == 0) cout << "."; cout << "\n"; } cout.flush(); memset(histogram, 0, HIST_SIZE*sizeof(int)); cout << "\n300 random integers in [0, 5] with GARandomInt(0,5):\n"; for(i=0; i<300; i++) histogram[GARandomInt(0,5)]++; for(i=0; i<=5; i++){ cout << i << "\t"; for(j=0; j<histogram[i]; j++) cout << "."; cout << "\n"; } cout.flush(); memset(histogram, 0, HIST_SIZE*sizeof(int)); cout << "\n10000 random integers in [0, 100] with GARandomInt(0,100):\n"; for(i=0; i<10000; i++) histogram[GARandomInt(0,100)]++; for(i=0; i<=100; i++){ cout << i << "\t"; for(j=0; j<histogram[i]; j++) if(j%2 == 0) cout << "."; cout << "\n"; } cout.flush(); memset(histogram, 0, HIST_SIZE*sizeof(int)); cout<<"\n10000 random integers in [-10, 100] with GARandomInt(-10,100):\n"; for(i=0; i<10000; i++) histogram[GARandomInt(-10,100)+10]++; for(i=0; i<=110; i++){ cout << (i-10) << "\t"; for(j=0; j<histogram[i]; j++) if(j%2 == 0) cout << "."; cout << "\n"; } cout.flush(); }// calculate means on various types if(domeans) { cout << "\n"; cerr << "means test...\n"; cout << "check for averages of repeated biased coin tosses...\n"; int i; double counter, mean; counter = 0; cout << NFLIPS << " calls to GARandomBit()\t\t"; for(i=0; i<NFLIPS; i++) counter += GARandomBit(); cout << counter << " hits (should be about " << 0.5*NFLIPS << ")\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomInt()\t\t"; for(i=0; i<NFLIPS; i++) counter += GARandomInt(); mean = counter/(double)NFLIPS; cout << mean << " (should be about 0.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomInt(0,5)\t\t"; for(i=0; i<NFLIPS; i++) counter += GARandomInt(0,5); mean = counter/(double)NFLIPS; cout << mean << " (should be about 2.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomFloat()\t\t"; for(i=0; i<NFLIPS; i++) counter += GARandomFloat(); mean = counter/(double)NFLIPS; cout << mean << " (should be about 0.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomFloat(0,5)\t"; for(i=0; i<NFLIPS; i++) counter += GARandomFloat(0,5); mean = counter/(double)NFLIPS; cout << mean << " (should be about 2.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomFloat(-10,-5)\t"; for(i=0; i<NFLIPS; i++) counter += GARandomFloat(-10,-5); mean = counter/(double)NFLIPS; cout << mean << " (should be about -7.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomFloat(-10,10)\t"; for(i=0; i<NFLIPS; i++) counter += GARandomFloat(-10,10); mean = counter/(double)NFLIPS; cout << mean << " (should be about 0.0)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomDouble()\t\t"; for(i=0; i<NFLIPS; i++) counter += GARandomDouble(); mean = counter/(double)NFLIPS; cout << mean << " (should be about 0.5)\n"; cout.flush(); counter = 0; cout << NFLIPS << " calls to GARandomDouble(0,2)\t"; for(i=0; i<NFLIPS; i++) counter += GARandomDouble(0,2); mean = counter/(double)NFLIPS; cout << mean << " (should be about 1.0)\n"; cout.flush();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -