From 2d863f73bde2133a99328c81b67a81251e7b98fe Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Mon, 5 Jan 2026 17:49:15 +0100 Subject: [PATCH 1/2] Improve error message for values out of support --- src/glmfit.jl | 26 +++++++++++++++++++------- test/runtests.jl | 27 +++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/glmfit.jl b/src/glmfit.jl index 0296af2e..31063178 100644 --- a/src/glmfit.jl +++ b/src/glmfit.jl @@ -846,16 +846,28 @@ function _initialeta!(eta::AbstractVector, end # Helper function to check that the values of y are in the allowed domain -function checky(y, d::Distribution) - if any(x -> !insupport(d, x), y) - throw(ArgumentError("y must be in the support of D")) +function checky(y::AbstractVector, d::Distribution) + for yy in y + if !insupport(d, yy) + minsupport, maxsupport = extrema(d) + left = insupport(d, minsupport) ? '[' : '(' + right = insupport(d, maxsupport) ? ']' : ')' + discrete = d isa DiscreteUnivariateDistribution && eltype(d) !== Bool ? + "discrete over " : "" + throw(ArgumentError("value $yy in response is not in the support of the " * + "$(nameof(typeof(d))) distribution, which is $(discrete)" * + "$left$minsupport, $maxsupport$right")) + end end return nothing end -function checky(y, d::Binomial) - for yy in y - 0 ≤ yy ≤ 1 || throw(ArgumentError("$yy in y is not in [0,1]")) - end +# we allow proportions but Distributions.jl takes only the number of successes +function checky(y::AbstractVector, d::Binomial) + for yy in y + 0 ≤ yy ≤ 1 || + throw(ArgumentError("value $yy in response is not in the support of " * + "the Binomial distribution, which is [0, 1]")) + end return nothing end diff --git a/test/runtests.jl b/test/runtests.jl index 8a8af377..92f45ba3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1702,8 +1702,6 @@ end [coef(lm1), stderror(lm1), coef(lm1) ./ stderror(lm1)] @test t.cols[4] ≈ [0.5515952883836446, 3.409192065429258e-7] @test hcat(t.cols[5:6]...) == confint(lm1) - # TODO: call coeftable(gm1, ...) directly once DataFrameRegressionModel - # supports keyword arguments t = coeftable(lm1; level=0.99) @test hcat(t.cols[5:6]...) == confint(lm1; level=0.99) @@ -2653,3 +2651,28 @@ end x -0.502451 0.675377 -0.74 0.4982 -2.3776 1.3727 ─────────────────────────────────────────────────────────────────────────""" end + +@testset "response in support" begin + @test GLM.checky([0.0, -0.0, 1.0, -1.0, Inf, -Inf], Normal()) === nothing + @test_throws(ArgumentError("value NaN in response is not in the support of " * + "the Normal distribution, which is [-Inf, Inf]"), + GLM.checky([NaN], Normal())) + + @test GLM.checky([0.0, -0.0, 1.0], Poisson()) === nothing + @test_throws(ArgumentError("value 0.5 in response is not in the support of " * + "the Poisson distribution, which is discrete over [0, Inf)"), + GLM.checky([0.5], Poisson())) + @test_throws(ArgumentError("value Inf in response is not in the support of " * + "the Poisson distribution, which is discrete over [0, Inf)"), + GLM.checky([Inf], Poisson())) + + @test GLM.checky([0.0, -0.0, 1.0, 0.5], Binomial()) === nothing + @test_throws(ArgumentError("value 2.0 in response is not in the support of " * + "the Binomial distribution, which is [0, 1]"), + GLM.checky([2.0], Binomial())) + + @test GLM.checky([0.0, -0.0, 1.0], Bernoulli()) === nothing + @test_throws(ArgumentError("value 0.5 in response is not in the support of " * + "the Bernoulli distribution, which is [false, true]"), + GLM.checky([0.5], Bernoulli())) +end \ No newline at end of file From e4f16a9e1f692b63c40a727d939f126463041dca Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Mon, 5 Jan 2026 18:09:35 +0100 Subject: [PATCH 2/2] Fix formatting --- src/glmfit.jl | 6 +++--- test/runtests.jl | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/glmfit.jl b/src/glmfit.jl index 31063178..4886ed3c 100644 --- a/src/glmfit.jl +++ b/src/glmfit.jl @@ -853,7 +853,7 @@ function checky(y::AbstractVector, d::Distribution) left = insupport(d, minsupport) ? '[' : '(' right = insupport(d, maxsupport) ? ']' : ')' discrete = d isa DiscreteUnivariateDistribution && eltype(d) !== Bool ? - "discrete over " : "" + "discrete over " : "" throw(ArgumentError("value $yy in response is not in the support of the " * "$(nameof(typeof(d))) distribution, which is $(discrete)" * "$left$minsupport, $maxsupport$right")) @@ -863,11 +863,11 @@ function checky(y::AbstractVector, d::Distribution) end # we allow proportions but Distributions.jl takes only the number of successes function checky(y::AbstractVector, d::Binomial) - for yy in y + for yy in y 0 ≤ yy ≤ 1 || throw(ArgumentError("value $yy in response is not in the support of " * "the Binomial distribution, which is [0, 1]")) - end + end return nothing end diff --git a/test/runtests.jl b/test/runtests.jl index 92f45ba3..17ae1663 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2656,23 +2656,23 @@ end @test GLM.checky([0.0, -0.0, 1.0, -1.0, Inf, -Inf], Normal()) === nothing @test_throws(ArgumentError("value NaN in response is not in the support of " * "the Normal distribution, which is [-Inf, Inf]"), - GLM.checky([NaN], Normal())) + GLM.checky([NaN], Normal())) @test GLM.checky([0.0, -0.0, 1.0], Poisson()) === nothing @test_throws(ArgumentError("value 0.5 in response is not in the support of " * "the Poisson distribution, which is discrete over [0, Inf)"), - GLM.checky([0.5], Poisson())) + GLM.checky([0.5], Poisson())) @test_throws(ArgumentError("value Inf in response is not in the support of " * "the Poisson distribution, which is discrete over [0, Inf)"), - GLM.checky([Inf], Poisson())) + GLM.checky([Inf], Poisson())) @test GLM.checky([0.0, -0.0, 1.0, 0.5], Binomial()) === nothing @test_throws(ArgumentError("value 2.0 in response is not in the support of " * "the Binomial distribution, which is [0, 1]"), - GLM.checky([2.0], Binomial())) + GLM.checky([2.0], Binomial())) @test GLM.checky([0.0, -0.0, 1.0], Bernoulli()) === nothing @test_throws(ArgumentError("value 0.5 in response is not in the support of " * "the Bernoulli distribution, which is [false, true]"), - GLM.checky([0.5], Bernoulli())) -end \ No newline at end of file + GLM.checky([0.5], Bernoulli())) +end