『ゼロからできるMCMC』 Chapter 2をJuliaで
最終更新:2020/11/7
『ゼロからできるMCMC』 Chapter 2のコードを, 練習を兼ねてJuliaで書いてみました. 詳細なことを書くと著作権的にだめな気もするので, 解説などはありません.
Julia Version 1.5.0
一様乱数を用いた円周率の計算 ( p.20 )
モンテカルロ法で円周率を求める.
Julia
- using Distributions
- using Random
- Random.seed!(12345)
- niter = 10000;
- xx = rand(Uniform(), niter);
- yy = rand(Uniform(), niter);
- 4*sum(@. (xx^2 + yy^2) < 1.0) / niter
- niter = 100で3.20
- niter = 1000で3.084
- niter = 10000で3.1064
- niter = 100000で3.1538
一様乱数を用いた積分 ( p.23 )
モンテカルロ法で円周率を求める.
Julia
- using Distributions
- using Random: seed!
- seed!(12345)
- niter = 1000;
- xx = rand(Uniform(), niter);
- res = sum(@. sqrt(1 - xx^2))/niter;
- println("$(4*res)")
- niter = 100で3.178
- niter = 1000で3.104
- niter = 10000で3.133
- niter = 100000で3.145
期待値と積分 ( p.30 )
モンテカルロ法で三次元球 ( 半径1 ) の体積を求める.
Julia
- using Random: seed!
- using BenchmarkTools
- seed!(12345)
- function main(niter)
- n_in = zero(Int64)
- z = 0.0
- for _ in 1:niter
- x, y = rand(), rand()
- if x^2 + y^2 ≤ 1
- n_in += 1
- z += sqrt(1.0-x*x-y*y)
- end
- end
- println(2π*z/n_in)
- end
- # result
- julia> @btime main(10^5)
- 922.678 μs (0 allocations: 0 bytes)
- 4.180887719852872
函数にした方がはやいらしいので. 早いのかは今ひとつわからないけど, 0 allocationsなのはいいことやと思う.
ボックスミュラー法を用いた⟨x2⟩ の計算 ( p.33 )
ボックスミュラー法を用いて⟨x2⟩ を計算してみる. 1になるはずである.
Julia
- using Random: seed!
- using BenchmarkTools
- seed!(12345)
- function main(niter)
- z = 0.0
- for _ in 1:niter
- p, q = rand(), rand()
- x = sqrt(-2log(p))*cos(2π*q)
- z += x*x
- end
- z/niter
- end
- # result
- julia> @btime main(10^5)
- 2.394 ms (0 allocations: 0 bytes)
- 0.9918424337202467
だいたい1になった.
函数から外すとどれくらい遅くなるのかと思い計算してみた. niter=108 で, 函数化すると2.5秒, 函数から外すと11秒であった.