Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
361 changes: 199 additions & 162 deletions src/exercises/MCMC_1-intro.jl
100755 → 100644

Large diffs are not rendered by default.

673 changes: 179 additions & 494 deletions src/exercises/MCMC_2-basics.jl
100755 → 100644

Large diffs are not rendered by default.

140 changes: 28 additions & 112 deletions src/exercises/MCMC_3-advanced.jl
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
### A Pluto.jl notebook ###
# v0.20.4
# v0.20.21

#> [frontmatter]
#> order = "22"
#> title = "4. MCMCM advanced"
#> date = "2025-08-06"
#> order = "29"
#> title = "5. MCMC advanced"
#> tags = ["exercises"]
#> description = "MCMC advanced"
#> layout = "layout.jlhtml"
#> description = "MCMC advanced"
#>
#> [[frontmatter.author]]
#> name = "Gauthier Vanhaelewyn"
#> name = "Bram Spanoghe"

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
#! format: off
quote
return quote
local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
local el = $(esc(element))
global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
Expand All @@ -28,6 +27,8 @@ macro bind(def, element)
end

# ╔═╡ 75581580-2fb2-4112-b397-2b775eb64630
# Running this yourself? Point this at your own environment —
# we advise one shared project in the parent folder: Pkg.activate("..")
using Pkg; Pkg.activate("../../pluto-deployment-environment")

# ╔═╡ e07a1ae5-43b7-4c12-831d-43e1738eeac0
Expand All @@ -52,9 +53,6 @@ At some known timepoints `ts`, we get noisy observations on the car's vertical p
# ╔═╡ 90f185f3-91d4-4ee7-8de3-b76251c0c169
ts = 1:10;

# ╔═╡ 852a8d4e-3374-4805-b372-da3e93f4c664
collect(ts)

# ╔═╡ 599ae818-fb28-4803-b720-9fcf2bb162b7
ys_obs = [0.6, 0.0, 0.8, -0.7, -0.5, 0.2, 1.0, 1.2, 1.8, 1.1];

Expand All @@ -72,7 +70,7 @@ md"""
At some point `t_switch` ∈ [0, 10], the car switches from lane 1 to lane 2. We can describe the model as follows:
- If `t <= t_switch`, then `y ~ Normal(0.0, σ)`,
- If `t > t_switch`, then `y ~ Normal(1.0, σ)`,
with `σ` some (small) noise parameter.
with `σ` a noise parameter, of which you only know that it's probably small.
"""

