haskell / statistics

A fast, high quality library for computing with statistics in Haskell.
http://hackage.haskell.org/package/statistics
BSD 2-Clause "Simplified" License
300 stars 68 forks source link

Possibility to use other random number generator #164

Closed dschrempf closed 2 years ago

dschrempf commented 4 years ago

Did you already think about the possibility to use another random number generator, for example, splitmix. Maybe it would also be possibly to leave this choice to the user?

I am working on an MCMC sampler, and speed is really important in my case. Splitmix is splittable, and much faster, and it would be the first choice for me, if I had one.

Thanks for your consideration!

Shimuuar commented 4 years ago

I did. I'm going to switch to new StatefulGen API once random-1.2 is released. Port should be very straightforward so I don't expect any problems with it

dschrempf commented 4 years ago

Great, thank you!

On June 12, 2020 11:36:09 AM GMT+02:00, Aleksey Khudyakov notifications@github.com wrote:

I did. I'm going to switch to new StatefulGen API once random-1.2 is released. Port should be very straightforward so I don't expect any problems with it

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/bos/statistics/issues/164#issuecomment-643177519

-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

infinity0 commented 4 years ago

FWIW it's already pretty straightforward to integrate this package with another RNG. Here is some code I'm using locally for integration with Crypto.Random.DRG from cryptonite (I already have one of these in my application, so would rather use it than add a second RNG).

-- | Generate a random value between [0, 1).
randomProbGenerate :: DRG g => g -> (Double, g)
randomProbGenerate g0 =
  let (w, g1) = randomWord64Generate g0
      w12     = (w .&. 0x000fffffffffffff .|. 0x3ff0000000000000) -- some double in [1, 2)
  in  (castWord64ToDouble w12 - 1.0, g1)

-- | Keep generating a value until it fits a predicate.
--
-- >>> let (p, g1) = generateUntil (/= 0.0) randomProbGenerate g0
generateUntil :: DRG g => (a -> Bool) -> (g -> (a, g)) -> g -> (a, g)
generateUntil match gen g0 =
  let (a, g1) = gen g0
  in  if match a then (a, g1) else generateUntil match gen g1

-- | Draw from a continuous distribution using the inverse cumulative density
-- function.
drawCont :: (ContDistr d, DRG g) => d -> g -> (Double, g)
drawCont d g0 =
  let (p, g1) = generateUntil (/= 0.0) randomProbGenerate g0
  in  (quantile d p, g1)

-- | Draw from a discrete distribution using a sequence of Bernoulli draws.
fromPMF :: DRG g => (Int -> Double) -> g -> (Int, g)
fromPMF prob g0 = f 0 1 g0
 where
  f i r g =
    let q       = prob i
        (p, g1) = randomProbGenerate g0
    in  if
          | r < 0          -> error "fromPMF: total PMF above 1"
          | q < 0 || q > 1 -> error "fromPMF: invalid probability value"
          | p * r < q      -> (i, g1)
          | i <= 0         -> f (1 - i) (r - q) g1
          | otherwise      -> f (-i) (r - q) g1

-- | Draw from a discrete distributions using the probability mass function.
drawDisc :: (DiscreteDistr d, DRG g) => d -> g -> (Int, g)
drawDisc = fromPMF . probability

fromPMF is adapted from monad-bayes (their version ignores negative values), and the precise implementation of randomWord64Generate will depend on your RNG.

dschrempf commented 4 years ago

FYI, random 1.2 has been released around a week ago, and it looks promising!

Shimuuar commented 4 years ago

I know :) but between day job, vector, random, mwc-random and statistics I only managed to almost prepare new release for mwc-random.

dschrempf commented 4 years ago

Sorry, I didn't mean to be pushy. I didn't know you were also maintaining these packages :).

On July 2, 2020 11:06:42 PM GMT+02:00, Aleksey Khudyakov notifications@github.com wrote:

I know :) but between day job, vector, random, mwc-random and statistics I only managed to almost prepare new release for mwc-random.

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/bos/statistics/issues/164#issuecomment-653220445

-- Sent from my Android device with K-9 Mail. Please excuse my brevity.

dschrempf commented 3 years ago

Hi! Sorry for bumping... Did you already find some time to work on this? Thanks!

dschrempf commented 3 years ago

Hi! I know, I am seriously annoying... But this is somewhat important to me. Let me know if I can help! The problem is, I don't know where to start. Thanks!

dschrempf commented 3 years ago

Sorry to bother you, I know this is all voluntary work. Any thoughts on moving forward with this?

Shimuuar commented 2 years ago

Finally fixed in #176. Sorry it took so long

dschrempf commented 2 years ago

Thank you very much and my apologies again for pressing on that matter! I am looking forward to using this feature!