Randoms

We again introduce some notation:

Mathematical Description Programmatic
X∈𝕏X\in \mathbb{X} A random variable in the set (of type) 𝕏\mathbb{X}. x:Random<X>
X∼p(dx)X\sim p(\mathrm{d}x) Assume that the random variable XX is distributed according to the distribution p(dx)p(\mathrm{d}x). x ~ p

In Birch code, a random variable is represented by an object of the Random class. Like Distribution, Random is a generic class: we use it as Random<X>, where X is the type of variate it accepts, e.g. Random<Real> (on ℝ\mathbb{R}), Random<Integer> (on ℤ\mathbb{Z}), Random<Real[_]> (on ℝD\mathbb{R}^D), etc.

We can declare a random variable:

x:Random<Real>;

and assign a value into it:

x <- 1.5823;

We can even simulate a value into it:

x <~ Gaussian(0.0, 4.0);

It is only possible to assign or simulate a value once into a random variable, however. Once it has a value, it cannot be reassigned. We can get the value assigned to a random with x.value(), possibly while observing:

x.value() ~> Gaussian(0.0, 4.0);

For these use cases, a Random<Real> object offers no real benefit over a basic x:Real value. Where it becomes more useful is in conjunction with the assume operator (~):

x ~ Gaussian(0.0, 4.0);

The assume operator can also be used to represent joint distributions between random variables:

x:Random<Real>;
y:Random<Boolean>;
x ~ Beta(2.0, 2.0);
y ~ Bernoulli(x);

Random objects, in combination with the assume operator (~), facilitate probabilistic computations such as automatic marginalization, conditioning and differentiation. We will return to such computations later.