/// <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(System.Random rnd, double[] alpha) { if (Control.CheckDistributionParameters && !IsValidParameterSet(alpha)) { throw new ArgumentException(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="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 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(System.Random rnd, double meanLocation, double meanScale, double precisionShape, double precisionInvScale) { if (Control.CheckDistributionParameters && !IsValidParameterSet(meanLocation, meanScale, precisionShape, precisionInvScale)) { throw new ArgumentException(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> /// 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)); }