...

/

Discrete Distribution on C# Objects

Discrete Distribution on C# Objects

In this lesson, we will learn how to apply discrete distribution on C# objects, and write a wrapper class for it.

In the previous lesson, we showed how we could implement more of the standard, straightforward probability distributions, like the Bernoulli distribution.


Uniformly Choosing Between Objects

Typically when we are working on a line-of-business program, we’re working on objects that are meaningful in that line of business, and not necessarily on integers. Just to pick an example, suppose we want to uniformly choose between a cat, a dog, and a goldfish:

using SDU = StandardDiscreteUniform;
...
var animals = new List<Animal>()
  { new Cat(), new Dog(), new Goldfish() };

Traditionally, as we noted a while back, we’d write some mechanism-heavy code like:

var choice = animals[random.Next(0, animals.Length)];

Now, we sincerely hope you’re not satisfied with:

var choice = animals[SDU.Distribution(0, animals.Length-1).Sample()];

The problem here is that we’ve failed to push the “mechanism” code into a helper class, so let’s do that:

// This is wrong!
public sealed class DiscreteUniform<T> : IDiscreteDistribution<T>
{
  private readonly SDU sdu;
  private readonly List<T> support;
  public static DiscreteUniform<T> Distribution(IEnumerable<T> items) => new DiscreteUniform<T>(items);

  private DiscreteUniform(IEnumerable<T> items)
  {
    this.support = items.ToList();
    this.sdu = SDU.Distribution(0, support.Count – 1);
  }

  public IEnumerable<T> Support() => support;
  public T Sample() => support[sdu.Sample()];
  public int Weight(T t) => this.support.Contains(t) ? 1 : 0;
  public override string ToString() =>
    $"DiscreteUniform[{string.Join(",", support)}]";
}

Exercise: That code is wrong in a number of ways; what are they? Give it some thought and then click on Show Hint.

Fixing Problems

We’ll fix all these problems in our final implementation at the bottom of this lesson.

Suppose ...