Вот один из вариантов, в котором основан максимальный размер выборки, тогда выполняется субсэмплинг, если start>0
(обработка ошибок не включена).
import numpy as np
import matplotlib.pyplot as plt
def monteCarloPi(n,start=0,stride=1):
np.random.seed() # seed the random number generator
y = np.random.rand(n)*2 - 1 # n random samples on (-1,1)
x = np.linspace(-1,1,n) # x axis to plot against
mask = ( x**2 + y**2 ) < 1 # masking
samples = {}
inds = arange(n)
for k in range(n-start,n+1,stride):
sub_inds = np.random.choice(inds,k,replace=False)
sub_mask = mask[sub_inds]
sub_hits = np.sum(sub_mask)
ratio = sub_hits/n
pi_approx = ratio * 4
samples[k]=pi_approx
return pi_approx
Для этого все еще требуется цикл for, но он обрабатывается внутри метода быстро, так как вы выполняете выборку из одной большой случайной выборки.Чтобы восстановить исходный вызов (от n=100
до n=1000
[обратите внимание, что здесь я набираю n=1000
]):
estimates = monteCarloPi(1000,start=900)
plt.plot(estimates.keys(),estimates.values())
Конечно, вы можете передать исходный x=arange(100,1001)
,но тогда в методе потребуется проверка ошибок (чтобы убедиться, что массив или список был передан), а затем n
будет равен последнему элементу x
(n=x[-1]
), и, наконец,зацикливание будет выполнено над элементами x
(for k in x:
).