From b4e3e461d18eb391e98477ea1d359f0e749de92d Mon Sep 17 00:00:00 2001 From: Nikos Ignatiadis Date: Tue, 30 Aug 2022 16:03:41 +0300 Subject: [PATCH 1/4] add beta binomial distribution --- src/MeasureTheory.jl | 1 + src/parameterized/betabinomial.jl | 48 +++++++++++++++++++++++++++++++ test/runtests.jl | 15 ++++++---- 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/parameterized/betabinomial.jl diff --git a/src/MeasureTheory.jl b/src/MeasureTheory.jl index 5be30634..a4534d14 100644 --- a/src/MeasureTheory.jl +++ b/src/MeasureTheory.jl @@ -155,6 +155,7 @@ include("parameterized/binomial.jl") include("parameterized/multinomial.jl") include("parameterized/lkj-cholesky.jl") include("parameterized/negativebinomial.jl") +include("parameterized/betabinomial.jl") include("parameterized/gamma.jl") include("parameterized/snedecorf.jl") include("parameterized/inverse-gaussian.jl") diff --git a/src/parameterized/betabinomial.jl b/src/parameterized/betabinomial.jl new file mode 100644 index 00000000..12640ac7 --- /dev/null +++ b/src/parameterized/betabinomial.jl @@ -0,0 +1,48 @@ +# Beta-Binomial distribution + +export BetaBinomial +import Base +using SpecialFunctions + + +@parameterized BetaBinomial(n, α, β) + +basemeasure(d::BetaBinomial) = CountingMeasure() + +testvalue(::BetaBinomial) = 0 + +@kwstruct BetaBinomial(n, α, β) + +function Base.rand(rng::AbstractRNG, ::Type, d::BetaBinomial{(:n, :α, :β)}) + rand(rng, Dists.BetaBinomial(d.n, d.α, d.β)) +end + +function Base.rand( + rng::AbstractRNG, + ::Type, + d::BetaBinomial{(:n, :α, :β),Tuple{I,A}}, +) where {I<:Integer,A} + rand(rng, Dists.BetaBinomial(d.n, d.α, d.β)) +end + + +@inline function insupport(d::BetaBinomial, x) + isinteger(x) && 0 ≤ x ≤ d.n +end + +@inline function logdensity_def(d::BetaBinomial{(:n, :α, :β)}, y) + (n, α, β) = (d.n, d.α, d.β) + logbinom = - log1p(n) - logbeta(y + 1, n - y + 1) + lognum = logbeta(y + α, n - y + β) + logdenom = logbeta(α, β) + return logbinom + lognum - logdenom +end + + +asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:α}) = asℝ₊ +asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:β}) = asℝ₊ + + +function proxy(d::BetaBinomial{(:n, :α, :β),Tuple{I,A}}) where {I<:Integer,A} + Dists.BetaBinomial(d.n, d.α, d.β) +end diff --git a/test/runtests.jl b/test/runtests.jl index aaea8646..ae5cd693 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -54,6 +54,7 @@ test_measures = Any[ Bernoulli(0.2) Beta(2, 3) Binomial(10, 0.3) + BetaBinomial(10, 2, 3) Cauchy() Dirichlet(ones(3)) Exponential() @@ -277,7 +278,7 @@ end @testset "Product of Diracs" begin x = randn(3) - t = as(productmeasure(Dirac.(x))) + t = as(productmeasure(Dirac.(x))) @test transform(t, []) == x end @@ -297,7 +298,7 @@ end # chain = Chain(kernel, μ) -# dyniterate(iter::TimeLift, ::Nothing) = dyniterate(iter, 0=>nothing) +# dyniterate(iter::TimeLift, ::Nothing) = dyniterate(iter, 0=>nothing) # tr1 = trace(TimeLift(chain), nothing, u -> u[1] > 15) # tr2 = trace(TimeLift(rand(Random.GLOBAL_RNG, chain)), nothing, u -> u[1] > 15) # collect(Iterators.take(chain, 10)) @@ -348,8 +349,8 @@ end # NOTE: The `test_broken` below are mostly because of the change to `Affine`. # For example, `Normal{(:μ,:σ)}` is now `Affine{(:μ,:σ), Normal{()}}`. # The problem is not really with these measures, but with the tests - # themselves. - # + # themselves. + # # We should instead probably be doing e.g. # `D = typeof(Normal(μ=0.3, σ=4.1))` @@ -371,6 +372,10 @@ end @test repro(Beta, (:α, :β)) end + @testset "BetaBinomial" begin + @test repro(BetaBinomial, (:n, :α, :β), (n = 10,)) + end + @testset "Cauchy" begin @test_broken repro(Cauchy, (:μ, :σ)) end @@ -652,7 +657,7 @@ end end x = rand(d) - + @test logdensityof(d, x) isa Real end From beb231627d4773ccda672e2699f2d6f400443cee Mon Sep 17 00:00:00 2001 From: Chad Scherrer Date: Tue, 30 Aug 2022 13:40:01 -0700 Subject: [PATCH 2/4] run JuliaFormatter --- src/parameterized/betabinomial.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/parameterized/betabinomial.jl b/src/parameterized/betabinomial.jl index 12640ac7..8cc7f6df 100644 --- a/src/parameterized/betabinomial.jl +++ b/src/parameterized/betabinomial.jl @@ -4,7 +4,6 @@ export BetaBinomial import Base using SpecialFunctions - @parameterized BetaBinomial(n, α, β) basemeasure(d::BetaBinomial) = CountingMeasure() @@ -25,24 +24,21 @@ function Base.rand( rand(rng, Dists.BetaBinomial(d.n, d.α, d.β)) end - @inline function insupport(d::BetaBinomial, x) isinteger(x) && 0 ≤ x ≤ d.n end @inline function logdensity_def(d::BetaBinomial{(:n, :α, :β)}, y) (n, α, β) = (d.n, d.α, d.β) - logbinom = - log1p(n) - logbeta(y + 1, n - y + 1) - lognum = logbeta(y + α, n - y + β) + logbinom = -log1p(n) - logbeta(y + 1, n - y + 1) + lognum = logbeta(y + α, n - y + β) logdenom = logbeta(α, β) return logbinom + lognum - logdenom end - asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:α}) = asℝ₊ asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:β}) = asℝ₊ - function proxy(d::BetaBinomial{(:n, :α, :β),Tuple{I,A}}) where {I<:Integer,A} Dists.BetaBinomial(d.n, d.α, d.β) end From ce0cc8deeca62b63742fa695db114b40780e67f9 Mon Sep 17 00:00:00 2001 From: Nikos Ignatiadis Date: Wed, 31 Aug 2022 00:56:41 +0300 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Chad Scherrer --- src/parameterized/betabinomial.jl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/parameterized/betabinomial.jl b/src/parameterized/betabinomial.jl index 8cc7f6df..87866ba3 100644 --- a/src/parameterized/betabinomial.jl +++ b/src/parameterized/betabinomial.jl @@ -12,16 +12,13 @@ testvalue(::BetaBinomial) = 0 @kwstruct BetaBinomial(n, α, β) -function Base.rand(rng::AbstractRNG, ::Type, d::BetaBinomial{(:n, :α, :β)}) - rand(rng, Dists.BetaBinomial(d.n, d.α, d.β)) -end - function Base.rand( rng::AbstractRNG, - ::Type, - d::BetaBinomial{(:n, :α, :β),Tuple{I,A}}, -) where {I<:Integer,A} - rand(rng, Dists.BetaBinomial(d.n, d.α, d.β)) + ::Type{T}, + d::BetaBinomial{(:n, :α, :β)}, +) where {T} + k = rand(rng, T, Beta(d.α, d.β)) + return rand(rng, T, Binomial(d.n, k)) end @inline function insupport(d::BetaBinomial, x) From d9a0bf99e4f81217de297eb3230385f372948897 Mon Sep 17 00:00:00 2001 From: Nikos Ignatiadis Date: Wed, 31 Aug 2022 01:15:43 +0300 Subject: [PATCH 4/4] remove proxy, bump version --- Project.toml | 2 +- src/parameterized/betabinomial.jl | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index 175faf41..02f6a0e0 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MeasureTheory" uuid = "eadaa1a4-d27c-401d-8699-e962e1bbc33b" authors = ["Chad Scherrer and contributors"] -version = "0.17.2" +version = "0.17.3" [deps] Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" diff --git a/src/parameterized/betabinomial.jl b/src/parameterized/betabinomial.jl index 87866ba3..00d48947 100644 --- a/src/parameterized/betabinomial.jl +++ b/src/parameterized/betabinomial.jl @@ -35,7 +35,3 @@ end asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:α}) = asℝ₊ asparams(::Type{<:BetaBinomial}, ::StaticSymbol{:β}) = asℝ₊ - -function proxy(d::BetaBinomial{(:n, :α, :β),Tuple{I,A}}) where {I<:Integer,A} - Dists.BetaBinomial(d.n, d.α, d.β) -end