Refactored to use generic TNum for any floating point type

This commit is contained in:
Thorsten Sommer 2023-07-07 14:41:01 +02:00
parent 6b656b90e3
commit 1c28a57c06
No known key found for this signature in database
GPG Key ID: B0B7E2FC074BF1F5
55 changed files with 578 additions and 1147 deletions

View File

@ -1,16 +1,16 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class BetaA2B2 : Distribution public sealed class BetaA2B2<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float ALPHA = 2f; private static readonly TNum ALPHA = TNum.One + TNum.One;
private const float BETA = 2f; private static readonly TNum BETA = TNum.One + TNum.One;
private const float CONSTANT = 4f; private static readonly TNum CONSTANT = TNum.CreateChecked(4);
public BetaA2B2(IRandom rng) : base(rng) public BetaA2B2(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); private protected override TNum ShapeFunction(TNum x) => CONSTANT * TNum.Pow(x, ALPHA - TNum.One) * TNum.Pow(TNum.One - x, BETA - TNum.One);
} }

View File

@ -1,16 +1,16 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class BetaA2B5 : Distribution public sealed class BetaA2B5<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float ALPHA = 2f; private static readonly TNum ALPHA = TNum.One + TNum.One;
private const float BETA = 5f; private static readonly TNum BETA = TNum.CreateChecked(5);
private const float CONSTANT = 12.2f; private static readonly TNum CONSTANT = TNum.CreateChecked(12.2f);
public BetaA2B5(IRandom rng) : base(rng) public BetaA2B5(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); private protected override TNum ShapeFunction(TNum x) => CONSTANT * TNum.Pow(x, ALPHA - TNum.One) * TNum.Pow(TNum.One - x, BETA - TNum.One);
} }

View File

@ -1,16 +1,16 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class BetaA5B2 : Distribution public sealed class BetaA5B2<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float ALPHA = 5f; private static readonly TNum ALPHA = TNum.CreateChecked(5f);
private const float BETA = 2f; private static readonly TNum BETA = TNum.One + TNum.One;
private const float CONSTANT = 12.2f; private static readonly TNum CONSTANT = TNum.CreateChecked(12.2f);
public BetaA5B2(IRandom rng) : base(rng) public BetaA5B2(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); private protected override TNum ShapeFunction(TNum x) => CONSTANT * TNum.Pow(x, ALPHA - TNum.One) * TNum.Pow(TNum.One - x, BETA - TNum.One);
} }

View File

@ -1,16 +1,17 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class CauchyLorentzX0 : Distribution public sealed class CauchyLorentzX0<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float CONSTANT = 0.31f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.31f);
private const float SCALE = 0.1f; private static readonly TNum SCALE = TNum.CreateChecked(0.1f);
private const float MEDIAN = 0.0f; private static readonly TNum MEDIAN = TNum.Zero;
private static readonly TNum TWO = TNum.CreateChecked(2f);
public CauchyLorentzX0(IRandom rng) : base(rng) public CauchyLorentzX0(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * (1.0f / (MathF.PI * SCALE)) * ((SCALE * SCALE) / (MathF.Pow(x - MEDIAN, 2f) + (SCALE * SCALE))); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ( TNum.One / (TNum.Pi * SCALE)) * ((SCALE * SCALE) / (TNum.Pow(x - MEDIAN, TWO) + (SCALE * SCALE)));
} }

View File

@ -1,16 +1,17 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class CauchyLorentzX1 : Distribution public sealed class CauchyLorentzX1<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float CONSTANT = 0.31f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.31f);
private const float SCALE = 0.1f; private static readonly TNum SCALE = TNum.CreateChecked(0.1f);
private const float MEDIAN = 1.0f; private static readonly TNum MEDIAN = TNum.One;
private static readonly TNum TWO = TNum.CreateChecked(2f);
public CauchyLorentzX1(IRandom rng) : base(rng) public CauchyLorentzX1(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * (1.0f / (MathF.PI * SCALE)) * ((SCALE * SCALE) / (MathF.Pow(x - MEDIAN, 2f) + (SCALE * SCALE))); private protected override TNum ShapeFunction(TNum x) => CONSTANT * (TNum.One / (TNum.Pi * SCALE)) * ((SCALE * SCALE) / (TNum.Pow(x - MEDIAN, TWO) + (SCALE * SCALE)));
} }

View File

@ -1,26 +1,28 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class ChiSquareK1 : Distribution public sealed class ChiSquareK1<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float K = 1.0f; private static readonly TNum HALF = TNum.CreateChecked(0.5f);
private const float K_HALF = K * 0.5f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; private static readonly TNum K = TNum.One;
private const float CONSTANT = 0.252f; private static readonly TNum K_HALF = K * HALF;
private static readonly TNum K_HALF_MINUS_ONE = K_HALF - TNum.One;
private static readonly TNum CONSTANT = TNum.CreateChecked(0.252f);
private static readonly float DIVISOR; private static readonly TNum DIVISOR;
static ChiSquareK1() static ChiSquareK1()
{ {
var twoToTheKHalf = MathF.Pow(2f, K_HALF); var twoToTheKHalf = TNum.Pow(TWO, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF); var gammaKHalf = FloatingPointMathTools<TNum>.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf; DIVISOR = twoToTheKHalf * gammaKHalf;
} }
public ChiSquareK1(IRandom rng) : base(rng) public ChiSquareK1(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ((TNum.Pow(x, K_HALF_MINUS_ONE) * TNum.Exp(-x * HALF)) / DIVISOR);
} }

View File

@ -1,26 +1,28 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class ChiSquareK10 : Distribution public sealed class ChiSquareK10<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float K = 10.0f; private static readonly TNum HALF = TNum.CreateChecked(0.5f);
private const float K_HALF = K * 0.5f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; private static readonly TNum K = TNum.CreateChecked(10.0f);
private const float CONSTANT = 0.252f; private static readonly TNum K_HALF = K * HALF;
private static readonly TNum K_HALF_MINUS_ONE = K_HALF - TNum.One;
private static readonly TNum CONSTANT = TNum.CreateChecked(0.252f);
private static readonly float DIVISOR; private static readonly TNum DIVISOR;
static ChiSquareK10() static ChiSquareK10()
{ {
var twoToTheKHalf = MathF.Pow(2f, K_HALF); var twoToTheKHalf = TNum.Pow(TWO, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF); var gammaKHalf = FloatingPointMathTools<TNum>.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf; DIVISOR = twoToTheKHalf * gammaKHalf;
} }
public ChiSquareK10(IRandom rng) : base(rng) public ChiSquareK10(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ((TNum.Pow(x, K_HALF_MINUS_ONE) * TNum.Exp(-x * HALF)) / DIVISOR);
} }

View File

@ -1,26 +1,28 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class ChiSquareK4 : Distribution public sealed class ChiSquareK4<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float K = 4.0f; private static readonly TNum HALF = TNum.CreateChecked(0.5f);
private const float K_HALF = K * 0.5f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; private static readonly TNum K = TNum.CreateChecked(4f);
private const float CONSTANT = 0.252f; private static readonly TNum K_HALF = K * HALF;
private static readonly TNum K_HALF_MINUS_ONE = K_HALF - TNum.One;
private static readonly TNum CONSTANT = TNum.CreateChecked(0.252f);
private static readonly float DIVISOR; private static readonly TNum DIVISOR;
static ChiSquareK4() static ChiSquareK4()
{ {
var twoToTheKHalf = MathF.Pow(2, K_HALF); var twoToTheKHalf = TNum.Pow(TWO, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF); var gammaKHalf = FloatingPointMathTools<TNum>.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf; DIVISOR = twoToTheKHalf * gammaKHalf;
} }
public ChiSquareK4(IRandom rng) : base(rng) public ChiSquareK4(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ((TNum.Pow(x, K_HALF_MINUS_ONE) * TNum.Exp(-x * HALF)) / DIVISOR);
} }

View File

@ -1,24 +1,25 @@
using System; using System;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public abstract class Distribution : IDistribution public abstract class Distribution<TNum> : IDistribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private readonly ShapeFitter fitter; private readonly ShapeFitter<TNum> fitter;
protected Distribution(IRandom rng) protected Distribution(IRandom<TNum> rng)
{ {
if (rng == null) if (rng == null)
throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); throw new ArgumentNullException(nameof(rng), "An IRandom<TNum> implementation is needed.");
this.fitter = new ShapeFitter(this.ShapeFunction, rng, 100); this.fitter = new ShapeFitter<TNum>(this.ShapeFunction, rng, 100);
} }
private protected abstract float ShapeFunction(float x); private protected abstract TNum ShapeFunction(TNum x);
public async ValueTask<float> GetDistributedValue(CancellationToken token = default) => await this.fitter.NextNumber(token); public async ValueTask<TNum> GetDistributedValue(CancellationToken token = default) => await this.fitter.NextNumber(token);
public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default)
{ {
@ -28,7 +29,7 @@ public abstract class Distribution : IDistribution
var range = rangeEnd - rangeStart; var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel); var distributedValue = await this.GetDistributedValue(cancel);
return (uint) ((distributedValue * range) + rangeStart); return (uint) ((float.CreateChecked(distributedValue) * range) + rangeStart);
} }
public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default) public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default)
@ -39,10 +40,10 @@ public abstract class Distribution : IDistribution
var range = rangeEnd - rangeStart; var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel); var distributedValue = await this.GetDistributedValue(cancel);
return (ulong) ((distributedValue * range) + rangeStart); return (ulong) ((double.CreateChecked(distributedValue) * range) + rangeStart);
} }
public async ValueTask<float> NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default) public async ValueTask<TNum> NextNumber(TNum rangeStart, TNum rangeEnd, CancellationToken cancel = default)
{ {
// Swap the values if the range start is greater than the range end: // Swap the values if the range start is greater than the range end:
if (rangeStart > rangeEnd) if (rangeStart > rangeEnd)
@ -53,9 +54,9 @@ public abstract class Distribution : IDistribution
return (distributedValue * range) + rangeStart; return (distributedValue * range) + rangeStart;
} }
public async ValueTask<float> NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); public async ValueTask<TNum> NextNumber(CancellationToken cancel = default) => await this.NextNumber(TNum.Zero, TNum.One, cancel);
public async ValueTask<bool> HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) public async ValueTask<bool> HasDecisionBeenMade(TNum above, TNum below, CancellationToken cancel = default)
{ {
var number = await this.NextNumber(cancel); var number = await this.NextNumber(cancel);
return number > above && number < below; return number > above && number < below;

View File

@ -1,15 +1,15 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class ExponentialLa10 : Distribution public sealed class ExponentialLa10<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float LAMBDA = 10.0f; private static readonly TNum LAMBDA = TNum.CreateChecked(10.0f);
private const float CONSTANT = 0.1106f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.1106f);
public ExponentialLa10(IRandom rng) : base(rng) public ExponentialLa10(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); private protected override TNum ShapeFunction(TNum x) => CONSTANT * LAMBDA * TNum.Exp(-LAMBDA * x);
} }

View File

@ -1,15 +1,15 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class ExponentialLa5 : Distribution public sealed class ExponentialLa5<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float LAMBDA = 5.0f; private static readonly TNum LAMBDA = TNum.CreateChecked(5.0f);
private const float CONSTANT = 0.2103f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.2103f);
public ExponentialLa5(IRandom rng) : base(rng) public ExponentialLa5(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); private protected override TNum ShapeFunction(TNum x) => CONSTANT * LAMBDA * TNum.Exp(-LAMBDA * x);
} }

View File

