Removed double implementation

This commit is contained in:
Thorsten Sommer 2023-07-06 10:02:38 +02:00
parent d1d89fc7f6
commit 7bc829482e
No known key found for this signature in database
GPG Key ID: B0B7E2FC074BF1F5
54 changed files with 0 additions and 4453 deletions

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA2B2 : Distribution
{
private const double ALPHA = 2;
private const double BETA = 2;
private const double CONSTANT = 4;
public BetaA2B2(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA2B5 : Distribution
{
private const double ALPHA = 2;
private const double BETA = 5;
private const double CONSTANT = 12.2;
public BetaA2B5(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA5B2 : Distribution
{
private const double ALPHA = 5;
private const double BETA = 2;
private const double CONSTANT = 12.2;
public BetaA5B2(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class CauchyLorentzX0 : Distribution
{
private const double CONSTANT = 0.31;
private const double SCALE = 0.1;
private const double MEDIAN = 0.0;
public CauchyLorentzX0(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class CauchyLorentzX1 : Distribution
{
private const double CONSTANT = 0.31;
private const double SCALE = 0.1;
private const double MEDIAN = 1.0;
public CauchyLorentzX1(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
}
}

View File

@ -1,29 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK1 : Distribution
{
private const double K = 1.0;
private const double K_HALF = K * 0.5d;
private const double K_HALF_MINUS_ONE = K_HALF - 1.0d;
private const double CONSTANT = 0.252;
private static readonly double DIVISOR;
static ChiSquareK1()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public ChiSquareK1(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -1,29 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK10 : Distribution
{
private const double K = 10.0;
private const double K_HALF = K * 0.5d;
private const double K_HALF_MINUS_ONE = K_HALF - 1.0d;
private const double CONSTANT = 0.252;
private static readonly double DIVISOR;
static ChiSquareK10()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public ChiSquareK10(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -1,29 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK4 : Distribution
{
private const double K = 4.0;
private const double K_HALF = K * 0.5d;
private const double K_HALF_MINUS_ONE = K_HALF - 1.0d;
private const double CONSTANT = 0.252;
private static readonly double DIVISOR;
static ChiSquareK4()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public ChiSquareK4(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -1,75 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public abstract class Distribution : IDistribution
{
private readonly ShapeFitter fitter;
private readonly IRandom random;
protected Distribution(IRandom rng)
{
if (rng == null)
throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed.");
this.random = rng;
this.fitter = new ShapeFitter(this.ShapeFunction, this.random, 100);
}
private protected abstract double ShapeFunction(double x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default) => await this.fitter.NextNumber(token);
public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default)
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (uint) ((distributedValue * range) + rangeStart);
}
public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default(CancellationToken))
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (ulong) ((distributedValue * range) + rangeStart);
}
public async ValueTask<double> NextNumber(double rangeStart, double rangeEnd, CancellationToken cancel = default(CancellationToken))
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (distributedValue * range) + rangeStart;
}
public async ValueTask<double> NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0, 1.0, cancel);
public async ValueTask<bool> HasDecisionBeenMade(double above, double below = 1, CancellationToken cancel = default)
{
var number = await this.NextNumber(cancel);
return number > above && number < below;
}
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ExponentialLa10 : Distribution
{
private const double LAMBDA = 10.0;
private const double CONSTANT = 0.1106;
public ExponentialLa10(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ExponentialLa5 : Distribution
{
private const double LAMBDA = 5.0;
private const double CONSTANT = 0.2103;
public ExponentialLa5(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
}
}

View File

@ -1,28 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class GammaA5B15 : Distribution
{
private const double ALPHA = 5.0;
private const double BETA = 15.0;
private const double CONSTANT = 0.341344210715475;
private static readonly double GAMMA_ALPHA;
private static readonly double BETA_TO_THE_ALPHA;
static GammaA5B15()
{
GAMMA_ALPHA = MathTools.Gamma(ALPHA);
BETA_TO_THE_ALPHA = Math.Pow(BETA, ALPHA);
}
public GammaA5B15(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * ((BETA_TO_THE_ALPHA * Math.Pow(x, ALPHA - 1.0d) * Math.Exp(-BETA * x)) / GAMMA_ALPHA);
}
}

View File

@ -1,20 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public interface IDistribution
{
public ValueTask<double> GetDistributedValue(CancellationToken token);
public ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default);
public ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default);
public ValueTask<double> NextNumber(double rangeStart, double rangeEnd, CancellationToken cancel = default);
public ValueTask<double> NextNumber(CancellationToken cancel = default);
public ValueTask<bool> HasDecisionBeenMade(double above, double below = 1.0, CancellationToken cancel = default);
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseExponentialLa10 : Distribution
{
private const double LAMBDA = 10.0;
private const double CONSTANT = 4.539992976248453e-06;
public InverseExponentialLa10(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
}
}

View File

@ -1,18 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseExponentialLa5 : Distribution
{
private const double LAMBDA = 5.0;
private const double CONSTANT = 0.001347589399817;
public InverseExponentialLa5(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
}
}

View File

@ -1,29 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseGammaA3B05 : Distribution
{
private const double ALPHA = 3.0;
private const double BETA = 0.5;
private const double CONSTANT = 0.213922656884911;
private static readonly double FACTOR_LEFT;
static InverseGammaA3B05()
{
var gammaAlpha = MathTools.Gamma(ALPHA);
var betaToTheAlpha = Math.Pow(BETA, ALPHA);
FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha);
}
public InverseGammaA3B05(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Pow(x, -ALPHA - 1.0d) * Math.Exp(-BETA / x);
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LaplaceB01M0 : Distribution
{
private const double B = 0.1;
private const double MU = 0.0;
private const double CONSTANT = 0.221034183615129;
private static readonly double FACTOR_LEFT;
static LaplaceB01M0()
{
FACTOR_LEFT = CONSTANT / (2.0d * B);
}
public LaplaceB01M0(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LaplaceB01M05 : Distribution
{
private const double B = 0.1;
private const double MU = 0.5;
private const double CONSTANT = 0.2;
private static readonly double FACTOR_LEFT;
static LaplaceB01M05()
{
FACTOR_LEFT = CONSTANT / (2.0d * B);
}
public LaplaceB01M05(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
}
}

View File

@ -1,26 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LogNormalS1M0 : Distribution
{
private const double SIGMA = 1.0;
private const double MU = 0.0;
private const double CONSTANT = 1.51998658387455;
private static readonly double FACTOR;
static LogNormalS1M0()
{
FACTOR = SIGMA * Math.Sqrt(2 * Math.PI);
}
public LogNormalS1M0(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => (CONSTANT / (x * FACTOR)) * Math.Exp( -(Math.Pow(Math.Log(x) - MU, 2) / (2 * Math.Pow(SIGMA, 2))));
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class NormalS02M05 : Distribution
{
private const double SQRT_2_PI = 2.506628275;
private const double STDDEV = 0.2;
private const double MEAN = 0.5;
public NormalS02M05(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => 1.0 / (STDDEV * SQRT_2_PI) * Math.Exp(-0.5 * Math.Pow((x - MEAN) / STDDEV, 2.0));
}
}

View File

@ -1,31 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class StudentTNu1 : Distribution
{
private const double NU = 1.0;
private const double START = 0.0;
private const double COMPRESS = 1.0;
private const double CONSTANT = 3.14190548592729;
private static readonly double DIVIDEND;
private static readonly double DIVISOR;
private static readonly double EXPONENT;
static StudentTNu1()
{
DIVIDEND = MathTools.Gamma((NU + 1.0d) * 0.5d);
DIVISOR = Math.Sqrt(NU * Math.PI) * MathTools.Gamma(NU * 0.5d);
EXPONENT = -((NU + 1.0d) * 0.5d);
}
public StudentTNu1(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * Math.Pow((DIVIDEND / DIVISOR) * Math.Pow(1.0d + Math.Pow(START + x * COMPRESS, 2) / NU, EXPONENT), COMPRESS);
}
}

View File

@ -1,71 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class Uniform : IDistribution
{
private readonly IRandom rng;
public Uniform(IRandom rng)
{
if (rng == null)
throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed.");
this.rng = rng;
}
public async ValueTask<double> GetDistributedValue(CancellationToken token = default) => await this.rng.GetUniform(token);
public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default)
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (uint) ((distributedValue * range) + rangeStart);
}
public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default(CancellationToken))
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (ulong) ((distributedValue * range) + rangeStart);
}
public async ValueTask<double> NextNumber(double rangeStart, double rangeEnd, CancellationToken cancel = default(CancellationToken))
{
if (rangeStart > rangeEnd)
{
var tmp = rangeStart;
rangeStart = rangeEnd;
rangeEnd = tmp;
}
var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel);
return (distributedValue * range) + rangeStart;
}
public async ValueTask<double> NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0, 1.0, cancel);
public async ValueTask<bool> HasDecisionBeenMade(double above, double below = 1, CancellationToken cancel = default)
{
var number = await this.NextNumber(cancel);
return number > above && number < below;
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class WeibullK05La1 : Distribution
{
private const double K = 0.5;
private const double LAMBDA = 1.0;
private const double CONSTANT = 0.221034183615129;
public WeibullK05La1(IRandom rng) : base(rng)
{
}
private protected override double ShapeFunction(double x) => CONSTANT * ( (K / LAMBDA) * Math.Pow(x / LAMBDA, K - 1.0d) * Math.Exp(-Math.Pow(x/LAMBDA, K)));
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using FastRng.Double.Distributions;
namespace FastRng.Double
{
/// <summary>
/// Interface for random number generators.
/// </summary>
public interface IRandom : IDisposable
{
/// <summary>
/// Returns a uniform distributed pseudo-random number from the interval (0,1].
/// This means, the result 0 is impossible, whereas 1 is possible.
/// </summary>
/// <remarks>
/// This method is thread-safe. You can consume numbers from the same generator
/// by using multiple threads at the same time.
/// </remarks>
/// <param name="cancel">An optional cancellation token.</param>
public ValueTask<double> GetUniform(CancellationToken cancel = default);
}
}

View File

@ -1,83 +0,0 @@
using System;
namespace FastRng.Double
{
/// <summary>
/// Provides some mathematical function, which are not available within in the .NET framework.
/// </summary>
public static class MathTools
{
private static readonly double SQRT_2 = Math.Sqrt(2.0);
private static readonly double SQRT_PI = Math.Sqrt(Math.PI);
/// <summary>
/// The mathematical gamma function.
/// </summary>
/// <param name="z">The value for which you want calculate gamma.</param>
public static double Gamma(double z)
{
// Source: http://rosettacode.org/wiki/Gamma_function#Go
const double F1 = 6.5;
const double A1 = .99999999999980993;
const double A2 = 676.5203681218851;
const double A3 = 1259.1392167224028;
const double A4 = 771.32342877765313;
const double A5 = 176.61502916214059;
const double A6 = 12.507343278686905;
const double A7 = .13857109526572012;
const double A8 = 9.9843695780195716e-6;
const double A9 = 1.5056327351493116e-7;
var t = z + F1;
var x = A1 +
A2 / z -
A3 / (z + 1) +
A4 / (z + 2) -
A5 / (z + 3) +
A6 / (z + 4) -
A7 / (z + 5) +
A8 / (z + 6) +
A9 / (z + 7);
return MathTools.SQRT_2 * MathTools.SQRT_PI * Math.Pow(t, z - 0.5) * Math.Exp(-t) * x;
}
/// <summary>
/// The mathematical factorial function for floating-point numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
public static double Factorial(double x) => MathTools.Gamma(x + 1.0);
/// <summary>
/// The mathematical factorial function for integer numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
/// <exception cref="ArgumentOutOfRangeException">Throws, when x is greater than 20. Due to limitations of 64bit ulong type.</exception>
public static ulong Factorial(uint x)
{
if (x > 20)
throw new ArgumentOutOfRangeException(nameof(x), $"Cannot compute {x}!, since ulong.max is 18_446_744_073_709_551_615.");
ulong accumulator = 1;
for (uint factor = 1; factor <= x; factor++)
accumulator *= factor;
return accumulator;
}
/// <summary>
/// The mathematical factorial function for integer numbers.
/// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param>
/// <exception cref="ArgumentOutOfRangeException">Throws, when x is greater than 20. Due to limitations
/// of 64bit ulong type. Throws also, when x is less than 0.</exception>
public static ulong Factorial(int x)
{
if(x < 0)
throw new ArgumentOutOfRangeException(nameof(x), "Given value must be greater as zero.");
return MathTools.Factorial((uint) x);
}
}
}

View File

@ -1,358 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using FastRng.Double.Distributions;
namespace FastRng.Double
{
/// <summary>
/// A fast multi-threaded pseudo random number generator.
/// </summary>
/// <remarks>
/// Please note, that Math.NET's (https://www.mathdotnet.com/) random number generator is in some situations faster.
/// Unlike Math.NET, MultiThreadedRng is multi-threaded and async. Consumers can await the next number without
/// blocking resources. Additionally, consumers can use a token to cancel e.g. timeout an operation as well.<br/><br/>
///
/// MultiThreadedRng using a shape fitter (a rejection sampler) to enforce arbitrary shapes of probabilities for
/// desired distributions. By using the shape fitter, it is even easy to define discontinuous, arbitrary functions
/// as shapes. Any consumer can define and use own distributions.<br/><br/>
///
/// This class uses the George Marsaglia's MWC algorithm. The algorithm's implementation based loosely on John D.
/// Cook's (johndcook.com) implementation (https://www.codeproject.com/Articles/25172/Simple-Random-Number-Generation).
/// Thanks John for the inspiration.<br/><br/>
///
/// Please notice: When using the debug environment, MultiThreadedRng uses a smaller buffer size. Please ensure,
/// that the production environment uses a release build, though.
/// </remarks>
public sealed class MultiThreadedRng : IRandom, IDisposable
{
#if DEBUG
private const int BUFFER_SIZE = 10_000;
#else
private const int BUFFER_SIZE = 1_000_000;
#endif
// The queue size means, how many buffer we store in a queue at the same time:
private const int QUEUE_SIZE = 2;
// Gets used to stop the producer threads:
private readonly CancellationTokenSource producerTokenSource = new CancellationTokenSource();
// The time a thread waits e.g. to check if the queue needs a new buffer:
private readonly TimeSpan waiter = TimeSpan.FromMilliseconds(10);
// The first queue, where to store buffers of random uint numbers:
private readonly ConcurrentQueue<uint[]> queueIntegers = new ConcurrentQueue<uint[]>();
// The second queue, where to store buffers of uniform random double numbers:
private readonly ConcurrentQueue<double[]> queueDoubles = new ConcurrentQueue<double[]>();
// The uint producer thread:
private Thread producerRandomUint;
// The uniform double producer thread:
private Thread producerRandomUniformDistributedDouble;
// Variable w and z for the uint generator. Both get used
// as seeding variable as well (cf. constructors)
private uint mW;
private uint mZ;
// This is the current buffer for the consumer side i.e. the public interfaces:
private double[] currentBuffer = Array.Empty<double>();
// The current pointer to the next current buffer's address to read from:
private int currentBufferPointer = BUFFER_SIZE;
#region Constructors
/// <summary>
/// Creates a multi-threaded random number generator.
/// </summary>
/// <remarks>
/// This constructor uses the user's current local time
/// to derive necessary parameters for the generator.
/// Thus, the results are depending on the time, where
/// the generator was created.
/// </remarks>
public MultiThreadedRng()
{
//
// Initialize the mW and mZ by using
// the system's time.
//
var now = DateTime.Now;
var ticks = now.Ticks;
this.mW = (uint) (ticks >> 16);
this.mZ = (uint) (ticks % 4_294_967_296);
this.StartProducerThreads();
}
/// <summary>
/// Creates a multi-threaded random number generator.
/// </summary>
/// <remarks>
/// A multi-threaded random number generator created by this constructor is
/// deterministic. It's behaviour is not depending on the time of its creation.<br/><br/>
///
/// <b>Please note:</b> Although the number generator and all distributions are deterministic,
/// the behavior of the consuming application might be non-deterministic. This is possible if
/// the application with multiple threads consumes the numbers. The scheduling of the threads
/// is up to the operating system and might not be predictable.
/// </remarks>
/// <param name="seedU">A seed value to generate a deterministic generator.</param>
public MultiThreadedRng(uint seedU)
{
this.mW = seedU;
this.mZ = 362_436_069;
this.StartProducerThreads();
}
/// <summary>
/// Creates a multi-threaded random number generator.
/// </summary>
/// <remarks>
/// A multi-threaded random number generator created by this constructor is
/// deterministic. It's behaviour is not depending on the time of its creation.<br/><br/>
///
/// <b>Please note:</b> Although the number generator and all distributions are deterministic,
/// the behavior of the consuming application might be non-deterministic. This is possible if
/// the application with multiple threads consumes the numbers. The scheduling of the threads
/// is up to the operating system and might not be predictable.
/// </remarks>
/// <param name="seedU">The first seed value.</param>
/// <param name="seedV">The second seed value.</param>
public MultiThreadedRng(uint seedU, uint seedV)
{
this.mW = seedU;
this.mZ = seedV;
this.StartProducerThreads();
}
private void StartProducerThreads()
{
this.producerRandomUint = new Thread(() => this.RandomProducerUint(this.producerTokenSource.Token)) {IsBackground = true};
this.producerRandomUint.Start();
this.producerRandomUniformDistributedDouble = new Thread(() => this.RandomProducerUniformDistributedDouble(this.producerTokenSource.Token)) {IsBackground = true};
this.producerRandomUniformDistributedDouble.Start();
}
#endregion
#region Producers
[ExcludeFromCodeCoverage]
private async void RandomProducerUint(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
// A local next buffer, which gets filled next:
var nextBuffer = new uint[BUFFER_SIZE];
// Produce the necessary number of random uints:
for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++)
{
this.mZ = 36_969 * (this.mZ & 65_535) + (this.mZ >> 16);
this.mW = 18_000 * (this.mW & 65_535) + (this.mW >> 16);
nextBuffer[n] = (this.mZ << 16) + this.mW;
}
// Inside this loop, we try to enqueue the produced buffer:
while (!cancellationToken.IsCancellationRequested)
{
try
{
// Ensure, that we do not produce more buffers, as configured:
if (this.queueIntegers.Count < QUEUE_SIZE)
{
this.queueIntegers.Enqueue(nextBuffer);
break;
}
// The queue was full. Wait a moment and try it again:
await Task.Delay(this.waiter, cancellationToken);
}
catch (TaskCanceledException)
{
// The producers should be stopped:
return;
}
}
}
}
catch (OperationCanceledException)
{
}
}
[ExcludeFromCodeCoverage]
private async void RandomProducerUniformDistributedDouble(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
// A local source buffer of uints:
uint[] bufferSource = null;
// Try to get the next source buffer:
while (!this.queueIntegers.TryDequeue(out bufferSource) && !cancellationToken.IsCancellationRequested)
await Task.Delay(this.waiter, cancellationToken);
// Case: The producers should be stopped:
if(bufferSource == null)
return;
// A local buffer to fill with uniform doubles:
var nextBuffer = new double[BUFFER_SIZE];
// Generate the necessary number of doubles:
for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++)
nextBuffer[n] = (bufferSource[n] + 1.0) * 2.328306435454494e-10;
// Inside this loop, we try to enqueue the generated buffer:
while (!cancellationToken.IsCancellationRequested)
{
try
{
// Ensure, that the queue contains only the configured number of buffers:
if (this.queueDoubles.Count < QUEUE_SIZE)
{
this.queueDoubles.Enqueue(nextBuffer);
break;
}
// The queue was full. Wait a moment and try it again:
await Task.Delay(this.waiter, cancellationToken);
}
catch (TaskCanceledException)
{
return;
}
}
}
}
catch (OperationCanceledException)
{
}
}
#endregion
#region Implementing interface
/// <summary>
/// Returns a uniform distributed pseudo-random number from the interval (0,1].
/// This means, the result 0 is impossible, whereas 1 is possible.
/// </summary>
/// <remarks>
/// This method is thread-safe. You can consume numbers from the same generator
/// by using multiple threads at the same time.
/// </remarks>
/// <param name="cancel">An optional cancellation token.</param>
public async ValueTask<double> GetUniform(CancellationToken cancel = default)
{
while (!cancel.IsCancellationRequested)
{
// Check, if we need a new buffer to read from:
if (this.currentBufferPointer >= BUFFER_SIZE)
{
// Create a local copy of the current buffer's pointer:
var currentBufferReference = this.currentBuffer;
// Here, we store the next buffer until we implement it:
var nextBuffer = Array.Empty<double>();
// Try to get the next buffer from the queue:
while (this.currentBufferPointer >= BUFFER_SIZE && currentBufferReference == this.currentBuffer && !this.queueDoubles.TryDequeue(out nextBuffer))
{
//
// Case: There is no next buffer available.
// Must wait for producer(s) to provide next.
//
try
{
await Task.Delay(this.waiter, cancel);
}
catch (TaskCanceledException)
{
//
// Case: The consumer cancelled the request.
//
return double.NaN;
}
}
//
// Note: In general, it does not matter if the following compare-exchange is successful.
// 1st case: It was successful -- everything is fine. But we are responsible to re-set the currentBufferPointer.
// 2nd case: It was not successful. This means, that another thread was successful, though.
// That case is fine as well. But we would loose one buffer of work. Thus, we
// check for this case and preserve the buffer full of work.
//
// Try to implement the dequeued buffer without locking other threads:
if (Interlocked.CompareExchange(ref this.currentBuffer, nextBuffer, currentBufferReference) != currentBufferReference)
{
//
// Case: Another thread updated the buffer already.
// Thus, we enqueue our copy of the next buffer to preserve it.
//
this.queueDoubles.Enqueue(nextBuffer);
// Next? We can go ahead and yield a random number...
}
else
{
//
// Case: We updated the buffer.
//
this.currentBufferPointer = 0;
// Next? We can go ahead and yield a random number...
}
}
// Made a local copy of the current pointer:
var myPointer = this.currentBufferPointer;
// Increment the pointer for the next thread or call:
var nextPointer = myPointer + 1;
// Try to update the pointer without locking other threads:
if (Interlocked.CompareExchange(ref this.currentBufferPointer, nextPointer, myPointer) == myPointer)
{
//
// Case: Success. We updated the pointer and, thus, can use the pointer to read a number.
//
return this.currentBuffer[myPointer];
}
//
// Case: Another thread updated the pointer already. Must restart the process
// to get a random number.
//
}
//
// Case: The consumer cancelled the request.
//
return double.NaN;
}
private void StopProducer() => this.producerTokenSource.Cancel();
/// <summary>
/// Disposes this generator. It is important to dispose a generator,
/// when it is no longer needed. Otherwise, the background threads
/// are still running.
/// </summary>
public void Dispose() => this.StopProducer();
#endregion
}
}

View File

@ -1,79 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using FastRng.Double.Distributions;
namespace FastRng.Double
{
/// <summary>
/// ShapeFitter is a rejection sampler, cf. https://en.wikipedia.org/wiki/Rejection_sampling
/// </summary>
public sealed class ShapeFitter
{
private readonly double[] probabilities;
private readonly IRandom rng;
private readonly double max;
private readonly double sampleSize;
private readonly IDistribution uniform;
/// <summary>
/// Creates a shape fitter instance.
/// </summary>
/// <param name="shapeFunction">The function which describes the desired shape.</param>
/// <param name="rng">The random number generator instance to use.</param>
/// <param name="sampleSize">The number of sampling steps to sample the given function.</param>
public ShapeFitter(Func<double, double> shapeFunction, IRandom rng, ushort sampleSize = 50)
{
this.rng = rng;
this.uniform = new Uniform(rng);
this.sampleSize = sampleSize;
this.probabilities = new double[sampleSize];
var sampleStepSize = 1.0d / sampleSize;
var nextStep = 0.0 + sampleStepSize;
var maxValue = 0.0d;
for (var n = 0; n < sampleSize; n++)
{
this.probabilities[n] = shapeFunction(nextStep);
if (this.probabilities[n] > maxValue)
maxValue = this.probabilities[n];
nextStep += sampleStepSize;
}
this.max = maxValue;
}
/// <summary>
/// Returns a random number regarding the given shape.
/// </summary>
/// <param name="token">An optional cancellation token.</param>
/// <returns>The next value regarding the given shape.</returns>
public async ValueTask<double> NextNumber(CancellationToken token = default)
{
while (!token.IsCancellationRequested)
{
var x = await this.rng.GetUniform(token);
if (double.IsNaN(x))
return x;
var nextBucket = (int)Math.Floor(x * this.sampleSize);
if (nextBucket >= this.probabilities.Length)
nextBucket = this.probabilities.Length - 1;
var threshold = this.probabilities[nextBucket];
var y = await this.uniform.NextNumber(0.0d, this.max, token);
if (double.IsNaN(y))
return y;
if(y > threshold)
continue;
return x;
}
return double.NaN;
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
using Uniform = FastRng.Double.Distributions.Uniform;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
public class DecisionTester
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task DecisionUniform01()
{
using var rng = new MultiThreadedRng();
var dist = new Uniform(rng);
var neededCoinTossesA = 0;
var neededCoinTossesB = 0;
var neededCoinTossesC = 0;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++;
var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC};
var max = values.Max();
var min = values.Min();
TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}");
Assert.That(max - min, Is.LessThanOrEqualTo(250));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task DecisionWeibull01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.WeibullK05La1(rng);
var neededCoinTossesA = 0;
var neededCoinTossesB = 0;
var neededCoinTossesC = 0;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++;
for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++;
var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC};
var max = values.Max();
var min = values.Min();
TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}");
Assert.That(max - min, Is.LessThanOrEqualTo(2_800));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class BetaA2B2
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.BetaA2B2(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0396).Within(0.3));
Assert.That(result[1], Is.EqualTo(0.0784).Within(0.3));
Assert.That(result[2], Is.EqualTo(0.1164).Within(0.3));
Assert.That(result[21], Is.EqualTo(0.6864).Within(0.3));
Assert.That(result[22], Is.EqualTo(0.7084).Within(0.3));
Assert.That(result[23], Is.EqualTo(0.7296).Within(0.3));
Assert.That(result[50], Is.EqualTo(0.9996).Within(0.3));
Assert.That(result[75], Is.EqualTo(0.7296).Within(0.3));
Assert.That(result[85], Is.EqualTo(0.4816).Within(0.3));
Assert.That(result[90], Is.EqualTo(0.3276).Within(0.3));
Assert.That(result[97], Is.EqualTo(0.0784).Within(0.3));
Assert.That(result[98], Is.EqualTo(0.0396).Within(0.3));
Assert.That(result[99], Is.EqualTo(0.0000).Within(0.3));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA2B2(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA2B2(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.BetaA2B2(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class BetaA2B5
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.BetaA2B5(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.11719271).Within(0.3));
Assert.That(result[1], Is.EqualTo(0.22505783).Within(0.3));
Assert.That(result[2], Is.EqualTo(0.32401717).Within(0.3));
Assert.That(result[21], Is.EqualTo(0.99348410).Within(0.3));
Assert.That(result[22], Is.EqualTo(0.98639433).Within(0.3));
Assert.That(result[23], Is.EqualTo(0.97684451).Within(0.3));
Assert.That(result[50], Is.EqualTo(0.35868592).Within(0.3));
Assert.That(result[75], Is.EqualTo(0.03076227).Within(0.03));
Assert.That(result[85], Is.EqualTo(0.00403061).Within(0.03));
Assert.That(result[90], Is.EqualTo(0.00109800).Within(0.01));
Assert.That(result[97], Is.EqualTo(0.00000191).Within(0.000003));
Assert.That(result[98], Is.EqualTo(0.00000012).Within(0.0000003));
Assert.That(result[99], Is.EqualTo(0.00000000).Within(0.0000003));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA2B5(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA2B5(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.BetaA2B5(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class BetaA5B2
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.BetaA5B2(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0000001).Within(0.0000003));
Assert.That(result[1], Is.EqualTo(0.0000019).Within(0.00001));
Assert.That(result[2], Is.EqualTo(0.0000096).Within(0.0004));
Assert.That(result[21], Is.EqualTo(0.0222918).Within(0.03));
Assert.That(result[22], Is.EqualTo(0.0262883).Within(0.03));
Assert.That(result[23], Is.EqualTo(0.0307623).Within(0.03));
Assert.That(result[50], Is.EqualTo(0.4044237).Within(0.2));
Assert.That(result[75], Is.EqualTo(0.9768445).Within(0.15));
Assert.That(result[85], Is.EqualTo(0.9552714).Within(0.15));
Assert.That(result[90], Is.EqualTo(0.8004420).Within(0.35));
Assert.That(result[97], Is.EqualTo(0.2250578).Within(0.03));
Assert.That(result[98], Is.EqualTo(0.1171927).Within(0.03));
Assert.That(result[99], Is.EqualTo(0.0000000).Within(0.00));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA5B2(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.BetaA5B2(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.BetaA5B2(null));
}
}
}

View File

@ -1,87 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class CauchyLorentzX0
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyDistribution01()
{
// The properties of the cauchy distribution cannot be tested by mean, media or variance,
// cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX0(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.976990739772031).Within(0.06));
Assert.That(result[1], Is.EqualTo(0.948808314586299).Within(0.06));
Assert.That(result[2], Is.EqualTo(0.905284997403441).Within(0.06));
Assert.That(result[21], Is.EqualTo(0.168965864241396).Within(0.04));
Assert.That(result[22], Is.EqualTo(0.156877686354491).Within(0.04));
Assert.That(result[23], Is.EqualTo(0.145970509936354).Within(0.04));
Assert.That(result[50], Is.EqualTo(0.036533159835978).Within(0.01));
Assert.That(result[75], Is.EqualTo(0.016793067514802).Within(0.01));
Assert.That(result[85], Is.EqualTo(0.01316382933791).Within(0.005));
Assert.That(result[90], Is.EqualTo(0.011773781734516).Within(0.005));
Assert.That(result[97], Is.EqualTo(0.010168596941156).Within(0.005));
Assert.That(result[98], Is.EqualTo(0.009966272570142).Within(0.005));
Assert.That(result[99], Is.EqualTo(0.00976990739772).Within(0.005));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.CauchyLorentzX0(null));
}
}
}

View File

@ -1,87 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class CauchyLorentzX1
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyDistribution01()
{
// The properties of the cauchy distribution cannot be tested by mean, media or variance,
// cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX1(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.009966272570142).Within(0.003));
Assert.That(result[1], Is.EqualTo(0.010168596941156).Within(0.004));
Assert.That(result[2], Is.EqualTo(0.010377123221893).Within(0.005));
Assert.That(result[21], Is.EqualTo(0.015956672819692).Within(0.005));
Assert.That(result[22], Is.EqualTo(0.016366904083094).Within(0.005));
Assert.That(result[23], Is.EqualTo(0.016793067514802).Within(0.005));
Assert.That(result[50], Is.EqualTo(0.039454644029179).Within(0.015));
Assert.That(result[75], Is.EqualTo(0.145970509936354).Within(0.03));
Assert.That(result[85], Is.EqualTo(0.333365083503296).Within(0.1));
Assert.That(result[90], Is.EqualTo(0.545171628270584).Within(0.1));
Assert.That(result[97], Is.EqualTo(0.948808314586302).Within(0.06));
Assert.That(result[98], Is.EqualTo(0.976990739772032).Within(0.03));
Assert.That(result[99], Is.EqualTo(0.986760647169751).Within(0.02));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.CauchyLorentzX0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.CauchyLorentzX1(null));
}
}
}

View File

@ -1,87 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class ChiSquareK1
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK1(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
{
var value = await dist.NextNumber();
fqa.CountThis(value);
}
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.00032041964207).Within(0.004));
Assert.That(result[1], Is.EqualTo(0.70380551227703).Within(0.05));
Assert.That(result[2], Is.EqualTo(0.571788691668126).Within(0.05));
Assert.That(result[21], Is.EqualTo(0.192011337664754).Within(0.07));
Assert.That(result[22], Is.EqualTo(0.186854182385981).Within(0.07));
Assert.That(result[23], Is.EqualTo(0.182007652359976).Within(0.07));
Assert.That(result[50], Is.EqualTo(0.109088865614875).Within(0.06));
Assert.That(result[75], Is.EqualTo(0.07886274821701).Within(0.02));
Assert.That(result[85], Is.EqualTo(0.070520397849883).Within(0.02));
Assert.That(result[90], Is.EqualTo(0.066863009640287).Within(0.02));
Assert.That(result[97], Is.EqualTo(0.062214737436948).Within(0.02));
Assert.That(result[98], Is.EqualTo(0.061590997922187).Within(0.02));
Assert.That(result[99], Is.EqualTo(0.060976622578824).Within(0.02));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.ChiSquareK1(null));
}
}
}

