©2023 Raazesh Sainudiin, Benny Avelin. Attribution 4.0 International (CC BY 4.0)
from Utils import linConGen
import numpy as np
import matplotlib.pyplot as plt
from Utils import discrete_histogram
m,a,b = (2**32, 1103515245,12345)
seed = 1
np.array(linConGen(m,a,b,seed,10))/m
def random():
"""Generates one random sample from the uniform [0,1] distribution"""
global seed
seed = linConGen(m,a,b,seed,2)[1]
return seed/m
unif_x = [random() for i in range(1000)]
_=plt.hist(unif_x,bins=10)
def unif_to_bernoulli(x,p):
from math import floor
return floor(x+p)
bernoulli_x = [unif_to_bernoulli(random(),0.9) for i in range(1000)]
discrete_histogram(bernoulli_x,normed=True)
import numpy as np
p = np.array([0.1,0.2,0.5,0.2])
p_cumsum = np.cumsum(p)
p_cumsum
uniform_x = np.array([random() for i in range(10000)])
#np.argmax(uniform_x-p_cumsum,)
xp = (uniform_x.reshape(-1,1)-p_cumsum.reshape(1,-1)) # (10000,1), (1,4) -> (10000,4)
xp.shape
xp <= 0
x - p1
x - p1 - p2
x - p1 - p2 -p3
...
(0,p1),(p1,p1+p2),...,(p1+p2+p3,1]
0, 1, ..., 3
from Utils import discrete_histogram
discrete_histogram(np.argmax(xp <= 0,axis=1),normed=True)
-- To shuffle an array a of n elements (indices 0..n-1):
for i from n−1 downto 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]
def randint(b):
"""Producing random integers between 0 and b inclusive"""
u = random()
from math import floor
return floor(u*(b+1))
from Utils import plotEDF,makeEDF
random_samples_int = [randint(10) for i in range(10000)]
discrete_histogram(random_samples_int)
plotEDF(makeEDF(random_samples_int))
arr = np.arange(0,100)
n = len(arr)
for i in range(n-1,0,-1):
j = randint(i) # Random integer between 0 and i inclusive
tmp = arr[j]
arr[j] = arr[i]
arr[i] = tmp
arr
def random_shuffle(arr):
"""Shuffles an array in place"""
n = len(arr)
for i in range(n-1,0,-1):
j = randint(i) # Random integer between 0 and i inclusive
tmp = arr[j]
arr[j] = arr[i]
arr[i] = tmp
return arr
aa = np.arange(10)
random_shuffle(aa)
aa
from sklearn.datasets import make_classification
X,y = make_classification()
index = np.arange(0,len(y))
random_shuffle(index)
X_shuffle = X[index,:]
y_shuffle = y[index]
See chapter 10 in All of Statistics
from math import floor
X = np.array([floor(random()+0.5) for i in range(100)])
Y = np.array([floor(random()+0.2) for i in range(100)])
XY = np.concatenate([X,Y])
def compute_diff(arr):
return np.abs(np.mean(arr[:100])-np.mean(arr[100:]))
compute_diff(XY)
differences = np.array([compute_diff(random_shuffle(XY)) for i in range(10000)])
from Utils import plotEDF,makeEDF
plotEDF(makeEDF(differences))
Suppose that $U_1,U_2 \overset{\text{IID}}{\sim} \text{Uniform}([0,1])$, then \begin{align*} Z_0 &= \sqrt{-2\ln(U_1)} \cos(2\pi U_2) \\ Z_1 &= \sqrt{-2\ln(U_1)} \sin(2\pi U_2) \\ \end{align*} are independent random variables, and $Z_0,Z_1 \sim \mathcal{N}(0,1)$.
uniform_sequence = np.array([random() for i in range(10000)])
re_unif = uniform_sequence.reshape(-1,2)
Z1 = np.sqrt(-2*np.log(re_unif[:,0]))*np.cos(2*np.pi*re_unif[:,1])
Z2 = np.sqrt(-2*np.log(re_unif[:,0]))*np.sin(2*np.pi*re_unif[:,1])
Z = np.column_stack([Z1,Z2])
import matplotlib.pyplot as plt
plt.scatter(Z1,Z2,alpha=0.1)
from Utils import makeEDF,plotEDF
from scipy.stats import norm
x_plot = np.linspace(-3,3)
plotEDF(makeEDF(Z.flatten()),force_display=False)
plt.plot(x_plot,norm.cdf(x_plot),color='red')
_=plt.hist(Z.flatten())
output: a sequence of samples $x_0, \ldots$ with distribution $f$
Sample initial state $X^{(0)}$ from $g$
REPEAT
UNTIL desired number of samples are obtained.
Let us sample from the uniform distribution on the unit disk, our proposal distribution can be taken to be the uniform distribution on the 2-square. The area of the disk is $r^2 \pi$, i.e. the density $f$ should be $1/\pi$ on the circle and 0 elsewhere. The 2-square has area $4$ so the density of $g = 1/4$, we thus need $M = 4/\pi$
samples = []
rejections = 0
while (len(samples) < 100000):
# We know that the ratio is 1 when x is in the circle and 0 if it is outside
(X1,X2) = (2*random()-1,2*random()-1)
if (np.linalg.norm([X1,X2]) <= 1): # We are inside the circle
samples.append((X1,X2))
else:
rejections+=1
100000/(100000+rejections)
np.pi/4
samp_arr = np.array(samples)
plt.scatter(samp_arr[:,0],samp_arr[:,1])
_=plt.hist2d(samp_arr[:,0],samp_arr[:,1])
f = np.array([0.1,0.2,0.5,0.2])
g = np.array([1/4,1/4,1/4,1/4])
M = 2
f-M*g
samples = []
r = f/(M*g)
rejections = 0
while (len(samples) < 10000):
x = randint(3)
r[x]
U = random()
if (U <= r[x]):
samples.append(x)
else:
rejections+=1
rejections/(10000+rejections)
discrete_histogram(samples,normed=True)
The Poisson has distribution function $$ F(x) = e^{-\lambda} \sum_{j=0}^{\lfloor x \rfloor} \frac{\lambda^j}{j!} $$
def sample_poisson():
from scipy.special import factorial
Y = random()
l = 2
F = 0
for i in range(1000):
F = F + np.exp(-l)*np.power(l,i)/factorial(i)
if (F > Y):
break
return i
poisson_samples = [sample_poisson() for i in range(1000)]
f = []
for i in range(13):
f.append(np.exp(-l)*np.power(l,i)/factorial(i))
F = np.cumsum(f)
plt.plot(F,color='black')
plotEDF(makeEDF(poisson_samples))
discrete_histogram(poisson_samples)