-
Notifications
You must be signed in to change notification settings - Fork 415
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
Computed field len and rand now returns type T in Uniform{T} #1796
base: master
Are you sure you want to change the base?
Conversation
Added computed field len which is the length of the interval to be sampled from. Also replaced all instances of (d.b-d.a) by the new field d.len.
The |
Regarding |
@@ -151,7 +152,7 @@ Base.:*(c::Real, d::Uniform) = Uniform(minmax(c * d.a, c * d.b)...) | |||
|
|||
#### Sampling | |||
|
|||
rand(rng::AbstractRNG, d::Uniform) = d.a + (d.b - d.a) * rand(rng) | |||
rand(rng::AbstractRNG, d::Uniform{T}) where T = d.a + d.len * rand(T, rng) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rand(rng::AbstractRNG, d::Uniform{T}) where T = d.a + d.len * rand(T, rng) | |
rand(rng::AbstractRNG, d::Uniform{T}) where T = d.a + d.len * rand(float(T), rng) |
You need to promote T
to a floating-point type.
In particular, this corresponds to issue #1783. |
With the current design, the "correct" fix would be to always return Float64 as the variates are supposed to be of type Float64. But as said, I'd rather fix this design. I'll try to write up our suggestions and draft a PR within the next few days. |
Why would one expect a Float64 result when sampling a distribution with parameters only specified to Float32 precision, especially if the parameters are from the same space as the random variable? I think that API to specify the output type would be nice, but in the absence of such an initiative and given the fact that there is no promise regarding Float64 output, the proposed change looks reasonable to me. |
I haven't used Distributions extensively, but currently calling rand on Uniform{Float32} does also return a Float32. Regarding your comment on the len field, I don't see why this would be a problem. For most design patterns in Julia we may assume a user won't directly change any struct fields, right? If so then inconsistencies shouldn't be a problem. |
@f-ij, was this a typo? It returns a julia> u = Uniform(1.0f0, 2.0f0)
Uniform{Float32}(a=1.0f0, b=2.0f0)
julia> rand(u)
1.8944514300368434
julia> typeof(ans)
Float64 |
Sorry that was indeed a typo! I meant Normal{Float32}.. |
Changing There are clear ideas for a better design and a push for making these changes. |
What is the issue/PR to track/contribute to? Sorry @f-ij for sending you in the wrong direction. I was under the false impression that this would be uncontroversial. |
There are two different aspects: The IMO the most natural way to address the first one is to create a spl = sampler(dist)
x = rand(spl)
for _ in 1:1_000_000
x += rand(spl)
end instead of x = rand(dist)
for _ in 1:1_000_000
x += rand(dist)
end (FYI these samplers are already used internally when you create an array of samples; if there exists no sampler for a distribution, The design question is discussed in multiple issues and even PRs (#1433), but it's a bit scattered since multiple duplicate issues have been opened and discussions started from scratch or recircled to already existing explanations. |
I did not know about |
Not a problem at all, it was not much work and I gained me some insight out of it. |
Added computed field len which is the length of the interval to be sampled from. Also replaced all instances of (d.b-d.a) by the new field d.len.
Fixed an issue where rand(::Uniform{Float32}) (and other, non Float64 types) did not in fact return a Float32, but a Float64, which caused some performance issues. This was done by modifiying the method rand(rng::AbstractRNG, d::Uniform) to include the subtype of Uniform and pass it to rand.
This was discussed on discourse