Skip to content

consistently treat Bernoulli as a distribution on Bools#2022

Open
aplavin wants to merge 1 commit intoJuliaStats:masterfrom
aplavin:berbool
Open

consistently treat Bernoulli as a distribution on Bools#2022
aplavin wants to merge 1 commit intoJuliaStats:masterfrom
aplavin:berbool

Conversation

@aplavin
Copy link
Contributor

@aplavin aplavin commented Dec 23, 2025

Currently, it's quite inconsistent: eg, eltype === Bool, rand()::Bool, minimum()::Bool, but mode and median are Int, and quantile is T (often, float).
With this PR Bernoulli returns Bool whenever possible and makes sense.

This is both self-consistent between functions on Bernoulli, and also makes it consistent with other discrete distributions like Binomial / Categorical / DiscreteUniform / DiscreteNonParametric that return the minimal type (often Int) for their quantile and other functions.

@codecov-commenter
Copy link

codecov-commenter commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 75.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.36%. Comparing base (7f59245) to head (53c3ea2).

Files with missing lines Patch % Lines
src/univariate/discrete/bernoulli.jl 71.42% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2022   +/-   ##
=======================================
  Coverage   86.36%   86.36%           
=======================================
  Files         146      146           
  Lines        8789     8789           
=======================================
  Hits         7591     7591           
  Misses       1198     1198           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.


function quantile(d::Bernoulli{T}, p::Real) where T<:Real
0 <= p <= 1 ? (p <= failprob(d) ? zero(T) : one(T)) : T(NaN)
function quantile(d::Bernoulli, p::Real)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert the changes to quantile and cquantile? The current API (probably historically based on Rmath) is to never error but to return NaN for invalid arguments. I think this should be changed, but that requires a more general change of the API of these functions: #1805

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverting quantile implies also reverting median for consistency, and then basically we lose the point of this PR

any hope of #1805 in the foreseeable future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, quantile throws sometimes already:

julia> quantile(Bernoulli{Int}(1), 2)
ERROR: InexactError: Int64(NaN)

Copy link
Member

@devmotion devmotion Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any hope of #1805 in the foreseeable future?

Has been ready since > 2 years, just needs a review.

reverting quantile implies also reverting median for consistency, and then basically we lose the point of this PR

The current implementation of quantile is wrong (IMO) but it's consistent. It would be worse if some distributions would behave differently, we can't start erroring just for Bernoulli. You can still change mode, modes and support without touching quantile/cquantile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't start erroring just for Bernoulli

It already errors sometimes (and with a different exception). In addition to the example above:

quantile(Bernoulli(1//3), 2)

Copy link
Contributor Author

@aplavin aplavin Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any references to that? Where do you get that "The current API is to return NaN for invalid inputs"?

Currently, the situation is that basically all discrete distributions return integers from quantile. And naturally, they throw an exception when p not in 0..1.
Documentation doesn't seem to contradict this in the slightest.
Even Bernoulli often behaves like that. It is Bernoulli{Float}() that is an exception (resolved by this PR).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I just noted at #1805, NaN is allowed for many continuous distributions (Normal, Geometric, Exponential, Cauchy, Bernoulli...). And discrete distributions don't throw DomainErrors, they just get an error during calculations, without any indication that it's intentional. Let's get that PR merged.

Copy link
Contributor Author

@aplavin aplavin Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discrete distributions don't throw DomainErrors

Technically, this doesn't throw a DomainError indeed:

0 <= q <= 1 || throw(DomainError())

But only because there's no zero-argument constructor for DomainError. Seems pretty much intentional :)

continuous distributions (<...>, Bernoulli...)

??

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But only because there's no zero-argument constructor for DomainError. Seems pretty much intentional :)

I was referring to

julia> quantile(Binomial(10, 0.2), 2)
ERROR: InexactError: Int64(NaN)

Though the DomainError error is funny.

continuous distributions (<...>, Bernoulli...)

Sorry, I was talking only about the special case of passing NaN: quantile(Bernoulli(), NaN).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

julia> quantile(Binomial(10, 0.2), 2)
ERROR: InexactError: Int64(NaN)

It's an error still, just a less understandable one. If preferred, this PR can be changed into throwing the same one for Bernoulli, although I think DomainError is cleaner.

Anyway, from experience with this and my previous PR attempts to Distributions over the years, I find it super hard to add/change anything in this package. I had barely any success with that, in stark contrast to other Julia packages. So I'll stop here, and just hope that some improvements do happen at some point...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants