public int MultinomialSample(double[] probabilities)
{
const double EPSILON = 0.01;
// normalize probabilities
var k = 1.0 / probabilities.Sum();
var probs = probabilities.Select(pr => k * pr);
if (probs.Sum() < 1 - EPSILON || probs.Sum() > 1 + EPSILON)
{
throw new Exception("Probabilities do not sum to 1.");
}
// draw intervals
double[] intervals = probs.Select((pr_1, i) => probs.Where((pr_2, j) => j < i).Sum() + pr_1).ToArray();
// draw a sample
var s = r.NextDouble();
// the inputchars at index idx is the char to mistype
for (int i = 0; i < intervals.Length; i++)
{
if (s > intervals[i])
{
continue;
}
else
{
return i;
}
}
throw new Exception("Cannot find appropriate bin.");
}