View File

@ -1,87 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class ChiSquareK10
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK10(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
{
var value = await dist.NextNumber();
fqa.CountThis(value);
}
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0000000164021588).Within(0.0000002));
Assert.That(result[1], Is.EqualTo(0.0000002611256437).Within(0.000003));
Assert.That(result[2], Is.EqualTo(0.0000013153553250).Within(0.00002));
Assert.That(result[21], Is.EqualTo(0.003459320622874).Within(0.005));
Assert.That(result[22], Is.EqualTo(0.004111875573379).Within(0.005));
Assert.That(result[23], Is.EqualTo(0.004850674298859).Within(0.005));
Assert.That(result[50], Is.EqualTo(0.086418773275056).Within(0.05));
Assert.That(result[75], Is.EqualTo(0.376092741436046).Within(0.08));
Assert.That(result[85], Is.EqualTo(0.586569751611096).Within(0.08));
Assert.That(result[90], Is.EqualTo(0.717189736168766).Within(0.08));
Assert.That(result[97], Is.EqualTo(0.931477764640217).Within(0.08));
Assert.That(result[98], Is.EqualTo(0.965244855212136).Within(0.08));
Assert.That(result[99], Is.EqualTo(0.999827884370044).Within(0.08));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.ChiSquareK10(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class ChiSquareK4
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK4(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.016417705906679).Within(0.02));
Assert.That(result[1], Is.EqualTo(0.032671644513723).Within(0.02));
Assert.That(result[2], Is.EqualTo(0.048763041010352).Within(0.02));
Assert.That(result[21], Is.EqualTo(0.32518779111264).Within(0.05));
Assert.That(result[22], Is.EqualTo(0.338273451612642).Within(0.05));
Assert.That(result[23], Is.EqualTo(0.351220492939994).Within(0.05));
Assert.That(result[50], Is.EqualTo(0.65209223303425).Within(0.08));
Assert.That(result[75], Is.EqualTo(0.857562207152294).Within(0.099));
Assert.That(result[85], Is.EqualTo(0.923072405412387).Within(0.099));
Assert.That(result[90], Is.EqualTo(0.952623623874265).Within(0.099));
Assert.That(result[97], Is.EqualTo(0.990616879396201).Within(0.099));
Assert.That(result[98], Is.EqualTo(0.995734077068522).Within(0.099));
Assert.That(result[99], Is.EqualTo(1.00077558852585).Within(0.1));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK4(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ChiSquareK4(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.ChiSquareK4(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class ExponentialLa10
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa10(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.00075018434777).Within(0.05));
Assert.That(result[1], Is.EqualTo(0.905516212904248).Within(0.05));
Assert.That(result[2], Is.EqualTo(0.81934495207398).Within(0.05));
Assert.That(result[21], Is.EqualTo(0.122548293148741).Within(0.12));
Assert.That(result[22], Is.EqualTo(0.110886281157421).Within(0.12));
Assert.That(result[23], Is.EqualTo(0.10033405633809).Within(0.12));
Assert.That(result[50], Is.EqualTo(0.00674300170146).Within(0.005));
Assert.That(result[75], Is.EqualTo(0.000553499285385).Within(0.001));
Assert.That(result[85], Is.EqualTo(0.000203621007796).Within(0.001));
Assert.That(result[90], Is.EqualTo(0.00012350238419).Within(0.001));
Assert.That(result[97], Is.EqualTo(0.0000613294689720).Within(0.0008));
Assert.That(result[98], Is.EqualTo(0.0000554931983541).Within(0.0008));
Assert.That(result[99], Is.EqualTo(0.0000502123223173).Within(0.0008));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.ExponentialLa10(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class ExponentialLa5
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa5(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.0002177398625).Within(0.05));
Assert.That(result[1], Is.EqualTo(0.951436545064811).Within(0.05));
Assert.That(result[2], Is.EqualTo(0.905034437210948).Within(0.05));
Assert.That(result[21], Is.EqualTo(0.35001394450853).Within(0.05));
Assert.That(result[22], Is.EqualTo(0.332943563002074).Within(0.05));
Assert.That(result[23], Is.EqualTo(0.31670571382568).Within(0.05));
Assert.That(result[50], Is.EqualTo(0.082102871800213).Within(0.01));
Assert.That(result[75], Is.EqualTo(0.023522866606758).Within(0.01));
Assert.That(result[85], Is.EqualTo(0.014267339801329).Within(0.01));
Assert.That(result[90], Is.EqualTo(0.011111415409621).Within(0.01));
Assert.That(result[97], Is.EqualTo(0.007830082099077).Within(0.008));
Assert.That(result[98], Is.EqualTo(0.007448204488898).Within(0.008));
Assert.That(result[99], Is.EqualTo(0.007084951269538).Within(0.008));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa5(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.ExponentialLa5(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.ExponentialLa5(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class GammaA5B15
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestGammaDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.GammaA5B15(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0000929594237282).Within(0.0008));
Assert.That(result[1], Is.EqualTo(0.0012801746797876).Within(0.002));
Assert.That(result[2], Is.EqualTo(0.0055781488254349).Within(0.004));
Assert.That(result[21], Is.EqualTo(0.9331608887752720).Within(0.09));
Assert.That(result[22], Is.EqualTo(0.9594734828891280).Within(0.09));
Assert.That(result[23], Is.EqualTo(0.9790895765535350).Within(0.09));
Assert.That(result[50], Is.EqualTo(0.3478287795336570).Within(0.06));
Assert.That(result[75], Is.EqualTo(0.0403399049422936).Within(0.009));
Assert.That(result[85], Is.EqualTo(0.0163628388658126).Within(0.009));
Assert.That(result[90], Is.EqualTo(0.0097147611446660).Within(0.005));
Assert.That(result[97], Is.EqualTo(0.0041135143233153).Within(0.008));
Assert.That(result[98], Is.EqualTo(0.0036872732029996).Within(0.008));
Assert.That(result[99], Is.EqualTo(0.0033038503429554).Within(0.008));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestGammaGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.GammaA5B15(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestGammaGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.GammaA5B15(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.GammaA5B15(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class InverseExponentialLa10
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa10(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0000501746820562).Within(0.0003));
Assert.That(result[1], Is.EqualTo(0.0000554515994322).Within(0.0003));
Assert.That(result[2], Is.EqualTo(0.0000612834950532).Within(0.0003));
Assert.That(result[21], Is.EqualTo(0.00040973497898).Within(0.00045));
Assert.That(result[22], Is.EqualTo(0.000452827182887).Within(0.00050));
Assert.That(result[23], Is.EqualTo(0.000500451433441).Within(0.00051));
Assert.That(result[50], Is.EqualTo(0.007446583070924).Within(0.003));
Assert.That(result[75], Is.EqualTo(0.090717953289412).Within(0.02));
Assert.That(result[85], Is.EqualTo(0.246596963941606).Within(0.05));
Assert.That(result[90], Is.EqualTo(0.406569659740598).Within(0.08));
Assert.That(result[97], Is.EqualTo(0.81873075307798).Within(0.08));
Assert.That(result[98], Is.EqualTo(0.904837418035957).Within(0.08));
Assert.That(result[99], Is.EqualTo(0.999999999999999).Within(0.08));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa10(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.InverseExponentialLa10(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class InverseExponentialLa5
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa5(rng);
var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fqa.CountThis(await dist.NextNumber());
var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.007083408929052).Within(0.008));
Assert.That(result[1], Is.EqualTo(0.007446583070924).Within(0.008));
Assert.That(result[2], Is.EqualTo(0.007828377549226).Within(0.008));
Assert.That(result[21], Is.EqualTo(0.020241911445804).Within(0.05));
Assert.That(result[22], Is.EqualTo(0.021279736438377).Within(0.05));
Assert.That(result[23], Is.EqualTo(0.022370771856166).Within(0.05));
Assert.That(result[50], Is.EqualTo(0.08629358649937).Within(0.02));
Assert.That(result[75], Is.EqualTo(0.301194211912202).Within(0.03));
Assert.That(result[85], Is.EqualTo(0.496585303791409).Within(0.05));
Assert.That(result[90], Is.EqualTo(0.637628151621772).Within(0.06));
Assert.That(result[97], Is.EqualTo(0.904837418035959).Within(0.08));
Assert.That(result[98], Is.EqualTo(0.951229424500713).Within(0.08));
Assert.That(result[99], Is.EqualTo(1).Within(0.08));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa5(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseExponentialLa5(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.InverseExponentialLa5(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class InverseGammaA3B05
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestInverseGammaDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseGammaA3B05(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0000000000000003).Within(0.0000001));
Assert.That(result[1], Is.EqualTo(0.0000011605257228).Within(0.00001));
Assert.That(result[2], Is.EqualTo(0.0009536970016103).Within(0.0015));
Assert.That(result[21], Is.EqualTo(0.5880485243048120).Within(0.05));
Assert.That(result[22], Is.EqualTo(0.5433842148912880).Within(0.05));
Assert.That(result[23], Is.EqualTo(0.5017780549216030).Within(0.05));
Assert.That(result[50], Is.EqualTo(0.0741442015957425).Within(0.009));
Assert.That(result[75], Is.EqualTo(0.0207568945092484).Within(0.006));
Assert.That(result[85], Is.EqualTo(0.0136661506653688).Within(0.006));
Assert.That(result[90], Is.EqualTo(0.0112550619601327).Within(0.006));
Assert.That(result[97], Is.EqualTo(0.0087026933539773).Within(0.005));
Assert.That(result[98], Is.EqualTo(0.0083995375385004).Within(0.005));
Assert.That(result[99], Is.EqualTo(0.0081094156379928).Within(0.005));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestInverseGammaGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseGammaA3B05(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestInverseGammaGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.InverseGammaA3B05(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.InverseGammaA3B05(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class LaplaceB01M0
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M0(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.0000000000000000).Within(0.05));
Assert.That(result[1], Is.EqualTo(0.9048374180359590).Within(0.05));
Assert.That(result[2], Is.EqualTo(0.8187307530779810).Within(0.05));
Assert.That(result[21], Is.EqualTo(0.1224564282529820).Within(0.05));
Assert.That(result[22], Is.EqualTo(0.1108031583623340).Within(0.05));
Assert.That(result[23], Is.EqualTo(0.1002588437228040).Within(0.05));
Assert.That(result[50], Is.EqualTo(0.0067379469990855).Within(0.003));
Assert.That(result[75], Is.EqualTo(0.0005530843701478).Within(0.0015));
Assert.That(result[85], Is.EqualTo(0.0002034683690106).Within(0.0015));
Assert.That(result[90], Is.EqualTo(0.0001234098040867).Within(0.0015));
Assert.That(result[97], Is.EqualTo(0.0000612834950532).Within(0.0002));
Assert.That(result[98], Is.EqualTo(0.0000554515994322).Within(0.0002));
Assert.That(result[99], Is.EqualTo(0.0000501746820562).Within(0.0002));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.LaplaceB01M0(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class LaplaceB01M05
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M05(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.0074465830709244).Within(0.004));
Assert.That(result[1], Is.EqualTo(0.0082297470490200).Within(0.004));
Assert.That(result[2], Is.EqualTo(0.0090952771016958).Within(0.01));
Assert.That(result[21], Is.EqualTo(0.0608100626252180).Within(0.02));
Assert.That(result[22], Is.EqualTo(0.0672055127397498).Within(0.02));
Assert.That(result[23], Is.EqualTo(0.0742735782143340).Within(0.02));
Assert.That(result[50], Is.EqualTo(1.0000000000000000).Within(0.2));
Assert.That(result[75], Is.EqualTo(0.0742735782143335).Within(0.01));
Assert.That(result[85], Is.EqualTo(0.0273237224472924).Within(0.01));
Assert.That(result[90], Is.EqualTo(0.0165726754017612).Within(0.01));
Assert.That(result[97], Is.EqualTo(0.0082297470490200).Within(0.004));
Assert.That(result[98], Is.EqualTo(0.0074465830709243).Within(0.004));
Assert.That(result[99], Is.EqualTo(0.0067379469990854).Within(0.004));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M05(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LaplaceB01M05(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.LaplaceB01M05(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class LogNormalS1M0
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLogNormalDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LogNormalS1M0(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(0.001505531).Within(0.003));
Assert.That(result[1], Is.EqualTo(0.014408709).Within(0.01));
Assert.That(result[2], Is.EqualTo(0.043222256).Within(0.02));
Assert.That(result[21], Is.EqualTo(0.876212056).Within(0.15));
Assert.That(result[22], Is.EqualTo(0.895582226).Within(0.15));
Assert.That(result[23], Is.EqualTo(0.912837250).Within(0.15));
Assert.That(result[50], Is.EqualTo(0.948062005).Within(0.2));
Assert.That(result[75], Is.EqualTo(0.768584762).Within(0.089));
Assert.That(result[85], Is.EqualTo(0.697303612).Within(0.089));
Assert.That(result[90], Is.EqualTo(0.663570581).Within(0.089));
Assert.That(result[97], Is.EqualTo(0.618792767).Within(0.089));
Assert.That(result[98], Is.EqualTo(0.612636410).Within(0.089));
Assert.That(result[99], Is.EqualTo(0.606540679).Within(0.089));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLogNormalGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LogNormalS1M0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestLogNormalGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.LogNormalS1M0(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.LogNormalS1M0(null));
}
}
}

View File

@ -1,80 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class NormalS02M05
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestNormalDistribution01()
{
const double MEAN = 0.5;
const double STANDARD_DEVIATION = 0.2;
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.NormalS02M05(rng);
var stats = new RunningStatistics();
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
{
var nextNumber = await dist.NextNumber();
stats.Push(nextNumber);
fra.CountThis(nextNumber);
}
fra.NormalizeAndPlotEvents(TestContext.WriteLine);
TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}");
TestContext.WriteLine($"variance={STANDARD_DEVIATION * STANDARD_DEVIATION} vs {stats.Variance}");
Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01), "Mean is out of range");
Assert.That(stats.Variance, Is.EqualTo(STANDARD_DEVIATION*STANDARD_DEVIATION).Within(0.01), "Variance is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestNormalGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.NormalS02M05(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestNormalGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
var dist = new FastRng.Double.Distributions.NormalS02M05(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.NormalS02M05(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class StudentTNu1
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestStudentTDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.StudentTNu1(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.000000000).Within(0.2));
Assert.That(result[1], Is.EqualTo(0.999700120).Within(0.2));
Assert.That(result[2], Is.EqualTo(0.999200719).Within(0.2));
Assert.That(result[21], Is.EqualTo(0.953929798).Within(0.2));
Assert.That(result[22], Is.EqualTo(0.949852788).Within(0.2));
Assert.That(result[23], Is.EqualTo(0.945631619).Within(0.2));
Assert.That(result[50], Is.EqualTo(0.793667169).Within(0.095));
Assert.That(result[75], Is.EqualTo(0.633937627).Within(0.09));
Assert.That(result[85], Is.EqualTo(0.574902276).Within(0.09));
Assert.That(result[90], Is.EqualTo(0.547070729).Within(0.09));
Assert.That(result[97], Is.EqualTo(0.510150990).Within(0.09));
Assert.That(result[98], Is.EqualTo(0.505075501).Within(0.09));
Assert.That(result[99], Is.EqualTo(0.500050000).Within(0.09));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestStudentTGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.StudentTNu1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestStudentTGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.StudentTNu1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.StudentTNu1(null));
}
}
}

View File

@ -1,297 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class Uniform
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestUniformDistribution01()
{
const double A = 0.0;
const double B = 1.0;
const double MEAN = 0.5 * (A + B);
const double VARIANCE = (1.0 / 12.0) * (B - A) * (B - A);
var stats = new RunningStatistics();
var fra = new FrequencyAnalysis();
using var rng = new MultiThreadedRng();
for (var n = 0; n < 100_000; n++)
{
var value = await rng.GetUniform();
stats.Push(value);
fra.CountThis(value);
}
fra.NormalizeAndPlotEvents(TestContext.WriteLine);
fra.PlotOccurence(TestContext.WriteLine);
TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}");
TestContext.WriteLine($"variance={VARIANCE} vs {stats.Variance}");
Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01), "Mean is out of range");
Assert.That(stats.Variance, Is.EqualTo(VARIANCE).Within(0.001), "Variance is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task KolmogorovSmirnovTest()
{
// Kolmogorov-Smirnov test for distributions.
// See Knuth volume 2, page 48-51 (third edition).
// This test should *fail* on average one time in 1000 runs.
// That's life with random number generators: if the test passed all the time,
// the source wouldn't be random enough! If the test were to fail more frequently,
// the most likely explanation would be a bug in the code.
const int NUM_ROUNDS = 10_000;
const double FAILURE_PROBABILITY = 0.001; // probability of test failing with normal distributed input
const double P_LOW = 0.25 * FAILURE_PROBABILITY;
const double P_HIGH = 1.0 - 0.25 * FAILURE_PROBABILITY;
var samples = new double[NUM_ROUNDS];
using var rng = new MultiThreadedRng();
int n;
for (n = 0; n != NUM_ROUNDS; ++n)
samples[n] = await rng.GetUniform();
Array.Sort(samples);
var jMinus = 0;
var jPlus = 0;
var kPlus = -double.MaxValue;
var kMinus = -double.MaxValue;
for (n = 0; n != NUM_ROUNDS; ++n)
{
var cdf = samples[n];
var temp = (n + 1.0) / NUM_ROUNDS - cdf;
if (kPlus < temp)
{
kPlus = temp;
jPlus = n;
}
temp = cdf - (n + 0.0) / NUM_ROUNDS;
if (kMinus < temp)
{
kMinus = temp;
jMinus = n;
}
}
var sqrtNumReps = Math.Sqrt(NUM_ROUNDS);
kPlus *= sqrtNumReps;
kMinus *= sqrtNumReps;
// We divide the failure probability by four because we have four tests:
// left and right tests for K+ and K-.
var cutoffLow = Math.Sqrt(0.5 * Math.Log(1.0 / (1.0 - P_LOW))) - 1.0 / (6.0 * sqrtNumReps);
var cutoffHigh = Math.Sqrt(0.5 * Math.Log(1.0 / (1.0 - P_HIGH))) - 1.0 / (6.0 * sqrtNumReps);
TestContext.WriteLine($"K+ = {kPlus} | K- = {kMinus}");
TestContext.WriteLine($"K+ max at position {jPlus} = {samples[jPlus]}");
TestContext.WriteLine($"K- max at position {jMinus} = {samples[jMinus]}");
TestContext.WriteLine($"Acceptable interval: [{cutoffLow}, {cutoffHigh}]");
Assert.That(kPlus, Is.GreaterThanOrEqualTo(cutoffLow), "K+ is lower than low cutoff");
Assert.That(kPlus, Is.LessThanOrEqualTo(cutoffHigh), "K+ is higher than high cutoff");
Assert.That(kMinus, Is.GreaterThanOrEqualTo(cutoffLow), "K- is lower than low cutoff");
Assert.That(kMinus, Is.LessThanOrEqualTo(cutoffHigh), "K- is lower than high cutoff");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange01()
{
var samples = new double[1_000];
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange02()
{
var samples = new double[1_000];
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange04()
{
using var rng = new MultiThreadedRng();
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await rng.GetUniform();
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange05Uint()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0, 100)]++;
for (var n = 0; n < distribution.Length - 1; n++)
Assert.That(distribution[n], Is.GreaterThan(0));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange05Ulong()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0UL, 100)]++;
for (var n = 0; n < distribution.Length - 1; n++)
Assert.That(distribution[n], Is.GreaterThan(0));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange05Float()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[(uint)Math.Floor(await dist.NextNumber(0.0, 100.0))]++;
for (var n = 0; n < distribution.Length - 1; n++)
Assert.That(distribution[n], Is.GreaterThan(0));
}
[Test]
[Category(TestCategories.NORMAL)]
public async Task TestDistribution001Uint()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0, 100)]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600));
}
[Test]
[Category(TestCategories.NORMAL)]
public async Task TestDistribution001Ulong()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0UL, 100)]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600));
}
[Test]
[Category(TestCategories.NORMAL)]
public async Task TestDistribution001Float()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 1_000_000;
for (var n = 0; n < runs; n++)
distribution[(uint)Math.Floor(await dist.NextNumber(0.0, 100.0))]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600));
}
[Test]
[Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Uint()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 100_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0, 100)]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000));
}
[Test]
[Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Ulong()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 100_000_000;
for (var n = 0; n < runs; n++)
distribution[await dist.NextNumber(0UL, 100)]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000));
}
[Test]
[Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Float()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.Uniform(rng);
var distribution = new uint[101];
var runs = 100_000_000;
for (var n = 0; n < runs; n++)
distribution[(uint)Math.Floor(await dist.NextNumber(0.0, 100.0))]++;
Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.Uniform(null));
}
}
}