@ -1,25 +1,25 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class GammaA5B15 : Distribution public sealed class GammaA5B15<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float ALPHA = 5.0f; private static readonly TNum ALPHA = TNum.CreateChecked(5.0f);
private const float BETA = 15.0f; private static readonly TNum BETA = TNum.CreateChecked(15.0f);
private const float CONSTANT = 0.341344210715475f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.341344210715475f);
private static readonly float GAMMA_ALPHA; private static readonly TNum GAMMA_ALPHA;
private static readonly float BETA_TO_THE_ALPHA; private static readonly TNum BETA_TO_THE_ALPHA;
static GammaA5B15() static GammaA5B15()
{ {
GAMMA_ALPHA = MathTools.Gamma(ALPHA); GAMMA_ALPHA = FloatingPointMathTools<TNum>.Gamma(ALPHA);
BETA_TO_THE_ALPHA = MathF.Pow(BETA, ALPHA); BETA_TO_THE_ALPHA = TNum.Pow(BETA, ALPHA);
} }
public GammaA5B15(IRandom rng) : base(rng) public GammaA5B15(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * ((BETA_TO_THE_ALPHA * MathF.Pow(x, ALPHA - 1.0f) * MathF.Exp(-BETA * x)) / GAMMA_ALPHA); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ((BETA_TO_THE_ALPHA * TNum.Pow(x, ALPHA - TNum.One) * TNum.Exp(-BETA * x)) / GAMMA_ALPHA);
} }

View File

@ -1,19 +1,20 @@
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public interface IDistribution public interface IDistribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
public ValueTask<float> GetDistributedValue(CancellationToken token); public ValueTask<TNum> GetDistributedValue(CancellationToken token);
public ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default); public ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default);
public ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default); public ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default);
public ValueTask<float> NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default); public ValueTask<TNum> NextNumber(TNum rangeStart, TNum rangeEnd, CancellationToken cancel = default);
public ValueTask<float> NextNumber(CancellationToken cancel = default); public ValueTask<TNum> NextNumber(CancellationToken cancel = default);
public ValueTask<bool> HasDecisionBeenMade(float above, float below = 1.0f, CancellationToken cancel = default); public ValueTask<bool> HasDecisionBeenMade(TNum above, TNum below, CancellationToken cancel = default);
} }

View File

@ -1,15 +1,15 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class InverseExponentialLa10 : Distribution public sealed class InverseExponentialLa10<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float LAMBDA = 10.0f; private static readonly TNum LAMBDA = TNum.CreateChecked(10.0f);
private const float CONSTANT = 4.539992976248453e-06f; private static readonly TNum CONSTANT = TNum.CreateChecked(4.539992976248453e-06f);
public InverseExponentialLa10(IRandom rng) : base(rng) public InverseExponentialLa10(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); private protected override TNum ShapeFunction(TNum x) => CONSTANT * LAMBDA * TNum.Exp(LAMBDA * x);
} }

View File

@ -1,15 +1,15 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class InverseExponentialLa5 : Distribution public sealed class InverseExponentialLa5<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float LAMBDA = 5.0f; private static readonly TNum LAMBDA = TNum.CreateChecked(5.0f);
private const float CONSTANT = 0.001347589399817f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.001347589399817f);
public InverseExponentialLa5(IRandom rng) : base(rng) public InverseExponentialLa5(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); private protected override TNum ShapeFunction(TNum x) => CONSTANT * LAMBDA * TNum.Exp(LAMBDA * x);
} }

View File

@ -1,26 +1,26 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class InverseGammaA3B05 : Distribution public sealed class InverseGammaA3B05<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float ALPHA = 3.0f; private static readonly TNum ALPHA = TNum.CreateChecked(3.0f);
private const float BETA = 0.5f; private static readonly TNum BETA = TNum.CreateChecked(0.5f);
private const float CONSTANT = 0.213922656884911f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.213922656884911f);
private static readonly float FACTOR_LEFT; private static readonly TNum FACTOR_LEFT;
static InverseGammaA3B05() static InverseGammaA3B05()
{ {
var gammaAlpha = MathTools.Gamma(ALPHA); var gammaAlpha = FloatingPointMathTools<TNum>.Gamma(ALPHA);
var betaToTheAlpha = MathF.Pow(BETA, ALPHA); var betaToTheAlpha = TNum.Pow(BETA, ALPHA);
FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha); FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha);
} }
public InverseGammaA3B05(IRandom rng) : base(rng) public InverseGammaA3B05(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Pow(x, -ALPHA - 1.0f) * MathF.Exp(-BETA / x); private protected override TNum ShapeFunction(TNum x) => FACTOR_LEFT * TNum.Pow(x, -ALPHA - TNum.One) * TNum.Exp(-BETA / x);
} }

View File

@ -1,23 +1,24 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class LaplaceB01M0 : Distribution public sealed class LaplaceB01M0<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float B = 0.1f; private static readonly TNum TWO = TNum.CreateChecked(2.0f);
private const float MU = 0.0f; private static readonly TNum B = TNum.CreateChecked(0.1f);
private const float CONSTANT = 0.221034183615129f; private static readonly TNum MU = TNum.Zero;
private static readonly TNum CONSTANT = TNum.CreateChecked(0.221034183615129f);
private static readonly float FACTOR_LEFT; private static readonly TNum FACTOR_LEFT;
static LaplaceB01M0() static LaplaceB01M0()
{ {
FACTOR_LEFT = CONSTANT / (2.0f * B); FACTOR_LEFT = CONSTANT / (TWO * B);
} }
public LaplaceB01M0(IRandom rng) : base(rng) public LaplaceB01M0(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); private protected override TNum ShapeFunction(TNum x) => FACTOR_LEFT * TNum.Exp(-TNum.Abs(x - MU) / B);
} }

View File

@ -1,23 +1,24 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class LaplaceB01M05 : Distribution public sealed class LaplaceB01M05<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float B = 0.1f; private static readonly TNum TWO = TNum.CreateChecked(2.0f);
private const float MU = 0.5f; private static readonly TNum B = TNum.CreateChecked(0.1f);
private const float CONSTANT = 0.2f; private static readonly TNum MU = TNum.CreateChecked(0.5f);
private static readonly TNum CONSTANT = TNum.CreateChecked(0.2f);
private static readonly float FACTOR_LEFT; private static readonly TNum FACTOR_LEFT;
static LaplaceB01M05() static LaplaceB01M05()
{ {
FACTOR_LEFT = CONSTANT / (2.0f * B); FACTOR_LEFT = CONSTANT / (TWO * B);
} }
public LaplaceB01M05(IRandom rng) : base(rng) public LaplaceB01M05(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); private protected override TNum ShapeFunction(TNum x) => FACTOR_LEFT * TNum.Exp(-TNum.Abs(x - MU) / B);
} }

View File

@ -1,23 +1,24 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class LogNormalS1M0 : Distribution public sealed class LogNormalS1M0<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float SIGMA = 1.0f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float MU = 0.0f; private static readonly TNum SIGMA = TNum.One;
private const float CONSTANT = 1.51998658387455f; private static readonly TNum MU = TNum.Zero;
private static readonly TNum CONSTANT = TNum.CreateChecked(1.51998658387455f);
private static readonly float FACTOR; private static readonly TNum FACTOR;
static LogNormalS1M0() static LogNormalS1M0()
{ {
FACTOR = SIGMA * MathF.Sqrt(2f * MathF.PI); FACTOR = SIGMA * TNum.Sqrt(TWO * TNum.Pi);
} }
public LogNormalS1M0(IRandom rng) : base(rng) public LogNormalS1M0(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => (CONSTANT / (x * FACTOR)) * MathF.Exp( -(MathF.Pow(MathF.Log(x) - MU, 2f) / (2f * MathF.Pow(SIGMA, 2f)))); private protected override TNum ShapeFunction(TNum x) => (CONSTANT / (x * FACTOR)) * TNum.Exp( -(TNum.Pow(TNum.Log(x) - MU, TWO) / (TWO * TNum.Pow(SIGMA, TWO))));
} }

View File

@ -1,16 +1,18 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class NormalS02M05 : Distribution public sealed class NormalS02M05<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float SQRT_2_PI = 2.506628275f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float STD_DEV = 0.2f; private static readonly TNum NEGATIVE_HALF = TNum.CreateChecked(-0.5f);
private const float MEAN = 0.5f; private static readonly TNum SQRT_2_PI = TNum.CreateChecked(2.506628275f);
private static readonly TNum STD_DEV = TNum.CreateChecked(0.2f);
private static readonly TNum MEAN = TNum.CreateChecked(0.5f);
public NormalS02M05(IRandom rng) : base(rng) public NormalS02M05(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => 1.0f / (STD_DEV * SQRT_2_PI) * MathF.Exp(-0.5f * MathF.Pow((x - MEAN) / STD_DEV, 2.0f)); private protected override TNum ShapeFunction(TNum x) => TNum.One / (STD_DEV * SQRT_2_PI) * TNum.Exp(NEGATIVE_HALF * TNum.Pow((x - MEAN) / STD_DEV, TWO));
} }

View File

@ -1,28 +1,30 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class StudentTNu1 : Distribution public sealed class StudentTNu1<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float NU = 1.0f; private static readonly TNum HALF = TNum.CreateChecked(0.5f);
private const float START = 0.0f; private static readonly TNum TWO = TNum.CreateChecked(2f);
private const float COMPRESS = 1.0f; private static readonly TNum NU = TNum.One;
private const float CONSTANT = 3.14190548592729f; private static readonly TNum START = TNum.Zero;
private static readonly TNum COMPRESS = TNum.One;
private static readonly TNum CONSTANT = TNum.CreateChecked(3.14190548592729f);
private static readonly float DIVIDEND; private static readonly TNum DIVIDEND;
private static readonly float DIVISOR; private static readonly TNum DIVISOR;
private static readonly float EXPONENT; private static readonly TNum EXPONENT;
static StudentTNu1() static StudentTNu1()
{ {
DIVIDEND = MathTools.Gamma((NU + 1.0f) * 0.5f); DIVIDEND = FloatingPointMathTools<TNum>.Gamma((NU + TNum.One) * HALF);
DIVISOR = MathF.Sqrt(NU * MathF.PI) * MathTools.Gamma(NU * 0.5f); DIVISOR = TNum.Sqrt(NU * TNum.Pi) * FloatingPointMathTools<TNum>.Gamma(NU * HALF);
EXPONENT = -((NU + 1.0f) * 0.5f); EXPONENT = -((NU + TNum.One) * HALF);
} }
public StudentTNu1(IRandom rng) : base(rng) public StudentTNu1(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow((DIVIDEND / DIVISOR) * MathF.Pow(1.0f + MathF.Pow(START + x * COMPRESS, 2f) / NU, EXPONENT), COMPRESS); private protected override TNum ShapeFunction(TNum x) => CONSTANT * TNum.Pow((DIVIDEND / DIVISOR) * TNum.Pow( TNum.One + TNum.Pow(START + x * COMPRESS, TWO) / NU, EXPONENT), COMPRESS);
} }

View File

