public override double ComputeValue() { if (!double.IsNaN(this.Mean)) { if (!double.IsNaN(this.Std)) { return(GenerateNormal.GetNormal(this.Mean, this.Std)); } return(this.Mean + GenerateNormal.GetNormal()); } return(GenerateNormal.GetNormal()); }
/// <summary> /// Get gamma random sample with parameters /// </summary> /// <param name="shape"></param> /// <param name="scale"></param> /// <returns></returns> public static double GetGamma(double shape, double scale) { // Implementation based on "A Simple Method for Generating Gamma Variables" // by George Marsaglia and Wai Wan Tsang. ACM Transactions on Mathematical Software // Vol 26, No 3, September 2000, pages 363-372. double d, c, x, xsquared, v, u; if (shape >= 1.0) { d = shape - 1.0 / 3.0; c = 1.0 / Math.Sqrt(9.0 * d); for (; ;) { do { x = GenerateNormal.GetNormal(); v = 1.0 + c * x; }while (v <= 0.0); v = v * v * v; u = GenerateUniform.GetUniform(); xsquared = x * x; if (u < 1.0 - .0331 * xsquared * xsquared || Math.Log(u) < 0.5 * xsquared + d * (1.0 - v + Math.Log(v))) { return(scale * d * v); } } } else if (shape <= 0.0) { string msg = string.Format("Shape must be positive. Received {0}.", shape); throw new ArgumentOutOfRangeException(msg); } else { double g = GetGamma(shape + 1.0, 1.0); double w = GenerateUniform.GetUniform(); return(scale * g * Math.Pow(w, 1.0 / shape)); } }