78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
#include "../rng.h"
|
|
#include "./rngtest.h"
|
|
#include "../math/incomplete_gamma.cpp"
|
|
#define vecdebug(list) for(auto vecdebugitem : list){ std::cout << vecdebugitem <<","; }std::cout << "\n";
|
|
|
|
|
|
|
|
namespace splat {
|
|
class runs_ones_test : public RNGTEST {
|
|
public:
|
|
runs_ones_test(std::vector<std::bitset<32>> &testData) : RNGTEST(testData) {
|
|
testPValue = runTest(data);
|
|
testPassed = testPValue > 0.01;
|
|
}
|
|
std::string getName() override {
|
|
return "Runs of 1s";
|
|
}
|
|
double runTest(std::vector<std::bitset<32>> &data) override {
|
|
long long totalSize = data.size() * 32;
|
|
|
|
if(totalSize < 750000){
|
|
std::cout << "Error, runs of ones test requires more than 750K bits of input\n";
|
|
return 0;
|
|
}
|
|
// we do it with M=10^4 here
|
|
|
|
std::vector<double> counts(7,0);
|
|
|
|
double chunks = totalSize / 10000;
|
|
|
|
for(int chunkIndex=0; chunkIndex<chunks; chunkIndex++){
|
|
|
|
int longestRun = 0;
|
|
|
|
int ones = 0;
|
|
|
|
for(int i=0; i<10000; i++){
|
|
long long index = chunkIndex*10000 + i;
|
|
int dataIndex = (index / 32);
|
|
int bitIndex = (index % 32);
|
|
|
|
if(data[dataIndex][bitIndex]){
|
|
ones++;
|
|
}else{
|
|
if(ones>longestRun) longestRun = ones;
|
|
ones = 0;
|
|
}
|
|
}
|
|
|
|
if(longestRun <=10){
|
|
counts[0]++;
|
|
}else if(longestRun>=16){
|
|
counts[6]++;
|
|
}else{
|
|
counts[longestRun-10]++;
|
|
}
|
|
}
|
|
|
|
double x2 = 0;
|
|
|
|
std::vector<double> probabilities = {
|
|
0.0882,
|
|
0.2092,
|
|
0.2483,
|
|
0.1933,
|
|
0.1208,
|
|
0.0675,
|
|
0.0727
|
|
};
|
|
|
|
for(int i=0; i<7; i++){
|
|
x2 += std::pow((counts[i] - (chunks * probabilities[i])),2.0) /(chunks * probabilities[i]);
|
|
|
|
}
|
|
return igamc(3, x2/2.0);
|
|
}
|
|
};
|
|
} |