Skip to content

Instantly share code, notes, and snippets.

@komasaru
Created November 24, 2017 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komasaru/7bc2cbd6c5da09ba7c237529b0cf3ae3 to your computer and use it in GitHub Desktop.
Save komasaru/7bc2cbd6c5da09ba7c237529b0cf3ae3 to your computer and use it in GitHub Desktop.
C++ source code to test for uniformity of random number with Chi-square algorithm.
/*********************************************
* 線形合同法による一様乱数の一様性検証
*********************************************/
#include <iostream> // for cout
#include <math.h> // for pow
#include <stdio.h> // for printf
using namespace std;
/*
* 計算クラス
*/
class Calc
{
// 宣言
static const int a = 1103515245; // 乗数
static const int c = 12345; // 加数
static const unsigned int m = pow(2, 31); // 法(2の31乗)
static const int n = 1000; // 発生させる乱数の個数
int r = 12345; // 乱数の種の初期値
static const int m_max = 10; // 整数乱数の範囲
double f = n / m_max; // 期待値
double s = 40.0 / f; // ヒストグラム用スケール
int rank; // 整数乱数
int hist[m_max+1]; // 件数格納用配列
double e = 0.0; // カイ2乗検定初期値
int i, j; // ループインデックス
public:
// コンストラクタ
Calc();
// 一様乱数生成
void generateRndnum();
// 1 ~ 10 の整数乱数
int rnd();
// 結果表示
void display();
};
/*
* コンストラクタ
*/
Calc::Calc()
{
// 件数格納用配列初期化
for (i = 1; i <= m_max; i++) {
hist[i] = 0;
}
}
/*
* 一様乱数生成
*/
void Calc::generateRndnum()
{
for (i = 0; i < n; i++) {
rank = rnd(); // 1 ~ 10 の整数乱数
hist[rank]++; // 1 ~ 10 別にカウント
}
}
/*
* 1 ~ 10 の整数乱数
*/
int Calc::rnd()
{
// 0 ~ 2の31乗 未満の整数乱数
r = (a * r + c) % m;
// 0 ~ 1 未満の実数乱数に 10 を乗じて 1 を加えることで
// 1 ~ 10 の整数乱数にする
return m_max * (r / (m - 0.9)) + 1;
}
/*
* 結果表示
*/
void Calc::display()
{
for (i = 1; i <= m_max; i++) {
// 件数表示
printf("%3d:%3d ", i, hist[i]);
// ヒストグラム表示
for (j = 0; j < hist[i] * s; j++)
printf("*");
printf("\n");
// カイ2乗検定
e = e + (double)(hist[i] - f) * (hist[i] - f) / f;
}
// カイ2乗検定値表示
printf("χ2 = %f\n", e);
}
/*
* メイン処理
*/
int main()
{
try
{
// 計算クラスインスタンス化
Calc objCalc;
// 一様乱数生成
objCalc.generateRndnum();
// 結果表示
objCalc.display();
}
catch (...) {
cout << "例外発生!" << endl;
return -1;
}
// 正常終了
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment