Skip to content

Instantly share code, notes, and snippets.

@komasaru
Created November 26, 2017 03:25
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/e890f28be886da1dad29fb10323ad309 to your computer and use it in GitHub Desktop.
Save komasaru/e890f28be886da1dad29fb10323ad309 to your computer and use it in GitHub Desktop.
C++ source code to compute random number with Box-Muller algorithm.
/*********************************************
* ボックス=ミューラー法法による正規乱数生成
*********************************************/
#include <iostream> // for cout
#include <math.h> // for cos, sin
#include <cstdlib> // for rand()
#include <stdio.h> // for printf()
using namespace std;
/*
* 計算クラス
*/
class Calc
{
// 各種定数
static const int m = 10; // 平均
static const double s = 2.5; // 標準偏差
static const int n = 10000; // 発生させる乱数の個数
static const double pi = 3.1415926535; // 円周率
// 各種変数
double r1, r2; // 一様乱数
double x, y; // 正規乱数
int hist[m*2+1]; // 件数格納用配列
double scale; // ヒストグラム用スケール
int i, j; // ループインデックス
public:
// コンストラクタ
Calc();
// 正規乱数生成
void generateRndnum();
// 整数乱数
void rnd(double s, double m, double *x, double *y);
// 結果表示
void display();
};
/*
* コンストラクタ
*/
Calc::Calc()
{
// 件数格納用配列初期化
for (i = 0; i <= m * 2; i++) {
hist[i] = 0;
}
// ヒストグラム用スケール
scale = n / 100.0;
}
/*
* 正規乱数生成
*/
void Calc::generateRndnum()
{
// n 回乱数生成処理を繰り返す
for (i = 0; i < n; i++) {
// 整数乱数を2個生成
rnd(s, m, &x, &y);
// 生成された2個の整数乱数を件数格納用配列に格納
hist[(int)x]++;
hist[(int)y]++;
}
}
/*
* 整数乱数
*/
void Calc::rnd(double s, double m, double *x, double *y)
{
// 一様乱数
// ( 32Bitマシンでの (0,1] の実数乱数 )
r1 = rand() / 2147483647.1;
r2 = rand() / 2147483647.1;
// 正規乱数計算
*x = s * sqrt(-2 * log(r1)) * cos(2 * pi * r2) + m;
*y = s * sqrt(-2 * log(r1)) * sin(2 * pi * r2) + m;
}
/*
* 結果表示
*/
void Calc::display()
{
// 0 ~ m * 2 を表示
for (i = 0; i <= m * 2; i++) {
// 件数表示
printf("%3d:%4d | ", i, hist[i]);
// ヒストグラム表示
for (j = 1; j <= hist[i] / scale; j++)
printf("*");
printf("\n");
}
}
/*
* メイン処理
*/
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