Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0 <= cdf(truncated(Normal(2.5, 0.2), lower=0.0),x) not always true. #1854

Closed
lrnv opened this issue Apr 20, 2024 · 3 comments · Fixed by #1865
Closed

0 <= cdf(truncated(Normal(2.5, 0.2), lower=0.0),x) not always true. #1854

lrnv opened this issue Apr 20, 2024 · 3 comments · Fixed by #1865

Comments

@lrnv
Copy link

lrnv commented Apr 20, 2024

Followup to #1853

Consider the following:

using Distributions
D = truncated(Normal(2.5, 0.2), lower=0.0)
cdf(D, 3.741058503233821e-17) > 0  # false
cdf(D, 1.4354474178676617e-18) > 0 # false
cdf(D, 8.834854780587132e-18) > 0  # false

I think I am simply hitting catastrophic cancellation in this line.

I understand that such numerical incauracies are always possible at borders, but would that be considered a bug ?

@devmotion
Copy link
Member

I'd consider a cdf that returns values < 0 or > 1 a bug. This is the case in your example:

julia> cdf(D, 3.741058503233821e-17)
-3.00686029885372e-50

julia> cdf(D, 1.4354474178676617e-18)
-3.00686029885372e-50

julia> cdf(D, 8.834854780587132e-18)
-3.00686029885372e-50

I'm leaning towards clamping the result in cdf because my initial feeling is that the truncated "wrapper" can be expected to be based on the cdf of the untruncated distribution.

Alternatively, one could define cdf(d::Truncated, x::Real) = exp(logcdf(d, x)). This would also fix the example:

julia> exp(logcdf(D, 3.741058503233821e-17))
0.0

julia> exp(logcdf(D, 1.4354474178676617e-18))
0.0

julia> exp(logcdf(D, 8.834854780587132e-18))
0.0

But I'm not sure if it's a good default since in many cases this will be less efficient - even though the current result from cdf is accurate enough.

@lrnv
Copy link
Author

lrnv commented Apr 21, 2024

I think clamping on the line that I quoted is better than cdf(d::Truncated, x::Real) = exp(logcdf(d, x)) for performance reasons. The same thing should be done to ccdf(d::Truncated,...) for the same reason

@burtonjosh
Copy link

Just came across this issue myself with the following values:

julia> cdf(
         truncated(Normal(2.122039143928797, 0.07327367710864985),
           lower = 1.9521656132878236,
           upper = 2.8274429454898398,
         ),
         2.82,
       )
1.0000000000000002

Julia version 1.10.3, Distributions.jl version 0.25.108

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 a pull request may close this issue.

3 participants