その2

回答は必要時応じて GNUPLOT で作った図や表を含め、LATEX により文章に
まとめよ。図には説明文 (caption) をつけ、x, y 軸のラベル、凡例も付けるよう
に。また使用したプログラムも一緒に提出すること。
問題 2:1 から 6 までの数字がでるサイコロを n 回ふり、6 が出る回数 S を記
録する。S は 0 から n までの値を取り得て、S は平均値である n/6 回を中心に分
布するはずである。この試行を m 回繰り返し行い、S の確率分布関数を以下のよ
うな C 言語による数値実験のプログラムを書いて調べよう。
(a)
(b)
(c)
(d)
(e)
(f)
要素の数 n の int 型の配列 A を用意する。全ての要素を 0 にしておく。
1 から 6 までの乱数を n 回発生させ、6 が出た回数 S を計算する。
配列 A の S 番目に格納されている数を+1 増加させる。
(b) ー (c) を m 回繰り返すと、S の頻度分布の配列 A が求まる。
m 回の試行を行っているので、配列 A 全体を m で割り規格化すると、
確率分布関数 P を得る。
S, P (X = S) をテキストファイルに書き出す。
このとき P は式 (8) のポアソン分布に従い、λ は S の期待値、すなわち n/6
に等しい。
P (X = S) = [λS exp(−λ)]/S!
(8)
乱数を発生させる方法は以下の例を参考にすること。rand()/(double)RAND_MAX
という関数で、[0,1] の乱数を得ることができる。ただし、起動する度に異なる乱
数を発生させるために、その時の時刻をもとにして初期化 (srand) するとよい。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int dice;
srand((unsigned)time(NULL));
/* 乱数を初期化する */
dice = (int)(rand()/(double)RAND_MAX*6 + 1); /*サイコロをふる*/
printf("%d\n",dice);
return 0;
}
(1) n の回数を 60 回のとき、m を 10 回、100 回、1,000 回にしてプログラムを
実行し、確率分布関数がどのように収束するか、GNUPLOT を用いて図示
せよ。
(2) m を十分大きくとり(例えば 10,000 回)、n を {6,12,24,42,60,120} 回として
確率分布関数を調べる。ポアソン分布関数は n が大きくなるとどのように
変化するかを図示せよ。このとき数値実験による結果と、式 (8) から得たポ
アソン確率を図上に示し、比較せよ。
注)P (X = S) を計算する際、S! は非常に大きな値になるため、S > 20 で
は 4 バイト長の整数では表現できないことに気をつけること。
1
(3) λ が大きい時、ポアソン分布は正規分布に近づく。n を {6,12,24,42,60,120}
回としたとき、数値実験で求めた確率分布の分散 (σ) をフィッティングによ
り求めよう。GNUPLOT でそれぞれ正規分布の式 (9) にフィットさせパラ
メーター a, µ, σ を求め、誤差とともに以下の表にまとめよ。
注)フィットがうまく収束しないときは、グラフから読み取ったおよその初
期値を与えてからフィットさせると良い。
[
f (x) = a exp
−(x − µ)2
2σ 2
]
(9)
Table 1: Fitting 結果
n
6
12
24
42
60
120
...
...
...
...
...
...
a
±
±
±
±
±
±
...
...
...
...
...
...
...
...
...
...
...
...
2
µ
±
±
±
±
±
±
...
...
...
...
...
...
...
...
...
...
...
...
σ
±
±
±
±
±
±
...
...
...
...
...
...