-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
fix rand(Float16|Float32) equal to 1 #9387
Conversation
Why not use rand(r::AbstractRNG, ::Type{Float16}) =
Float16(reinterpret(Float32, rand(r, UInt16) % UInt32 & 0x007fe000 | 0x3f800000) - 1)
rand(r::AbstractRNG, ::Type{Float32}) =
reinterpret(Float32, rand(r, UInt32) % UInt32 & 0x007fffff | 0x3f800000) - 1 so that all other AbstracRNG implementations becomes correct for Be aware that I don't understand what |
The reason was that if a particular RNG defines e.g.
That way, the general fallback will be chosen only if not other implementation at all is available. Another solution would be for an RNG to call a like macro Concerning |
If we don't figure out a way to implement rand{T<:Union(Float16,Float32,Float64)}(r::AbstractRNG, ::Type{T}) correctly, I can't see why other implementations would want to do that. Either there is a way to write that generic implementation, or there isn't. For PS: I hope you enjoy my comments, and don't get frustrated with my lack of understanding. I have big interest in random numbers and extensible generic interfaces, and believe that any code review is typically better than none. |
That was an improbable example, but which still could happen: let's say I'm writing a wrapper RNG: for floating points, I want it to wrap
is the normal way of writing the wrapping, but the Base generic implementation would get in the way. PS: I enjoy a lot your comments! to the point and lead to better code most of the time. Having my code reviewed is new for me and appreciate how useful/efficient it can be. |
My vision for the fallback system is that we should only need a single method to plug a new RNG into the system (eg It's sad that we have to resort to |
It would certainly be nice if the implementation for Float16 and Float32 here could be for AbstractRNG. Is there something we can do here to fix this particular issue, and a more general solution that we adopt in the near future? We certainly could use an RNG.jl package that adds more RNGs to julia, and helps us refine the interfaces in base. |
Cf. bug reported by @tkelman in #9301. As noted by @ivarne, converting a Float64 different from 1 to Float16 or Float32 can produce a value equal to one, which doesn't agree with the documented API. So instead of converting, let's produce a Float16/Float32 in [1,2) at the bit level, and then substract 1 (as was done in the array versions). As a side effect, this also makes rand(Float16) about twice as fast.
8a27658
to
f1ab1c9
Compare
I updated to make I agree that it would be better to provide Within a |
I am inclined to merge this to fix the reported issue, and figure out the APIs in future work. @ivarne would that be ok? |
I don't like postponing API discussions, but as this actually fixes a real problem in a correct way for the existing RNGs, I think we can merge this now. I see the potential ambiguity problem @rfourquet is concerned about, but I don't think he makes the right tradeoff. I might be wrong, and it would be great if others could comment on the issue. |
fix rand(Float16|Float32) equal to 1
I too would prefer that if you have a new RNG, all you have to do is provide a method for dSFMT is a bit different in that it produces |
I'm all for having everything work out automatically, but my reserve comes from having had more that once ambiguity warning caused by a method in base which is not enough constrained. As long as there is no way of telling the compiler that a method should take precedence over another one (i.e. explicitly playing with the "hierarchy" of methods), I think a method
but I wish we did the same for all types. Asking the user to define traits for her RNG seems workable but not friendly/robust enough given Julia's introspection capabilities. There is probably a solution with I would see a package RNG.jl as an easier playgroud to devise a satisfying automating mecanism. I guess I could start by properly wrapping rdrand, hopefully within few weeks. |
I didn't understand @ViralBShah 's "Producing Float16 from RandomDevice should ideally just work out" as I thought it worked, and then saw I forgot to add a shift when I changed the implementation to use |
As the build looks ok, I'll merge the fix. |
Yes, please do |
Cf. bug reported by @tkelman in #9301.
As noted by @ivarne, converting a Float64 different from 1 to Float16
or Float32 can produce a value equal to one, which doesn't agree with
the documented API.
So instead of converting, let's produce a Float16/Float32 in [1,2) at
the bit level, and then substract 1 (as was done in the array versions).
As a side effect, this also makes rand(Float16) about twice as fast.