Repository navigation
randomR could produce NaNs when the upper bound is infinity #54
Description
Activity
- Agreed. This is def a bug. I’ll make sure the next release and the associated old-random package don’t have this issue…On Tue, Apr 2, 2019 at 6:16 PM Shaobo ***@***.***> wrote: When the upper bound is infinity, NaNs could be produced. For example, filter (\x-> x/= (1/0)) $ randomRs ((0::Float), 1/0) $ mkStdGen 0 [NaN,NaN,NaN Although it's unclear what should be produced when the upper bound is infinity, I don't think NaNs should be there anyways. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#54>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAAQwld-TzcoAR8aIZDNhKt-pVzmz52xks5vc9bagaJpZM4cZO2-> .
- added a commit that references this issue
on May 5, 2020 - added a commit that references this issue
on May 19, 2020 NaNis caused by0 * ±Infinity, happening inuniformRMwhenuniformFloat01Mreturns exactly 0 or 1.We can probably guard this case explicitly:
instance UniformRange Float where uniformRM (l, h) g | isNaN l = l | isNaN h = h | l == h = return l | isInfinite l, isInfinite h = 0/0 | isInfinite l = l | isInfinite h = h | otherwise = do x <- uniformFloat01M g return $ x * l + (1 - x) * h
@curiousleo what do you think about it?
@Bodigrim you might be interested to look at discussion in this PR: idontgetoutmuch#138
Or directly here: https://hackage.haskell.org/package/random-1.2.0/docs/System-Random-Stateful.html#g:14
@Bodigrim great minds think alike :) Here's what I cooked up for my "truly random floats" experiment.
| isNaN l = l | isNaN h = h
The
isNaNguards unnecessary; if one oflorhisNaN, the result will beNaN.| l == h = return l
(This guard already exists, added here: idontgetoutmuch#169)
| isInfinite l, isInfinite h = 0/0
This is the current behaviour: you get
NaN. One alternative would be to generateInfor-Infeach with p=0.5.| isInfinite l = l | isInfinite h = h
This is already the current behaviour for
x \in (0,1). Ifx == 0orx == 1, you can currently getNaNinstead, as you pointed out. This case is currently not documented.I see two alternatives:
- We document that when
lorhis infinite, you can get aNaNback (ifx == 1orx == 0) - We add guards for infinities
@Bodigrim, would you mind clarifying whether the intent of the code you proposed was to change behaviour, or primarily to "document" current behaviour?
(Edited heavily, sorry - I misunderstood part of the proposed code.)
- We document that when
In the email notification I just received, I see
| isInfinite l && isInfinite h = bool negate id <$> uniformMI think asking to sample a range with infinties is indication that the user has made a mistake. If they really wanted +Inf / -Inf with equal probability then it would be much better for them to be explicit about it. I'd much prefer a NaN here.
| isInfinite l, isInfinite h = 0/0
I think this is right thing to do.
When the upper bound is infinity, NaNs could be produced. For example,
Although it's unclear what should be produced when the upper bound is infinity, I don't think NaNs should be there anyways.