I have tried to predict the value of Pi using a random function generated from scratch. But it is giving an output of 4 instead of 3.14.My code for predicting Pi works perfectly when I'm using "np.random.uniform" instead of my random function.How can I improve my random function so that I can get an output of 3.14?
import numpy as np
import matplotlib.pyplot as plt
#random function using linear congruent generator
def generate_rand(mult=16807,mod=(2**31)-1, seed=123456789, size=1):
U = np.zeros(size)
X = (seed*mult 1)%mod
U[0] = X/mod
for i in range(1, size):
X = (X*mult 1)%mod
U[i] = X/mod
return U
def generate_random(low=0,high=1, seed=123456789, size=1):
#Generates uniformly random number between 'low' and 'high' limits
return low (high-low) *generate_rand(seed=seed, size=size)
def pi_estimator(samples):
points_inside_circle= 0
total_num_points = 0
for _ in range(samples):
x = generate_random()
y = generate_random()
distance = x**2 y**2
if distance <= 1:
points_inside_circle =1
total_num_points = 1
return 4* points_inside_circle/total_num_points
pi_estimator(10000)
CodePudding user response:
The problem is that your numbers aren't actually random. You're asking for one random number giving the same "seed" so you always getting the same number.
You need to either have your generate_rand
be a class saving the "seed" and using the last number as "seed" or ask for all the numbers at once. I decided for the 2nd approach
def pi_estimator(samples):
points_inside_circle= 0
total_num_points = 0
X,Y = generate_rand(size=2*samples).reshape(2,-1)
for x,y in zip(X,Y):
distance = x**2 y**2
if distance <= 1:
points_inside_circle =1
total_num_points = 1
return 4* points_inside_circle/total_num_points
Now pi_estimator(10**7)
gives 3.1418544
which looks like pi
to me.