Exercises Notebook
Exercises Notebook
Converted from
exercises.ipynbfor web reading.
Sampling Methods - Exercises
Ten graded exercises on direct sampling, estimators, MCMC, and ML sampling previews.
Code cell 2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
try:
import seaborn as sns
sns.set_theme(style="whitegrid", palette="colorblind")
HAS_SNS = True
except ImportError:
plt.style.use("seaborn-v0_8-whitegrid")
HAS_SNS = False
mpl.rcParams.update({
"figure.figsize": (10, 6),
"figure.dpi": 120,
"font.size": 13,
"axes.titlesize": 15,
"axes.labelsize": 13,
"xtick.labelsize": 11,
"ytick.labelsize": 11,
"legend.fontsize": 11,
"legend.framealpha": 0.85,
"lines.linewidth": 2.0,
"axes.spines.top": False,
"axes.spines.right": False,
"savefig.bbox": "tight",
"savefig.dpi": 150,
})
np.random.seed(42)
print("Plot setup complete.")
Code cell 3
import numpy as np
def header(title): print("\n"+"="*72+"\n"+title+"\n"+"="*72)
def check_close(name,value,expected,tol=1e-2):
ok=np.allclose(value,expected,atol=tol,rtol=tol); print(f"{'PASS' if ok else 'FAIL'} - {name}: value={value}, expected={expected}"); return ok
def check_true(name,condition): ok=bool(condition); print(f"{'PASS' if ok else 'FAIL'} - {name}"); return ok
def softmax(z):
z=np.asarray(z,dtype=float); e=np.exp(z-np.max(z)); return e/e.sum()
np.random.seed(42)
print("Exercise helpers ready.")
Exercise 1: Inverse exponential (*)
Sample exponential variables by inverse CDF.
Code cell 5
# Your Solution
u=np.random.rand(1000)
x=None
print(x)
Code cell 6
# Solution
header("Exercise 1: Inverse exponential")
u=np.random.rand(10000); lam=2.; x=-np.log(1-u)/lam
check_close("mean", x.mean(), 1/lam, tol=0.03)
print("\nTakeaway: inverse-transform sampling converts uniforms through an inverse CDF.")
Exercise 2: Categorical sampler (*)
Sample from cumulative probabilities.
Code cell 8
# Your Solution
p=np.array([0.2,0.8])
s=None
print(s)
Code cell 9
# Solution
header("Exercise 2: Categorical sampler")
p=np.array([0.2,0.8]); cdf=np.cumsum(p); u=np.random.rand(10000); s=np.searchsorted(cdf,u); freq=np.bincount(s,minlength=2)/len(s)
check_close("frequencies", freq, p, tol=0.02)
print("\nTakeaway: categorical sampling is inverse CDF on a discrete CDF.")
Exercise 3: Monte Carlo E[X^2] (*)
Estimate E[X^2] for standard normal.
Code cell 11
# Your Solution
x=np.random.normal(size=1000)
est=None
print(est)
Code cell 12
# Solution
header("Exercise 3: Monte Carlo E[X^2]")
x=np.random.normal(size=20000); est=np.mean(x**2)
check_close("E[X^2]", est, 1.0, tol=0.03)
print("\nTakeaway: Monte Carlo turns expectations into sample means.")
Exercise 4: Confidence interval (**)
Build a normal-approximation CI.
Code cell 14
# Your Solution
x=np.random.normal(size=100)
ci=None
print(ci)
Code cell 15
# Solution
header("Exercise 4: Confidence interval")
x=np.random.normal(loc=1.,scale=2.,size=500); mean=x.mean(); se=x.std(ddof=1)/np.sqrt(len(x)); ci=(mean-1.96*se, mean+1.96*se)
check_true("CI contains true mean", ci[0]<1<ci[1])
print("\nTakeaway: estimator uncertainty shrinks as standard error falls.")
Exercise 5: Rejection sampling (**)
Sample from density p(x)=2x on [0,1].
Code cell 17
# Your Solution
accepted=[]
print(accepted)
Code cell 18
# Solution
header("Exercise 5: Rejection sampling")
accepted=[]; trials=0
while len(accepted)<3000:
x=np.random.rand(); u=np.random.rand(); trials+=1
if u <= (2*x)/2: accepted.append(x)
accepted=np.array(accepted)
check_close("mean", accepted.mean(), 2/3, tol=0.03)
print("\nTakeaway: rejection sampling trades proposal simplicity for rejected draws.")
Exercise 6: Importance ESS (**)
Compute ESS for weighted samples.
Code cell 20
# Your Solution
w=np.array([10.,1.,1.])
ess=None
print(ess)
Code cell 21
# Solution
header("Exercise 6: Importance ESS")
w=np.array([10.,1.,1.]); ess=(w.sum()**2)/np.sum(w**2)
check_true("ESS less than sample count", ess<3)
print("\nTakeaway: high weight concentration reduces effective sample size.")
Exercise 7: Metropolis sampler (***)
Run a short random-walk Metropolis chain.
Code cell 23
# Your Solution
chain=[]
print(chain)
Code cell 24
# Solution
header("Exercise 7: Metropolis sampler")
def logp(x): return -0.5*x*x
cur=0.; chain=[]; acc=0
for t in range(6000):
prop=cur+np.random.normal()
if np.log(np.random.rand()) < logp(prop)-logp(cur): cur=prop; acc+=1
if t>500: chain.append(cur)
chain=np.array(chain)
check_close("variance", chain.var(), 1.0, tol=0.15)
print("\nTakeaway: MCMC samples are dependent but can approximate the target distribution.")
Exercise 8: Reparameterization (***)
Sample z=mu+sigma eps.
Code cell 26
# Your Solution
mu=1.; sigma=2.; z=None
print(z)
Code cell 27
# Solution
header("Exercise 8: Reparameterization")
mu=1.; sigma=2.; eps=np.random.normal(size=10000); z=mu+sigma*eps
check_close("mean", z.mean(), mu, tol=0.06)
check_close("std", z.std(), sigma, tol=0.06)
print("\nTakeaway: reparameterization separates randomness from differentiable parameters.")
Exercise 9: Gumbel-Max (***)
Sample categorical values with Gumbel-Max.
Code cell 29
# Your Solution
p=np.array([0.25,0.75])
freq=None
print(freq)
Code cell 30
# Solution
header("Exercise 9: Gumbel-Max")
p=np.array([0.25,0.75]); logits=np.log(p); u=np.random.uniform(1e-12,1-1e-12,size=(10000,2)); g=-np.log(-np.log(u)); s=np.argmax(logits+g,axis=1); freq=np.bincount(s,minlength=2)/len(s)
check_close("frequencies", freq, p, tol=0.02)
print("\nTakeaway: Gumbel-Max converts logits plus Gumbel noise into categorical samples.")
Exercise 10: Top-k top-p (***)
Filter a categorical distribution.
Code cell 32
# Your Solution
logits=np.array([5.,4.,3.,2.])
keep=None
print(keep)
Code cell 33
# Solution
header("Exercise 10: Top-k top-p")
logits=np.array([5.,4.,3.,2.]); probs=softmax(logits); topk=np.argsort(probs)[-2:][::-1]
order=np.argsort(probs)[::-1]; cum=np.cumsum(probs[order]); topp=order[cum<=0.8]; topp=np.r_[topp, order[len(topp)]] if len(topp)<len(order) else topp
check_true("top-k keeps two", len(topk)==2)
check_true("top-p keeps at least one", len(topp)>=1)
print("\nTakeaway: top-k fixes set size; top-p fixes cumulative probability mass.")