static private SampleBoxMuller ( |
||
rnd | The random number generator to use. | |
리턴 | double>.Tuple |
internal static Tuple<double, double> SampleBoxMuller(Random rnd) {
var v1 = (2.0 * rnd.NextDouble()) - 1.0;
var v2 = (2.0 * rnd.NextDouble()) - 1.0;
var r = (v1 * v1) + (v2 * v2);
while(r >= 1.0 || Math.Abs(r - 0.0) < double.Epsilon) {
v1 = (2.0 * rnd.NextDouble()) - 1.0;
v2 = (2.0 * rnd.NextDouble()) - 1.0;
r = (v1 * v1) + (v2 * v2);
}
var fac = Math.Sqrt(-2.0 * Math.Log(r) / r);
return new Tuple<double, double>(v1 * fac, v2 * fac);
}
}
/// <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> private static IEnumerable <double> DoSamples(Random rnd, double dof) { while (true) { var n = Normal.SampleBoxMuller(rnd).Item1; var g = Gamma.Sample(rnd, 0.5 * dof, 0.5); yield return(Math.Sqrt(dof / g) * n); } }