/// <summary> /// Samples one multinomial distributed random variable. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="p">An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic.</param> /// <param name="n">The number of trials.</param> /// <returns>the counts for each of the different possible values.</returns> public static int[] Sample(System.Random rnd, double[] p, int n) { if (Control.CheckDistributionParameters && !IsValidParameterSet(p, n)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } // The cumulative density of p. var cp = Categorical.ProbabilityMassToCumulativeDistribution(p); // The variable that stores the counts. var ret = new int[p.Length]; for (var i = 0; i < n; i++) { ret[Categorical.SampleUnchecked(rnd, cp)]++; } return(ret); }
/// <summary> /// Samples a multinomially distributed random variable. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="p">An array of nonnegative ratios: this array does not need to be normalized /// as this is often impossible using floating point arithmetic.</param> /// <param name="n">The number of variables needed.</param> /// <returns>a sequence of counts for each of the different possible values.</returns> public static IEnumerable <int[]> Samples(Random rnd, double[] p, int n) { if (Control.CheckDistributionParameters && !IsValidParameterSet(p, n)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } // The cumulative density of p. var cp = Categorical.UnnormalizedCdf(p); while (true) { // The variable that stores the counts. var ret = new int[p.Length]; for (var i = 0; i < n; i++) { ret[Categorical.SampleUnchecked(rnd, cp)]++; } yield return(ret); } }