/// <summary> /// Returns a chi distributed floating point random number. /// </summary> /// <returns>A chi distributed double-precision floating point number.</returns> public override double NextDouble() { double sum = 0.0; for (int i = 0; i < _N; i++) { sum += Math.Pow(_normalDistribution.NextDouble(), 2); } return(Math.Sqrt(sum)); }
/// <summary> /// Returns a lognormal distributed floating point random number. /// </summary> /// <returns>A lognormal distributed double-precision floating point number.</returns> public override double NextDouble() { return(Math.Exp(normalDistribution.NextDouble() * sigma + mu)); }
/// <summary> /// Returns a rayleigh distributed floating point random number. /// </summary> /// <returns>A rayleigh distributed double-precision floating point number.</returns> public override double NextDouble() { return(Math.Sqrt(Math.Pow(normalDistribution1.NextDouble(), 2) + Math.Pow(normalDistribution2.NextDouble(), 2))); }
/// <summary> /// Returns a t-distributed floating point random number. /// </summary> /// <returns>A t-distributed double-precision floating point number.</returns> public override double NextDouble() { return(normalDistribution.NextDouble() / Math.Sqrt(chiSquareDistribution.NextDouble() / nu)); }
public override double NextDouble() { // algorithm GD for A >= 1 if (algorithmGD) { const double // coefficients a(k) for q = q0+(t*t/2)*sum(a(k)*v**k) a1 = 0.3333333, a2 = -0.250003, a3 = 0.2000062, a4 = -0.1662921, a5 = 0.1423657, a6 = -0.1367177, a7 = 0.1233795, // coefficients e(k) for exp(q)-1 = sum(e(k)*q**k) e1 = 1.0, e2 = 0.4999897, e3 = 0.166829, e4 = 4.07753E-2, e5 = 1.0293E-2; double q, w, gamdis; // standard normal deviate double t = normalDistribution.NextDouble(); // original this->NormalDistribution::operator()(); // (s,1/2)-normal deviate double x = s + 0.5 * t; // immediate acceptance gamdis = x * x; if (t >= 0.0) { return(gamdis / _invTheta); } // (0,1) uniform sample, squeeze acceptance double u = normalDistribution.Generator.Next() * scale; // original NormalDistribution::gen->Long() * scale; if (d * u <= t * t * t) { return(gamdis / _invTheta); } // no quotient test if x not positive if (x > 0.0) { // calculation of v and quotient q double vv = t / (s + s); if (Math.Abs(vv) <= 0.25) { q = q0 + 0.5 * t * t * ((((((a7 * vv + a6) * vv + a5) * vv + a4) * vv + a3) * vv + a2) * vv + a1) * vv; } else { q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.Log(1.0 + vv); } // quotient acceptance if (Math.Log(1.0 - u) <= q) { return(gamdis / _invTheta); } } loop: // stdandard exponential deviate double e = exponentialDistribution.NextDouble(); // original this->ExponentialDistribution::operator()(); // (0,1) uniform deviate u = normalDistribution.Generator.Next() * scale; // NormalDistribution::gen->Long() * scale; u += (u - 1.0); // (b,si) double exponential (Laplace) t = b + CopySign(si * e, u); // rejection if t < tau(1) = -0.71874483771719 if (t < -0.71874483771719) { goto loop; } // calculation of v and quotient q double v = t / (s + s); if (Math.Abs(v) <= 0.25) { q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; } else { q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.Log(1.0 + v); } // hat acceptance if (q <= 0.0) { goto loop; } if (q <= 0.5) { w = ((((e5 * q + e4) * q + e3) * q + e2) * q + e1) * q; } else { w = Math.Exp(q) - 1.0; } // if t is rejected, sample again if (c * Math.Abs(u) > w * Math.Exp(e - 0.5 * t * t)) { goto loop; } x = s + 0.5 * t; gamdis = x * x; return(gamdis / _invTheta); // algorithm GS for 0 < A < 1 } else { double gamdis; for (; ;) { double p = b * normalDistribution.Generator.Next() * scale; if (p < 1.0) { gamdis = Math.Exp(Math.Log(p) / alpha); if (exponentialDistribution.NextDouble() >= gamdis) { return(gamdis / _invTheta); } } else { gamdis = -Math.Log((b - p) / alpha); if (exponentialDistribution.NextDouble() >= (1.0 - alpha) * Math.Log(gamdis)) { return(gamdis / _invTheta); } } } // for } }