-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #135 from biaslab/dev-improved-tests
Parallel tests + VSCode integration
- Loading branch information
Showing
80 changed files
with
4,052 additions
and
4,092 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# Bernoulli comes from Distributions.jl and most of the things should be covered there | ||
# Here we test some extra ExponentialFamily.jl specific functionality | ||
|
||
@testitem "Bernoulli: vague" begin | ||
include("distributions_setuptests.jl") | ||
|
||
d = vague(Bernoulli) | ||
|
||
@test typeof(d) <: Bernoulli | ||
@test mean(d) === 0.5 | ||
@test succprob(d) === 0.5 | ||
@test failprob(d) === 0.5 | ||
end | ||
|
||
@testitem "Bernoulli: probvec" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test probvec(Bernoulli(0.5)) === (0.5, 0.5) | ||
@test probvec(Bernoulli(0.3)) === (0.7, 0.3) | ||
@test probvec(Bernoulli(0.6)) === (0.4, 0.6) | ||
end | ||
|
||
@testitem "Bernoulli: logscale Bernoulli-Bernoulli/Categorical" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test compute_logscale(Bernoulli(0.5), Bernoulli(0.5), Bernoulli(0.5)) ≈ log(0.5) | ||
@test compute_logscale(Bernoulli(1), Bernoulli(0.5), Bernoulli(1)) ≈ log(0.5) | ||
@test compute_logscale(Categorical([0.5, 0.5]), Bernoulli(0.5), Categorical([0.5, 0.5])) ≈ log(0.5) | ||
@test compute_logscale(Categorical([0.5, 0.5]), Categorical([0.5, 0.5]), Bernoulli(0.5)) ≈ log(0.5) | ||
@test compute_logscale(Categorical([1.0, 0.0]), Bernoulli(0.5), Categorical([1])) ≈ log(0.5) | ||
@test compute_logscale(Categorical([1.0, 0.0, 0.0]), Bernoulli(0.5), Categorical([1.0, 0, 0])) ≈ log(0.5) | ||
end | ||
|
||
@testitem "Bernoulli: ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for p in 0.1:0.1:0.9 | ||
@testset let d = Bernoulli(p) | ||
ef = test_exponentialfamily_interface(d; option_assume_no_allocations = true) | ||
η₁ = logit(p) | ||
|
||
for x in (0, 1) | ||
@test @inferred(isbasemeasureconstant(ef)) === ConstantBaseMeasure() | ||
@test @inferred(basemeasure(ef, x)) === oneunit(x) | ||
@test @inferred(sufficientstatistics(ef, x)) === (x,) | ||
@test @inferred(logpartition(ef)) ≈ log(1 + exp(η₁)) | ||
end | ||
|
||
@test !@inferred(insupport(ef, -0.5)) | ||
@test !@inferred(insupport(ef, 0.5)) | ||
|
||
# Not in the support | ||
@test_throws Exception logpdf(ef, 0.5) | ||
@test_throws Exception logpdf(ef, -0.5) | ||
end | ||
end | ||
|
||
# Test failing isproper cases | ||
@test !isproper(MeanParametersSpace(), Bernoulli, [-1]) | ||
@test !isproper(MeanParametersSpace(), Bernoulli, [0.5, 0.5]) | ||
@test !isproper(NaturalParametersSpace(), Bernoulli, [0.5, 0.5]) | ||
@test !isproper(NaturalParametersSpace(), Bernoulli, [Inf]) | ||
|
||
@test_throws Exception convert(ExponentialFamilyDistribution, Bernoulli(1.0)) # We cannot convert from `1.0`, `logit` function returns `Inf` | ||
end | ||
|
||
@testitem "Bernoulli: prod with Distribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for strategy in (ClosedProd(), PreserveTypeProd(Distribution), PreserveTypeLeftProd(), PreserveTypeRightProd(), GenericProd()) | ||
@test @inferred(prod(strategy, Bernoulli(0.5), Bernoulli(0.5))) ≈ Bernoulli(0.5) | ||
@test @inferred(prod(strategy, Bernoulli(0.1), Bernoulli(0.6))) ≈ Bernoulli(0.14285714285714285) | ||
@test @inferred(prod(strategy, Bernoulli(0.78), Bernoulli(0.05))) ≈ Bernoulli(0.1572580645161291) | ||
end | ||
|
||
for strategy in (ClosedProd(), PreserveTypeProd(Distribution), GenericProd()) | ||
# Test symmetric case | ||
@test @inferred(prod(strategy, Bernoulli(0.5), Categorical([0.5, 0.5]))) ≈ Categorical([0.5, 0.5]) | ||
@test @inferred(prod(strategy, Categorical([0.5, 0.5]), Bernoulli(0.5))) ≈ Categorical([0.5, 0.5]) | ||
end | ||
|
||
@test @allocated(prod(ClosedProd(), Bernoulli(0.5), Bernoulli(0.5))) === 0 | ||
@test @allocated(prod(PreserveTypeProd(Distribution), Bernoulli(0.5), Bernoulli(0.5))) === 0 | ||
@test @allocated(prod(GenericProd(), Bernoulli(0.5), Bernoulli(0.5))) === 0 | ||
end | ||
|
||
@testitem "Bernoulli: prod with Categorical" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test prod(ClosedProd(), Bernoulli(0.5), Categorical([0.5, 0.5])) ≈ | ||
Categorical([0.5, 0.5]) | ||
@test prod(ClosedProd(), Bernoulli(0.1), Categorical(0.4, 0.6)) ≈ | ||
Categorical([1 - 0.14285714285714285, 0.14285714285714285]) | ||
@test prod(ClosedProd(), Bernoulli(0.78), Categorical([0.95, 0.05])) ≈ | ||
Categorical([1 - 0.1572580645161291, 0.1572580645161291]) | ||
@test prod(ClosedProd(), Bernoulli(0.5), Categorical([0.3, 0.3, 0.4])) ≈ | ||
Categorical([0.5, 0.5, 0]) | ||
@test prod(ClosedProd(), Bernoulli(0.5), Categorical([1.0])) ≈ | ||
Categorical([1.0, 0]) | ||
end | ||
|
||
@testitem "Bernoulli: prod with ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for pleft in 0.1:0.1:0.9, pright in 0.1:0.1:0.9 | ||
@testset let (left, right) = (Bernoulli(pleft), Bernoulli(pright)) | ||
@test test_generic_simple_exponentialfamily_product( | ||
left, | ||
right, | ||
strategies = ( | ||
ClosedProd(), | ||
GenericProd(), | ||
PreserveTypeProd(ExponentialFamilyDistribution), | ||
PreserveTypeProd(ExponentialFamilyDistribution{Bernoulli}) | ||
) | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
|
||
# Beta comes from Distributions.jl and most of the things should be covered there | ||
# Here we test some extra ExponentialFamily.jl specific functionality | ||
|
||
@testitem "Beta: vague" begin | ||
include("distributions_setuptests.jl") | ||
|
||
d = vague(Beta) | ||
|
||
@test typeof(d) <: Beta | ||
@test mean(d) === 0.5 | ||
@test params(d) === (1.0, 1.0) | ||
end | ||
|
||
@testitem "Beta: mean(::typeof(log))" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test mean(log, Beta(1.0, 3.0)) ≈ -1.8333333333333335 | ||
@test mean(log, Beta(0.1, 0.3)) ≈ -7.862370395825961 | ||
@test mean(log, Beta(4.5, 0.3)) ≈ -0.07197681436958758 | ||
end | ||
|
||
@testitem "Beta: mean(::typeof(mirrorlog))" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test mean(mirrorlog, Beta(1.0, 3.0)) ≈ -0.33333333333333337 | ||
@test mean(mirrorlog, Beta(0.1, 0.3)) ≈ -0.9411396776150167 | ||
@test mean(mirrorlog, Beta(4.5, 0.3)) ≈ -4.963371962929249 | ||
end | ||
|
||
@testitem "Beta: ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for a in 0.1:0.2:0.9, b in 0.1:0.2:0.9 | ||
@testset let d = Beta(a, b) | ||
ef = test_exponentialfamily_interface(d; option_assume_no_allocations = true) | ||
|
||
(η₁, η₂) = (a - 1, b - 1) | ||
|
||
for x in 0.1:0.1:0.9 | ||
@test @inferred(isbasemeasureconstant(ef)) === ConstantBaseMeasure() | ||
@test @inferred(basemeasure(ef, x)) === oneunit(x) | ||
@test all(@inferred(sufficientstatistics(ef, x)) .≈ (log(x), log(1 - x))) | ||
@test @inferred(logpartition(ef)) ≈ (logbeta(η₁ + 1, η₂ + 1)) | ||
end | ||
|
||
@test !@inferred(insupport(ef, -0.5)) | ||
@test @inferred(insupport(ef, 0.5)) | ||
|
||
# Not in the support | ||
@test_throws Exception logpdf(ef, -0.5) | ||
end | ||
end | ||
|
||
# Test failing isproper cases | ||
@test !isproper(MeanParametersSpace(), Beta, [-1]) | ||
@test !isproper(MeanParametersSpace(), Beta, [1, -0.1]) | ||
@test !isproper(MeanParametersSpace(), Beta, [-0.1, 1]) | ||
@test !isproper(NaturalParametersSpace(), Beta, [-1.1]) | ||
@test !isproper(NaturalParametersSpace(), Beta, [1, -1.1]) | ||
@test !isproper(NaturalParametersSpace(), Beta, [-1.1, 1]) | ||
|
||
# `a`s must add up to something more than 1, otherwise is not proper | ||
let ef = convert(ExponentialFamilyDistribution, Beta(0.1, 1.0)) | ||
@test !isproper(prod(PreserveTypeProd(ExponentialFamilyDistribution), ef, ef)) | ||
end | ||
|
||
# `b`s must add up to something more than 1, otherwise is not proper | ||
let ef = convert(ExponentialFamilyDistribution, Beta(1.0, 0.1)) | ||
@test !isproper(prod(PreserveTypeProd(ExponentialFamilyDistribution), ef, ef)) | ||
end | ||
end | ||
|
||
@testitem "Beta: prod with Distributions" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for strategy in (ClosedProd(), PreserveTypeProd(Distribution), PreserveTypeLeftProd(), PreserveTypeRightProd(), GenericProd()) | ||
@test prod(strategy, Beta(3.0, 2.0), Beta(2.0, 1.0)) ≈ Beta(4.0, 2.0) | ||
@test prod(strategy, Beta(7.0, 1.0), Beta(0.1, 4.5)) ≈ Beta(6.1, 4.5) | ||
@test prod(strategy, Beta(1.0, 3.0), Beta(0.2, 0.4)) ≈ Beta(0.19999999999999996, 2.4) | ||
end | ||
|
||
@test @allocated(prod(ClosedProd(), Beta(3.0, 2.0), Beta(2.0, 1.0))) === 0 | ||
@test @allocated(prod(GenericProd(), Beta(3.0, 2.0), Beta(2.0, 1.0))) === 0 | ||
end | ||
|
||
@testitem "Beta: prod with ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for aleft in 0.51:1.0:5.0, aright in 0.51:1.0:5.0, bleft in 0.51:1.0:5.0, bright in 0.51:1.0:5.0 | ||
@testset let (left, right) = (Beta(aleft, bleft), Beta(aright, bright)) | ||
@test test_generic_simple_exponentialfamily_product( | ||
left, | ||
right, | ||
strategies = ( | ||
ClosedProd(), | ||
GenericProd(), | ||
PreserveTypeProd(ExponentialFamilyDistribution), | ||
PreserveTypeProd(ExponentialFamilyDistribution{Beta}) | ||
) | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
|
||
# Binomial comes from Distributions.jl and most of the things should be covered there | ||
# Here we test some extra ExponentialFamily.jl specific functionality | ||
|
||
@testitem "Binomial: probvec" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test all(probvec(Binomial(2, 0.8)) .≈ (0.2, 0.8)) | ||
@test probvec(Binomial(2, 0.2)) == (0.8, 0.2) | ||
@test probvec(Binomial(2, 0.1)) == (0.9, 0.1) | ||
@test probvec(Binomial(2)) == (0.5, 0.5) | ||
end | ||
|
||
@testitem "Binomial: vague" begin | ||
include("distributions_setuptests.jl") | ||
|
||
@test_throws MethodError vague(Binomial) | ||
@test_throws MethodError vague(Binomial, 1 / 2) | ||
|
||
vague_dist = vague(Binomial, 5) | ||
@test typeof(vague_dist) <: Binomial | ||
@test probvec(vague_dist) == (0.5, 0.5) | ||
end | ||
|
||
@testitem "Binomial: ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for n in (2, 3, 4), p in 0.1:0.2:0.9 | ||
@testset let d = Binomial(n, p) | ||
ef = test_exponentialfamily_interface(d; option_assume_no_allocations = true) | ||
|
||
η₁ = log(p / (1 - p)) | ||
|
||
for x in 0:n | ||
@test @inferred(isbasemeasureconstant(ef)) === NonConstantBaseMeasure() | ||
@test @inferred(basemeasure(ef, x)) === binomial(n, x) | ||
@test all(@inferred(sufficientstatistics(ef, x)) .≈ (x,)) | ||
@test @inferred(logpartition(ef)) ≈ (n * log(1 + exp(η₁))) | ||
end | ||
|
||
@test !@inferred(insupport(ef, -1)) | ||
@test @inferred(insupport(ef, 0)) | ||
|
||
# Not in the support | ||
@test_throws Exception logpdf(ef, -1) | ||
end | ||
end | ||
|
||
# Test failing isproper cases | ||
@test !isproper(MeanParametersSpace(), Binomial, [-1], 1) | ||
@test !isproper(MeanParametersSpace(), Binomial, [0.5], -1) | ||
@test !isproper(MeanParametersSpace(), Binomial, [-0.1, 1], 10) | ||
@test !isproper(NaturalParametersSpace(), Binomial, [-1.1], -1) | ||
@test !isproper(NaturalParametersSpace(), Binomial, [1, -1.1], 10) | ||
end | ||
|
||
@testitem "Binomial: prod ExponentialFamilyDistribution" begin | ||
include("distributions_setuptests.jl") | ||
|
||
for nleft in 1:1, pleft in 0.1:0.1:0.1, nright in 1:1, pright in 0.1:0.1:0.1 | ||
@testset let (left, right) = (Binomial(nleft, pleft), Binomial(nright, pright)) | ||
for (efleft, efright) in ((left, right), (convert(ExponentialFamilyDistribution, left), convert(ExponentialFamilyDistribution, right))) | ||
for strategy in (PreserveTypeProd(ExponentialFamilyDistribution),) | ||
prod_dist = prod(strategy, efleft, efright) | ||
|
||
@test prod_dist isa ExponentialFamilyDistribution | ||
|
||
hist_sum(x) = | ||
basemeasure(prod_dist, x) * exp( | ||
dot(ExponentialFamily.flatten_parameters(sufficientstatistics(prod_dist, x)), getnaturalparameters(prod_dist)) - | ||
logpartition(prod_dist) | ||
) | ||
|
||
support = 0:1:max(nleft, nright) | ||
|
||
@test sum(hist_sum, support) ≈ 1.0 atol = 1e-9 | ||
|
||
for x in support | ||
@test basemeasure(prod_dist, x) ≈ (binomial(nleft, x) * binomial(nright, x)) | ||
@test all(sufficientstatistics(prod_dist, x) .≈ (x,)) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.