/// \file DistributionModel.cs /// /// Contains the class that serves as the base class for various random number generator, it also serves as the utility class for random number generation using uniform random distribution /// using System; using System.Collections.Generic; using System.Linq; using System.Text; /*! \mainpage HiddenMarkovModels.MathUtils Source Code Documentation * * HiddenMarkovModels.MathUtils provides the math functions to be used in various simulation, machine learning, mining, and optimization package in the SimuKit framework * * The library currently contains a set of random number generator with various distribution models which includes: *
    *
  1. Uniform Distribution
  2. *
  3. Erlang Distribution
  4. *
  5. Gaussian Distribution
  6. *
  7. Poisson Distribution
  8. *
  9. LogNormal Distribution
  10. *
  11. Exponential Distribution
  12. *
*/ namespace BotSharp.Algorithm.HiddenMarkovModel.MathUtils.Distribution { /// /// Class that serves as the base class for various random number generator, it also serves as the utility class for random number generation using uniform random distribution /// public abstract class DistributionModel { /// /// Variable representing the the seed of the generator (the default value is the one used by Marsaglia) /// private static uint m_w = 521288629; /// /// Variable representing another seed that forms the pair of unsigned integers with m_w (the default value is the one used by Marsaglia) /// private static uint m_z = 362436069; /// /// Method that returns a randomly generated double value /// /// public abstract double Next(); /// /// Member variable representing the mean of the underlying distribution /// protected double mMean = 0; /// /// Member variable representing the standard deviation of the underlying distribution /// protected double mStdDev = 1; /// /// Method that sets the seed for the random number generator /// /// public static void SetSeed(uint u) { m_w = u; } public abstract DistributionModel Clone(); /// /// Method that returns a randomly generated double value in the range (0, 1) /// /// A randomly generated double value in the range (0, 1) public static double GetUniform() { // 0 <= u < 2^32 uint u = GetUint(); // The magic number below is 1/(2^32 + 2). // The result is strictly between 0 and 1. return (u + 1.0) * 2.328306435454494e-10; } /// /// Method that return a randomly generated unsigned integer. /// The method uses George Marsaglia's MWC algorithm to produce an unsigned integer. /// Please refers to http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt /// /// A randomly generated unsigned integer private static uint GetUint() { m_z = 36969 * (m_z & 65535) + (m_z >> 16); m_w = 18000 * (m_w & 65535) + (m_w >> 16); return (m_z << 16) + m_w; } /// /// Method that set the seed using the system time /// public static void SetSeedFromSystemTime() { System.DateTime dt = System.DateTime.Now; long x = dt.ToFileTime(); SetSeed((uint)(x >> 16), (uint)(x % 4294967296)); } /// /// Method that sets the two seeds of the random number generator /// /// The first seed /// The second seed public static void SetSeed(uint u, uint v) { if (u != 0) m_w = u; if (v != 0) m_z = v; } /// /// Constructor /// /// The seed for the random number generator public DistributionModel(uint seed) { SetSeed(seed); } /// /// Constructor /// public DistributionModel() { SetSeedFromSystemTime(); } /// /// Property representing the mean of the underlying distribution model /// public double Mean { get { return mMean; } set { mMean = value; } } public double Variance { get { return mStdDev * mStdDev; } set { mStdDev = System.Math.Sqrt(value); } } /// /// Property representing the standard deviation of the underlying distribution model /// public double StdDev { get { return mStdDev; } set { mStdDev = value; } } /// /// Method that returns a randomly generated integer in the range [0, upper_bound) /// /// The upper bound for the randomly generated integer (exclusive) /// A randomly generated integer in the range [0, upper_bound) public static int NextInt(int upper_bound) { if (upper_bound == 0) return 0; return (int)(GetUint() % (uint)upper_bound); } /// /// Return the log of either PDF(x) or PMF(x) (if PDF is not defined for the distribution) /// /// value for the variable /// The log of either PDF(x) or PMF(x) (if PDF is not defined for the distribution) public abstract double LogProbabilityFunction(double x); public abstract void Process(double[] values); public abstract void Process(double[] values, double[] weights); public abstract double GetPDF(double x); //return the probability density function for x public abstract double GetCDF(double x); //return the cumulative density function for x: P(X <= x) /// /// Return the value for probability mass function at value x /// /// /// P(X = x) public virtual double GetPMF(int x) { throw new NotImplementedException(); } public static void Shuffle(T[] data) { int indexer = 0; int len = data.Length; int upper = len - 1; T temp; int indexer2 = 0; while (indexer < upper) { indexer2 = NextInt(len - indexer) + indexer; temp = data[indexer2]; data[indexer2] = data[indexer]; data[indexer] = temp; } } public static void Shuffle(List data) { int indexer = 0; int len = data.Count; int upper = len - 1; T temp; int indexer2 = 0; while (indexer < upper) { indexer2 = NextInt(len - indexer) + indexer; temp = data[indexer2]; data[indexer2] = data[indexer]; data[indexer] = temp; } } } }