public void DiscreteChoiceFromCDF() { var r = new TMGRandom(12345); var choiceModel = new DiscreteChoiceFromCDF() { Name = "Choice Model" }; float[] data = Enumerable.Repeat(0f, 100).ToArray(); for (int i = 0; i < data.Length; i++) { data[i] = r.Pop(); } var invSum = 1.0f / VectorHelper.Sum(data, 0, data.Length); data[0] *= invSum; for (int i = 1; i < data.Length; i++) { data[i] = (data[i] * invSum) + data[i - 1]; } for (int i = 0; i < 100; i++) { var result = choiceModel.Invoke((r, data)); if (result < 0) { Assert.Fail("Generated a number less than zero!"); } if (result >= data.Length) { Assert.Fail("Generated a number greater than the number of choices!"); } } }
public void DiscreteChoiceFromProbabilities() { var r = new TMGRandom(12345); var choiceModel = new DiscreteChoiceFromProbabilities() { Name = "Choice Model" }; float[] data = Enumerable.Repeat(0f, 100).ToArray(); for (int i = 0; i < data.Length; i++) { data[i] = r.Pop(); } var total = VectorHelper.Sum(data, 0, data.Length); VectorHelper.Multiply(data, data, 1.0f / total); for (int i = 0; i < 100; i++) { var result = choiceModel.Invoke((r, data)); if (result < 0) { Assert.Fail("Generated a number less than zero!"); } if (result >= data.Length) { Assert.Fail("Generated a number greater than the number of choices!"); } } }
/// <summary> /// Randomly select an element from a CDF vector. /// </summary> /// <param name="random">The random algorithm to use.</param> /// <param name="cdf">The CDF vector to chose from.</param> /// <returns>The index that was selected.</returns> public static int DiscreteChoiceFromCDF(TMGRandom random, Span <float> cdf) { var pop = random.Pop(); // there is no need to check the last element for (int i = 0; i < cdf.Length - 1; i++) { if (pop > cdf[i]) { return(i); } } return(cdf.Length - 1); }
/// <summary> /// Randomly select an element from a probability vector. /// </summary> /// <param name="random">The random algorithm to use.</param> /// <param name="probabilities">The probability vector to chose from.</param> /// <returns>The index that was selected.</returns> public static int DiscreteChoiceFromProbabilities(TMGRandom random, Span <float> probabilities) { var pop = random.Pop(); var acc = 0.0f; for (int i = 0; i < probabilities.Length; i++) { acc += probabilities[i]; if (acc >= pop) { return(i); } } return(probabilities.Length - 1); }