/// <summary> /// Samples a Dirichlet distributed random vector. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="alpha">The Dirichlet distribution parameter.</param> /// <returns>a sample from the distribution.</returns> public static double[] Sample(Random rnd, double[] alpha) { if (Control.CheckDistributionParameters && !IsValidParameterSet(alpha)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } var n = alpha.Length; var gv = new double[n]; var sum = 0.0; for (var i = 0; i < n; i++) { if (alpha[i] == 0.0) { gv[i] = 0.0; } else { gv[i] = Gamma.Sample(rnd, alpha[i], 1.0); } sum += gv[i]; } for (var i = 0; i < n; i++) { gv[i] /= sum; } return(gv); }
/// <summary> /// Samples the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="nu">The nu parameter to use.</param> /// <param name="s">The S parameter to use.</param> /// <param name="chol">The cholesky decomposition to use.</param> /// <returns>a random number from the distribution.</returns> private static Matrix <double> DoSample(Random rnd, double nu, Matrix <double> s, Cholesky <double> chol) { var count = s.RowCount; // First generate a lower triangular matrix with Sqrt(Chi-Squares) on the diagonal // and normal distributed variables in the lower triangle. var a = new DenseMatrix(count, count, 0.0); for (var d = 0; d < count; d++) { a[d, d] = Math.Sqrt(Gamma.Sample(rnd, (nu - d) / 2.0, 0.5)); } for (var i = 1; i < count; i++) { for (var j = 0; j < i; j++) { a[i, j] = Normal.Sample(rnd, 0.0, 1.0); } } var factor = chol.Factor; return(factor * a * a.Transpose() * factor.Transpose()); }
/// <summary> /// Samples standard student-t distributed random variables. /// </summary> /// <remarks>The algorithm is method 2 in section 5, chapter 9 /// in L. Devroye's "Non-Uniform Random Variate Generation"</remarks> /// <param name="rnd">The random number generator to use.</param> /// <param name="dof">The degrees of freedom for the standard student-t distribution.</param> /// <returns>a random number from the standard student-t distribution.</returns> internal static double Sample(Random rnd, double dof) { var n = Normal.SampleBoxMuller(rnd).Item1; var g = Gamma.Sample(rnd, 0.5 * dof, 0.5); return(Math.Sqrt(dof / g) * n); }
/// <summary> /// Samples the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="degreesOfFreedom">The degrees of freedom (n) for the Wishart distribution.</param> /// <param name="scale">The scale matrix (V) for the Wishart distribution.</param> /// <param name="chol">The cholesky decomposition to use.</param> /// <returns>a random number from the distribution.</returns> static Matrix <double> DoSample(System.Random rnd, double degreesOfFreedom, Matrix <double> scale, Cholesky <double> chol) { var count = scale.RowCount; // First generate a lower triangular matrix with Sqrt(Chi-Squares) on the diagonal // and normal distributed variables in the lower triangle. var a = new DenseMatrix(count, count); for (var d = 0; d < count; d++) { a.At(d, d, Math.Sqrt(Gamma.Sample(rnd, (degreesOfFreedom - d) / 2.0, 0.5))); } for (var i = 1; i < count; i++) { for (var j = 0; j < i; j++) { a.At(i, j, Normal.Sample(rnd, 0.0, 1.0)); } } var factor = chol.Factor; return(factor * a * a.Transpose() * factor.Transpose()); }
/// <summary> /// Generates a sample from the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="shape">The shape (α) of the distribution. Range: α > 0.</param> /// <param name="scale">The scale (β) of the distribution. Range: β > 0.</param> /// <returns>a sample from the distribution.</returns> public static double Sample(System.Random rnd, double shape, double scale) { if (shape <= 0.0 || scale <= 0.0) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } return(1.0 / Gamma.Sample(rnd, shape, scale)); }
/// <summary> /// Samples the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="dof">The degrees of freedom.</param> /// <returns>a random number from the distribution.</returns> private static double DoSample(Random rnd, double dof) { //Use the simple method if the dof is an integer anyway if (Math.Floor(dof) == dof && dof < Int32.MaxValue) { double sum = 0; var n = (int)dof; for (var i = 0; i < n; i++) { sum += Math.Pow(Normal.Sample(rnd, 0.0, 1.0), 2); } return(sum); } //Call the gamma function (see http://en.wikipedia.org/wiki/Gamma_distribution#Specializations //for a justification) return(Gamma.Sample(rnd, dof / 2.0, .5)); }
/// <summary> /// Run example /// </summary> /// <a href="http://en.wikipedia.org/wiki/Gamma_distribution">Gamma distribution</a> public void Run() { // 1. Initialize the new instance of the Gamma distribution class with parameter Shape = 1, Scale = 0.5. var gamma = new Gamma(1, 2.0); Console.WriteLine(@"1. Initialize the new instance of the Gamma distribution class with parameters Shape = {0}, Scale = {1}", gamma.Shape, gamma.Scale); Console.WriteLine(); // 2. Distributuion properties: Console.WriteLine(@"2. {0} distributuion properties:", gamma); // Cumulative distribution function Console.WriteLine(@"{0} - Сumulative distribution at location '0.3'", gamma.CumulativeDistribution(0.3).ToString(" #0.00000;-#0.00000")); // Probability density Console.WriteLine(@"{0} - Probability density at location '0.3'", gamma.Density(0.3).ToString(" #0.00000;-#0.00000")); // Log probability density Console.WriteLine(@"{0} - Log probability density at location '0.3'", gamma.DensityLn(0.3).ToString(" #0.00000;-#0.00000")); // Entropy Console.WriteLine(@"{0} - Entropy", gamma.Entropy.ToString(" #0.00000;-#0.00000")); // Largest element in the domain Console.WriteLine(@"{0} - Largest element in the domain", gamma.Maximum.ToString(" #0.00000;-#0.00000")); // Smallest element in the domain Console.WriteLine(@"{0} - Smallest element in the domain", gamma.Minimum.ToString(" #0.00000;-#0.00000")); // Mean Console.WriteLine(@"{0} - Mean", gamma.Mean.ToString(" #0.00000;-#0.00000")); // Mode Console.WriteLine(@"{0} - Mode", gamma.Mode.ToString(" #0.00000;-#0.00000")); // Variance Console.WriteLine(@"{0} - Variance", gamma.Variance.ToString(" #0.00000;-#0.00000")); // Standard deviation Console.WriteLine(@"{0} - Standard deviation", gamma.StdDev.ToString(" #0.00000;-#0.00000")); // Skewness Console.WriteLine(@"{0} - Skewness", gamma.Skewness.ToString(" #0.00000;-#0.00000")); Console.WriteLine(); // 3. Generate 10 samples of the Gamma distribution Console.WriteLine(@"3. Generate 10 samples of the Gamma distribution"); for (var i = 0; i < 10; i++) { Console.Write(gamma.Sample().ToString("N05") + @" "); } Console.WriteLine(); Console.WriteLine(); // 4. Generate 100000 samples of the Gamma(1, 2) distribution and display histogram Console.WriteLine(@"4. Generate 100000 samples of the Gamma(1, 2) distribution and display histogram"); var data = new double[100000]; Gamma.Samples(data, 1, 2); ConsoleHelper.DisplayHistogram(data); Console.WriteLine(); // 5. Generate 100000 samples of the Gamma(8) distribution and display histogram Console.WriteLine(@"5. Generate 100000 samples of the Gamma(5, 1) distribution and display histogram"); Gamma.Samples(data, 5, 1); ConsoleHelper.DisplayHistogram(data); }
/// <summary> /// Generates a sequence of samples from the NormalGamma distribution /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="meanLocation">The location of the mean.</param> /// <param name="meanScale">The scale of the mean.</param> /// <param name="precisionShape">The shape of the precision.</param> /// <param name="precisionInvScale">The inverse scale of the precision.</param> /// <returns>a sequence of samples from the distribution.</returns> public static IEnumerable <MeanPrecisionPair> Samples(Random rnd, double meanLocation, double meanScale, double precisionShape, double precisionInvScale) { if (Control.CheckDistributionParameters && !IsValidParameterSet(meanLocation, meanScale, precisionShape, precisionInvScale)) { throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); } while (true) { var mp = new MeanPrecisionPair(); // Sample the precision. mp.Precision = Double.IsPositiveInfinity(precisionInvScale) ? precisionShape : Gamma.Sample(rnd, precisionShape, precisionInvScale); // Sample the mean. mp.Mean = meanScale == 0.0 ? meanLocation : Normal.Sample(rnd, meanLocation, Math.Sqrt(1.0 / (meanScale * mp.Precision))); yield return(mp); } }
/// <summary> /// Samples the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="shape">The shape (alpha) parameter of the inverse Gamma distribution.</param> /// <param name="scale">The scale (beta) parameter of the inverse Gamma distribution.</param> /// <returns>a random number from the distribution.</returns> internal static double SampleUnchecked(Random rnd, double shape, double scale) { return(1.0 / Gamma.Sample(rnd, shape, scale)); }
/// <summary> /// Generates a sample from the distribution. /// </summary> /// <param name="shape">The shape (k) of the Erlang distribution. Range: k ≥ 0.</param> /// <param name="rate">The rate or inverse scale (λ) of the Erlang distribution. Range: λ ≥ 0.</param> /// <returns>a sample from the distribution.</returns> public static double Sample(int shape, double rate) { return(Gamma.Sample(shape, rate)); }
/// <summary> /// Generates a sample from the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="shape">The shape (k) of the Erlang distribution. Range: k ≥ 0.</param> /// <param name="rate">The rate or inverse scale (λ) of the Erlang distribution. Range: λ ≥ 0.</param> /// <returns>a sample from the distribution.</returns> public static double Sample(System.Random rnd, int shape, double rate) { return(Gamma.Sample(rnd, shape, rate)); }
/// <summary> /// Generates a sample from the <c>NormalGamma</c> distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="meanLocation">The location of the mean.</param> /// <param name="meanScale">The scale of the mean.</param> /// <param name="precisionShape">The shape of the precision.</param> /// <param name="precisionInverseScale">The inverse scale of the precision.</param> /// <returns>a sample from the distribution.</returns> public static MeanPrecisionPair Sample(System.Random rnd, double meanLocation, double meanScale, double precisionShape, double precisionInverseScale) { if (Control.CheckDistributionParameters && !IsValidParameterSet(meanLocation, meanScale, precisionShape, precisionInverseScale)) { throw new ArgumentException(Resources.InvalidDistributionParameters); } var mp = new MeanPrecisionPair(); // Sample the precision. mp.Precision = double.IsPositiveInfinity(precisionInverseScale) ? precisionShape : Gamma.Sample(rnd, precisionShape, precisionInverseScale); // Sample the mean. mp.Mean = meanScale == 0.0 ? meanLocation : Normal.Sample(rnd, meanLocation, Math.Sqrt(1.0 / (meanScale * mp.Precision))); return(mp); }
/// <summary> /// Draws a random sample from the distribution. /// </summary> /// <returns>A random number from this distribution.</returns> public double Sample() { return(1.0 / Gamma.Sample(_random, _shape, _scale)); }
/// <summary> /// Samples a negative binomial distributed random variable. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="r">The r parameter.</param> /// <param name="p">The p parameter.</param> /// <returns>a sample from the distribution.</returns> private static int DoSample(Random rnd, double r, double p) { var lambda = Gamma.Sample(rnd, r, p); return(DoPoissonSample(rnd, lambda)); }
/// <summary> /// Samples the distribution. /// </summary> /// <param name="rnd">The random number generator to use.</param> /// <param name="shape"> /// The shape (alpha) parameter of the inverse Gamma distribution. /// </param> /// <param name="scale"> /// The scale (beta) parameter of the inverse Gamma distribution. /// </param> /// <returns>a random number from the distribution.</returns> private static double DoSample(Random rnd, double shape, double scale) { return(1.0 / Gamma.Sample(rnd, shape, scale)); }