...

/

Probability Distribution Monad with Round Numbers

Probability Distribution Monad with Round Numbers

In this lesson, we will learn an example of probability distribution monads by using rounded numbers.

We'll cover the following...

In the previous lesson, we made a correct, efficient implementation of SelectMany to bind a likelihood function and projection onto a prior, and gave a simple example.


Example with Rounded Numbers

We deliberately chose “weird” numbers for all the weights; let’s do that same example again but with more “nice round number” weights:

var prior = new List<Height>() { Tall, Medium, Short}.ToWeighted(60, 30, 10);
[...]

IDiscreteDistribution<Severity> likelihood(Height h)
{
  switch(h)
  {
    case Tall: return severity.ToWeighted(45, 55, 0);
    case Medium: return severity.ToWeighted(0, 70, 30);
    default: return severity.ToWeighted(0, 0, 1);
  }
}

[... projection as before ...]
Console.WriteLine(prior.SelectMany(likelihood, projection).ShowWeights());

This produces the output:

DoubleDose:270000
NormalDose:540000
HalfDose:190000

which is correct, but you’ll notice how multiplying the weights during the SelectMany made for some unnecessarily large weights. If we then did another SelectMany on this thing, they’d get even larger, and we’d be getting into integer overflow territory.

Integer overflow is always possible in the system we’ve developed so far in this course, and we are deliberately glossing over this serious problem. A better implementation would either use doubles for weights, which have a much larger range, or arbitrary-precision integers, or arbitrary-precision rationals. We are using integers to keep it simple, but as with many aspects of the code in this course, that would become problematic in a realistic implementation.

One thing we can do to tame this slightly is to reduce all the weights when possible, in this case, we could ...