モンテカルロ法とは乱数を用いて行うシミュレーションの手法のことです。本記事の内容は、ググったら出てくるような内容をPythonを用いて実行できる雛形コードを載せました。本コードの特徴は次の2つです。
1. 乱数を一様乱数の場合と、正規乱数の場合で実行できる仕様にしました
2. 計算過程をmatplotlibのグラフ描画し、その動画をmp4ファイルに保存する仕様にしました。特に、matplotlibのグラフテクニックとして、軸目盛の間隔や表記角度などを盛り込んでいます。
▼本コードの実施例は下記リンク先です (動画編集には別ソフトを使用しています)
www.youtube.com
■本プログラム
import math
import random
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.ticker as ticker
import matplotlib.animation as animation
def random_uniform_func(n):
min = -1 * my_radius
max = my_radius
a = random.uniform(min, max)
b = random.uniform(min, max)
return (a, b)
def random_normalvariate_func(n):
mu = 0
sigma = my_radius/3
a = random.normalvariate(mu, sigma)
b = random.normalvariate(mu, sigma)
return (a, b)
def update_ani(i, X, Y, pai_list):
if (i % 20) == 0:
print(i, '/', N)
ax.set_title(str(i) + '/' + str(N) + ' ' + 'pai=' + str(pai_list[i]), fontsize = my_fontsize)
if math.sqrt(X[i]*X[i] + Y[i]*Y[i]) <= my_radius:
ax.scatter(X[i], Y[i], s=80, color='b', marker='.')
else:
ax.scatter(X[i], Y[i], s=80, color='r', marker='.')
def main():
global ax
my_random_func_list = [random_uniform_func, random_normalvariate_func]
for k, my_random_func in enumerate(my_random_func_list):
fig, ax = plt.subplots()
ax.scatter([], [])
myCircle = patches.Circle(xy=(0, 0), radius=my_radius, ec='k', fill=False)
ax.add_patch(myCircle)
tick_spacing = my_radius/2
ax.set_xlabel("x", fontsize = my_fontsize)
ax.set_xlim(-1*my_radius, my_radius)
x_ticklabels = ax.get_xticklabels()
plt.setp(x_ticklabels, rotation=45, fontsize=my_fontsize)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
ax.set_ylabel("y", fontsize = my_fontsize)
ax.set_ylim(-1*my_radius, my_radius)
y_ticklabels = ax.get_yticklabels()
plt.setp(y_ticklabels, rotation=0, fontsize=my_fontsize)
ax.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
ax.grid()
ax.set_aspect('equal')
plt.tight_layout()
cnt = 0
X = []
Y = []
pai_list = []
for n in range(N):
x, y = my_random_func(n)
if math.sqrt(x*x + y*y) <= my_radius:
cnt = cnt + 1
X.append(x)
Y.append(y)
P = cnt / (n+1)
calc_pai = 4 * P
pai_list.append(round(calc_pai, 2))
print("pai:", calc_pai)
ani = animation.FuncAnimation(fig,
update_ani,
frames = N,
interval = 200,
blit = False,
repeat = False,
fargs = (X,Y, pai_list))
ani.save('anim_' + str(k) + '_N' + str(N) + '_pai' + str(calc_pai) + '.mp4', writer='ffmpeg', fps=30)
plt.close("all")
if __name__ == '__main__':
my_radius = 10
my_diameter = my_radius * 2
my_fontsize = 15
N = 100
random.seed(200727)
main()
print("finished")
以上
<広告>
リンク