Hi, I just wanted to mention that I have just published Alea, a library to work with random variables.
It is still in a pretty early stage, and some things may not work very well, but this is an example of use:
import alea, future
import random/urandom, random/mersenne
type Coin = enum Head, Tails
proc asInt(x: float): int = x.int
lift(asInt)
var rng = wrap(initMersenneTwister(urandom(16)))
let
p = poisson(20).asInt.filter((x: int) => x mod 2 == 0)
g = gaussian(mu = 3, sigma = 12).where(p, (t: int) => t > 6)
coin = choose(@[Head, Tails])
echo rng.stddev(g)
echo rng.sample(coin)
Well, filter samples until a condition is true.
Where conditions on a different random variable. It does exactly what you say: it samples from p until the condition in true, then return what g samples in that point.
The example above is really artificial, since the two random variables are independent, but when the two variables are dependent it may very well be important. Think of all the problems like "What is the expected value of something knowing that something else..."
Interesting library!
I just want to confirm that I'm using it correctly. Say I want to sample a normally distributed integer between 4 and 10, is the following feasible:
import alea, future
import random/urandom, random/mersenne
var rng = wrap(initMersenneTwister(urandom(16)))
let
g = gaussian(mu = 0, sigma = 1)
a = g.map((x: float) => x + 7)
b = a.filter((x: float) => x > 4)
c = b.filter((x: float) => x < 10)
echo int(rng.sample(c))
A single call, as in:
g = gaussian(mu = 7, sigma = 1).filter((x: float) => x > 4).filter((x: float) => x < 10)