モンテカルロ法において粒子に対する精度の話になったときに「えー,粒子数をとしたとき精度はでしょー」という話を聞いたときから,モンテカルロ法の精度が気になってはいたんですよね.いったい精度がとはどういう状態を指すのか.
というわけで今回調べてみました.(モンテカルロ法自体については,itさんの素晴らしい解説があるのでそちらに丸投げで ゚ω゚) つ○)
さて,精度がというのは,粒子数がのモンテカルロ法の解を,真の解をしたとき,
が成り立つことかなー,とか思ってたんですけど,これだと左辺はnに対して単調減少なのに右辺は単調増加でおかしなことになるわなー,ということで,こうか,と.
仮説:モンテカルロ法の精度がであるとは,次の式が成り立つことである.
つまり,Log10(粒子数)に対して誤差()をプロットしたときに,
この曲線に乗るようにプロット点がくるのかなぁと.
さて,実際に粒子数を増やしてを順次求めるプログラムを書いてみる.
Program MonteCarlo implicit none real(8) :: pi, seed, seed2, test, ans,error,fe,re,nr real(8),dimension(100000000) :: x,y integer :: i,j,k,ntest,nmax,sum,fntest pi = 3.14159265358979d0 call random_number(x) call random_number(y) write(*,'(A16,A9,A16,A16,A16)'),"squre of n ratio","ntest","answer","error","error ratio" do i = 1,8 ntest = 10 ** i sum = 0 error = 0.d0 do j = 1,ntest test = x(j) ** 2 + y(j) ** 2 if (test < 1.d0) sum = sum + 1 end do ans = 4.d0 * dble(sum) / dble(ntest) error = ans - pi error = abs(error) if(i == 1) then fe = error re = fe / fe fntest = ntest else re = error / fe end if nr = dble(ntest) / (fntest) nr = sqrt(nr) write(*,'(f16.4,I9,f16.8,f16.8,f16.8)'),nr,ntest,ans,error,re end do end Program MonteCarlo
うーん,良く分からんなー,ということでLog10(粒子数) - 誤差曲線を取ってみると,
となって,まぁ乗ってるのかなぁ,と思わなくもないけど粒子数が多くなると桁が小さくなって良く分からない.
しょうがないから誤差でも両対数(ただし底は全部10である)を取ってみる.
グラフの意味としては,正の方向に行けば行くほど誤差が大きいってことですー.
つまり,このグラフは粒子数が大きくなればなるほど,誤差が小さくなっていることを表しています.
で,仮説が正しければこれは次のグラフに乗るはず.
で,重ね合わせてみると,
お,けっこう綺麗に乗ってるじゃん,ということで,
仮説:モンテカルロ法において,粒子数を,粒子数での解を,真の解をとしたとき,精度がであるとは,次の式が成り立つことである.
がある程度正しいのかなーという結論に至りました.
多分ねー,もう少し拡張できて,
任意の粒子数に対して,
ぐらいが成り立つのではないか,と思ったりもする.