import torch
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import arviz as az
%matplotlib inline
# Retina display
%config InlineBackend.figure_format = 'retina'
import warnings
'ignore') warnings.filterwarnings(
from tueplots import bundles
plt.rcParams.update(bundles.beamer_moml())
# Also add despine to the bundle using rcParams
'axes.spines.right'] = False
plt.rcParams['axes.spines.top'] = False
plt.rcParams[
# Increase font size to match Beamer template
'font.size'] = 16
plt.rcParams[# Make background transparent
'figure.facecolor'] = 'none' plt.rcParams[
# Define values of lambda
= [0.5, 1.0, 1.5]
lambdas = torch.linspace(0, 5, 100)
x
# Create a figure with two subplots
= plt.subplots(1, 2,)
fig, (ax1, ax2)
# Plot PDFs in the first subplot
for lam in lambdas:
= torch.distributions.Exponential(rate=lam)
exponential_dist = exponential_dist.log_prob(x).exp()
pdf =f'$\lambda = {lam}$')
ax1.plot(x, pdf, label
'x')
ax1.set_xlabel('PDF')
ax1.set_ylabel('Exponential Distribution PDF')
ax1.set_title(
ax1.legend()
# Plot CDFs in the second subplot
for lam in lambdas:
= torch.distributions.Exponential(rate=lam)
exponential_dist = exponential_dist.cdf(x)
cdf =f'$\lambda = {lam}$')
ax2.plot(x, cdf, label
'x')
ax2.set_xlabel('CDF')
ax2.set_ylabel('Exponential Distribution CDF')
ax2.set_title(
ax2.legend()
# Show the plots
plt.tight_layout()"../figures/sampling/exp-cdf.pdf") plt.savefig(
import torch
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
# Create the exponential distribution
def plot_n_samples(n):
= torch.distributions.Exponential(rate=1)
exponential_dist = torch.linspace(0, 5, 100)
x
# Create the CDF plot
= plt.subplots()
fig, ax 'x')
ax.set_xlabel('CDF')
ax.set_ylabel('Exponential Distribution CDF')
ax.set_title(
# Initialize an empty line for the animated point
= ax.plot([], [], 'ko', ms=5)
point, # Draw the CDF curve
= exponential_dist.cdf(x)
cdf ='CDF', lw=2)
ax.plot(x, cdf, label42)
torch.manual_seed(= torch.rand(n)
u # Calculate the corresponding point on the CDF
= exponential_dist.icdf(u)
point_x = u
point_y # Add the point to the plot
point.set_data(point_x, point_y)
# Add vertical and horizontal dashed lines
0, point_y, linestyle='--', lw=1)
ax.vlines(point_x, 0, point_x, linestyle='--', lw=1)
ax.hlines(point_y, f"../figures/sampling/exp-cdf-samples-{n}.pdf")
plt.savefig(
for i in range(1, 10):
plot_n_samples(i)
# Compare KDE to the true PDF
= torch.distributions.Exponential(rate=1)
expon = torch.linspace(0, 5, 100)
x = expon.log_prob(x).exp()
pdf
# Sample from the distribution
42)
torch.manual_seed(= expon.sample((10000,))
random_numbers
=False, label='KDE from Torch')
az.plot_kde(np.array(random_numbers), rug
='True PDF', color='C1')
plt.plot(x, pdf, label
plt.legend()
# Samples using inverse CDF method
= torch.rand(10000)
u = expon.icdf(u)
samples =False, label='KDE using inverse CDF', plot_kwargs={"color":'C2', "ls":"--"})
az.plot_kde(np.array(samples), rug
0, 5) plt.xlim(
(0.0, 5.0)
# Similarly generating samples from a normal distribution
= torch.distributions.Normal(loc=0, scale=1)
normal = torch.linspace(-5, 5, 100)
x = normal.log_prob(x).exp()
pdf
= normal.cdf(x)
cdf
='PDF')
plt.plot(x, pdf, label='CDF')
plt.plot(x, cdf, label plt.legend()
<matplotlib.legend.Legend at 0x7f3eaa3452b0>
= torch.rand(10000)
u = normal.icdf(u)
samples
=False, label='KDE using inverse CDF', plot_kwargs={"color":'C2', "ls":"--"})
az.plot_kde(np.array(samples), rug
='True PDF', color='C1')
plt.plot(x, pdf, label
-5, 5)
plt.xlim( plt.legend()
<matplotlib.legend.Legend at 0x7f3eaa2b6040>
def inverse_cdf(u, lam):
return -torch.log(1 - u) / lam
def sample_exponential(n_samples, lam):
= torch.rand(n_samples)
u return inverse_cdf(u, lam)
class SimplePRNG:
def __init__(self, seed=0):
self.seed = seed
self.a = 1664525
self.c = 1013904223
self.m = 2**32
def random(self):
self.seed = (self.a * self.seed + self.c) % self.m
return self.seed / self.m
def generate_N_random_numbers(self, N):
= []
random_numbers for _ in range(N):
self.random())
random_numbers.append(return random_numbers
# Usage
= SimplePRNG(seed=42) # You can change the seed value
prng = 10000 # Change N to the number of random numbers you want to generate
N = prng.generate_N_random_numbers(N)
random_numbers
= plt.hist(random_numbers, bins=10) _
=False) az.plot_kde(np.array(random_numbers), rug
<AxesSubplot:>
= plt.hist(np.random.rand(10000), bins=10) _
10000), rug=False) az.plot_kde(np.random.rand(
<AxesSubplot:>
### Uniform (a, b)
= -2
a = 2
b
= a + (b - a) * np.array(random_numbers) random_numbers_a_b
=10) plt.hist(random_numbers_a_b, bins
(array([1006., 1012., 963., 964., 1008., 939., 1039., 1012., 1031.,
1026.]),
array([-1.99864224e+00, -1.59883546e+00, -1.19902869e+00, -7.99221917e-01,
-3.99415144e-01, 3.91628593e-04, 4.00198402e-01, 8.00005174e-01,
1.19981195e+00, 1.59961872e+00, 1.99942549e+00]),
<BarContainer object of 10 artists>)