初学者Python蒙特卡洛模拟

时间:2019-01-28 11:05:01

标签: python montecarlo

我是Python的初学者,正在通过我们的讲师设置的练习进行工作。我正在为这个问题而苦苦挣扎。

在Python编辑器中,编写蒙特卡洛模拟,以估计数字π的值。 具体来说,请按照下列步骤操作: A.产生两个数组,一个称为x,一个称为y,每个数组包含100个元素, 它们是介于-1和1之间的随机且均匀分布的实数。 B.将y和x绘制为图中的点。相应地标记轴。 C.写下一个数学表达式,该数学表达式定义哪些(x,y)对数据点 位于半径为1的圆中,并以图形的(0,0)原点为中心。 D.使用布尔型遮罩识别圆内的点,并在其中 您已经在B中绘制的数据点顶部的颜色和标记大小不同。

这就是我目前的状况。

import numpy as np
import math
import matplotlib.pyplot as plt
np.random.seed(12345)
x = np.random.uniform(-1,1,100) 
y = np.random.uniform(-1,1,100) 
plt.plot(x,y) //this works


for i in x:
    newarray = (1>math.sqrt(y[i]*y[i] + x[i]*x[i]))
plt.plot(newarray)

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

如注释中所指出,您的代码错误为for i in x应该为for i in xrange(len(x))

如果您要按照声明中的说明实际使用布尔掩码,则可以执行以下操作

    import pandas as pd
    allpoints = pd.DataFrame({'x':x, 'y':y})

    # this is your boolean mask
    mask = pow(allpoints.x, 2) + pow(allpoints.y, 2) < 1
    circlepoints = allpoints[mask]

    plt.scatter(allpoints.x, allpoints.y)
    plt.scatter(circlepoints.x, circlepoints.y)

将点的数量增加到10000,您将获得类似这样的信息 scatter plot

要估算PI,您可以使用著名的蒙特卡洛推导法

    >>> n = 10000
    >>> ( len(circlepoints) * 4 ) / float(n)
    <<< 3.1464

答案 1 :(得分:2)

您已接近解决方案。我稍微重塑了您的MCVE:

import numpy as np
import math
import matplotlib.pyplot as plt

np.random.seed(12345)

N = 10000
x = np.random.uniform(-1, 1, N) 
y = np.random.uniform(-1, 1, N) 

现在,我们计算一个在这种情况下有意义的准则,例如点到原点的距离:

d = x**2 + y**2

然后我们使用Boolean Indexing来区分单位圆内和外的点:

q = (d <= 1)

这是蒙特卡洛假设。我们假设圆和平面U(-1,1)xU(-1,1)中均匀分布点的比率代表单位圆和正方形的面积。然后,我们可以根据“圆/平方”内的点的比率对pi = 4*(Ac/As)进行统计评估。这导致:

pi = 4*q.sum()/q.size # 3.1464

最后我们绘制结果:

fig, axe = plt.subplots()
axe.plot(x[q], y[q], '.', color='green', label=r'$d \leq 1$')
axe.plot(x[~q], y[~q], '.', color='red', label=r'$d > 1$')
axe.set_aspect('equal')
axe.set_title(r'Monte Carlo: $\pi$ Estimation')
axe.set_xlabel('$x$')
axe.set_ylabel('$y$')
axe.legend(bbox_to_anchor=(1, 1), loc='upper left')
fig.savefig('MonteCarlo.png', dpi=120)

它输出:

enter image description here