/// \file Exponential.cs /// /// Contains the class representing a random number generator Exponential(\f$\lambda\f$). /// using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BotSharp.Algorithm.HiddenMarkovModel.MathUtils.Distribution { /// /// Class representing a random number generator Exponential(\f$\lambda\f$). /// The \f$\lambda\f$ is the rate parameter or inverse scale of the Exponential distribution ///
    ///
  1. The mean is \f$\mu = \frac{1}{\lambda}\f$
  2. ///
  3. The variance is \f$\sigma^2 = \frac{1}{\lambda^2}\f$
  4. ///
  5. The skewness is 2
  6. ///
///
public class Exponential : DistributionModel { protected double mLnlambda; protected double mLambda; /// /// Constructor /// /// The seed for the random number generator public Exponential(uint seed) : base(seed) { } public Exponential() { } /// /// Return the log of the PDF(x) /// /// /// public override double LogProbabilityFunction(double x) { return mLnlambda - mLambda * x; } public override double GetCDF(double x) { return 1 - System.Math.Exp(-mLambda * x); } public override double GetPDF(double x) { return mLambda * System.Math.Exp(-mLambda * x); } /// /// Constructor /// public Exponential(double rate) { mLambda = rate; mMean = 1 / mLambda; mLnlambda = System.Math.Log(mLambda); } public override DistributionModel Clone() { return new Exponential(mLambda); } /// /// Method that returns a random number generated from the Exponential distribution with mean \f$\mu = 1\f$ /// /// private double GetExponential() { return -System.Math.Log(GetUniform()); } /// /// Method that returns a random number generated from the Exponential distribution with \f$\lambda=\frac{1}{\mu}\f$ (\f$\mu\f$ is the mean of the distribution) /// /// public override double Next() { if (mMean <= 0.0) { string msg = string.Format("Mean must be positive. Received {0}.", mMean); throw new ArgumentOutOfRangeException(msg); } return mMean * GetExponential(); } public override void Process(double[] values) { int count = values.Length; if (count == 0) { mMean = 0; mStdDev = 0; return; } mMean = values.Average(); mLambda = 1 / mMean; mLnlambda = System.Math.Log(mLambda); } public override void Process(double[] values, double[] weights) { double sum = 0; int count = values.Length; for (int i = 0; i < count; ++i) { sum += (values[i] * weights[i]); } double weight_sum = 0; for (int i = 0; i < count; ++i) { weight_sum += weights[i]; } mMean = sum / weight_sum; mLambda = 1 / mMean; mLnlambda = System.Math.Log(mLambda); } } }