While 循环比矢量化函数更有效

While loop more efficient than vectorised function

提问人:PortorogasDS 提问时间:11/11/2023 最后编辑:PortorogasDS 更新时间:11/11/2023 访问量:88

问:

我正在尝试使用随机数估计π值。最初,我使用了一种方法,即生成 1,000,000 个随机数,并计算其中有多少落在单位圆内以估计π。但是,当使用 while 循环时,我可以通过较少的绘制次数获得更精确的π估计值。为什么与具有固定次数的初始方法相比,这种循环方法在较少的绘制次数下产生更准确的结果?

1,000,000 次抽奖的初始代码:

def pi_estimation1(n):
    # Create a random number generator
    rng = np.random.default_rng()

    # Generate x and y coordinates simultaneously
    coordinates = rng.random((n, 2))

    # Use vectorized operations (UFunc) to filter points inside and outside the circle
    x_in_circle = coordinates[coordinates[:, 0]**2 + coordinates[:, 1]**2 <= 1]
    x_out_circle = coordinates[coordinates[:, 0]**2 + coordinates[:, 1]**2 > 1]

    

    # Calculate the value of pi based on the ratio of points inside the circle
    pi = 4 * len(x_in_circle) / n
    return pi, x_in_circle, x_out_circle,n

# Example of usage
estimated_pi, x_in_circle, x_out_circle,n = pi_estimation1(1000000)
# # Plot points inside and outside the circle
plt.figure(figsize=(5, 5))
plt.scatter(x_in_circle[:, 0], x_in_circle[:, 1], color='blue')
plt.scatter(x_out_circle[:, 0], x_out_circle[:, 1], color='red')
plt.show()

print("The estimated value of pi is ", estimated_pi)
print("The exact value of pi is ", np.pi)
print("The error relative to the exact value is ", abs(estimated_pi - np.pi) / np.pi)
print("Number of points ",n)

结果:

The estimated value of pi is  3.140236
The exact value of pi is  3.141592653589793
The error relative to the exact value is  0.0004318362497579398
Number of points  1000000

带有 while 循环的代码:

def pi_estimation_while_loop(deviation):
    
    # Initialize variables
    pi = 0
    n = 0
    dev=1
    in_circle = 0
    
    rng=np.random.default_rng()
    
    # Loop until the deviation is less than 0.0001
    while deviation < dev :
        coordinate = rng.random((1, 2))
        if coordinate[0,0]**2 + coordinate[0,1]**2 <= 1:
            in_circle += 1
        
    
        n += 1
        pi = 4 * in_circle / n
        dev=(abs(pi-np.pi)/np.pi)
        #
        
        
        
    return pi, n, dev

pi, n, dev = pi_estimation_while_loop(1e-9)
print("The estimated value of pi is ", pi)
print("The exact value of pi is ", np.pi)
print("The error relative to the exact value is ", abs(pi - np.pi) / np.pi)
print("The number of iterations is ", n)

结果:

The estimated value of pi is  3.141592654644592
The exact value of pi is  3.141592653589793
The error relative to the exact value is  3.3575292254192973e-10
The number of iterations is  499581

我想知道这两种方法之间准确性差异的可能原因,以及如何以最少的平局次数优化π的估计。任何帮助或解释将不胜感激。谢谢!

python-3.x numpy 性能 while-loop

评论

4赞 pho 11/11/2023
对于苹果到苹果的比较,将循环更改为与矢量化代码选择的点数相同的操作次数(反之亦然),并在两次调用之前使用相同的数字为随机数生成器播种。(伪-)就其性质而言,随机数是伪随机的,因此获取更多数字不一定会使您的结果更准确。请参阅 online-python.com/jWPtagD0RQ,我修改了您的代码以执行我所说的操作,并且它们都给出了相同的估计 pi
0赞 PortorogasDS 11/11/2023
谢谢。我认为精度完全取决于抽奖次数,而很少取决于种子,因为随机抽奖的统一性。我认为通过增加绘图次数,精度将齐头并进。
1赞 Nick ODell 11/12/2023
while deviation < dev:你的 while 循环条件是使用 pi。这是不现实的 - 你写这样的循环的唯一原因是如果你不知道你估计的数量。根据定义,为了终止 while 循环,估计值必须接近 pi。这就是为什么它比固定数量的试验更准确。

答: 暂无答案