Sample from probability distributions

Hey all!

I have little experience using Haskell outside of Tidal, so this question might be a bit silly.
I'm trying to sample from an exponential probability distribution using its quantile function:

rexp :: Pattern Double -> Pattern Double
rexp lambda = log (1 - p) / lambda * (-1) where
  p = rand

p must be a random number between 0 and 1, hence p = rand.

However, if I run

d1 $ slow (rexp 1) $ s "bd"

I get the error Couldn't match type 'Double' with 'Ratio Integer'. I have tried changing the input-output types, but still ran into issues.

How can I solve this? Is there a better way to achieve what I want?

1 Like

Welcome @las, slow only accepts values of type Pattern Time, which is an alias of Pattern Rational, i.e. patterns of rational numbers, not doubles. The realToFrac function can convert from doubles to other fractional types, including floating points ones. You can apply it like this:

rexp :: Fractional a => Pattern Double -> Pattern a
rexp lambda = realToFrac $ log (1 - rand) / lambda * (-1)

I'd rejig it a bit like this though:

rexp :: Fractional a => Pattern Double -> Pattern a
rexp lambda = (\x -> realToFrac $ log (1 - x) / lambda * (-1)) <$> rand

That is, work on the numbers inside the random pattern, rather than do arithmetic on the pattern level. It'll be more efficient that way, and generally less confusing when it comes to the structure of the resulting pattern.

Hey @yaxu, thanks a lot! I'll experiment with sampling from other distributions and if I find any interesting patterns while doing it I might do a write up on this topic. Thanks for the work by the way, I'm loving Tidal so far - it's incredibly expressive.