@ -1,19 +1,20 @@
using System; using System;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class Uniform : IDistribution public sealed class Uniform<TNum> : IDistribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private readonly IRandom rng; private readonly IRandom<TNum> rng;
public Uniform(IRandom rng) public Uniform(IRandom<TNum> rng)
{ {
this.rng = rng ?? throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); this.rng = rng ?? throw new ArgumentNullException(nameof(rng), "An IRandom<TNum> implementation is needed.");
} }
public async ValueTask<float> GetDistributedValue(CancellationToken token = default) => await this.rng.GetUniform(token); public async ValueTask<TNum> GetDistributedValue(CancellationToken token = default) => await this.rng.GetUniform(token);
public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) public async ValueTask<uint> NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default)
{ {
@ -23,7 +24,7 @@ public sealed class Uniform : IDistribution
var range = rangeEnd - rangeStart; var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel); var distributedValue = await this.GetDistributedValue(cancel);
return (uint) ((distributedValue * range) + rangeStart); return (uint) ((float.CreateChecked(distributedValue) * range) + rangeStart);
} }
public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default) public async ValueTask<ulong> NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default)
@ -34,10 +35,10 @@ public sealed class Uniform : IDistribution
var range = rangeEnd - rangeStart; var range = rangeEnd - rangeStart;
var distributedValue = await this.GetDistributedValue(cancel); var distributedValue = await this.GetDistributedValue(cancel);
return (ulong) ((distributedValue * range) + rangeStart); return (ulong) ((double.CreateChecked(distributedValue) * range) + rangeStart);
} }
public async ValueTask<float> NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default) public async ValueTask<TNum> NextNumber(TNum rangeStart, TNum rangeEnd, CancellationToken cancel = default)
{ {
// Swap the values if the range start is greater than the range end: // Swap the values if the range start is greater than the range end:
if (rangeStart > rangeEnd) if (rangeStart > rangeEnd)
@ -48,9 +49,9 @@ public sealed class Uniform : IDistribution
return (distributedValue * range) + rangeStart; return (distributedValue * range) + rangeStart;
} }
public async ValueTask<float> NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); public async ValueTask<TNum> NextNumber(CancellationToken cancel = default) => await this.NextNumber(TNum.Zero, TNum.One, cancel);
public async ValueTask<bool> HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) public async ValueTask<bool> HasDecisionBeenMade(TNum above, TNum below, CancellationToken cancel = default)
{ {
var number = await this.NextNumber(cancel); var number = await this.NextNumber(cancel);
return number > above && number < below; return number > above && number < below;

View File

@ -1,16 +1,16 @@
using System; using System.Numerics;
namespace FastRng.Distributions; namespace FastRng.Distributions;
public sealed class WeibullK05La1 : Distribution public sealed class WeibullK05La1<TNum> : Distribution<TNum> where TNum : IFloatingPointIeee754<TNum>
{ {
private const float K = 0.5f; private static readonly TNum K = TNum.CreateChecked(0.5f);
private const float LAMBDA = 1.0f; private static readonly TNum LAMBDA = TNum.One;
private const float CONSTANT = 0.221034183615129f; private static readonly TNum CONSTANT = TNum.CreateChecked(0.221034183615129f);
public WeibullK05La1(IRandom rng) : base(rng) public WeibullK05La1(IRandom<TNum> rng) : base(rng)
{ {
} }
private protected override float ShapeFunction(float x) => CONSTANT * ( (K / LAMBDA) * MathF.Pow(x / LAMBDA, K - 1.0f) * MathF.Exp(-MathF.Pow(x/LAMBDA, K))); private protected override TNum ShapeFunction(TNum x) => CONSTANT * ( (K / LAMBDA) * TNum.Pow(x / LAMBDA, K - TNum.One) * TNum.Exp(-TNum.Pow(x/LAMBDA, K)));
} }

View File

@ -0,0 +1,63 @@
using System;
using System.Numerics;
namespace FastRng;
/// <summary>
/// Provides some mathematical function, which are not available within in .NET itself.
/// </summary>
public static class FloatingPointMathTools<TNum> where TNum : IFloatingPointIeee754<TNum>, IAdditionOperators<TNum, TNum, TNum>
{
private static readonly TNum SQRT_2 = TNum.Sqrt(TNum.One + TNum.One);
private static readonly TNum SQRT_PI = TNum.Sqrt(TNum.Pi);
// Source: http://rosettacode.org/wiki/Gamma_function#Go
private static readonly TNum F1 = TNum.CreateChecked(6.5f);
private static readonly TNum A1 = TNum.CreateChecked(.99999999999980993f);
private static readonly TNum A2 = TNum.CreateChecked(676.5203681218851f);
private static readonly TNum A3 = TNum.CreateChecked(1259.1392167224028f);
private static readonly TNum A4 = TNum.CreateChecked(771.32342877765313f);
private static readonly TNum A5 = TNum.CreateChecked(176.61502916214059f);
private static readonly TNum A6 = TNum.CreateChecked(12.507343278686905f);
private static readonly TNum A7 = TNum.CreateChecked(.13857109526572012f);
private static readonly TNum A8 = TNum.CreateChecked(9.9843695780195716e-6f);
private static readonly TNum A9 = TNum.CreateChecked(1.5056327351493116e-7f);
private static readonly TNum CONST1 = TNum.One;
private static readonly TNum CONST2 = CONST1 + TNum.One;
private static readonly TNum CONST3 = CONST2 + TNum.One;
private static readonly TNum CONST4 = CONST3 + TNum.One;
private static readonly TNum CONST5 = CONST4 + TNum.One;
private static readonly TNum CONST6 = CONST5 + TNum.One;
private static readonly TNum CONST7 = CONST6 + TNum.One;
private static readonly TNum CONST_HALF = TNum.CreateChecked(0.5f);
/// <summary>
/// The mathematical gamma function.
/// </summary>
/// <param name="z">The value for which you want calculate gamma.</param>
public static TNum Gamma(TNum z)
{
// Source: http://rosettacode.org/wiki/Gamma_function#Go
var t = z + F1;
var x = A1 +
A2 / z -
A3 / (z + CONST1) +
A4 / (z + CONST2) -
A5 / (z + CONST3) +
A6 / (z + CONST4) -
A7 / (z + CONST5) +
A8 / (z + CONST6) +
A9 / (z + CONST7);
return SQRT_2 * SQRT_PI * TNum.Pow(t, z - CONST_HALF) * TNum.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 TNum Factorial(TNum x) => Gamma(x + CONST1);
}

View File

@ -1,555 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using System.Numerics;
namespace FastRng;
public struct HugeInteger<TOtherNum> :
IBinaryInteger<HugeInteger<TOtherNum>>,
IComparisonOperators<HugeInteger<TOtherNum>, TOtherNum, HugeInteger<TOtherNum>>,
IMultiplyOperators<HugeInteger<TOtherNum>, TOtherNum, HugeInteger<TOtherNum>>
where TOtherNum : IBinaryInteger<TOtherNum>
{
private ulong value = default;
public HugeInteger(ulong value) => this.value = value;
#region IBinaryInteger
#region Implementation of IComparable
/// <inheritdoc />
public int CompareTo(object obj) => this.value.CompareTo(obj);
#endregion
#region Implementation of IComparable<in HugeInteger>
/// <inheritdoc />
public int CompareTo(HugeInteger<TOtherNum> other) => this.value.CompareTo(other.value);
#endregion
#region Implementation of IEquatable<HugeInteger>
/// <inheritdoc />
public bool Equals(HugeInteger<TOtherNum> other) => this.value.Equals(other.value);
#endregion
#region Implementation of IFormattable
/// <inheritdoc />
public string ToString(string format, IFormatProvider formatProvider) => this.value.ToString(format, formatProvider);
#endregion
#region Implementation of IParsable<HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> Parse(string s, IFormatProvider provider) => new(ulong.Parse(s, provider));
/// <inheritdoc />
public static bool TryParse(string s, IFormatProvider provider, out HugeInteger<TOtherNum> result)
{
if (ulong.TryParse(s, NumberStyles.Integer, provider, out var value))
{
result = new HugeInteger<TOtherNum>(value);
return true;
}
result = default;
return false;
}
#endregion
#region Implementation of ISpanFormattable
/// <inheritdoc />
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider provider) => this.value.TryFormat(destination, out charsWritten, format, provider);
#endregion
#region Implementation of ISpanParsable<HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> Parse(ReadOnlySpan<char> s, IFormatProvider provider) => new(ulong.Parse(s, provider));
/// <inheritdoc />
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider provider, out HugeInteger<TOtherNum> result)
{
if (ulong.TryParse(s, NumberStyles.Integer, provider, out var value))
{
result = new HugeInteger<TOtherNum>(value);
return true;
}
result = default;
return false;
}
#endregion
#region Implementation of IAdditionOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator +(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value + right.value);
#endregion
#region Implementation of IAdditiveIdentity<HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> AdditiveIdentity => new(0);
#endregion
#region Implementation of IBitwiseOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator &(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value & right.value);
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator |(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value | right.value);
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator ^(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value ^ right.value);
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator ~(HugeInteger<TOtherNum> value) => new(~value.value);
#endregion
#region Implementation of IEqualityOperators<HugeInteger,HugeInteger,bool>
/// <inheritdoc />
public static bool operator ==(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value == right.value;
/// <inheritdoc />
public static bool operator !=(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value != right.value;
#endregion
#region Implementation of IComparisonOperators<HugeInteger,HugeInteger,bool>
/// <inheritdoc />
public static bool operator >(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value > right.value;
/// <inheritdoc />
public static bool operator >=(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value >= right.value;
/// <inheritdoc />
public static bool operator <(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value < right.value;
/// <inheritdoc />
public static bool operator <=(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => left.value <= right.value;
#endregion
#region Implementation of IDecrementOperators<HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator --(HugeInteger<TOtherNum> value)
{
value.value--;
return value;
}
#endregion
#region Implementation of IDivisionOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator /(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value / right.value);
#endregion
#region Implementation of IIncrementOperators<HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator ++(HugeInteger<TOtherNum> value)
{
value.value++;
return value;
}
#endregion
#region Implementation of IModulusOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator %(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value % right.value);
#endregion
#region Implementation of IMultiplicativeIdentity<HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> MultiplicativeIdentity => new(1);
#endregion
#region Implementation of IMultiplyOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator *(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value * right.value);
#endregion
#region Implementation of ISubtractionOperators<HugeInteger,HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator -(HugeInteger<TOtherNum> left, HugeInteger<TOtherNum> right) => new(left.value - right.value);
#endregion
#region Implementation of IUnaryNegationOperators<HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator -(HugeInteger<TOtherNum> value) => throw new NotImplementedException();
#endregion
#region Implementation of IUnaryPlusOperators<HugeInteger,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator +(HugeInteger<TOtherNum> value) => throw new NotImplementedException();
#endregion
#region Implementation of INumberBase<HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> Abs(HugeInteger<TOtherNum> value) => value;
/// <inheritdoc />
public static bool IsCanonical(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsComplexNumber(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsEvenInteger(HugeInteger<TOtherNum> value) => ulong.IsEvenInteger(value.value);
/// <inheritdoc />
public static bool IsFinite(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsImaginaryNumber(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsInfinity(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsInteger(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsNaN(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsNegative(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsNegativeInfinity(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsNormal(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsOddInteger(HugeInteger<TOtherNum> value) => ulong.IsOddInteger(value.value);
/// <inheritdoc />
public static bool IsPositive(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsPositiveInfinity(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsRealNumber(HugeInteger<TOtherNum> value) => true;
/// <inheritdoc />
public static bool IsSubnormal(HugeInteger<TOtherNum> value) => false;
/// <inheritdoc />
public static bool IsZero(HugeInteger<TOtherNum> value) => value.value == 0;
/// <inheritdoc />
public static HugeInteger<TOtherNum> MaxMagnitude(HugeInteger<TOtherNum> x, HugeInteger<TOtherNum> y) => x.value > y.value ? x : y;
/// <inheritdoc />
public static HugeInteger<TOtherNum> MaxMagnitudeNumber(HugeInteger<TOtherNum> x, HugeInteger<TOtherNum> y) => x.value > y.value ? x : y;
/// <inheritdoc />
public static HugeInteger<TOtherNum> MinMagnitude(HugeInteger<TOtherNum> x, HugeInteger<TOtherNum> y) => x.value < y.value ? x : y;
/// <inheritdoc />
public static HugeInteger<TOtherNum> MinMagnitudeNumber(HugeInteger<TOtherNum> x, HugeInteger<TOtherNum> y) => x.value < y.value ? x : y;
/// <inheritdoc />
public static HugeInteger<TOtherNum> Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider) => new(ulong.Parse(s, style, provider));
/// <inheritdoc />
public static HugeInteger<TOtherNum> Parse(string s, NumberStyles style, IFormatProvider provider) => new(ulong.Parse(s, style, provider));
/// <inheritdoc />
public static bool TryConvertFromChecked<TOther>(TOther value, out HugeInteger<TOtherNum> result) where TOther : INumberBase<TOther>
{
result = new HugeInteger<TOtherNum>(ulong.CreateChecked(value));
return true;
}
/// <inheritdoc />
public static bool TryConvertFromSaturating<TOther>(TOther value, out HugeInteger<TOtherNum> result) where TOther : INumberBase<TOther>
{
result = new HugeInteger<TOtherNum>(ulong.CreateSaturating(value));
return true;
}
/// <inheritdoc />
public static bool TryConvertFromTruncating<TOther>(TOther value, out HugeInteger<TOtherNum> result) where TOther : INumberBase<TOther>
{
result = new HugeInteger<TOtherNum>(ulong.CreateTruncating(value));
return true;
}
/// <inheritdoc />
public static bool TryConvertToChecked<TOther>(HugeInteger<TOtherNum> value, out TOther result) where TOther : INumberBase<TOther>
{
result = TOther.CreateChecked(value.value);
return true;
}
/// <inheritdoc />
public static bool TryConvertToSaturating<TOther>(HugeInteger<TOtherNum> value, out TOther result) where TOther : INumberBase<TOther>
{
result = TOther.CreateSaturating(value.value);
return true;
}
/// <inheritdoc />
public static bool TryConvertToTruncating<TOther>(HugeInteger<TOtherNum> value, out TOther result) where TOther : INumberBase<TOther>
{
result = TOther.CreateTruncating(value.value);
return true;
}
/// <inheritdoc />
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider, out HugeInteger<TOtherNum> result)
{
var state = ulong.TryParse(s, style, provider, out var value);
if(state)
result = new HugeInteger<TOtherNum>(value);
else
result = default;
return state;
}
/// <inheritdoc />
public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out HugeInteger<TOtherNum> result)
{
var state = ulong.TryParse(s, style, provider, out var value);
if(state)
result = new HugeInteger<TOtherNum>(value);
else
result = default;
return state;
}
/// <inheritdoc />
public static HugeInteger<TOtherNum> One => new(1);
/// <inheritdoc />
public static int Radix => 2;
/// <inheritdoc />
public static HugeInteger<TOtherNum> Zero => new(0);
#endregion
#region Implementation of IBinaryNumber<HugeInteger>
/// <inheritdoc />
public static bool IsPow2(HugeInteger<TOtherNum> value) => ulong.IsPow2(value.value);
/// <inheritdoc />
public static HugeInteger<TOtherNum> Log2(HugeInteger<TOtherNum> value) => new(ulong.Log2(value.value));
#endregion
#region Implementation of IShiftOperators<HugeInteger,int,HugeInteger>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator <<(HugeInteger<TOtherNum> value, int shiftAmount) => new(value.value << shiftAmount);
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator >> (HugeInteger<TOtherNum> value, int shiftAmount) => new(value.value >> shiftAmount);
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator >>> (HugeInteger<TOtherNum> value, int shiftAmount) => new(value.value >>> shiftAmount);
#endregion
#region Implementation of IBinaryInteger<HugeInteger>
/// <inheritdoc />
public int GetByteCount() => sizeof(ulong);
/// <inheritdoc />
public int GetShortestBitLength() => (sizeof(ulong) * 8) - BitOperations.LeadingZeroCount(this.value);
/// <inheritdoc />
public static HugeInteger<TOtherNum> PopCount(HugeInteger<TOtherNum> value) => new((ulong)BitOperations.PopCount(value.value));
/// <inheritdoc />
public static HugeInteger<TOtherNum> TrailingZeroCount(HugeInteger<TOtherNum> value) => new((ulong)BitOperations.TrailingZeroCount(value.value));
/// <inheritdoc />
public static bool TryReadBigEndian(ReadOnlySpan<byte> source, bool isUnsigned, out HugeInteger<TOtherNum> value)
{
if (!isUnsigned)
{
value = default;
return false;
}
if(source.Length != sizeof(ulong))
{
value = default;
return false;
}
var sourceBytes = source.ToArray();
if (BitConverter.IsLittleEndian)
sourceBytes = sourceBytes.Reverse().ToArray();
value = new HugeInteger<TOtherNum>(BitConverter.ToUInt64(sourceBytes));
return true;
}
/// <inheritdoc />
public static bool TryReadLittleEndian(ReadOnlySpan<byte> source, bool isUnsigned, out HugeInteger<TOtherNum> value)
{
if (!isUnsigned)
{
value = default;
return false;
}
if(source.Length != sizeof(ulong))
{
value = default;
return false;
}
var sourceBytes = source.ToArray();
if (!BitConverter.IsLittleEndian)
sourceBytes = sourceBytes.Reverse().ToArray();
value = new HugeInteger<TOtherNum>(BitConverter.ToUInt64(sourceBytes));
return true;
}
/// <inheritdoc />
public bool TryWriteBigEndian(Span<byte> destination, out int bytesWritten)
{
var bytes = BitConverter.GetBytes(this.value);
if (BitConverter.IsLittleEndian)
bytes = bytes.Reverse().ToArray();
bytes.CopyTo(destination);
bytesWritten = bytes.Length;
return true;
}
/// <inheritdoc />
public bool TryWriteLittleEndian(Span<byte> destination, out int bytesWritten)
{
var bytes = BitConverter.GetBytes(this.value);
if (!BitConverter.IsLittleEndian)
bytes = bytes.Reverse().ToArray();
bytes.CopyTo(destination);
bytesWritten = bytes.Length;
return true;
}
#endregion
#endregion
#region Necessary extra operators
#region Implementation of IEqualityOperators<HugeInteger<TOtherNum>,TOtherNum,HugeInteger<TOtherNum>>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator ==(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left == right;
}
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator !=(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left != right;
}
#endregion
#region Implementation of IComparisonOperators<HugeInteger<TOtherNum>,TOtherNum,HugeInteger<TOtherNum>>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator >(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left > right;
}
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator >=(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left >= right;
}
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator <(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left < right;
}
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator <=(HugeInteger<TOtherNum> left, TOtherNum right)
{
return left <= right;
}
#endregion
#region Implementation of IMultiplyOperators<HugeInteger<TOtherNum>,TOtherNum,HugeInteger<TOtherNum>>
/// <inheritdoc />
public static HugeInteger<TOtherNum> operator *(HugeInteger<TOtherNum> left, TOtherNum right)
{
// Would work, but TOtherNum might not be able to hold the result! Thus, we cannot convert
// left to TOtherNum, and we cannot convert right to HugeInteger<TOtherNum>.
// return new HugeInteger<TOtherNum>(ulong.CreateSaturating(TOtherNum.CreateSaturating(left.value) * right));
return left * right;
}
#endregion
#endregion
/// <summary>
/// Converts a ulong to a HugeInteger.
/// </summary>
public static implicit operator HugeInteger<TOtherNum>(ulong value) => new(value);
/// <summary>
/// Converts a HugeInteger to a ulong.
/// </summary>
public static implicit operator ulong(HugeInteger<TOtherNum> value) => value.value;
}

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -7,7 +8,7 @@ namespace FastRng;
/// <summary> /// <summary>
/// Interface for random number generators. /// Interface for random number generators.
/// </summary> /// </summary>
public interface IRandom : IDisposable public interface IRandom<TNum> : IDisposable where TNum : IFloatingPointIeee754<TNum>
{ {
/// <summary> /// <summary>
/// Returns a uniform distributed pseudo-random number from the interval (0,1]. /// Returns a uniform distributed pseudo-random number from the interval (0,1].
@ -18,5 +19,5 @@ public interface IRandom : IDisposable
/// by using multiple threads at the same time. /// by using multiple threads at the same time.
/// </remarks> /// </remarks>
/// <param name="cancel">An optional cancellation token.</param> /// <param name="cancel">An optional cancellation token.</param>
public ValueTask<float> GetUniform(CancellationToken cancel = default); public ValueTask<TNum> GetUniform(CancellationToken cancel = default);
} }

View File

@ -1,27 +1,24 @@
using System; using System;
using System.Numerics;
namespace FastRng; namespace FastRng;
/// <summary> /// <summary>
/// Provides some mathematical function, which are not available within in .NET itself. /// Provides some mathematical function, which are not available within in .NET itself.
/// </summary> /// </summary>
public static class IntegerMathTools<TNum> where TNum : IBinaryInteger<TNum>, IComparisonOperators<HugeInteger<TNum>, TNum, HugeInteger<TNum>>, IMultiplyOperators<HugeInteger<TNum>, TNum, HugeInteger<TNum>> public static class IntegerMathTools
{ {
private static readonly TNum CONST20 = TNum.CreateChecked(20);
/// <summary> /// <summary>
/// The mathematical factorial function for integer numbers. /// The mathematical factorial function for integer numbers.
/// </summary> /// </summary>
/// <param name="x">The value, for which you want to know the factorial.</param> /// <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> /// <exception cref="ArgumentOutOfRangeException">Throws, when x is greater than 20. Due to limitations of 64bit ulong type.</exception>
public static ulong Factorial(TNum x) public static ulong Factorial(uint x)
{ {
if (x > CONST20) if (x > 20)
throw new ArgumentOutOfRangeException(nameof(x), $"Cannot compute {x}!, since ulong.max is 18_446_744_073_709_551_615."); throw new ArgumentOutOfRangeException(nameof(x), $"Cannot compute {x}!, since ulong.max is 18_446_744_073_709_551_615.");
var accumulator = new HugeInteger<TNum>(1); ulong accumulator = 1;
for (var factor = TNum.One; factor <= x; factor++) for (uint factor = 1; factor <= x; factor++)
accumulator *= factor; accumulator *= factor;
return accumulator; return accumulator;

View File

@ -1,82 +0,0 @@
using System;
namespace FastRng;
/// <summary>
/// Provides some mathematical function, which are not available within in the .NET framework.
/// </summary>
public static class MathTools
{
private static readonly float SQRT_2 = MathF.Sqrt(2.0f);
private static readonly float SQRT_PI = MathF.Sqrt(MathF.PI);
/// <summary>
/// The mathematical gamma function.
/// </summary>
/// <param name="z">The value for which you want calculate gamma.</param>
public static float Gamma(float z)
{
// Source: http://rosettacode.org/wiki/Gamma_function#Go
const float F1 = 6.5f;
const float A1 = .99999999999980993f;
const float A2 = 676.5203681218851f;
const float A3 = 1259.1392167224028f;
const float A4 = 771.32342877765313f;
const float A5 = 176.61502916214059f;
const float A6 = 12.507343278686905f;
const float A7 = .13857109526572012f;
const float A8 = 9.9843695780195716e-6f;
const float A9 = 1.5056327351493116e-7f;
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 SQRT_2 * SQRT_PI * MathF.Pow(t, z - 0.5f) * MathF.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 float Factorial(float x) => Gamma(x + 1.0f);
/// <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 Factorial((uint) x);
}
}

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -25,7 +26,7 @@ namespace FastRng;
/// Please notice: When using the debug environment, MultiThreadedRng uses a smaller buffer size. Please ensure, /// Please notice: When using the debug environment, MultiThreadedRng uses a smaller buffer size. Please ensure,
/// that the production environment uses a release build, though. /// that the production environment uses a release build, though.
/// </remarks> /// </remarks>
public sealed class MultiThreadedRng : IRandom, IDisposable public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TNum : IFloatingPointIeee754<TNum>, IAdditionOperators<TNum, TNum, TNum>
{ {
#if DEBUG #if DEBUG
private const int BUFFER_SIZE = 10_000; private const int BUFFER_SIZE = 10_000;
@ -35,6 +36,8 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
// The queue size means, how many buffer we store in a queue at the same time: // The queue size means, how many buffer we store in a queue at the same time:
private const int QUEUE_SIZE = 2; private const int QUEUE_SIZE = 2;
private static readonly TNum CONST_FLOAT_CONVERSION = TNum.CreateChecked(2.328306435454494e-10f);
// Gets used to stop the producer threads: // Gets used to stop the producer threads:
private readonly CancellationTokenSource producerTokenSource = new(); private readonly CancellationTokenSource producerTokenSource = new();
@ -46,7 +49,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
private readonly ConcurrentQueue<uint[]> queueIntegers = new(); private readonly ConcurrentQueue<uint[]> queueIntegers = new();
// The second queue, where to store buffers of uniform random floating point numbers: // The second queue, where to store buffers of uniform random floating point numbers:
private readonly ConcurrentQueue<float[]> queueFloats = new(); private readonly ConcurrentQueue<TNum[]> queueFloats = new();
// The uint producer thread: // The uint producer thread:
private Thread producerRandomUint; private Thread producerRandomUint;
@ -60,7 +63,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
private uint mZ; private uint mZ;
// This is the current buffer for the consumer side i.e. the public interfaces: // This is the current buffer for the consumer side i.e. the public interfaces:
private float[] currentBuffer = Array.Empty<float>(); private TNum[] currentBuffer = Array.Empty<TNum>();
// The current pointer to the next current buffer's address to read from: // The current pointer to the next current buffer's address to read from:
private int currentBufferPointer = BUFFER_SIZE; private int currentBufferPointer = BUFFER_SIZE;
@ -207,11 +210,11 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
return; return;
// A local buffer to fill with uniform floats: // A local buffer to fill with uniform floats:
var nextBuffer = new float[BUFFER_SIZE]; var nextBuffer = new TNum[BUFFER_SIZE];
// Generate the necessary number of floats: // Generate the necessary number of floats:
for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++) for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++)
nextBuffer[n] = (bufferSource[n] + 1.0f) * 2.328306435454494e-10f; nextBuffer[n] = (TNum.CreateChecked(bufferSource[n]) + TNum.One) * CONST_FLOAT_CONVERSION;
// Inside this loop, we try to enqueue the generated buffer: // Inside this loop, we try to enqueue the generated buffer:
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
@ -253,7 +256,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
/// by using multiple threads at the same time. /// by using multiple threads at the same time.
/// </remarks> /// </remarks>
/// <param name="cancel">An optional cancellation token.</param> /// <param name="cancel">An optional cancellation token.</param>
public async ValueTask<float> GetUniform(CancellationToken cancel = default) public async ValueTask<TNum> GetUniform(CancellationToken cancel = default)
{ {
while (!cancel.IsCancellationRequested) while (!cancel.IsCancellationRequested)
{ {
@ -264,7 +267,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
var currentBufferReference = this.currentBuffer; var currentBufferReference = this.currentBuffer;
// Here, we store the next buffer until we implement it: // Here, we store the next buffer until we implement it:
var nextBuffer = Array.Empty<float>(); var nextBuffer = Array.Empty<TNum>();
// Try to get the next buffer from the queue: // Try to get the next buffer from the queue:
while (this.currentBufferPointer >= BUFFER_SIZE && currentBufferReference == this.currentBuffer && !this.queueFloats.TryDequeue(out nextBuffer)) while (this.currentBufferPointer >= BUFFER_SIZE && currentBufferReference == this.currentBuffer && !this.queueFloats.TryDequeue(out nextBuffer))
@ -282,7 +285,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
// //
// Case: The consumer cancelled the request. // Case: The consumer cancelled the request.
// //
return float.NaN; return TNum.NaN;
} }
} }
@ -340,7 +343,7 @@ public sealed class MultiThreadedRng : IRandom, IDisposable
// //
// Case: The consumer cancelled the request. // Case: The consumer cancelled the request.
// //
return float.NaN; return TNum.NaN;
} }
private void StopProducer() => this.producerTokenSource.Cancel(); private void StopProducer() => this.producerTokenSource.Cancel();

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastRng.Distributions; using FastRng.Distributions;
@ -8,13 +9,13 @@ namespace FastRng;
/// <summary> /// <summary>
/// ShapeFitter is a rejection sampler, cf. https://en.wikipedia.org/wiki/Rejection_sampling /// ShapeFitter is a rejection sampler, cf. https://en.wikipedia.org/wiki/Rejection_sampling
/// </summary> /// </summary>
public sealed class ShapeFitter public sealed class ShapeFitter<TNum> where TNum : IFloatingPointIeee754<TNum>, IDivisionOperators<TNum, TNum, TNum>
{ {
private readonly float[] probabilities; private readonly TNum[] probabilities;
private readonly IRandom rng; private readonly IRandom<TNum> rng;
private readonly float max; private readonly TNum max;
private readonly float sampleSize; private readonly TNum sampleSize;
private readonly IDistribution uniform; private readonly IDistribution<TNum> uniform;
/// <summary> /// <summary>
/// Creates a shape fitter instance. /// Creates a shape fitter instance.
@ -22,16 +23,16 @@ public sealed class ShapeFitter
/// <param name="shapeFunction">The function which describes the desired shape.</param> /// <param name="shapeFunction">The function which describes the desired shape.</param>
/// <param name="rng">The random number generator instance to use.</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> /// <param name="sampleSize">The number of sampling steps to sample the given function.</param>
public ShapeFitter(Func<float, float> shapeFunction, IRandom rng, ushort sampleSize = 50) public ShapeFitter(Func<TNum, TNum> shapeFunction, IRandom<TNum> rng, ushort sampleSize = 50)
{ {
this.rng = rng; this.rng = rng;
this.uniform = new Uniform(rng); this.uniform = new Uniform<TNum>(rng);
this.sampleSize = sampleSize; this.sampleSize = TNum.CreateChecked(sampleSize);
this.probabilities = new float[sampleSize]; this.probabilities = new TNum[sampleSize];
var sampleStepSize = 1.0f / sampleSize; var sampleStepSize = TNum.One / TNum.CreateChecked(sampleSize);
var nextStep = 0.0f + sampleStepSize; var nextStep = TNum.Zero + sampleStepSize;
var maxValue = 0.0f; var maxValue = TNum.Zero;
for (var n = 0; n < sampleSize; n++) for (var n = 0; n < sampleSize; n++)
{ {
this.probabilities[n] = shapeFunction(nextStep); this.probabilities[n] = shapeFunction(nextStep);
@ -49,21 +50,21 @@ public sealed class ShapeFitter
/// </summary> /// </summary>
/// <param name="token">An optional cancellation token.</param> /// <param name="token">An optional cancellation token.</param>
/// <returns>The next value regarding the given shape.</returns> /// <returns>The next value regarding the given shape.</returns>
public async ValueTask<float> NextNumber(CancellationToken token = default) public async ValueTask<TNum> NextNumber(CancellationToken token = default)
{ {
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
{ {
var x = await this.rng.GetUniform(token); var x = await this.rng.GetUniform(token);
if (float.IsNaN(x)) if (TNum.IsNaN(x))
return x; return x;
var nextBucket = (int)MathF.Floor(x * this.sampleSize); var nextBucket = int.CreateChecked(TNum.Floor(x * this.sampleSize));
if (nextBucket >= this.probabilities.Length) if (nextBucket >= this.probabilities.Length)
nextBucket = this.probabilities.Length - 1; nextBucket = this.probabilities.Length - 1;
var threshold = this.probabilities[nextBucket]; var threshold = this.probabilities[nextBucket];
var y = await this.uniform.NextNumber(0.0f, this.max, token); var y = await this.uniform.NextNumber(TNum.Zero, this.max, token);
if (float.IsNaN(y)) if (TNum.IsNaN(y))
return y; return y;
if(y > threshold) if(y > threshold)
@ -72,6 +73,6 @@ public sealed class ShapeFitter
return x; return x;
} }
return float.NaN; return TNum.NaN;
} }
} }

View File

@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastRng; using FastRng;
using FastRng.Distributions;
using FastRngTests.Distributions;
using NUnit.Framework; using NUnit.Framework;
using Uniform = FastRng.Distributions.Uniform;
using WeibullK05La1 = FastRng.Distributions.WeibullK05La1;
namespace FastRngTests; namespace FastRngTests;
@ -16,8 +16,8 @@ public class DecisionTester
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task DecisionUniform01() public async Task DecisionUniform01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new Uniform(rng); var dist = new Uniform<float>(rng);
var neededCoinTossesA = 0; var neededCoinTossesA = 0;
var neededCoinTossesB = 0; var neededCoinTossesB = 0;
@ -40,8 +40,8 @@ public class DecisionTester
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task DecisionWeibull01() public async Task DecisionWeibull01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new WeibullK05La1(rng); var dist = new WeibullK05La1<float>(rng);
var neededCoinTossesA = 0; var neededCoinTossesA = 0;
var neededCoinTossesB = 0; var neededCoinTossesB = 0;

View File

@ -15,8 +15,8 @@ public class BetaA2B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01() public async Task TestBetaDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.BetaA2B2(rng); var dist = new FastRng.Distributions.BetaA2B2<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,9 +48,9 @@ public class BetaA2B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01() public async Task TestBetaGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA2B2(rng); var dist = new FastRng.Distributions.BetaA2B2<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,9 +63,9 @@ public class BetaA2B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02() public async Task TestBetaGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA2B2(rng); var dist = new FastRng.Distributions.BetaA2B2<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class BetaA2B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA2B2(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA2B2<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class BetaA2B5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01() public async Task TestBetaDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.BetaA2B5(rng); var dist = new FastRng.Distributions.BetaA2B5<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,9 +48,9 @@ public class BetaA2B5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01() public async Task TestBetaGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA2B5(rng); var dist = new FastRng.Distributions.BetaA2B5<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,9 +63,9 @@ public class BetaA2B5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02() public async Task TestBetaGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA2B5(rng); var dist = new FastRng.Distributions.BetaA2B5<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class BetaA2B5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA2B5(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA2B5<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class BetaA5B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaDistribution01() public async Task TestBetaDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.BetaA5B2(rng); var dist = new FastRng.Distributions.BetaA5B2<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,9 +48,9 @@ public class BetaA5B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange01() public async Task TestBetaGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA5B2(rng); var dist = new FastRng.Distributions.BetaA5B2<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,9 +63,9 @@ public class BetaA5B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestBetaGeneratorWithRange02() public async Task TestBetaGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.BetaA5B2(rng); var dist = new FastRng.Distributions.BetaA5B2<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class BetaA5B2
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA5B2(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.BetaA5B2<float>(null));
} }
} }

View File

@ -18,8 +18,8 @@ public class CauchyLorentzX0
// The properties of the cauchy distribution cannot be tested by mean, media or variance, // 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 // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX0(rng); var dist = new FastRng.Distributions.CauchyLorentzX0<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -51,8 +51,8 @@ public class CauchyLorentzX0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange01() public async Task TestCauchyGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX0(rng); var dist = new FastRng.Distributions.CauchyLorentzX0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -66,8 +66,8 @@ public class CauchyLorentzX0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange02() public async Task TestCauchyGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX0(rng); var dist = new FastRng.Distributions.CauchyLorentzX0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -81,6 +81,6 @@ public class CauchyLorentzX0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.CauchyLorentzX0(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.CauchyLorentzX0<float>(null));
} }
} }

View File

@ -18,8 +18,8 @@ public class CauchyLorentzX1
// The properties of the cauchy distribution cannot be tested by mean, media or variance, // 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 // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX1(rng); var dist = new FastRng.Distributions.CauchyLorentzX1<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -51,8 +51,8 @@ public class CauchyLorentzX1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange01() public async Task TestCauchyGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX0(rng); var dist = new FastRng.Distributions.CauchyLorentzX0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -66,8 +66,8 @@ public class CauchyLorentzX1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestCauchyGeneratorWithRange02() public async Task TestCauchyGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.CauchyLorentzX0(rng); var dist = new FastRng.Distributions.CauchyLorentzX0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -81,6 +81,6 @@ public class CauchyLorentzX1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.CauchyLorentzX1(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.CauchyLorentzX1<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class ChiSquareK1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01() public async Task TestChiSquareDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK1(rng); var dist = new FastRng.Distributions.ChiSquareK1<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -51,8 +51,8 @@ public class ChiSquareK1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01() public async Task TestChiSquareGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK1(rng); var dist = new FastRng.Distributions.ChiSquareK1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -66,8 +66,8 @@ public class ChiSquareK1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02() public async Task TestChiSquareGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK1(rng); var dist = new FastRng.Distributions.ChiSquareK1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -81,6 +81,6 @@ public class ChiSquareK1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK1(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK1<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class ChiSquareK10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01() public async Task TestChiSquareDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK10(rng); var dist = new FastRng.Distributions.ChiSquareK10<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -51,8 +51,8 @@ public class ChiSquareK10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01() public async Task TestChiSquareGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK10(rng); var dist = new FastRng.Distributions.ChiSquareK10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -66,8 +66,8 @@ public class ChiSquareK10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02() public async Task TestChiSquareGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK10(rng); var dist = new FastRng.Distributions.ChiSquareK10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -81,6 +81,6 @@ public class ChiSquareK10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK10(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK10<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class ChiSquareK4
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareDistribution01() public async Task TestChiSquareDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK4(rng); var dist = new FastRng.Distributions.ChiSquareK4<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class ChiSquareK4
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange01() public async Task TestChiSquareGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK4(rng); var dist = new FastRng.Distributions.ChiSquareK4<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class ChiSquareK4
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestChiSquareGeneratorWithRange02() public async Task TestChiSquareGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ChiSquareK4(rng); var dist = new FastRng.Distributions.ChiSquareK4<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class ChiSquareK4
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK4(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ChiSquareK4<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class ExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01() public async Task TestExponentialDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa10(rng); var dist = new FastRng.Distributions.ExponentialLa10<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class ExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01() public async Task TestExponentialGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa10(rng); var dist = new FastRng.Distributions.ExponentialLa10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class ExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02() public async Task TestExponentialGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa10(rng); var dist = new FastRng.Distributions.ExponentialLa10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class ExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ExponentialLa10(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ExponentialLa10<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class ExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01() public async Task TestExponentialDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa5(rng); var dist = new FastRng.Distributions.ExponentialLa5<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class ExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01() public async Task TestExponentialGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa5(rng); var dist = new FastRng.Distributions.ExponentialLa5<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class ExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02() public async Task TestExponentialGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.ExponentialLa5(rng); var dist = new FastRng.Distributions.ExponentialLa5<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class ExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ExponentialLa5(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.ExponentialLa5<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class GammaA5B15
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestGammaDistribution01() public async Task TestGammaDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.GammaA5B15(rng); var dist = new FastRng.Distributions.GammaA5B15<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class GammaA5B15
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestGammaGeneratorWithRange01() public async Task TestGammaGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.GammaA5B15(rng); var dist = new FastRng.Distributions.GammaA5B15<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class GammaA5B15
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestGammaGeneratorWithRange02() public async Task TestGammaGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.GammaA5B15(rng); var dist = new FastRng.Distributions.GammaA5B15<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class GammaA5B15
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.GammaA5B15(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.GammaA5B15<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class InverseExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01() public async Task TestExponentialDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa10(rng); var dist = new FastRng.Distributions.InverseExponentialLa10<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class InverseExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01() public async Task TestExponentialGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa10(rng); var dist = new FastRng.Distributions.InverseExponentialLa10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class InverseExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02() public async Task TestExponentialGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa10(rng); var dist = new FastRng.Distributions.InverseExponentialLa10<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class InverseExponentialLa10
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseExponentialLa10(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseExponentialLa10<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class InverseExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialDistribution01() public async Task TestExponentialDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa5(rng); var dist = new FastRng.Distributions.InverseExponentialLa5<float>(rng);
var fqa = new FrequencyAnalysis(); var fqa = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class InverseExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange01() public async Task TestExponentialGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa5(rng); var dist = new FastRng.Distributions.InverseExponentialLa5<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class InverseExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestExponentialGeneratorWithRange02() public async Task TestExponentialGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseExponentialLa5(rng); var dist = new FastRng.Distributions.InverseExponentialLa5<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class InverseExponentialLa5
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseExponentialLa5(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseExponentialLa5<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class InverseGammaA3B05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestInverseGammaDistribution01() public async Task TestInverseGammaDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseGammaA3B05(rng); var dist = new FastRng.Distributions.InverseGammaA3B05<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class InverseGammaA3B05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestInverseGammaGeneratorWithRange01() public async Task TestInverseGammaGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseGammaA3B05(rng); var dist = new FastRng.Distributions.InverseGammaA3B05<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class InverseGammaA3B05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestInverseGammaGeneratorWithRange02() public async Task TestInverseGammaGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.InverseGammaA3B05(rng); var dist = new FastRng.Distributions.InverseGammaA3B05<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class InverseGammaA3B05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseGammaA3B05(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.InverseGammaA3B05<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class LaplaceB01M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceDistribution01() public async Task TestLaplaceDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M0(rng); var dist = new FastRng.Distributions.LaplaceB01M0<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class LaplaceB01M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange01() public async Task TestLaplaceGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M0(rng); var dist = new FastRng.Distributions.LaplaceB01M0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class LaplaceB01M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange02() public async Task TestLaplaceGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M0(rng); var dist = new FastRng.Distributions.LaplaceB01M0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class LaplaceB01M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LaplaceB01M0(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LaplaceB01M0<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class LaplaceB01M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceDistribution01() public async Task TestLaplaceDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M05(rng); var dist = new FastRng.Distributions.LaplaceB01M05<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class LaplaceB01M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange01() public async Task TestLaplaceGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M05(rng); var dist = new FastRng.Distributions.LaplaceB01M05<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class LaplaceB01M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLaplaceGeneratorWithRange02() public async Task TestLaplaceGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LaplaceB01M05(rng); var dist = new FastRng.Distributions.LaplaceB01M05<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class LaplaceB01M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LaplaceB01M05(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LaplaceB01M05<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class LogNormalS1M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLogNormalDistribution01() public async Task TestLogNormalDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LogNormalS1M0(rng); var dist = new FastRng.Distributions.LogNormalS1M0<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class LogNormalS1M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLogNormalGeneratorWithRange01() public async Task TestLogNormalGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LogNormalS1M0(rng); var dist = new FastRng.Distributions.LogNormalS1M0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class LogNormalS1M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestLogNormalGeneratorWithRange02() public async Task TestLogNormalGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.LogNormalS1M0(rng); var dist = new FastRng.Distributions.LogNormalS1M0<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class LogNormalS1M0
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LogNormalS1M0(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.LogNormalS1M0<float>(null));
} }
} }

View File

@ -18,8 +18,8 @@ public class NormalS02M05
const float MEAN = 0.5f; const float MEAN = 0.5f;
const float STANDARD_DEVIATION = 0.2f; const float STANDARD_DEVIATION = 0.2f;
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.NormalS02M05(rng); var dist = new FastRng.Distributions.NormalS02M05<float>(rng);
var stats = new RunningStatistics(); var stats = new RunningStatistics();
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
@ -44,9 +44,9 @@ public class NormalS02M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestNormalGeneratorWithRange01() public async Task TestNormalGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.NormalS02M05(rng); var dist = new FastRng.Distributions.NormalS02M05<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -59,9 +59,9 @@ public class NormalS02M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestNormalGeneratorWithRange02() public async Task TestNormalGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.NormalS02M05(rng); var dist = new FastRng.Distributions.NormalS02M05<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -74,6 +74,6 @@ public class NormalS02M05
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.NormalS02M05(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.NormalS02M05<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class StudentTNu1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestStudentTDistribution01() public async Task TestStudentTDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.StudentTNu1(rng); var dist = new FastRng.Distributions.StudentTNu1<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class StudentTNu1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestStudentTGeneratorWithRange01() public async Task TestStudentTGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.StudentTNu1(rng); var dist = new FastRng.Distributions.StudentTNu1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class StudentTNu1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestStudentTGeneratorWithRange02() public async Task TestStudentTGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.StudentTNu1(rng); var dist = new FastRng.Distributions.StudentTNu1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class StudentTNu1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.StudentTNu1(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.StudentTNu1<float>(null));
} }
} }

View File

@ -20,7 +20,7 @@ public class Uniform
const float MEAN = 0.5f * (A + B); const float MEAN = 0.5f * (A + B);
const float VARIANCE = (1.0f / 12.0f) * (B - A) * (B - A); const float VARIANCE = (1.0f / 12.0f) * (B - A) * (B - A);
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var stats = new RunningStatistics(); var stats = new RunningStatistics();
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
@ -58,7 +58,7 @@ public class Uniform
const float P_HIGH = 1.0f - 0.25f * FAILURE_PROBABILITY; const float P_HIGH = 1.0f - 0.25f * FAILURE_PROBABILITY;
var samples = new float[NUM_ROUNDS]; var samples = new float[NUM_ROUNDS];
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
int n; int n;
for (n = 0; n != NUM_ROUNDS; ++n) for (n = 0; n != NUM_ROUNDS; ++n)
@ -115,9 +115,9 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange01() public async Task TestUniformGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -130,9 +130,9 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange02() public async Task TestUniformGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -145,7 +145,7 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestUniformGeneratorWithRange04() public async Task TestUniformGeneratorWithRange04()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await rng.GetUniform(); samples[n] = await rng.GetUniform();
@ -159,8 +159,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange05Uint() public async Task TestRange05Uint()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -175,8 +175,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange05Ulong() public async Task TestRange05Ulong()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -191,8 +191,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange05Float() public async Task TestRange05Float()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -206,8 +206,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDistribution001Uint() public async Task TestDistribution001Uint()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -220,8 +220,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDistribution001Ulong() public async Task TestDistribution001Ulong()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -234,8 +234,8 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDistribution001Float() public async Task TestDistribution001Float()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 1_000_000; var runs = 1_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -248,8 +248,8 @@ public class Uniform
[Category(TestCategories.LONG_RUNNING)] [Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Uint() public async Task TestDistribution002Uint()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 100_000_000; var runs = 100_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -262,8 +262,8 @@ public class Uniform
[Category(TestCategories.LONG_RUNNING)] [Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Ulong() public async Task TestDistribution002Ulong()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 100_000_000; var runs = 100_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -276,8 +276,8 @@ public class Uniform
[Category(TestCategories.LONG_RUNNING)] [Category(TestCategories.LONG_RUNNING)]
public async Task TestDistribution002Float() public async Task TestDistribution002Float()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.Uniform(rng); var dist = new FastRng.Distributions.Uniform<float>(rng);
var distribution = new uint[101]; var distribution = new uint[101];
var runs = 100_000_000; var runs = 100_000_000;
for (var n = 0; n < runs; n++) for (var n = 0; n < runs; n++)
@ -291,6 +291,6 @@ public class Uniform
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.Uniform(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.Uniform<float>(null));
} }
} }

View File

@ -15,8 +15,8 @@ public class WeibullK05La1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestWeibullDistribution01() public async Task TestWeibullDistribution01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.WeibullK05La1(rng); var dist = new FastRng.Distributions.WeibullK05La1<float>(rng);
var fra = new FrequencyAnalysis(); var fra = new FrequencyAnalysis();
for (var n = 0; n < 100_000; n++) for (var n = 0; n < 100_000; n++)
@ -48,8 +48,8 @@ public class WeibullK05La1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestWeibullGeneratorWithRange01() public async Task TestWeibullGeneratorWithRange01()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.WeibullK05La1(rng); var dist = new FastRng.Distributions.WeibullK05La1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(-1.0f, 1.0f); samples[n] = await dist.NextNumber(-1.0f, 1.0f);
@ -63,8 +63,8 @@ public class WeibullK05La1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestWeibullGeneratorWithRange02() public async Task TestWeibullGeneratorWithRange02()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new FastRng.Distributions.WeibullK05La1(rng); var dist = new FastRng.Distributions.WeibullK05La1<float>(rng);
var samples = new float[1_000]; var samples = new float[1_000];
for (var n = 0; n < samples.Length; n++) for (var n = 0; n < samples.Length; n++)
samples[n] = await dist.NextNumber(0.0f, 1.0f); samples[n] = await dist.NextNumber(0.0f, 1.0f);
@ -78,6 +78,6 @@ public class WeibullK05La1
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void NoRandomNumberGenerator01() public void NoRandomNumberGenerator01()
{ {
Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.WeibullK05La1(null)); Assert.Throws<ArgumentNullException>(() => new FastRng.Distributions.WeibullK05La1<float>(null));
} }
} }

View File

@ -15,7 +15,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest01() public void GammaTest01()
{ {
Assert.That(MathTools.Gamma(-0.5f), Is.EqualTo(-3.544907701811087f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(-0.5f), Is.EqualTo(-3.544907701811087f).Within(1e-6f));
} }
[Test] [Test]
@ -23,7 +23,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest02() public void GammaTest02()
{ {
Assert.That(MathTools.Gamma(0.1f), Is.EqualTo(9.51350975f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(0.1f), Is.EqualTo(9.51350975f).Within(1e-6f));
} }
[Test] [Test]
@ -31,7 +31,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest03() public void GammaTest03()
{ {
Assert.That(MathTools.Gamma(0.5f), Is.EqualTo(1.772453850905517f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(0.5f), Is.EqualTo(1.772453850905517f).Within(1e-6f));
} }
[Test] [Test]
@ -39,7 +39,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest04() public void GammaTest04()
{ {
Assert.That(MathTools.Gamma(1.0f), Is.EqualTo(1.0f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(1.0f), Is.EqualTo(1.0f).Within(1e-6f));
} }
[Test] [Test]
@ -47,7 +47,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest05() public void GammaTest05()
{ {
Assert.That(MathTools.Gamma(1.5f), Is.EqualTo(0.8862269254527587f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(1.5f), Is.EqualTo(0.8862269254527587f).Within(1e-6f));
} }
[Test] [Test]
@ -55,7 +55,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest06() public void GammaTest06()
{ {
Assert.That(MathTools.Gamma(2.0f), Is.EqualTo(1.0f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(2.0f), Is.EqualTo(1.0f).Within(1e-6f));
} }
[Test] [Test]
@ -63,7 +63,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest07() public void GammaTest07()
{ {
Assert.That(MathTools.Gamma(3.0f), Is.EqualTo(2.0f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(3.0f), Is.EqualTo(2.0f).Within(1e-6f));
} }
[Test] [Test]
@ -71,7 +71,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest08() public void GammaTest08()
{ {
Assert.That(MathTools.Gamma(10.0f), Is.EqualTo(362_880.719f).Within(1e-6f)); Assert.That(FloatingPointMathTools<float>.Gamma(10.0f), Is.EqualTo(362_880.719f).Within(1e-6f));
} }
[Test] [Test]
@ -79,7 +79,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest09() public void GammaTest09()
{ {
Assert.That(MathTools.Gamma(140.0f), Is.EqualTo(float.NaN)); Assert.That(FloatingPointMathTools<float>.Gamma(140.0f), Is.EqualTo(float.NaN));
} }
[Test] [Test]
@ -87,7 +87,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void GammaTest10() public void GammaTest10()
{ {
Assert.That(MathTools.Gamma(170.0f), Is.EqualTo(float.NaN)); Assert.That(FloatingPointMathTools<float>.Gamma(170.0f), Is.EqualTo(float.NaN));
} }
#endregion #endregion
@ -99,7 +99,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger01() public void FactorialInteger01()
{ {
Assert.That(MathTools.Factorial(0), Is.EqualTo(1)); Assert.That(IntegerMathTools.Factorial(0), Is.EqualTo(1));
} }
[Test] [Test]
@ -107,7 +107,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger02() public void FactorialInteger02()
{ {
Assert.That(MathTools.Factorial(1), Is.EqualTo(1)); Assert.That(IntegerMathTools.Factorial(1), Is.EqualTo(1));
} }
[Test] [Test]
@ -115,7 +115,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger03() public void FactorialInteger03()
{ {
Assert.That(MathTools.Factorial(2), Is.EqualTo(2)); Assert.That(IntegerMathTools.Factorial(2), Is.EqualTo(2));
} }
[Test] [Test]
@ -123,7 +123,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger04() public void FactorialInteger04()
{ {
Assert.That(MathTools.Factorial(3), Is.EqualTo(6)); Assert.That(IntegerMathTools.Factorial(3), Is.EqualTo(6));
} }
[Test] [Test]
@ -131,7 +131,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger05() public void FactorialInteger05()
{ {
Assert.That(MathTools.Factorial(4), Is.EqualTo(24)); Assert.That(IntegerMathTools.Factorial(4), Is.EqualTo(24));
} }
[Test] [Test]
@ -139,7 +139,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger06() public void FactorialInteger06()
{ {
Assert.That(MathTools.Factorial(5), Is.EqualTo(120)); Assert.That(IntegerMathTools.Factorial(5), Is.EqualTo(120));
} }
[Test] [Test]
@ -147,7 +147,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger07() public void FactorialInteger07()
{ {
Assert.That(MathTools.Factorial(6), Is.EqualTo(720)); Assert.That(IntegerMathTools.Factorial(6), Is.EqualTo(720));
} }
[Test] [Test]
@ -155,7 +155,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger08() public void FactorialInteger08()
{ {
Assert.That(MathTools.Factorial(7), Is.EqualTo(5_040)); Assert.That(IntegerMathTools.Factorial(7), Is.EqualTo(5_040));
} }
[Test] [Test]
@ -163,7 +163,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger09() public void FactorialInteger09()
{ {
Assert.That(MathTools.Factorial(8), Is.EqualTo(40_320)); Assert.That(IntegerMathTools.Factorial(8), Is.EqualTo(40_320));
} }
[Test] [Test]
@ -171,7 +171,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger10() public void FactorialInteger10()
{ {
Assert.That(MathTools.Factorial(9), Is.EqualTo(362_880)); Assert.That(IntegerMathTools.Factorial(9), Is.EqualTo(362_880));
} }
[Test] [Test]
@ -179,7 +179,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger11() public void FactorialInteger11()
{ {
Assert.That(MathTools.Factorial(10), Is.EqualTo(3_628_800)); Assert.That(IntegerMathTools.Factorial(10), Is.EqualTo(3_628_800));
} }
[Test] [Test]
@ -187,7 +187,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger12() public void FactorialInteger12()
{ {
Assert.That(MathTools.Factorial(11), Is.EqualTo(39_916_800)); Assert.That(IntegerMathTools.Factorial(11), Is.EqualTo(39_916_800));
} }
[Test] [Test]
@ -195,7 +195,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger13() public void FactorialInteger13()
{ {
Assert.That(MathTools.Factorial(12), Is.EqualTo(479_001_600)); Assert.That(IntegerMathTools.Factorial(12), Is.EqualTo(479_001_600));
} }
[Test] [Test]
@ -203,7 +203,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger14() public void FactorialInteger14()
{ {
Assert.That(MathTools.Factorial(13), Is.EqualTo(6_227_020_800)); Assert.That(IntegerMathTools.Factorial(13), Is.EqualTo(6_227_020_800));
} }
[Test] [Test]
@ -211,7 +211,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger15() public void FactorialInteger15()
{ {
Assert.That(MathTools.Factorial(14), Is.EqualTo(87_178_291_200)); Assert.That(IntegerMathTools.Factorial(14), Is.EqualTo(87_178_291_200));
} }
[Test] [Test]
@ -219,7 +219,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger16() public void FactorialInteger16()
{ {
Assert.That(MathTools.Factorial(15), Is.EqualTo(1_307_674_368_000)); Assert.That(IntegerMathTools.Factorial(15), Is.EqualTo(1_307_674_368_000));
} }
[Test] [Test]
@ -227,7 +227,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger17() public void FactorialInteger17()
{ {
Assert.That(MathTools.Factorial(16), Is.EqualTo(20_922_789_888_000)); Assert.That(IntegerMathTools.Factorial(16), Is.EqualTo(20_922_789_888_000));
} }
[Test] [Test]
@ -235,7 +235,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger18() public void FactorialInteger18()
{ {
Assert.That(MathTools.Factorial(17), Is.EqualTo(355_687_428_096_000)); Assert.That(IntegerMathTools.Factorial(17), Is.EqualTo(355_687_428_096_000));
} }
[Test] [Test]
@ -243,7 +243,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger19() public void FactorialInteger19()
{ {
Assert.That(MathTools.Factorial(18), Is.EqualTo(6_402_373_705_728_000)); Assert.That(IntegerMathTools.Factorial(18), Is.EqualTo(6_402_373_705_728_000));
} }
[Test] [Test]
@ -251,7 +251,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger20() public void FactorialInteger20()
{ {
Assert.That(MathTools.Factorial(19), Is.EqualTo(121_645_100_408_832_000)); Assert.That(IntegerMathTools.Factorial(19), Is.EqualTo(121_645_100_408_832_000));
} }
[Test] [Test]
@ -259,7 +259,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger21() public void FactorialInteger21()
{ {
Assert.That(MathTools.Factorial(20), Is.EqualTo(2_432_902_008_176_640_000)); Assert.That(IntegerMathTools.Factorial(20), Is.EqualTo(2_432_902_008_176_640_000));
} }
[Test] [Test]
@ -267,7 +267,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger22() public void FactorialInteger22()
{ {
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(21)); Assert.Throws<ArgumentOutOfRangeException>(() => IntegerMathTools.Factorial(21));
// Note: 21! is not possible in C# until we got 128 bit integers, since: // 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 // ulong.max == 18_446_744_073_709_551_615 < 51_090_942_171_709_400_000
@ -278,27 +278,11 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialInteger23() public void FactorialInteger23()
{ {
Assert.Throws<ArgumentOutOfRangeException>(() => MathTools.Factorial(45_646)); Assert.Throws<ArgumentOutOfRangeException>(() => IntegerMathTools.Factorial(45_646));
// Note: 45_646! is not possible in C# since: // Note: 45_646! is not possible in C# since:
// ulong.max == 18_446_744_073_709_551_615 // 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 #endregion
@ -309,7 +293,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint01() public void FactorialFloatingPoint01()
{ {
Assert.That(MathTools.Factorial(0.5f), Is.EqualTo(0.886226925f).Within(1e6f)); Assert.That(FloatingPointMathTools<float>.Factorial(0.5f), Is.EqualTo(0.886226925f).Within(1e6f));
} }
[Test] [Test]
@ -317,7 +301,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint02() public void FactorialFloatingPoint02()
{ {
Assert.That(MathTools.Factorial(1.5f), Is.EqualTo(1.329340388f).Within(1e6f)); Assert.That(FloatingPointMathTools<float>.Factorial(1.5f), Is.EqualTo(1.329340388f).Within(1e6f));
} }
[Test] [Test]
@ -325,7 +309,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint03() public void FactorialFloatingPoint03()
{ {
Assert.That(MathTools.Factorial(-1.5f), Is.EqualTo(-1.329340388f).Within(1e6f)); Assert.That(FloatingPointMathTools<float>.Factorial(-1.5f), Is.EqualTo(-1.329340388f).Within(1e6f));
} }
[Test] [Test]
@ -333,7 +317,7 @@ public class MathToolsTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public void FactorialFloatingPoint04() public void FactorialFloatingPoint04()
{ {
Assert.That(MathTools.Factorial(7.5f), Is.EqualTo(14_034.407293483f).Within(1e6f)); Assert.That(FloatingPointMathTools<float>.Factorial(7.5f), Is.EqualTo(14_034.407293483f).Within(1e6f));
} }
#endregion #endregion

View File

@ -4,6 +4,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FastRng; using FastRng;
using FastRng.Distributions; using FastRng.Distributions;
using FastRngTests.Distributions;
using NUnit.Framework; using NUnit.Framework;
namespace FastRngTests; namespace FastRngTests;
@ -11,14 +12,14 @@ namespace FastRngTests;
[ExcludeFromCodeCoverage] [ExcludeFromCodeCoverage]
public class MultiThreadedRngTests public class MultiThreadedRngTests
{ {
private readonly IRandom rng = new MultiThreadedRng(); private readonly IRandom<float> rng = new MultiThreadedRng<float>();
[Test] [Test]
[Category(TestCategories.COVER)] [Category(TestCategories.COVER)]
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange01Uint() public async Task TestRange01Uint()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
for (uint n = 0; n < 1_000_000; n++) for (uint n = 0; n < 1_000_000; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
} }
@ -28,7 +29,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange01Ulong() public async Task TestRange01Ulong()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
for (ulong n = 0; n < 1_000_000; n++) for (ulong n = 0; n < 1_000_000; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
} }
@ -38,7 +39,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange01Float() public async Task TestRange01Float()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
for (var n = 0.0f; n < 1e6f; n++) for (var n = 0.0f; n < 1e6f; n++)
Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n));
} }
@ -48,7 +49,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange02Uint() public async Task TestRange02Uint()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5, 5), Is.EqualTo(5)); 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(0, 0), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_000), Is.EqualTo(3_000_000_000)); Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_000), Is.EqualTo(3_000_000_000));
@ -59,7 +60,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange02Ulong() public async Task TestRange02Ulong()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5UL, 5), Is.EqualTo(5)); 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(0UL, 0), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_000), Is.EqualTo(3_000_000_000)); Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_000), Is.EqualTo(3_000_000_000));
@ -70,7 +71,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange02Float() public async Task TestRange02Float()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5f, 5f), Is.EqualTo(5)); 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(0f, 0f), Is.EqualTo(0));
Assert.That(await dist.NextNumber(3e9f, 3e9f), Is.EqualTo(3e9f)); Assert.That(await dist.NextNumber(3e9f, 3e9f), Is.EqualTo(3e9f));
@ -81,7 +82,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange03Uint() public async Task TestRange03Uint()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5, 6), Is.InRange(5, 6)); 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(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)); Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002));
@ -92,7 +93,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange03Ulong() public async Task TestRange03Ulong()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5UL, 6), Is.InRange(5, 6)); 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(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)); Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002));
@ -103,7 +104,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange03Float() public async Task TestRange03Float()
{ {
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(5f, 6f), Is.InRange(5f, 6f)); Assert.That(await dist.NextNumber(5f, 6f), Is.InRange(5f, 6f));
Assert.That(await dist.NextNumber(0f, 1f), Is.InRange(0f, 1f)); Assert.That(await dist.NextNumber(0f, 1f), Is.InRange(0f, 1f));
Assert.That(await dist.NextNumber(3e9f, 3e9f+2f), Is.InRange(3e9f, 3e9f+2f)); Assert.That(await dist.NextNumber(3e9f, 3e9f+2f), Is.InRange(3e9f, 3e9f+2f));
@ -114,8 +115,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange04Uint() public async Task TestRange04Uint()
{ {
var distUniform = new Uniform(this.rng); var distUniform = new Uniform<float>(this.rng);
var distNormal = new NormalS02M05(this.rng); var distNormal = new NormalS02M05<float>(this.rng);
Assert.That(await distUniform.NextNumber(10, 1), Is.InRange(1, 10)); 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 distNormal.NextNumber(10, 1), Is.InRange(1, 10));
@ -129,8 +130,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange04Ulong() public async Task TestRange04Ulong()
{ {
var distUniform = new Uniform(this.rng); var distUniform = new Uniform<float>(this.rng);
var distNormal = new NormalS02M05(this.rng); var distNormal = new NormalS02M05<float>(this.rng);
Assert.That(await distUniform.NextNumber(10UL, 1), Is.InRange(1, 10)); 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 distNormal.NextNumber(10UL, 1), Is.InRange(1, 10));
@ -144,8 +145,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestRange04Float() public async Task TestRange04Float()
{ {
var distUniform = new Uniform(this.rng); var distUniform = new Uniform<float>(this.rng);
var distNormal = new NormalS02M05(this.rng); var distNormal = new NormalS02M05<float>(this.rng);
Assert.That(await distUniform.NextNumber(10.0f, 1), Is.InRange(1, 10)); Assert.That(await distUniform.NextNumber(10.0f, 1), Is.InRange(1, 10));
Assert.That(await distNormal.NextNumber(10.0f, 1), Is.InRange(1, 10)); Assert.That(await distNormal.NextNumber(10.0f, 1), Is.InRange(1, 10));
@ -158,8 +159,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.LONG_RUNNING)] [Category(TestCategories.LONG_RUNNING)]
public async Task TestRange05() public async Task TestRange05()
{ {
var distUniform = new Uniform(this.rng); var distUniform = new Uniform<float>(this.rng);
var distLorentz = new CauchyLorentzX1(this.rng); var distLorentz = new CauchyLorentzX1<float>(this.rng);
var rngContains0 = false; var rngContains0 = false;
var rngContains1 = false; var rngContains1 = false;
@ -229,7 +230,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestStoppingProducers01() public async Task TestStoppingProducers01()
{ {
var rng2 = new MultiThreadedRng(); var rng2 = new MultiThreadedRng<float>();
rng2.Dispose(); rng2.Dispose();
var masterToken = new CancellationTokenSource(TimeSpan.FromSeconds(16)).Token; var masterToken = new CancellationTokenSource(TimeSpan.FromSeconds(16)).Token;
@ -255,19 +256,19 @@ public class MultiThreadedRngTests
Assert.That(wasCanceled, Is.True, "The consumer was not canceled"); Assert.That(wasCanceled, Is.True, "The consumer was not canceled");
var tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); var tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(tokenSource2.Token); await new NormalS02M05<float>(rng2).NextNumber(tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True); Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(-1f, 1f, tokenSource2.Token); await new NormalS02M05<float>(rng2).NextNumber(-1f, 1f, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True); Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(0u, 6u, tokenSource2.Token); await new NormalS02M05<float>(rng2).NextNumber(0u, 6u, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True); Assert.That(tokenSource2.IsCancellationRequested, Is.True);
tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await new NormalS02M05(rng2).NextNumber(0ul, 6ul, tokenSource2.Token); await new NormalS02M05<float>(rng2).NextNumber(0ul, 6ul, tokenSource2.Token);
Assert.That(tokenSource2.IsCancellationRequested, Is.True); Assert.That(tokenSource2.IsCancellationRequested, Is.True);
} }
@ -276,9 +277,9 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task OneSeed01() public async Task OneSeed01()
{ {
using var rng1 = new MultiThreadedRng(6); using var rng1 = new MultiThreadedRng<float>(6);
using var rng2 = new MultiThreadedRng(6); using var rng2 = new MultiThreadedRng<float>(6);
using var rng3 = new MultiThreadedRng(7); using var rng3 = new MultiThreadedRng<float>(7);
var rng1Sample = new float[10]; var rng1Sample = new float[10];
for (var n = 0; n < rng1Sample.Length; n++) for (var n = 0; n < rng1Sample.Length; n++)
@ -302,10 +303,10 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TwoSeeds01() public async Task TwoSeeds01()
{ {
using var rng1 = new MultiThreadedRng(3, 6); using var rng1 = new MultiThreadedRng<float>(3, 6);
using var rng2 = new MultiThreadedRng(3, 6); using var rng2 = new MultiThreadedRng<float>(3, 6);
using var rng3 = new MultiThreadedRng(3, 7); using var rng3 = new MultiThreadedRng<float>(3, 7);
using var rng4 = new MultiThreadedRng(6, 3); using var rng4 = new MultiThreadedRng<float>(6, 3);
var rng1Sample = new float[10]; var rng1Sample = new float[10];
for (var n = 0; n < rng1Sample.Length; n++) for (var n = 0; n < rng1Sample.Length; n++)
@ -336,9 +337,9 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task NoSeed01() public async Task NoSeed01()
{ {
using var rng1 = new MultiThreadedRng(); using var rng1 = new MultiThreadedRng<float>();
using var rng2 = new MultiThreadedRng(); using var rng2 = new MultiThreadedRng<float>();
using var rng3 = new MultiThreadedRng(); using var rng3 = new MultiThreadedRng<float>();
var rng1Sample = new float[10]; var rng1Sample = new float[10];
for (var n = 0; n < rng1Sample.Length; n++) for (var n = 0; n < rng1Sample.Length; n++)
@ -366,8 +367,8 @@ public class MultiThreadedRngTests
var token = tokenSource.Token; var token = tokenSource.Token;
tokenSource.Cancel(); tokenSource.Cancel();
using var rng2 = new MultiThreadedRng(); using var rng2 = new MultiThreadedRng<float>();
var dist = new Uniform(this.rng); var dist = new Uniform<float>(this.rng);
Assert.That(await dist.NextNumber(1, 100_000, token), Is.EqualTo(0)); Assert.That(await dist.NextNumber(1, 100_000, token), Is.EqualTo(0));
} }
@ -380,7 +381,7 @@ public class MultiThreadedRngTests
var token = tokenSource.Token; var token = tokenSource.Token;
tokenSource.Cancel(); tokenSource.Cancel();
using var rng2 = new MultiThreadedRng(); using var rng2 = new MultiThreadedRng<float>();
Assert.That(await rng2.GetUniform(token), Is.NaN); Assert.That(await rng2.GetUniform(token), Is.NaN);
} }
@ -389,7 +390,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic01() public async Task TestDeterministic01()
{ {
using var rng2 = new MultiThreadedRng(16); using var rng2 = new MultiThreadedRng<float>(16);
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); 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.5764246).Within(1e-7f));
@ -428,8 +429,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic02() public async Task TestDeterministic02()
{ {
using var rng2 = new MultiThreadedRng(16); using var rng2 = new MultiThreadedRng<float>(16);
var dist = new Uniform(rng2); var dist = new Uniform<float>(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); 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(58));
@ -468,8 +469,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic03() public async Task TestDeterministic03()
{ {
using var rng2 = new MultiThreadedRng(16); using var rng2 = new MultiThreadedRng<float>(16);
var dist = new CauchyLorentzX0(rng2); var dist = new CauchyLorentzX0<float>(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); 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(17));
@ -508,7 +509,7 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic01b() public async Task TestDeterministic01b()
{ {
using var rng2 = new MultiThreadedRng(16, 362_436_069); using var rng2 = new MultiThreadedRng<float>(16, 362_436_069);
Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); 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.5764246).Within(1e-7f));
@ -547,8 +548,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic02b() public async Task TestDeterministic02b()
{ {
using var rng2 = new MultiThreadedRng(16, 362_436_069); using var rng2 = new MultiThreadedRng<float>(16, 362_436_069);
var dist = new Uniform(rng2); var dist = new Uniform<float>(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); 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(58));
@ -587,8 +588,8 @@ public class MultiThreadedRngTests
[Category(TestCategories.NORMAL)] [Category(TestCategories.NORMAL)]
public async Task TestDeterministic03b() public async Task TestDeterministic03b()
{ {
using var rng2 = new MultiThreadedRng(16, 362_436_069); using var rng2 = new MultiThreadedRng<float>(16, 362_436_069);
var dist = new CauchyLorentzX0(rng2); var dist = new CauchyLorentzX0<float>(rng2);
Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); 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(17));

View File

@ -20,7 +20,7 @@ public class PerformanceTests
[Category(TestCategories.PERFORMANCE)] [Category(TestCategories.PERFORMANCE)]
public async Task Generate1MUniform() public async Task Generate1MUniform()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var data = new float[1_000_000]; var data = new float[1_000_000];
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
@ -38,8 +38,8 @@ public class PerformanceTests
[Category(TestCategories.PERFORMANCE)] [Category(TestCategories.PERFORMANCE)]
public async Task Generate1MNormal() public async Task Generate1MNormal()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new NormalS02M05(rng); var dist = new NormalS02M05<float>(rng);
var data = new float[1_000_000]; var data = new float[1_000_000];
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator
@ -57,8 +57,8 @@ public class PerformanceTests
[Category(TestCategories.PERFORMANCE)] [Category(TestCategories.PERFORMANCE)]
public async Task Generate1MChiSquare() public async Task Generate1MChiSquare()
{ {
using var rng = new MultiThreadedRng(); using var rng = new MultiThreadedRng<float>();
var dist = new ChiSquareK4(rng); var dist = new ChiSquareK4<float>(rng);
var data = new float[1_000_000]; var data = new float[1_000_000];
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator