回答編集履歴

1

a

2018/10/10 09:45

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -123,3 +123,147 @@
123
123
  正規分布を生成するアルゴリズムは他にもあるようです。
124
124
 
125
125
  いろいろなアルゴリズムの実装が提供されている [Github](https://github.com/miloyip/normaldist-benchmark) を見つけたので、見てみると面白いかもしれません。
126
+
127
+
128
+
129
+ ## 追記 グラフの生成方法について
130
+
131
+
132
+
133
+ 以下のコードでテキストファイルに出力して、Python で読み込んで seaborn というライブラリでプロットしました。
134
+
135
+ Cだけでプロットする場合は gunplot とか使うことになるのでしょうけど、それでも結構面倒くさいです。Python だと1行できれいなグラフが出力できます。
136
+
137
+
138
+
139
+ ```cpp
140
+
141
+ #include <fstream>
142
+
143
+ #include <math.h>
144
+
145
+ #include <stdio.h>
146
+
147
+ #include <stdlib.h>
148
+
149
+
150
+
151
+ /**
152
+
153
+ @brief [-1, 1] の一様分布に従う乱数を生成する。
154
+
155
+ @return [-1, 1] の一様分布に従う乱数
156
+
157
+ */
158
+
159
+ double urand()
160
+
161
+ {
162
+
163
+ return (double)rand() / RAND_MAX * 2. - 1.;
164
+
165
+ }
166
+
167
+
168
+
169
+ double nrand()
170
+
171
+ {
172
+
173
+ // 1度に2個の正規分布に従う値 r1, r2 が得られるので
174
+
175
+ // 生成したときは r1、次に呼び出したときは r2 を返す。
176
+
177
+ static int sw = 0; // switch 用のフラグ
178
+
179
+ static double r1, r2, s;
180
+
181
+
182
+
183
+ if (sw == 0) {
184
+
185
+ sw = 1;
186
+
187
+ // (x, y) \in [-1, 1]^2 を満たす点をランダムに選ぶ。
188
+
189
+ do {
190
+
191
+ r1 = urand();
192
+
193
+ r2 = urand();
194
+
195
+ s = r1 * r1 + r2 * r2;
196
+
197
+ } while (s > 1.0 || s == 0.0);
198
+
199
+
200
+
201
+ // 正規分布に従う点に変換する。
202
+
203
+ s = sqrt(-2. * log(s) / s);
204
+
205
+ return r1 * s;
206
+
207
+ }
208
+
209
+ else {
210
+
211
+ sw = 0;
212
+
213
+ return r2 * s;
214
+
215
+ }
216
+
217
+ }
218
+
219
+
220
+
221
+ int main()
222
+
223
+ {
224
+
225
+ int seed = 1234567;
226
+
227
+
228
+
229
+ srand(seed);
230
+
231
+ std::ofstream ofs("values.csv");
232
+
233
+ for (int i = 0; i < 1000; i++)
234
+
235
+ ofs << nrand() << std::endl;
236
+
237
+ }
238
+
239
+ ```
240
+
241
+
242
+
243
+ ファイルを読み込んで、出力する。
244
+
245
+
246
+
247
+ ```python
248
+
249
+ import seaborn as sns
250
+
251
+ import matplotlib.pyplot as plt
252
+
253
+ import numpy as np
254
+
255
+
256
+
257
+ array = np.loadtxt('values.csv')
258
+
259
+ print(array.shape)
260
+
261
+
262
+
263
+ sns.set()
264
+
265
+ ax = sns.distplot(array)
266
+
267
+ plt.show()
268
+
269
+ ```