rng/randomness_tests/runs_ones.cpp
2025-07-07 10:27:51 +01:00

77 lines
1.9 KiB
C++

#include "../rng.h"
#include "./rngtest.h"
#include "../math/incomplete_gamma.h"
#include "./runs_ones.h"
namespace splat {
runs_ones_test::runs_ones_test(std::vector<std::bitset<32>> &testData) : RNGTEST(testData) {
testPValue = runTest(data);
testPassed = testPValue > 0.01;
}
std::string runs_ones_test::getName(){
return "Runs of 1s";
}
double runs_ones_test::runTest(std::vector<std::bitset<32>> &data) {
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);
}
}