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)

2017-01-11 08:52:04
Ok, I looked at it, and I do not really get what where does. All I got was that it samples from p until the condition is true, but then as far as I can see it does not use that value.
2017-01-11 11:11:22

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..."

2017-01-11 11:26:26

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))

2017-02-10 17:05:37
It should work like this, yes. By the way, you can directly set mu = 7 and skip the map, as well as do both filters in a single call
2017-02-10 17:14:19

A single call, as in:

g = gaussian(mu = 7, sigma = 1).filter((x: float) => x > 4).filter((x: float) => x < 10)

2017-02-10 17:21:19