回答編集履歴
1
a
answer
CHANGED
@@ -60,4 +60,76 @@
|
|
60
60
|
## 他のアルゴリズム
|
61
61
|
|
62
62
|
正規分布を生成するアルゴリズムは他にもあるようです。
|
63
|
-
いろいろなアルゴリズムの実装が提供されている [Github](https://github.com/miloyip/normaldist-benchmark) を見つけたので、見てみると面白いかもしれません。
|
63
|
+
いろいろなアルゴリズムの実装が提供されている [Github](https://github.com/miloyip/normaldist-benchmark) を見つけたので、見てみると面白いかもしれません。
|
64
|
+
|
65
|
+
## 追記 グラフの生成方法について
|
66
|
+
|
67
|
+
以下のコードでテキストファイルに出力して、Python で読み込んで seaborn というライブラリでプロットしました。
|
68
|
+
Cだけでプロットする場合は gunplot とか使うことになるのでしょうけど、それでも結構面倒くさいです。Python だと1行できれいなグラフが出力できます。
|
69
|
+
|
70
|
+
```cpp
|
71
|
+
#include <fstream>
|
72
|
+
#include <math.h>
|
73
|
+
#include <stdio.h>
|
74
|
+
#include <stdlib.h>
|
75
|
+
|
76
|
+
/**
|
77
|
+
@brief [-1, 1] の一様分布に従う乱数を生成する。
|
78
|
+
@return [-1, 1] の一様分布に従う乱数
|
79
|
+
*/
|
80
|
+
double urand()
|
81
|
+
{
|
82
|
+
return (double)rand() / RAND_MAX * 2. - 1.;
|
83
|
+
}
|
84
|
+
|
85
|
+
double nrand()
|
86
|
+
{
|
87
|
+
// 1度に2個の正規分布に従う値 r1, r2 が得られるので
|
88
|
+
// 生成したときは r1、次に呼び出したときは r2 を返す。
|
89
|
+
static int sw = 0; // switch 用のフラグ
|
90
|
+
static double r1, r2, s;
|
91
|
+
|
92
|
+
if (sw == 0) {
|
93
|
+
sw = 1;
|
94
|
+
// (x, y) \in [-1, 1]^2 を満たす点をランダムに選ぶ。
|
95
|
+
do {
|
96
|
+
r1 = urand();
|
97
|
+
r2 = urand();
|
98
|
+
s = r1 * r1 + r2 * r2;
|
99
|
+
} while (s > 1.0 || s == 0.0);
|
100
|
+
|
101
|
+
// 正規分布に従う点に変換する。
|
102
|
+
s = sqrt(-2. * log(s) / s);
|
103
|
+
return r1 * s;
|
104
|
+
}
|
105
|
+
else {
|
106
|
+
sw = 0;
|
107
|
+
return r2 * s;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
int main()
|
112
|
+
{
|
113
|
+
int seed = 1234567;
|
114
|
+
|
115
|
+
srand(seed);
|
116
|
+
std::ofstream ofs("values.csv");
|
117
|
+
for (int i = 0; i < 1000; i++)
|
118
|
+
ofs << nrand() << std::endl;
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
ファイルを読み込んで、出力する。
|
123
|
+
|
124
|
+
```python
|
125
|
+
import seaborn as sns
|
126
|
+
import matplotlib.pyplot as plt
|
127
|
+
import numpy as np
|
128
|
+
|
129
|
+
array = np.loadtxt('values.csv')
|
130
|
+
print(array.shape)
|
131
|
+
|
132
|
+
sns.set()
|
133
|
+
ax = sns.distplot(array)
|
134
|
+
plt.show()
|
135
|
+
```
|