Skip to content

Instantly share code, notes, and snippets.

@mschauer
Last active March 3, 2021 15:27
Show Gist options
  • Select an option

  • Save mschauer/f86a226cd8171c9dec46bc12d83dd785 to your computer and use it in GitHub Desktop.

Select an option

Save mschauer/f86a226cd8171c9dec46bc12d83dd785 to your computer and use it in GitHub Desktop.
Guided processes for conditional mixed Bernoulli
using Mitosis
using MeasureTheory
using Random
using Test
n = 30
ρ = rand(n)
struct PlusBernoulli{S,T} <: MeasureTheory.AbstractMeasure
x::S
ρ::T
end
struct MinusBinomial{S,T} <: MeasureTheory.AbstractMeasure
N::S
n::S
ρ::T
end
MeasureTheory.density(p::MinusBinomial, x) = MeasureTheory.Distributions.pdf(MeasureTheory.Distributions.Binomial(p.n, 1-p.ρ), x - (p.N - p.n))
(p::MinusBinomial)(x) = density(p, x)
struct PBParam{T}
ρ::T
end
(p::PBParam)(x) = (x, p.ρ)
Random.rand(p::PlusBernoulli) = p.x + (rand() < p.ρ )
κ = kernel(PBParam(0.3), PlusBernoulli)
genκ = ρ -> kernel(x->(x, ρ), PlusBernoulli)
function ⋅(κ::Kernel{PlusBernoulli}, h::Vector)
ρ = κ.ops.ρ
n = length(h)
h0 = zeros(n+1)
h0[1:n] = ρ*h
h0[2:n+1] += (1-ρ)*h
h0
end
h1 = (genκ(0.3)⋅(genκ(0.3)⋅[1.0]))
h1b = [density(MinusBinomial(2, 2, 0.3), i) for i in 0:2]
@test h1 ≈ h1b
function ⋅(κ::Kernel{PlusBernoulli}, p::MinusBinomial)
ρ = κ.ops.ρ
p.ρ != ρ && throw(ArgumentError("ρ ≠ p"))
MinusBinomial(p.N, p.n + 1, ρ)
end
h = genκ(0.3)⋅(genκ(0.3)⋅(genκ(0.3)⋅MinusBinomial(10, 0, 0.3)))
function Mitosis.backward(κ::Kernel{PlusBernoulli}, p::MinusBinomial)
p0 = κ⋅p
Mitosis.message(p0, p), p0
end
function Mitosis.forward(κ::Kernel{PlusBernoulli}, m, (w0,x))
h0, h = m.q0, m.q
ρ = κ.ops.ρ
den = ρ*h(x+1) + (1-ρ)*h(x)
ρeff = ρ*h(x+1)/den
0 ≤ ρeff ≤ 1 || throw(ArgumentError("Singular"))
w = w0*den/h0(x)
w, rand(PlusBernoulli(x, ρeff))
end
m, h0 = backward(κ, h)
x = 6
forward(κ, m, (1.0, x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment