Non-Uniform Random Numbers in C# QuickStart Sample
Illustrates how to generate random numbers from a non-uniform distribution in C#.
View this sample in: Visual Basic F# IronPython
using System;
using Numerics.NET.Statistics.Distributions;
using Numerics.NET.Random;
namespace Numerics.NET.QuickStart.CSharp
{
/// <summary>
/// Illustrates generating non-uniform random numbers
/// using the classes in the Numerics.NET.Statistics.Random
/// namespace.
/// </summary>
class NonUniformRandomNumbers
{
static void Main(string[] args)
{
// The license is verified at runtime. We're using
// a 30 day trial key here. For more information, see
// https://numerics.net/trial-key
Numerics.NET.License.Verify("64542-18980-57619-62268");
// Random number generators and the generation
// of uniform pseudo-random numbers are illustrated
// in the UniformRandomNumbers QuickStart Sample.
// In this sample, we will generate numbers from
// an exponential distribution, and compare summary
// results to what would be expected from
// the corresponding Poisson distribution.
double meanTimeBetweenEvents = 0.42;
// We will use the exponential distribution to generate the time
// between events. The number of events per unit time follows
// a Poisson distribution.
// The parameter of the exponential distribution is the time between events.
var exponential = new ExponentialDistribution(meanTimeBetweenEvents);
// The parameter of the Poisson distribution is the mean number of events
// per unit time, which is the reciprocal of the time between events:
var poisson = new PoissonDistribution(1 / meanTimeBetweenEvents);
// We use a MersenneTwister to generate the random numbers:
var random = new MersenneTwister();
// The totals array will track the number of events per time unit.
int[] totals = new int[15];
double currentTime = 0;
double endOfCurrentTimeUnit = 1;
int eventsInUnit = 0;
double totalTime = 0;
int count = 0;
while (currentTime < 100000)
{
double timeBetween = exponential.Sample(random);
totalTime += timeBetween; count++;
// Alternatively, we could have written
// timeBetween = random.NextDouble(exponential);
// which would give an identical result.
currentTime += timeBetween;
while (currentTime > endOfCurrentTimeUnit)
{
if (eventsInUnit >= totals.Length)
eventsInUnit = totals.Length-1;
totals[eventsInUnit]++;
eventsInUnit = 0;
endOfCurrentTimeUnit++;
}
eventsInUnit++;
}
Console.WriteLine($"{totalTime / count}");
// Now print the totals
Console.WriteLine("# Events Actual Expected");
for(int i = 0; i < totals.Length; i++)
{
int expected = (int)(100000 * poisson.Probability(i));
Console.WriteLine("{0,8} {1,8} {2,8}", i, totals[i], expected);
}
Console.Write("Press any key to exit.");
Console.ReadLine();
}
}
}