View File

@ -1,84 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double.Distributions
{
[ExcludeFromCodeCoverage]
public class WeibullK05La1
{
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestWeibullDistribution01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.WeibullK05La1(rng);
var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++)
fra.CountThis(await dist.NextNumber());
var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine);
Assert.That(result[0], Is.EqualTo(1.000000000).Within(0.2));
Assert.That(result[1], Is.EqualTo(0.678415772).Within(0.09));
Assert.That(result[2], Is.EqualTo(0.536595233).Within(0.09));
Assert.That(result[21], Is.EqualTo(0.147406264).Within(0.02));
Assert.That(result[22], Is.EqualTo(0.142654414).Within(0.02));
Assert.That(result[23], Is.EqualTo(0.138217760).Within(0.02));
Assert.That(result[50], Is.EqualTo(0.075769787).Within(0.095));
Assert.That(result[75], Is.EqualTo(0.053016799).Within(0.05));
Assert.That(result[85], Is.EqualTo(0.047144614).Within(0.05));
Assert.That(result[90], Is.EqualTo(0.044629109).Within(0.05));
Assert.That(result[97], Is.EqualTo(0.041484591).Within(0.05));
Assert.That(result[98], Is.EqualTo(0.041067125).Within(0.05));
Assert.That(result[99], Is.EqualTo(0.040656966).Within(0.05));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestWeibullGeneratorWithRange01()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.WeibullK05La1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0), "Min out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestWeibullGeneratorWithRange02()
{
using var rng = new MultiThreadedRng();
var dist = new FastRng.Double.Distributions.WeibullK05La1(rng);
var samples = new double[1_000];
for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0, 1.0);
Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0), "Min is out of range");
Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0), "Max is out of range");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01()
{
Assert.Throws<ArgumentNullException>(() => new FastRng.Double.Distributions.WeibullK05La1(null));
}
}
}