# ╔═╡ 0bdac14c-db71-47b5-95d5-d83fb1e68cab
Expand Down Expand Up @@ -100,33 +98,11 @@ md"""

# ╔═╡ 70fd793a-3ce3-446f-adc1-65ce0a68e48a
@model function cars(ts)
t_switch ~ Uniform(0, 10)
σ ~ Exponential(1.0)

ys_obs = zeros(length(ts))
for pointidx in 1:length(ts)
if ts[pointidx] <= t_switch
ys_obs[pointidx] ~ Normal(0.0, σ)
else
ys_obs[pointidx] ~ Normal(1.0, σ)
end
end
missing
end

# ╔═╡ 3db9343e-9fb1-4f5c-bbfd-81e5a3623b44
carmodel = cars(ts) | (ys_obs = ys_obs,)

# ╔═╡ b39b4b09-95ee-49db-924c-0280847b408e
carchain = sample(carmodel, NUTS(), 2000)

# ╔═╡ 36c7809e-7597-491d-a79e-100cca700597
plot(carchain)

# ╔═╡ 261e426a-60d6-4dbd-aad5-88a96f408b1d
histogram(carchain[:t_switch], normalized=:probability)

# ╔═╡ 0c389fd7-35ba-41e1-9154-0c374d996156
mean(carchain[:t_switch])
# ╔═╡ fb202b86-c058-4f03-9062-ab282c71d5c4
missing # histogram of `t_switch`

# ╔═╡ 34bf815a-3bd3-49b5-b06d-d4297ca213a8
md"## Petridish peril (inference edition)"
Expand Down Expand Up @@ -163,57 +139,27 @@ logistic(t, P0, r, K) = K / (1 + (K - P0)/P0 * exp(-r*t))
md"### 1"

# ╔═╡ f080f708-a457-40a3-936c-b82d5159975d
dropletdist = MixtureModel([Poisson(10), Poisson(30)], [0.75, 0.25]);
dropletdist = missing

# ╔═╡ 7b4aef69-10ec-4935-b7fd-4c1d49aa9b3d
@model function petrigrowth(t_obs)
P0 ~ dropletdist
r ~ LogNormal(0.0, 0.3)
K ~ Normal(1e5, 1e4)

logfun = t -> logistic(t, P0, r, K)

Pt = logfun(t_obs) # Number of bacteria at the observed time
P_obs ~ Poisson(Pt) # The observed number is Poisson distributed

return logfun
@model function petrigrowth()
missing
end

# ╔═╡ a5b5a65e-2bac-49fa-b4ca-2fcaf64e4ada
petrimodel = petrigrowth(5) | (P_obs = 21_000,)

# ╔═╡ b579ccc6-993e-451b-a137-6fff6b630b49
petrichain = sample(petrimodel, MH(), 100_000) # better and faster than PG(40)

# ╔═╡ 9633f07a-d583-4680-b3cc-f5701540968f
plot(petrichain)

# ╔═╡ 7d0e5f0b-2cdf-4946-a186-f70774e363bb
logfuns = generated_quantities(petrimodel, petrichain);

# ╔═╡ c642574c-c01b-4398-aac9-43e514d7fa25
sp_petri = [logfun(8.0) for logfun in logfuns]

# ╔═╡ d15fa091-839c-4239-96e2-eaf7335ce620
prob_splittable = mean((sp_petri .>= 1e4) .&& (sp_petri .<= 1e5))
# ╔═╡ 3e98c640-4bb0-4b5d-bae0-769133a599a7
prob_splittable = missing

# ╔═╡ 0ea95b67-d4da-4c5a-ad2e-05024ad074a3
md"### 2"

# ╔═╡ 3d9b73ef-2aae-4c19-bddc-4081927ec92d
plot(logfuns[1:10:1000], xlims = (0, 12), legend = false, color = :skyblue, alpha = 0.5)
# ╔═╡ 47b15322-0b8c-48f1-b123-271ebae92655
missing # plot

# ╔═╡ 9ab88be4-4cf8-4747-ac36-3f1b82899be0
md"### 3🌟"

# ╔═╡ 113d8311-7bdc-461c-b077-920e23b33d39
dropletdist🌟 = MixtureModel(
[
truncated(Normal(10, sqrt(10)), lower = 0.0),
truncated(Normal(30, sqrt(30)), lower = 0.0)
],
[0.75, 0.25]
);
dropletdist🌟 = missing

# ╔═╡ 4e730df9-f619-464a-b8a3-57448132404b
begin
Expand All @@ -223,31 +169,12 @@ begin
end

# ╔═╡ d9b50958-20ae-4085-80d6-19420c7d89df
@model function petrigrowth🌟(t_obs)
P0 ~ dropletdist🌟
r ~ LogNormal(0.0, 0.3)
K ~ Normal(1e5, 1e4)

logfun = t -> logistic(t, P0, r, K)
Pt = logfun(t_obs)
P_obs ~ Poisson(Pt)

return logfun
end

# ╔═╡ 9ac7aa12-d945-4078-ae63-d598d7171112
let # so we dont need to rename all variables
petrimodel = petrigrowth🌟(5) | (P_obs = 21_000,)
petrichain = sample(petrimodel, NUTS(), 2_000)
logfuns = generated_quantities(petrimodel, petrichain);
sp_petri = [logfun(8.0) for logfun in logfuns]
prob_splittable = mean((sp_petri .>= 1e4) .&& (sp_petri .<= 1e5))
println("The new `prob_splittable` is ", prob_splittable)
plot(petrichain)
@model function petrigrowth🌟()
missing
end

# ╔═╡ 2f4308df-4451-4ac2-8a31-65cd49a275af
md"Changing to all continuous distributions made the inference much higher quality in this case, as can be seen from the chain plots. This also means this result is more reliable!"
# ╔═╡ 0704ed4d-5b3e-401d-a496-98782cb20b09
prob_splittable🌟 = missing

# ╔═╡ Cell order:
# ╟─f84d9259-69c0-4165-8bc0-d924fef18182
Expand All @@ -257,7 +184,6 @@ md"Changing to all continuous distributions made the inference much higher quali
# ╟─aa2b6263-7d13-4683-bc92-25663ed02604
# ╟─f3510387-1ab6-4aa2-bed9-9c8297a8b3c5
# ╠═90f185f3-91d4-4ee7-8de3-b76251c0c169
# ╠═852a8d4e-3374-4805-b372-da3e93f4c664
# ╠═599ae818-fb28-4803-b720-9fcf2bb162b7
# ╟─b2da9dc3-006c-49d0-81a7-6375a2dc6872
# ╟─46d3214c-e724-4b98-bc1f-5b9913d2b14a
Expand All @@ -266,11 +192,7 @@ md"Changing to all continuous distributions made the inference much higher quali
# ╟─cc0d6b32-6f12-46b8-915f-8a471317c35e
# ╟─96fc1412-83fc-4f67-8995-065b163d739c
# ╠═70fd793a-3ce3-446f-adc1-65ce0a68e48a
# ╠═3db9343e-9fb1-4f5c-bbfd-81e5a3623b44
# ╠═b39b4b09-95ee-49db-924c-0280847b408e
# ╠═36c7809e-7597-491d-a79e-100cca700597
# ╠═261e426a-60d6-4dbd-aad5-88a96f408b1d
# ╠═0c389fd7-35ba-41e1-9154-0c374d996156
# ╠═fb202b86-c058-4f03-9062-ab282c71d5c4
# ╟─34bf815a-3bd3-49b5-b06d-d4297ca213a8
# ╟─78571fb5-c44f-4e7f-afde-4436db6c945b
# ╟─2a84472c-cb6f-4607-9b98-c88cc2744e3d
Expand All @@ -279,17 +201,11 @@ md"Changing to all continuous distributions made the inference much higher quali
# ╟─234b2c87-fe91-4be4-bf0c-a6f20dcc38fe
# ╠═f080f708-a457-40a3-936c-b82d5159975d
# ╠═7b4aef69-10ec-4935-b7fd-4c1d49aa9b3d
# ╠═a5b5a65e-2bac-49fa-b4ca-2fcaf64e4ada
# ╠═b579ccc6-993e-451b-a137-6fff6b630b49
# ╠═9633f07a-d583-4680-b3cc-f5701540968f
# ╠═7d0e5f0b-2cdf-4946-a186-f70774e363bb
# ╠═c642574c-c01b-4398-aac9-43e514d7fa25
# ╠═d15fa091-839c-4239-96e2-eaf7335ce620
# ╠═3e98c640-4bb0-4b5d-bae0-769133a599a7
# ╟─0ea95b67-d4da-4c5a-ad2e-05024ad074a3
# ╠═3d9b73ef-2aae-4c19-bddc-4081927ec92d
# ╠═47b15322-0b8c-48f1-b123-271ebae92655
# ╟─9ab88be4-4cf8-4747-ac36-3f1b82899be0
# ╠═113d8311-7bdc-461c-b077-920e23b33d39
# ╠═4e730df9-f619-464a-b8a3-57448132404b
# ╠═d9b50958-20ae-4085-80d6-19420c7d89df
# ╠═9ac7aa12-d945-4078-ae63-d598d7171112
# ╟─2f4308df-4451-4ac2-8a31-65cd49a275af
# ╠═0704ed4d-5b3e-401d-a496-98782cb20b09
Loading
Loading