From f13b618dc70fb1b4b5e667fbf4097fd4ac2ddb07 Mon Sep 17 00:00:00 2001 From: David Widmann Date: Wed, 29 Sep 2021 10:09:29 +0200 Subject: [PATCH] Ensure that `binomlogpdf` returns non-positive values, t distributions with infinite parameter are supported, and add integration tests (#126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ensure that `binomlogpdf` returns non-positive values * Add test * Add integration test * Bump version * Handle student t distribution with infinite `ν` --- .github/workflows/IntegrationTest.yml | 52 +++++++++++++++++++++++++++ Project.toml | 2 +- src/distrs/binom.jl | 2 +- src/distrs/tdist.jl | 1 + test/misc.jl | 7 ++++ test/rmath.jl | 2 ++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/IntegrationTest.yml diff --git a/.github/workflows/IntegrationTest.yml b/.github/workflows/IntegrationTest.yml new file mode 100644 index 0000000..2bf2e5a --- /dev/null +++ b/.github/workflows/IntegrationTest.yml @@ -0,0 +1,52 @@ +name: IntegrationTest + +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' + +jobs: + test: + name: ${{ matrix.package.repo }}/${{ matrix.package.group }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + julia-version: [1] + os: [ubuntu-latest] + package: + - {user: JuliaStats, repo: Distributions.jl} + + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.julia-version }} + arch: x64 + - uses: julia-actions/julia-buildpkg@latest + - name: Clone Downstream + uses: actions/checkout@v2 + with: + repository: ${{ matrix.package.user }}/${{ matrix.package.repo }} + path: downstream + - name: Load this and run the downstream tests + shell: julia --color=yes --project=downstream {0} + run: | + using Pkg + try + # force it to use this PR's version of the package + Pkg.develop(PackageSpec(path=".")) # resolver may fail with main deps + Pkg.update() + Pkg.test() # resolver may fail with test time deps + catch err + err isa Pkg.Resolve.ResolverError || rethrow() + # If we can't resolve that means this is incompatible by SemVer and this is fine + # It means we marked this as a breaking change, so we don't need to worry about + # Mistakenly introducing a breaking change, as we have intentionally made one + @info "Not compatible with this release. No problem." exception=err + exit(0) # Exit immediately, as a success + end diff --git a/Project.toml b/Project.toml index 32f5bd1..a9975f5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "StatsFuns" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.9.11" +version = "0.9.12" [deps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" diff --git a/src/distrs/binom.jl b/src/distrs/binom.jl index 09b1c2a..73f8185 100644 --- a/src/distrs/binom.jl +++ b/src/distrs/binom.jl @@ -19,6 +19,6 @@ binompdf(n::Real, p::Real, k::Real) = exp(binomlogpdf(n, p, k)) binomlogpdf(n::Real, p::Real, k::Real) = binomlogpdf(promote(n, p, k)...) function binomlogpdf(n::T, p::T, k::T) where {T<:Real} m = clamp(k, 0, n) - val = betalogpdf(m + 1, n - m + 1, p) - log(n + 1) + val = min(0, betalogpdf(m + 1, n - m + 1, p) - log(n + 1)) return 0 <= k <= n && isinteger(k) ? val : oftype(val, -Inf) end diff --git a/src/distrs/tdist.jl b/src/distrs/tdist.jl index b7aefbc..4544efa 100644 --- a/src/distrs/tdist.jl +++ b/src/distrs/tdist.jl @@ -17,6 +17,7 @@ tdistpdf(ν::Real, x::Real) = exp(tdistlogpdf(ν, x)) tdistlogpdf(ν::Real, x::Real) = tdistlogpdf(promote(ν, x)...) function tdistlogpdf(ν::T, x::T) where {T<:Real} + isinf(ν) && return normlogpdf(x) νp12 = (ν + 1) / 2 return loggamma(νp12) - (logπ + log(ν)) / 2 - loggamma(ν / 2) - νp12 * log1p(x^2 / ν) end diff --git a/test/misc.jl b/test/misc.jl index c72491c..1d5d7f0 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -63,3 +63,10 @@ end @test binomlogpdf(1, 0.5, prevfloat(1.0)) == -Inf @test binomlogpdf(1, 0.5, nextfloat(1.0)) == -Inf end + +@testset "binom special cases" begin + for (n, p, k) in ((5, 0.0, 0), (5, 1.0, 5)) + @test iszero(binomlogpdf(n, p, k)) + @test isone(binompdf(n, p, k)) + end +end diff --git a/test/rmath.jl b/test/rmath.jl index f3c5829..cf22c47 100644 --- a/test/rmath.jl +++ b/test/rmath.jl @@ -301,6 +301,8 @@ end ((1,), -5f0:0.1f0:5f0), ((1,), -Float16(5):Float16(0.1):Float16(5)), ((1,), -5//1:5//1), + ((Inf,), -5.0:0.1:5.0), + ((Inf32,), -5f0:0.1f0:5f0), ]) rmathcomp_tests("srdist", [