C# Advanced RNG Example

[TOC]

using System;

using CenterSpace.NMath.Core;

namespace CenterSpace.NMath.Core.Examples.CSharp
{
  /// <summary>
  /// A .NET example in C# showing how to create a random number generator for a 
  /// particular probability distribution using a specified uniform deviate
  /// method. Also shown is how to access and modify the uniform deviate
  /// generating object from the NMath Core random number generator object.
  /// </summary>
  class AdvancedRNGExample
  {

    static void Main(string[] args)
    {
      Console.WriteLine();

      // Create a RandomNumberGenerator.UniformRandomNumber delegate object
      // from the method System.Random.NextDouble().
      Random sysRand = new Random();
      RandomNumberGenerator.UniformRandomNumber uniformDeviates =
        new RandomNumberGenerator.UniformRandomNumber(sysRand.NextDouble);

      // Now, construct a binomial random number generator using this delegate to
      // generate uniformly distributed random deviates between 0 and 1 (the 
      // binomial generator will transform these uniform deviates into binomial
      // deviates).
      int trials = 2000;
      double prob = .002;
      RandGenBinomial binRand = new RandGenBinomial(trials, prob, uniformDeviates);

      // Create a vector of binomial deviates and use it to create a histogram.
      int n = 200;
      DoubleVector randomVec = new DoubleVector(n, binRand);

      // Create histogram
      int numBins = 20;
      Histogram h = new Histogram(numBins, randomVec);
      Console.WriteLine(h.StemLeaf());

      // Change the uniform deviate generator to use the method NextDouble() form
      // NMath Cores RandGenMTwist class.
      int seed = 0x124;

      // Construct the MT generator with the given seed.
      RandGenMTwist mt = new RandGenMTwist(seed);

      // Create the delegate.
      uniformDeviates = new RandomNumberGenerator.UniformRandomNumber(mt.NextDouble);

      // Use the delegate to generate the uniform deviates necessary to for the 
      // binomial generator.
      binRand.UniformDeviateMethod = uniformDeviates;

      // Generate a vector of binomial deviates.
      DoubleVector randomSequence1 = new DoubleVector(n, binRand);

      // All NMathCore random number generator classes have Reset() and Reset(int) 
      // methods that attempt to reset the underlying uniform generator with the
      // time of day, for the no argument reset, or the given seed, for the integer
      // argument version. These methods return true if the reset was successfull and
      // false if it was not. The reset methods will succeed if the following 
      // conditions are met:
      // 1. The uniform generator delegate is an instance method, i.e. the Target 
      //    property of the Delegate class returns a non-null reference.
      // 2. The object reference thus obtained has a method named Initialize that
      //    returns void and takes no arguments, for the Reset() method, or a 
      //    single integer argument for the Reset(int) method.
      // The RandGenMTwist class has an Initialize(int) method, so the Reset(int)
      // method should succeed.
      if (binRand.Reset(seed))
      {
        // Random sequences started using the same seed, so they should be identical.
        DoubleVector randomSequence2 = new DoubleVector(n, binRand);
        Console.WriteLine("randomSequence1 == randomSequence2 is {0}", randomSequence1 == randomSequence2);
      }
      else
      {
        Console.WriteLine("Could not reset generator");
      }

      Console.WriteLine();
      Console.WriteLine("Press Enter Key");
      Console.Read();
    }
  }
}

[TOC]