View File

@ -1,85 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
public sealed class FrequencyAnalysis
{
private readonly uint[] data;
public FrequencyAnalysis(int samples = 100)
{
this.data = new uint[samples];
}
public void CountThis(double value)
{
var bucket = (int)Math.Floor(value * this.data.Length);
this.data[bucket]++;
}
public double[] GetNormalizedEvents()
{
var max = (double) this.data.Max();
var result = new double[this.data.Length];
for (var n = 0; n < this.data.Length; n++)
{
result[n] = this.data[n] / max;
}
return result;
}
private double[] Normalize()
{
var max = (double)this.data.Max();
var result = new double[this.data.Length];
for (var n = 0; n < this.data.Length; n++)
result[n] = this.data[n] / max;
return result;
}
public double[] NormalizeAndPlotEvents(Action<string> writer)
{
var result = this.Normalize();
FrequencyAnalysis.Plot(result, writer, "Event Distribution");
return result;
}
public void PlotOccurence(Action<string> writer)
{
var data = this.data.Select(n => n > 0 ? 1.0 : 0.0).ToArray();
FrequencyAnalysis.Plot(data, writer, "Occurrence Distribution");
}
private static void Plot(double[] data, Action<string> writer, string name)
{
const int HEIGHT = 16;
var values = new double[data.Length];
for (var n = 0; n < data.Length; n++)
{
values[n] = data[n] * HEIGHT;
}
var sb = new StringBuilder();
for (var line = HEIGHT; line > 0; line--)
{
for (var column = 0; column < data.Length; column++)
sb.Append(values[column] >= line ? '█' : '░');
writer.Invoke(sb.ToString());
sb.Clear();
}
writer.Invoke(name);
writer.Invoke(string.Empty);
}
}
}

View File

@ -1,341 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using FastRng.Double;
using NUnit.Framework;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
public class MathToolsTests
{
#region Gamma
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest01()
{
Assert.That(MathTools.Gamma(-0.5), Is.EqualTo(-3.544907701811087).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest02()
{
Assert.That(MathTools.Gamma(0.1), Is.EqualTo(9.513507698668752).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest03()
{
Assert.That(MathTools.Gamma(0.5), Is.EqualTo(1.772453850905517).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest04()
{
Assert.That(MathTools.Gamma(1.0), Is.EqualTo(1.0).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest05()
{
Assert.That(MathTools.Gamma(1.5), Is.EqualTo(0.8862269254527587).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest06()
{
Assert.That(MathTools.Gamma(2.0), Is.EqualTo(1.0).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest07()
{
Assert.That(MathTools.Gamma(3.0), Is.EqualTo(2.0).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest08()
{
Assert.That(MathTools.Gamma(10.0), Is.EqualTo(362_880.0000000015).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest09()
{
Assert.That(MathTools.Gamma(140.0), Is.EqualTo(9.6157231969402357e+238).Within(1e-6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void GammaTest10()
{
Assert.That(MathTools.Gamma(170.0), Is.EqualTo(double.PositiveInfinity));
}
#endregion
#region Factorial (integer)
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger01()
{
Assert.That(MathTools.Factorial(0), Is.EqualTo(1));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger02()
{
Assert.That(MathTools.Factorial(1), Is.EqualTo(1));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger03()
{
Assert.That(MathTools.Factorial(2), Is.EqualTo(2));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger04()
{
Assert.That(MathTools.Factorial(3), Is.EqualTo(6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger05()
{
Assert.That(MathTools.Factorial(4), Is.EqualTo(24));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger06()
{
Assert.That(MathTools.Factorial(5), Is.EqualTo(120));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger07()
{
Assert.That(MathTools.Factorial(6), Is.EqualTo(720));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger08()
{
Assert.That(MathTools.Factorial(7), Is.EqualTo(5_040));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger09()
{
Assert.That(MathTools.Factorial(8), Is.EqualTo(40_320));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger10()
{
Assert.That(MathTools.Factorial(9), Is.EqualTo(362_880));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger11()
{
Assert.That(MathTools.Factorial(10), Is.EqualTo(3_628_800));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger12()
{
Assert.That(MathTools.Factorial(11), Is.EqualTo(39_916_800));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger13()
{
Assert.That(MathTools.Factorial(12), Is.EqualTo(479_001_600));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger14()
{
Assert.That(MathTools.Factorial(13), Is.EqualTo(6_227_020_800));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger15()
{
Assert.That(MathTools.Factorial(14), Is.EqualTo(87_178_291_200));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger16()
{
Assert.That(MathTools.Factorial(15), Is.EqualTo(1_307_674_368_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger17()
{
Assert.That(MathTools.Factorial(16), Is.EqualTo(20_922_789_888_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger18()
{
Assert.That(MathTools.Factorial(17), Is.EqualTo(355_687_428_096_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger19()
{
Assert.That(MathTools.Factorial(18), Is.EqualTo(6_402_373_705_728_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger20()
{
Assert.That(MathTools.Factorial(19), Is.EqualTo(121_645_100_408_832_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger21()
{
Assert.That(MathTools.Factorial(20), Is.EqualTo(2_432_902_008_176_640_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger22()
{
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(21));
// Note: 21! is not possible in C# until we got 128 bit integers, since:
// ulong.max == 18_446_744_073_709_551_615 < 51_090_942_171_709_400_000
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger23()
{
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(45_646));
// Note: 45_646! is not possible in C# since:
// ulong.max == 18_446_744_073_709_551_615
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger24()
{
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(-1));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialInteger25()
{
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(-6_565));
}
#endregion
#region Factorial (floating point)
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint01()
{
Assert.That(MathTools.Factorial(0.5), Is.EqualTo(0.886226925).Within(1e6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint02()
{
Assert.That(MathTools.Factorial(1.5), Is.EqualTo(1.329340388).Within(1e6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint03()
{
Assert.That(MathTools.Factorial(-1.5), Is.EqualTo(-1.329340388).Within(1e6));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint04()
{
Assert.That(MathTools.Factorial(7.5), Is.EqualTo(14_034.407293483).Within(1e6));
}
#endregion
}
}

View File

@ -1,625 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using FastRng.Double;
using FastRng.Double.Distributions;
using NUnit.Framework;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
public class MultiThreadedRngTests
{
private readonly IRandom rng = new MultiThreadedRng();
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange01Uint()
{
var dist = new Uniform(this.rng);
for (uint n = 0; n < 1_000_000; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange01Ulong()
{
var dist = new Uniform(this.rng);
for (ulong n = 0; n < 1_000_000; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange01Float()
{
var dist = new Uniform(this.rng);
for (var n = 0.0; n < 1e6; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange02Uint()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5, 5), Is.EqualTo(5));
Assert.That(await dist.NextNumber(0, 0), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_000), Is.EqualTo(3_000_000_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange02Ulong()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5UL, 5), Is.EqualTo(5));
Assert.That(await dist.NextNumber(0UL, 0), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_000), Is.EqualTo(3_000_000_000));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange02Float()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5f, 5f), Is.EqualTo(5));
Assert.That(await dist.NextNumber(0f, 0f), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3e9, 3e9), Is.EqualTo(3e9));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange03Uint()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5, 6), Is.InRange(5, 6));
Assert.That(await dist.NextNumber(0, 1), Is.InRange(0, 1));
Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange03Ulong()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5UL, 6), Is.InRange(5, 6));
Assert.That(await dist.NextNumber(0UL, 1), Is.InRange(0, 1));
Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange03Float()
{
var dist = new Uniform(this.rng);
Assert.That(await dist.NextNumber(5f, 6), Is.InRange(5, 6));
Assert.That(await dist.NextNumber(0f, 1), Is.InRange(0, 1));
Assert.That(await dist.NextNumber(3e9, 3e9+2), Is.InRange(3e9, 3e9+2));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange04Uint()
{
var distUniform = new Uniform(this.rng);
var distNormal = new NormalS02M05(this.rng);
Assert.That(await distUniform.NextNumber(10, 1), Is.InRange(1, 10));
Assert.That(await distNormal.NextNumber(10, 1), Is.InRange(1, 10));
Assert.That(await distUniform.NextNumber(20, 1), Is.InRange(1, 20));
Assert.That(await distNormal.NextNumber(20, 1), Is.InRange(1, 20));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange04Ulong()
{
var distUniform = new Uniform(this.rng);
var distNormal = new NormalS02M05(this.rng);
Assert.That(await distUniform.NextNumber(10UL, 1), Is.InRange(1, 10));
Assert.That(await distNormal.NextNumber(10UL, 1), Is.InRange(1, 10));
Assert.That(await distUniform.NextNumber(20UL, 1), Is.InRange(1, 20));
Assert.That(await distNormal.NextNumber(20UL, 1), Is.InRange(1, 20));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestRange04Float()
{
var distUniform = new Uniform(this.rng);
var distNormal = new NormalS02M05(this.rng);
Assert.That(await distUniform.NextNumber(10.0, 1), Is.InRange(1, 10));
Assert.That(await distNormal.NextNumber(10.0, 1), Is.InRange(1, 10));
Assert.That(await distUniform.NextNumber(20.0, 1), Is.InRange(1, 20));
Assert.That(await distNormal.NextNumber(20.0, 1), Is.InRange(1, 20));
}
[Test]
[Category(TestCategories.LONG_RUNNING)]
public async Task TestRange05()
{
var distUniform = new Uniform(this.rng);
var distLorentz = new CauchyLorentzX1(this.rng);
var rngContains0 = false;
var rngContains1 = false;
var uniformContains0 = false;
var uniformContains1 = false;
var lorentzContains0 = false;
var lorentzContains1 = false;
for (int i = 0; i < 100_000_000; i++)
{
var rngValue = await rng.GetUniform();
var uniform = await distUniform.NextNumber();
var lorentz = await distLorentz.NextNumber();
switch (rngValue)
{
case 0.0:
rngContains0 = true;
break;
case 1.0:
rngContains1 = true;
break;
}
switch (uniform)
{
case 0.0:
uniformContains0 = true;
break;
case 1.0:
uniformContains1 = true;
break;
}
switch (lorentz)
{
case 0.0:
lorentzContains0 = true;
break;
case 1.0:
lorentzContains1 = true;
break;
}
}
TestContext.WriteLine($"Uniform generator contained 0? {rngContains0} (expected=false)");
TestContext.WriteLine($"Uniform generator contained 1? {rngContains1} (expected=true)");
TestContext.WriteLine($"Uniform distribution contained 0? {uniformContains0} (expected=false)");
TestContext.WriteLine($"Uniform distribution contained 1? {uniformContains1} (expected=true)");
TestContext.WriteLine($"Lorentz distribution contained 0? {lorentzContains0} (expected=false)");
TestContext.WriteLine($"Lorentz distribution contained 1? {lorentzContains1} (expected=true)");
Assert.That(rngContains0, Is.False, "Uniform generator contained 0");
Assert.That(rngContains1, Is.True, "Uniform generator does not contained 1");
Assert.That(uniformContains0, Is.False, "Uniform distribution contained 0");
Assert.That(uniformContains1, Is.True, "Uniform distribution does not contained 1");
Assert.That(lorentzContains0, Is.False, "Lorentz distribution contained 0");
Assert.That(lorentzContains1, Is.True, "Lorentz distribution does not contained 1");
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestStoppingProducers01()
{
var rng2 = new MultiThreadedRng();
rng2.Dispose();
var masterToken = new CancellationTokenSource(TimeSpan.FromSeconds(16)).Token;
var wasCanceled = false;
while(true)
{
var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await rng2.GetUniform(tokenSource.Token);
if (tokenSource.IsCancellationRequested)
{
wasCanceled = true;
break;
}
if (masterToken.IsCancellationRequested)
{
break;
}
}
Assert.That(masterToken.IsCancellationRequested, Is.False, "Master token was used to stop test");
Assert.That(wasCanceled, Is.True, "The consumer was not canceled");
var tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(-1d, 1d, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(0u, 6u, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(0ul, 6ul, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True);
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task OneSeed01()
{
using var rng1 = new MultiThreadedRng(6);
using var rng2 = new MultiThreadedRng(6);
using var rng3 = new MultiThreadedRng(7);
var rng1Sample = new double[10];
for (var n = 0; n < rng1Sample.Length; n++)
rng1Sample[n] = await rng1.GetUniform();
var rng2Sample = new double[10];
for (var n = 0; n < rng2Sample.Length; n++)
rng2Sample[n] = await rng2.GetUniform();
var rng3Sample = new double[10];
for (var n = 0; n < rng3Sample.Length; n++)
rng3Sample[n] = await rng3.GetUniform();
Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample));
Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample));
Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TwoSeeds01()
{
using var rng1 = new MultiThreadedRng(3, 6);
using var rng2 = new MultiThreadedRng(3, 6);
using var rng3 = new MultiThreadedRng(3, 7);
using var rng4 = new MultiThreadedRng(6, 3);
var rng1Sample = new double[10];
for (var n = 0; n < rng1Sample.Length; n++)
rng1Sample[n] = await rng1.GetUniform();
var rng2Sample = new double[10];
for (var n = 0; n < rng2Sample.Length; n++)
rng2Sample[n] = await rng2.GetUniform();
var rng3Sample = new double[10];
for (var n = 0; n < rng3Sample.Length; n++)
rng3Sample[n] = await rng3.GetUniform();
var rng4Sample = new double[10];
for (var n = 0; n < rng4Sample.Length; n++)
rng4Sample[n] = await rng4.GetUniform();
Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample));
Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample));
Assert.That(rng1Sample, Is.Not.EquivalentTo(rng4Sample));
Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample));
Assert.That(rng2Sample, Is.Not.EquivalentTo(rng4Sample));
Assert.That(rng3Sample, Is.Not.EquivalentTo(rng4Sample));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task NoSeed01()
{
using var rng1 = new MultiThreadedRng();
using var rng2 = new MultiThreadedRng();
using var rng3 = new MultiThreadedRng();
var rng1Sample = new double[10];
for (var n = 0; n < rng1Sample.Length; n++)
rng1Sample[n] = await rng1.GetUniform();
var rng2Sample = new double[10];
for (var n = 0; n < rng2Sample.Length; n++)
rng2Sample[n] = await rng2.GetUniform();
var rng3Sample = new double[10];
for (var n = 0; n < rng3Sample.Length; n++)
rng3Sample[n] = await rng3.GetUniform();
Assert.That(rng1Sample, Is.Not.EquivalentTo(rng2Sample));
Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample));
Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCancellation01()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
tokenSource.Cancel();
using var rng2 = new MultiThreadedRng();
var dist = new Uniform(rng2);
Assert.That(await dist.NextNumber(1, 100_000, token), Is.EqualTo(0));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestCancellation02()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
tokenSource.Cancel();
using var rng2 = new MultiThreadedRng();
Assert.That(await rng2.GetUniform(token), Is.NaN);
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic01()
{
using var rng2 = new MultiThreadedRng(16);
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic02()
{
using var rng2 = new MultiThreadedRng(16);
var dist = new Uniform(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic03()
{
using var rng2 = new MultiThreadedRng(16);
var dist = new CauchyLorentzX0(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic01b()
{
using var rng2 = new MultiThreadedRng(16, 362_436_069);
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f));
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic02b()
{
using var rng2 = new MultiThreadedRng(16, 362_436_069);
var dist = new Uniform(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83));
}
[Test]
[Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)]
public async Task TestDeterministic03b()
{
using var rng2 = new MultiThreadedRng(16, 362_436_069);
var dist = new CauchyLorentzX0(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4));
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56));
}
}
}

View File

@ -1,137 +0,0 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using FastRng.Double;
using FastRng.Double.Distributions;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
public class PerformanceTests
{
#region FastRng
[Test]
[Category(TestCategories.PERFORMANCE)]
public async Task Generate1MUniform()
{
using var rng = new MultiThreadedRng();
var data = new double[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = await rng.GetUniform();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M uniform distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
[Test]
[Category(TestCategories.PERFORMANCE)]
public async Task Generate1MNormal()
{
using var rng = new MultiThreadedRng();
var dist = new NormalS02M05(rng);
var data = new double[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = await dist.NextNumber();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M normal distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
[Test]
[Category(TestCategories.PERFORMANCE)]
public async Task Generate1MChiSquare()
{
using var rng = new MultiThreadedRng();
var dist = new ChiSquareK4(rng);
var data = new double[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = await dist.NextNumber();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M chi-square distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
#endregion
#region Math.NET
[Test]
[Category(TestCategories.PERFORMANCE)]
public void ComparisonMathNet1MUniform()
{
var rng = new Xorshift(true);
var data = new float[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = (float) rng.NextDouble();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M uniform distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
[Test]
[Category(TestCategories.PERFORMANCE)]
public void ComparisonMathNet1MNormal()
{
var rng = new Xorshift(true);
var dist = new Normal(stddev: 0.2f, mean: 0.5f, randomSource: rng);
var data = new float[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = (float) dist.Sample();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M normal distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
[Test]
[Category(TestCategories.PERFORMANCE)]
public void ComparisonMathNet1MChiSquare()
{
var rng = new Xorshift(true);
var dist = new ChiSquared(4);
var data = new float[1_000_000];
var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
stopwatch.Start();
for (uint n = 0; n < data.Length; n++)
data[n] = (float) dist.Sample();
stopwatch.Stop();
TestContext.WriteLine($"Generated 1M chi-squared distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds.");
}
#endregion
}
}

View File

@ -1,49 +0,0 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace FastRngTests.Double
{
[ExcludeFromCodeCoverage]
internal sealed class RunningStatistics
{
private double previousM;
private double previousS;
private double nextM;
private double nextS;
public RunningStatistics()
{
}
public int NumberRecords { get; private set; } = 0;
public void Clear() => this.NumberRecords = 0;
public void Push(double x)
{
this.NumberRecords++;
// See Knuth TAOCP vol 2, 3rd edition, page 232
if (this.NumberRecords == 1)
{
this.previousM = this.nextM = x;
this.previousS = 0.0;
}
else
{
this.nextM = this.previousM + (x - this.previousM) / this.NumberRecords;
this.nextS = this.previousS + (x - this.previousM) * (x - this.nextM);
// set up for next iteration
this.previousM = this.nextM;
this.previousS = this.nextS;
}
}
public double Mean => this.NumberRecords > 0 ? this.nextM : 0.0;
public double Variance => this.NumberRecords > 1 ? this.nextS / (this.NumberRecords - 1) : 0.0;
public double StandardDeviation => Math.Sqrt(this.Variance);
}
}