From e8cf1284d73f3e0d88f9cd7a3bf73ffa32b52e8a Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Thu, 6 Jul 2023 10:26:12 +0200 Subject: [PATCH] Applied .NET 7 syntax or feature changes --- FastRng/Distributions/BetaA2B2.cs | 21 +- FastRng/Distributions/BetaA2B5.cs | 21 +- FastRng/Distributions/BetaA5B2.cs | 23 +- FastRng/Distributions/CauchyLorentzX0.cs | 21 +- FastRng/Distributions/CauchyLorentzX1.cs | 21 +- FastRng/Distributions/ChiSquareK1.cs | 41 +- FastRng/Distributions/ChiSquareK10.cs | 41 +- FastRng/Distributions/ChiSquareK4.cs | 39 +- FastRng/Distributions/Distribution.cs | 116 +- FastRng/Distributions/ExponentialLa10.cs | 19 +- FastRng/Distributions/ExponentialLa5.cs | 19 +- FastRng/Distributions/GammaA5B15.cs | 37 +- FastRng/Distributions/IDistribution.cs | 19 +- .../Distributions/InverseExponentialLa10.cs | 19 +- .../Distributions/InverseExponentialLa5.cs | 19 +- FastRng/Distributions/InverseGammaA3B05.cs | 39 +- FastRng/Distributions/LaplaceB01M0.cs | 37 +- FastRng/Distributions/LaplaceB01M05.cs | 37 +- FastRng/Distributions/LogNormalS1M0.cs | 37 +- FastRng/Distributions/NormalS02M05.cs | 21 +- FastRng/Distributions/StudentTNu1.cs | 47 +- FastRng/Distributions/Uniform.cs | 107 +- FastRng/Distributions/WeibullK05La1.cs | 21 +- FastRng/IRandom.cs | 29 +- FastRng/MathTools.cs | 131 +- FastRng/MultiThreadedRng.cs | 685 +++++----- FastRng/ShapeFitter.cs | 115 +- FastRngTests/DecisionTester.cs | 81 +- FastRngTests/Distributions/BetaA2B2.cs | 121 +- FastRngTests/Distributions/BetaA2B5.cs | 121 +- FastRngTests/Distributions/BetaA5B2.cs | 121 +- FastRngTests/Distributions/CauchyLorentzX0.cs | 125 +- FastRngTests/Distributions/CauchyLorentzX1.cs | 125 +- FastRngTests/Distributions/ChiSquareK1.cs | 127 +- FastRngTests/Distributions/ChiSquareK10.cs | 137 +- FastRngTests/Distributions/ChiSquareK4.cs | 121 +- FastRngTests/Distributions/ExponentialLa10.cs | 121 +- FastRngTests/Distributions/ExponentialLa5.cs | 121 +- FastRngTests/Distributions/GammaA5B15.cs | 121 +- .../Distributions/InverseExponentialLa10.cs | 121 +- .../Distributions/InverseExponentialLa5.cs | 121 +- .../Distributions/InverseGammaA3B05.cs | 121 +- FastRngTests/Distributions/LaplaceB01M0.cs | 121 +- FastRngTests/Distributions/LaplaceB01M05.cs | 121 +- FastRngTests/Distributions/LogNormalS1M0.cs | 121 +- FastRngTests/Distributions/NormalS02M05.cs | 123 +- FastRngTests/Distributions/StudentTNu1.cs | 121 +- FastRngTests/Distributions/Uniform.cs | 491 ++++--- FastRngTests/Distributions/WeibullK05La1.cs | 121 +- FastRngTests/FrequencyAnalysis.cs | 121 +- FastRngTests/MathToolsTests.cs | 663 +++++----- FastRngTests/MultiThreadedRngTests.cs | 1131 ++++++++--------- FastRngTests/PerformanceTests.cs | 241 ++-- FastRngTests/RunningStatistics.cs | 73 +- FastRngTests/TestCategories.cs | 17 +- 55 files changed, 3485 insertions(+), 3567 deletions(-) diff --git a/FastRng/Distributions/BetaA2B2.cs b/FastRng/Distributions/BetaA2B2.cs index a2cbcc3..b2864aa 100644 --- a/FastRng/Distributions/BetaA2B2.cs +++ b/FastRng/Distributions/BetaA2B2.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class BetaA2B2 : Distribution { - public sealed class BetaA2B2 : Distribution + private const float ALPHA = 2f; + private const float BETA = 2f; + private const float CONSTANT = 4f; + + public BetaA2B2(IRandom rng) : base(rng) { - private const float ALPHA = 2f; - private const float BETA = 2f; - private const float CONSTANT = 4f; - - public BetaA2B2(IRandom 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 float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); } \ No newline at end of file diff --git a/FastRng/Distributions/BetaA2B5.cs b/FastRng/Distributions/BetaA2B5.cs index 5fcfbcc..acaba4c 100644 --- a/FastRng/Distributions/BetaA2B5.cs +++ b/FastRng/Distributions/BetaA2B5.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class BetaA2B5 : Distribution { - public sealed class BetaA2B5 : Distribution + private const float ALPHA = 2f; + private const float BETA = 5f; + private const float CONSTANT = 12.2f; + + public BetaA2B5(IRandom rng) : base(rng) { - private const float ALPHA = 2f; - private const float BETA = 5f; - private const float CONSTANT = 12.2f; - - public BetaA2B5(IRandom 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 float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); } \ No newline at end of file diff --git a/FastRng/Distributions/BetaA5B2.cs b/FastRng/Distributions/BetaA5B2.cs index 68f0ded..b2dc15a 100644 --- a/FastRng/Distributions/BetaA5B2.cs +++ b/FastRng/Distributions/BetaA5B2.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions -{ - public sealed class BetaA5B2 : Distribution - { - private const float ALPHA = 5f; - private const float BETA = 2f; - private const float CONSTANT = 12.2f; +namespace FastRng.Distributions; - public BetaA5B2(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); +public sealed class BetaA5B2 : Distribution +{ + private const float ALPHA = 5f; + private const float BETA = 2f; + private const float CONSTANT = 12.2f; + + public BetaA5B2(IRandom rng) : base(rng) + { } + + private protected override float ShapeFunction(float x) => CONSTANT * MathF.Pow(x, ALPHA - 1f) * MathF.Pow(1f - x, BETA - 1f); } \ No newline at end of file diff --git a/FastRng/Distributions/CauchyLorentzX0.cs b/FastRng/Distributions/CauchyLorentzX0.cs index d0a4139..2f4d2db 100644 --- a/FastRng/Distributions/CauchyLorentzX0.cs +++ b/FastRng/Distributions/CauchyLorentzX0.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class CauchyLorentzX0 : Distribution { - public sealed class CauchyLorentzX0 : Distribution + private const float CONSTANT = 0.31f; + private const float SCALE = 0.1f; + private const float MEDIAN = 0.0f; + + public CauchyLorentzX0(IRandom rng) : base(rng) { - private const float CONSTANT = 0.31f; - private const float SCALE = 0.1f; - private const float MEDIAN = 0.0f; - - public CauchyLorentzX0(IRandom 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 float ShapeFunction(float x) => CONSTANT * (1.0f / (MathF.PI * SCALE)) * ((SCALE * SCALE) / (MathF.Pow(x - MEDIAN, 2f) + (SCALE * SCALE))); } \ No newline at end of file diff --git a/FastRng/Distributions/CauchyLorentzX1.cs b/FastRng/Distributions/CauchyLorentzX1.cs index 3fd831c..121b24d 100644 --- a/FastRng/Distributions/CauchyLorentzX1.cs +++ b/FastRng/Distributions/CauchyLorentzX1.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class CauchyLorentzX1 : Distribution { - public sealed class CauchyLorentzX1 : Distribution + private const float CONSTANT = 0.31f; + private const float SCALE = 0.1f; + private const float MEDIAN = 1.0f; + + public CauchyLorentzX1(IRandom rng) : base(rng) { - private const float CONSTANT = 0.31f; - private const float SCALE = 0.1f; - private const float MEDIAN = 1.0f; - - public CauchyLorentzX1(IRandom 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 float ShapeFunction(float x) => CONSTANT * (1.0f / (MathF.PI * SCALE)) * ((SCALE * SCALE) / (MathF.Pow(x - MEDIAN, 2f) + (SCALE * SCALE))); } \ No newline at end of file diff --git a/FastRng/Distributions/ChiSquareK1.cs b/FastRng/Distributions/ChiSquareK1.cs index cdf5f6c..cffe2f3 100644 --- a/FastRng/Distributions/ChiSquareK1.cs +++ b/FastRng/Distributions/ChiSquareK1.cs @@ -1,27 +1,26 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class ChiSquareK1 : Distribution { - public sealed class ChiSquareK1 : Distribution + private const float K = 1.0f; + private const float K_HALF = K * 0.5f; + private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; + private const float CONSTANT = 0.252f; + + private static readonly float DIVISOR; + + static ChiSquareK1() { - private const float K = 1.0f; - private const float K_HALF = K * 0.5f; - private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; - private const float CONSTANT = 0.252f; - - private static readonly float DIVISOR; - - static ChiSquareK1() - { - var twoToTheKHalf = MathF.Pow(2f, K_HALF); - var gammaKHalf = MathTools.Gamma(K_HALF); - DIVISOR = twoToTheKHalf * gammaKHalf; - } - - public ChiSquareK1(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); + var twoToTheKHalf = MathF.Pow(2f, K_HALF); + var gammaKHalf = MathTools.Gamma(K_HALF); + DIVISOR = twoToTheKHalf * gammaKHalf; } + + public ChiSquareK1(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); } \ No newline at end of file diff --git a/FastRng/Distributions/ChiSquareK10.cs b/FastRng/Distributions/ChiSquareK10.cs index ecbc065..12f21ee 100644 --- a/FastRng/Distributions/ChiSquareK10.cs +++ b/FastRng/Distributions/ChiSquareK10.cs @@ -1,27 +1,26 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class ChiSquareK10 : Distribution { - public sealed class ChiSquareK10 : Distribution + private const float K = 10.0f; + private const float K_HALF = K * 0.5f; + private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; + private const float CONSTANT = 0.252f; + + private static readonly float DIVISOR; + + static ChiSquareK10() { - private const float K = 10.0f; - private const float K_HALF = K * 0.5f; - private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; - private const float CONSTANT = 0.252f; - - private static readonly float DIVISOR; - - static ChiSquareK10() - { - var twoToTheKHalf = MathF.Pow(2f, K_HALF); - var gammaKHalf = MathTools.Gamma(K_HALF); - DIVISOR = twoToTheKHalf * gammaKHalf; - } - - public ChiSquareK10(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); + var twoToTheKHalf = MathF.Pow(2f, K_HALF); + var gammaKHalf = MathTools.Gamma(K_HALF); + DIVISOR = twoToTheKHalf * gammaKHalf; } + + public ChiSquareK10(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); } \ No newline at end of file diff --git a/FastRng/Distributions/ChiSquareK4.cs b/FastRng/Distributions/ChiSquareK4.cs index 7187b25..b4d0884 100644 --- a/FastRng/Distributions/ChiSquareK4.cs +++ b/FastRng/Distributions/ChiSquareK4.cs @@ -1,27 +1,26 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class ChiSquareK4 : Distribution { - public sealed class ChiSquareK4 : Distribution - { - private const float K = 4.0f; - private const float K_HALF = K * 0.5f; - private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; - private const float CONSTANT = 0.252f; + private const float K = 4.0f; + private const float K_HALF = K * 0.5f; + private const float K_HALF_MINUS_ONE = K_HALF - 1.0f; + private const float CONSTANT = 0.252f; - private static readonly float DIVISOR; + private static readonly float DIVISOR; - static ChiSquareK4() - { - var twoToTheKHalf = MathF.Pow(2, K_HALF); - var gammaKHalf = MathTools.Gamma(K_HALF); - DIVISOR = twoToTheKHalf * gammaKHalf; - } - - public ChiSquareK4(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); + static ChiSquareK4() + { + var twoToTheKHalf = MathF.Pow(2, K_HALF); + var gammaKHalf = MathTools.Gamma(K_HALF); + DIVISOR = twoToTheKHalf * gammaKHalf; } + + public ChiSquareK4(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => CONSTANT * ((MathF.Pow(x, K_HALF_MINUS_ONE) * MathF.Exp(-x * 0.5f)) / DIVISOR); } \ No newline at end of file diff --git a/FastRng/Distributions/Distribution.cs b/FastRng/Distributions/Distribution.cs index 9014e33..7b12978 100644 --- a/FastRng/Distributions/Distribution.cs +++ b/FastRng/Distributions/Distribution.cs @@ -2,74 +2,62 @@ using System; using System.Threading; using System.Threading.Tasks; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public abstract class Distribution : IDistribution { - public abstract class Distribution : IDistribution + private readonly ShapeFitter fitter; + + protected Distribution(IRandom rng) { - private readonly ShapeFitter fitter; - private readonly IRandom random; - - protected Distribution(IRandom rng) - { - if (rng == null) - throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); - - this.random = rng; - this.fitter = new ShapeFitter(this.ShapeFunction, this.random, 100); - } - - private protected abstract float ShapeFunction(float x); + if (rng == null) + throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); - public async ValueTask GetDistributedValue(CancellationToken token = default) => await this.fitter.NextNumber(token); + this.fitter = new ShapeFitter(this.ShapeFunction, rng, 100); + } + + private protected abstract float ShapeFunction(float x); - public async ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (uint) ((distributedValue * range) + rangeStart); - } - - public async ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default(CancellationToken)) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (ulong) ((distributedValue * range) + rangeStart); - } - - public async ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default(CancellationToken)) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (distributedValue * range) + rangeStart; - } - - public async ValueTask NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); + public async ValueTask GetDistributedValue(CancellationToken token = default) => await this.fitter.NextNumber(token); - public async ValueTask HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) - { - var number = await this.NextNumber(cancel); - return number > above && number < below; - } + public async ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); + + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (uint) ((distributedValue * range) + rangeStart); + } + + public async ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); + + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (ulong) ((distributedValue * range) + rangeStart); + } + + public async ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); + + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (distributedValue * range) + rangeStart; + } + + public async ValueTask NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); + + public async ValueTask HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) + { + var number = await this.NextNumber(cancel); + return number > above && number < below; } } \ No newline at end of file diff --git a/FastRng/Distributions/ExponentialLa10.cs b/FastRng/Distributions/ExponentialLa10.cs index 776a5af..c84561f 100644 --- a/FastRng/Distributions/ExponentialLa10.cs +++ b/FastRng/Distributions/ExponentialLa10.cs @@ -1,16 +1,15 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class ExponentialLa10 : Distribution { - public sealed class ExponentialLa10 : Distribution + private const float LAMBDA = 10.0f; + private const float CONSTANT = 0.1106f; + + public ExponentialLa10(IRandom rng) : base(rng) { - private const float LAMBDA = 10.0f; - private const float CONSTANT = 0.1106f; - - public ExponentialLa10(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); } + + private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); } \ No newline at end of file diff --git a/FastRng/Distributions/ExponentialLa5.cs b/FastRng/Distributions/ExponentialLa5.cs index c3f8804..ddde778 100644 --- a/FastRng/Distributions/ExponentialLa5.cs +++ b/FastRng/Distributions/ExponentialLa5.cs @@ -1,16 +1,15 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class ExponentialLa5 : Distribution { - public sealed class ExponentialLa5 : Distribution + private const float LAMBDA = 5.0f; + private const float CONSTANT = 0.2103f; + + public ExponentialLa5(IRandom rng) : base(rng) { - private const float LAMBDA = 5.0f; - private const float CONSTANT = 0.2103f; - - public ExponentialLa5(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); } + + private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(-LAMBDA * x); } \ No newline at end of file diff --git a/FastRng/Distributions/GammaA5B15.cs b/FastRng/Distributions/GammaA5B15.cs index 52201e4..444b074 100644 --- a/FastRng/Distributions/GammaA5B15.cs +++ b/FastRng/Distributions/GammaA5B15.cs @@ -1,26 +1,25 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class GammaA5B15 : Distribution { - public sealed class GammaA5B15 : Distribution - { - private const float ALPHA = 5.0f; - private const float BETA = 15.0f; - private const float CONSTANT = 0.341344210715475f; + private const float ALPHA = 5.0f; + private const float BETA = 15.0f; + private const float CONSTANT = 0.341344210715475f; - private static readonly float GAMMA_ALPHA; - private static readonly float BETA_TO_THE_ALPHA; + private static readonly float GAMMA_ALPHA; + private static readonly float BETA_TO_THE_ALPHA; - static GammaA5B15() - { - GAMMA_ALPHA = MathTools.Gamma(ALPHA); - BETA_TO_THE_ALPHA = MathF.Pow(BETA, ALPHA); - } - - public GammaA5B15(IRandom 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); + static GammaA5B15() + { + GAMMA_ALPHA = MathTools.Gamma(ALPHA); + BETA_TO_THE_ALPHA = MathF.Pow(BETA, ALPHA); } + + public GammaA5B15(IRandom 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); } \ No newline at end of file diff --git a/FastRng/Distributions/IDistribution.cs b/FastRng/Distributions/IDistribution.cs index 867975a..5f254c2 100644 --- a/FastRng/Distributions/IDistribution.cs +++ b/FastRng/Distributions/IDistribution.cs @@ -1,20 +1,19 @@ using System.Threading; using System.Threading.Tasks; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public interface IDistribution { - public interface IDistribution - { - public ValueTask GetDistributedValue(CancellationToken token); + public ValueTask GetDistributedValue(CancellationToken token); - public ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default); + public ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default); - public ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default); + public ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default); - public ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default); + public ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default); - public ValueTask NextNumber(CancellationToken cancel = default); + public ValueTask NextNumber(CancellationToken cancel = default); - public ValueTask HasDecisionBeenMade(float above, float below = 1.0f, CancellationToken cancel = default); - } + public ValueTask HasDecisionBeenMade(float above, float below = 1.0f, CancellationToken cancel = default); } \ No newline at end of file diff --git a/FastRng/Distributions/InverseExponentialLa10.cs b/FastRng/Distributions/InverseExponentialLa10.cs index 3201af6..0fce9f2 100644 --- a/FastRng/Distributions/InverseExponentialLa10.cs +++ b/FastRng/Distributions/InverseExponentialLa10.cs @@ -1,16 +1,15 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class InverseExponentialLa10 : Distribution { - public sealed class InverseExponentialLa10 : Distribution + private const float LAMBDA = 10.0f; + private const float CONSTANT = 4.539992976248453e-06f; + + public InverseExponentialLa10(IRandom rng) : base(rng) { - private const float LAMBDA = 10.0f; - private const float CONSTANT = 4.539992976248453e-06f; - - public InverseExponentialLa10(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); } + + private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); } \ No newline at end of file diff --git a/FastRng/Distributions/InverseExponentialLa5.cs b/FastRng/Distributions/InverseExponentialLa5.cs index 400d102..63b5e9c 100644 --- a/FastRng/Distributions/InverseExponentialLa5.cs +++ b/FastRng/Distributions/InverseExponentialLa5.cs @@ -1,16 +1,15 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class InverseExponentialLa5 : Distribution { - public sealed class InverseExponentialLa5 : Distribution + private const float LAMBDA = 5.0f; + private const float CONSTANT = 0.001347589399817f; + + public InverseExponentialLa5(IRandom rng) : base(rng) { - private const float LAMBDA = 5.0f; - private const float CONSTANT = 0.001347589399817f; - - public InverseExponentialLa5(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); } + + private protected override float ShapeFunction(float x) => CONSTANT * LAMBDA * MathF.Exp(LAMBDA * x); } \ No newline at end of file diff --git a/FastRng/Distributions/InverseGammaA3B05.cs b/FastRng/Distributions/InverseGammaA3B05.cs index e51048e..4c49d83 100644 --- a/FastRng/Distributions/InverseGammaA3B05.cs +++ b/FastRng/Distributions/InverseGammaA3B05.cs @@ -1,27 +1,26 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class InverseGammaA3B05 : Distribution { - public sealed class InverseGammaA3B05 : Distribution + private const float ALPHA = 3.0f; + private const float BETA = 0.5f; + private const float CONSTANT = 0.213922656884911f; + + private static readonly float FACTOR_LEFT; + + static InverseGammaA3B05() { - private const float ALPHA = 3.0f; - private const float BETA = 0.5f; - private const float CONSTANT = 0.213922656884911f; - - private static readonly float FACTOR_LEFT; - - static InverseGammaA3B05() - { - var gammaAlpha = MathTools.Gamma(ALPHA); - var betaToTheAlpha = MathF.Pow(BETA, ALPHA); + var gammaAlpha = MathTools.Gamma(ALPHA); + var betaToTheAlpha = MathF.Pow(BETA, ALPHA); - FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha); - } - - public InverseGammaA3B05(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Pow(x, -ALPHA - 1.0f) * MathF.Exp(-BETA / x); + FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha); } + + public InverseGammaA3B05(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Pow(x, -ALPHA - 1.0f) * MathF.Exp(-BETA / x); } \ No newline at end of file diff --git a/FastRng/Distributions/LaplaceB01M0.cs b/FastRng/Distributions/LaplaceB01M0.cs index 96ce19b..50afef0 100644 --- a/FastRng/Distributions/LaplaceB01M0.cs +++ b/FastRng/Distributions/LaplaceB01M0.cs @@ -1,24 +1,23 @@ using System; -namespace FastRng.Distributions -{ - public sealed class LaplaceB01M0 : Distribution - { - private const float B = 0.1f; - private const float MU = 0.0f; - private const float CONSTANT = 0.221034183615129f; - - private static readonly float FACTOR_LEFT; - - static LaplaceB01M0() - { - FACTOR_LEFT = CONSTANT / (2.0f * B); - } - - public LaplaceB01M0(IRandom rng) : base(rng) - { - } +namespace FastRng.Distributions; - private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); +public sealed class LaplaceB01M0 : Distribution +{ + private const float B = 0.1f; + private const float MU = 0.0f; + private const float CONSTANT = 0.221034183615129f; + + private static readonly float FACTOR_LEFT; + + static LaplaceB01M0() + { + FACTOR_LEFT = CONSTANT / (2.0f * B); } + + public LaplaceB01M0(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); } \ No newline at end of file diff --git a/FastRng/Distributions/LaplaceB01M05.cs b/FastRng/Distributions/LaplaceB01M05.cs index 3ca0e6a..4a219dd 100644 --- a/FastRng/Distributions/LaplaceB01M05.cs +++ b/FastRng/Distributions/LaplaceB01M05.cs @@ -1,24 +1,23 @@ using System; -namespace FastRng.Distributions -{ - public sealed class LaplaceB01M05 : Distribution - { - private const float B = 0.1f; - private const float MU = 0.5f; - private const float CONSTANT = 0.2f; - - private static readonly float FACTOR_LEFT; - - static LaplaceB01M05() - { - FACTOR_LEFT = CONSTANT / (2.0f * B); - } - - public LaplaceB01M05(IRandom rng) : base(rng) - { - } +namespace FastRng.Distributions; - private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); +public sealed class LaplaceB01M05 : Distribution +{ + private const float B = 0.1f; + private const float MU = 0.5f; + private const float CONSTANT = 0.2f; + + private static readonly float FACTOR_LEFT; + + static LaplaceB01M05() + { + FACTOR_LEFT = CONSTANT / (2.0f * B); } + + public LaplaceB01M05(IRandom rng) : base(rng) + { + } + + private protected override float ShapeFunction(float x) => FACTOR_LEFT * MathF.Exp(-MathF.Abs(x - MU) / B); } \ No newline at end of file diff --git a/FastRng/Distributions/LogNormalS1M0.cs b/FastRng/Distributions/LogNormalS1M0.cs index c318e0c..d6d538e 100644 --- a/FastRng/Distributions/LogNormalS1M0.cs +++ b/FastRng/Distributions/LogNormalS1M0.cs @@ -1,24 +1,23 @@ using System; -namespace FastRng.Distributions -{ - public sealed class LogNormalS1M0 : Distribution - { - private const float SIGMA = 1.0f; - private const float MU = 0.0f; - private const float CONSTANT = 1.51998658387455f; - - private static readonly float FACTOR; - - static LogNormalS1M0() - { - FACTOR = SIGMA * MathF.Sqrt(2f * MathF.PI); - } - - public LogNormalS1M0(IRandom rng) : base(rng) - { - } +namespace FastRng.Distributions; - private protected override float ShapeFunction(float x) => (CONSTANT / (x * FACTOR)) * MathF.Exp( -(MathF.Pow(MathF.Log(x) - MU, 2f) / (2f * MathF.Pow(SIGMA, 2f)))); +public sealed class LogNormalS1M0 : Distribution +{ + private const float SIGMA = 1.0f; + private const float MU = 0.0f; + private const float CONSTANT = 1.51998658387455f; + + private static readonly float FACTOR; + + static LogNormalS1M0() + { + FACTOR = SIGMA * MathF.Sqrt(2f * MathF.PI); } + + public LogNormalS1M0(IRandom 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)))); } \ No newline at end of file diff --git a/FastRng/Distributions/NormalS02M05.cs b/FastRng/Distributions/NormalS02M05.cs index c3baa5a..5cb0168 100644 --- a/FastRng/Distributions/NormalS02M05.cs +++ b/FastRng/Distributions/NormalS02M05.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class NormalS02M05 : Distribution { - public sealed class NormalS02M05 : Distribution + private const float SQRT_2_PI = 2.506628275f; + private const float STD_DEV = 0.2f; + private const float MEAN = 0.5f; + + public NormalS02M05(IRandom rng) : base(rng) { - private const float SQRT_2_PI = 2.506628275f; - private const float STDDEV = 0.2f; - private const float MEAN = 0.5f; - - public NormalS02M05(IRandom rng) : base(rng) - { - } - - private protected override float ShapeFunction(float x) => 1.0f / (STDDEV * SQRT_2_PI) * MathF.Exp(-0.5f * MathF.Pow((x - MEAN) / STDDEV, 2.0f)); } + + 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)); } \ No newline at end of file diff --git a/FastRng/Distributions/StudentTNu1.cs b/FastRng/Distributions/StudentTNu1.cs index 8349b76..cc64255 100644 --- a/FastRng/Distributions/StudentTNu1.cs +++ b/FastRng/Distributions/StudentTNu1.cs @@ -1,29 +1,28 @@ using System; -namespace FastRng.Distributions -{ - public sealed class StudentTNu1 : Distribution - { - private const float NU = 1.0f; - private const float START = 0.0f; - private const float COMPRESS = 1.0f; - private const float CONSTANT = 3.14190548592729f; - - private static readonly float DIVIDEND; - private static readonly float DIVISOR; - private static readonly float EXPONENT; - - static StudentTNu1() - { - DIVIDEND = MathTools.Gamma((NU + 1.0f) * 0.5f); - DIVISOR = MathF.Sqrt(NU * MathF.PI) * MathTools.Gamma(NU * 0.5f); - EXPONENT = -((NU + 1.0f) * 0.5f); - } - - public StudentTNu1(IRandom rng) : base(rng) - { - } +namespace FastRng.Distributions; - 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); +public sealed class StudentTNu1 : Distribution +{ + private const float NU = 1.0f; + private const float START = 0.0f; + private const float COMPRESS = 1.0f; + private const float CONSTANT = 3.14190548592729f; + + private static readonly float DIVIDEND; + private static readonly float DIVISOR; + private static readonly float EXPONENT; + + static StudentTNu1() + { + DIVIDEND = MathTools.Gamma((NU + 1.0f) * 0.5f); + DIVISOR = MathF.Sqrt(NU * MathF.PI) * MathTools.Gamma(NU * 0.5f); + EXPONENT = -((NU + 1.0f) * 0.5f); } + + public StudentTNu1(IRandom 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); } \ No newline at end of file diff --git a/FastRng/Distributions/Uniform.cs b/FastRng/Distributions/Uniform.cs index 0c9920b..2cd7e55 100644 --- a/FastRng/Distributions/Uniform.cs +++ b/FastRng/Distributions/Uniform.cs @@ -2,70 +2,57 @@ using System; using System.Threading; using System.Threading.Tasks; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class Uniform : IDistribution { - public sealed class Uniform : IDistribution + private readonly IRandom rng; + + public Uniform(IRandom rng) { - private readonly IRandom rng; + this.rng = rng ?? throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); + } + + public async ValueTask GetDistributedValue(CancellationToken token = default) => await this.rng.GetUniform(token); - public Uniform(IRandom rng) - { - if (rng == null) - throw new ArgumentNullException(nameof(rng), "An IRandom implementation is needed."); - - this.rng = rng; - } + public async ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); - public async ValueTask GetDistributedValue(CancellationToken token = default) => await this.rng.GetUniform(token); + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (uint) ((distributedValue * range) + rangeStart); + } + + public async ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); + + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (ulong) ((distributedValue * range) + rangeStart); + } + + public async ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default) + { + // Swap the values if the range start is greater than the range end: + if (rangeStart > rangeEnd) + (rangeStart, rangeEnd) = (rangeEnd, rangeStart); + + var range = rangeEnd - rangeStart; + var distributedValue = await this.GetDistributedValue(cancel); + return (distributedValue * range) + rangeStart; + } + + public async ValueTask NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); - public async ValueTask NextNumber(uint rangeStart, uint rangeEnd, CancellationToken cancel = default) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (uint) ((distributedValue * range) + rangeStart); - } - - public async ValueTask NextNumber(ulong rangeStart, ulong rangeEnd, CancellationToken cancel = default(CancellationToken)) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (ulong) ((distributedValue * range) + rangeStart); - } - - public async ValueTask NextNumber(float rangeStart, float rangeEnd, CancellationToken cancel = default(CancellationToken)) - { - if (rangeStart > rangeEnd) - { - var tmp = rangeStart; - rangeStart = rangeEnd; - rangeEnd = tmp; - } - - var range = rangeEnd - rangeStart; - var distributedValue = await this.GetDistributedValue(cancel); - return (distributedValue * range) + rangeStart; - } - - public async ValueTask NextNumber(CancellationToken cancel = default) => await this.NextNumber(0.0f, 1.0f, cancel); - - public async ValueTask HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) - { - var number = await this.NextNumber(cancel); - return number > above && number < below; - } + public async ValueTask HasDecisionBeenMade(float above, float below = 1, CancellationToken cancel = default) + { + var number = await this.NextNumber(cancel); + return number > above && number < below; } } \ No newline at end of file diff --git a/FastRng/Distributions/WeibullK05La1.cs b/FastRng/Distributions/WeibullK05La1.cs index 75a41ea..ef7df03 100644 --- a/FastRng/Distributions/WeibullK05La1.cs +++ b/FastRng/Distributions/WeibullK05La1.cs @@ -1,17 +1,16 @@ using System; -namespace FastRng.Distributions +namespace FastRng.Distributions; + +public sealed class WeibullK05La1 : Distribution { - public sealed class WeibullK05La1 : Distribution + private const float K = 0.5f; + private const float LAMBDA = 1.0f; + private const float CONSTANT = 0.221034183615129f; + + public WeibullK05La1(IRandom rng) : base(rng) { - private const float K = 0.5f; - private const float LAMBDA = 1.0f; - private const float CONSTANT = 0.221034183615129f; - - public WeibullK05La1(IRandom 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 float ShapeFunction(float x) => CONSTANT * ( (K / LAMBDA) * MathF.Pow(x / LAMBDA, K - 1.0f) * MathF.Exp(-MathF.Pow(x/LAMBDA, K))); } \ No newline at end of file diff --git a/FastRng/IRandom.cs b/FastRng/IRandom.cs index 265b8e6..489363c 100644 --- a/FastRng/IRandom.cs +++ b/FastRng/IRandom.cs @@ -2,22 +2,21 @@ using System; using System.Threading; using System.Threading.Tasks; -namespace FastRng +namespace FastRng; + +/// +/// Interface for random number generators. +/// +public interface IRandom : IDisposable { /// - /// Interface for random number generators. + /// Returns a uniform distributed pseudo-random number from the interval (0,1]. + /// This means, the result 0 is impossible, whereas 1 is possible. /// - public interface IRandom : IDisposable - { - /// - /// Returns a uniform distributed pseudo-random number from the interval (0,1]. - /// This means, the result 0 is impossible, whereas 1 is possible. - /// - /// - /// This method is thread-safe. You can consume numbers from the same generator - /// by using multiple threads at the same time. - /// - /// An optional cancellation token. - public ValueTask GetUniform(CancellationToken cancel = default); - } + /// + /// This method is thread-safe. You can consume numbers from the same generator + /// by using multiple threads at the same time. + /// + /// An optional cancellation token. + public ValueTask GetUniform(CancellationToken cancel = default); } \ No newline at end of file diff --git a/FastRng/MathTools.cs b/FastRng/MathTools.cs index f94c891..3e6e0b6 100644 --- a/FastRng/MathTools.cs +++ b/FastRng/MathTools.cs @@ -1,83 +1,82 @@ using System; -namespace FastRng +namespace FastRng; + +/// +/// Provides some mathematical function, which are not available within in the .NET framework. +/// +public static class MathTools { + private static readonly float SQRT_2 = MathF.Sqrt(2.0f); + private static readonly float SQRT_PI = MathF.Sqrt(MathF.PI); + /// - /// Provides some mathematical function, which are not available within in the .NET framework. + /// The mathematical gamma function. /// - public static class MathTools + /// The value for which you want calculate gamma. + public static float Gamma(float z) { - private static readonly float SQRT_2 = MathF.Sqrt(2.0f); - private static readonly float SQRT_PI = MathF.Sqrt(MathF.PI); - - /// - /// The mathematical gamma function. - /// - /// The value for which you want calculate gamma. - public static float Gamma(float z) - { - // Source: http://rosettacode.org/wiki/Gamma_function#Go + // 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; + 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); + var t = z + F1; + var x = A1 + + A2 / z - + A3 / (z + 1) + + A4 / (z + 2) - + A5 / (z + 3) + + A6 / (z + 4) - + A7 / (z + 5) + + A8 / (z + 6) + + A9 / (z + 7); - return MathTools.SQRT_2 * MathTools.SQRT_PI * MathF.Pow(t, z - 0.5f) * MathF.Exp(-t) * x; - } + return SQRT_2 * SQRT_PI * MathF.Pow(t, z - 0.5f) * MathF.Exp(-t) * x; + } - /// - /// The mathematical factorial function for floating-point numbers. - /// - /// The value, for which you want to know the factorial. - public static float Factorial(float x) => MathTools.Gamma(x + 1.0f); + /// + /// The mathematical factorial function for floating-point numbers. + /// + /// The value, for which you want to know the factorial. + public static float Factorial(float x) => Gamma(x + 1.0f); - /// - /// The mathematical factorial function for integer numbers. - /// - /// The value, for which you want to know the factorial. - /// Throws, when x is greater than 20. Due to limitations of 64bit ulong type. - 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."); + /// + /// The mathematical factorial function for integer numbers. + /// + /// The value, for which you want to know the factorial. + /// Throws, when x is greater than 20. Due to limitations of 64bit ulong type. + 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; + ulong accumulator = 1; + for (uint factor = 1; factor <= x; factor++) + accumulator *= factor; - return accumulator; - } + return accumulator; + } - /// - /// The mathematical factorial function for integer numbers. - /// - /// The value, for which you want to know the factorial. - /// Throws, when x is greater than 20. Due to limitations - /// of 64bit ulong type. Throws also, when x is less than 0. - public static ulong Factorial(int x) - { - if(x < 0) - throw new ArgumentOutOfRangeException(nameof(x), "Given value must be greater as zero."); + /// + /// The mathematical factorial function for integer numbers. + /// + /// The value, for which you want to know the factorial. + /// Throws, when x is greater than 20. Due to limitations + /// of 64bit ulong type. Throws also, when x is less than 0. + public static ulong Factorial(int x) + { + if(x < 0) + throw new ArgumentOutOfRangeException(nameof(x), "Given value must be greater as zero."); - return MathTools.Factorial((uint) x); - } + return Factorial((uint) x); } } \ No newline at end of file diff --git a/FastRng/MultiThreadedRng.cs b/FastRng/MultiThreadedRng.cs index f2a76c5..2445969 100644 --- a/FastRng/MultiThreadedRng.cs +++ b/FastRng/MultiThreadedRng.cs @@ -4,354 +4,353 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; -namespace FastRng +namespace FastRng; + +/// +/// A fast multi-threaded pseudo random number generator. +/// +/// +/// Please note, that Math.NET's (https://www.mathdotnet.com/) random number generator is in some situations faster. +/// Unlike Math.NET, MultiThreadedRng is multi-threaded and async. Consumers can await the next number without +/// blocking resources. Additionally, consumers can use a token to cancel e.g. timeout an operation as well.

+/// +/// MultiThreadedRng using a shape fitter (a rejection sampler) to enforce arbitrary shapes of probabilities for +/// desired distributions. By using the shape fitter, it is even easy to define discontinuous, arbitrary functions +/// as shapes. Any consumer can define and use own distributions.

+/// +/// This class uses the George Marsaglia's MWC algorithm. The algorithm's implementation based loosely on John D. +/// Cook's (johndcook.com) implementation (https://www.codeproject.com/Articles/25172/Simple-Random-Number-Generation). +/// Thanks John for the inspiration.

+/// +/// Please notice: When using the debug environment, MultiThreadedRng uses a smaller buffer size. Please ensure, +/// that the production environment uses a release build, though. +///
+public sealed class MultiThreadedRng : IRandom, IDisposable { +#if DEBUG + private const int BUFFER_SIZE = 10_000; +#else + private const int BUFFER_SIZE = 1_000_000; +#endif + + // The queue size means, how many buffer we store in a queue at the same time: + private const int QUEUE_SIZE = 2; + + // Gets used to stop the producer threads: + private readonly CancellationTokenSource producerTokenSource = new(); + + // The time a thread waits e.g. to check if the queue needs a new buffer: + private readonly TimeSpan waiter = TimeSpan.FromMilliseconds(10); + + // The first queue, where to store buffers of random uint numbers: + private readonly ConcurrentQueue queueIntegers = new(); + + // The second queue, where to store buffers of uniform random floating point numbers: + private readonly ConcurrentQueue queueFloats = new(); + + // The uint producer thread: + private Thread producerRandomUint; + + // The uniform float producer thread: + private Thread producerRandomUniformDistributedFloat; + + // Variable w and z for the uint generator. Both get used + // as seeding variable as well (cf. constructors) + private uint mW; + private uint mZ; + + // This is the current buffer for the consumer side i.e. the public interfaces: + private float[] currentBuffer = Array.Empty(); + + // The current pointer to the next current buffer's address to read from: + private int currentBufferPointer = BUFFER_SIZE; + + #region Constructors + /// - /// A fast multi-threaded pseudo random number generator. + /// Creates a multi-threaded random number generator. /// /// - /// Please note, that Math.NET's (https://www.mathdotnet.com/) random number generator is in some situations faster. - /// Unlike Math.NET, MultiThreadedRng is multi-threaded and async. Consumers can await the next number without - /// blocking resources. Additionally, consumers can use a token to cancel e.g. timeout an operation as well.

- /// - /// MultiThreadedRng using a shape fitter (a rejection sampler) to enforce arbitrary shapes of probabilities for - /// desired distributions. By using the shape fitter, it is even easy to define discontinuous, arbitrary functions - /// as shapes. Any consumer can define and use own distributions.

- /// - /// This class uses the George Marsaglia's MWC algorithm. The algorithm's implementation based loosely on John D. - /// Cook's (johndcook.com) implementation (https://www.codeproject.com/Articles/25172/Simple-Random-Number-Generation). - /// Thanks John for the inspiration.

- /// - /// Please notice: When using the debug environment, MultiThreadedRng uses a smaller buffer size. Please ensure, - /// that the production environment uses a release build, though. + /// This constructor uses the user's current local time + /// to derive necessary parameters for the generator. + /// Thus, the results are depending on the time, where + /// the generator was created. ///
- public sealed class MultiThreadedRng : IRandom, IDisposable + public MultiThreadedRng() { - #if DEBUG - private const int BUFFER_SIZE = 10_000; - #else - private const int BUFFER_SIZE = 1_000_000; - #endif - - // The queue size means, how many buffer we store in a queue at the same time: - private const int QUEUE_SIZE = 2; - - // Gets used to stop the producer threads: - private readonly CancellationTokenSource producerTokenSource = new CancellationTokenSource(); - - // The time a thread waits e.g. to check if the queue needs a new buffer: - private readonly TimeSpan waiter = TimeSpan.FromMilliseconds(10); - - // The first queue, where to store buffers of random uint numbers: - private readonly ConcurrentQueue queueIntegers = new ConcurrentQueue(); - - // The second queue, where to store buffers of uniform random floating point numbers: - private readonly ConcurrentQueue queueFloats = new ConcurrentQueue(); - - // The uint producer thread: - private Thread producerRandomUint; - - // The uniform float producer thread: - private Thread producerRandomUniformDistributedFloat; - - // Variable w and z for the uint generator. Both get used - // as seeding variable as well (cf. constructors) - private uint mW; - private uint mZ; - - // This is the current buffer for the consumer side i.e. the public interfaces: - private float[] currentBuffer = Array.Empty(); - - // The current pointer to the next current buffer's address to read from: - private int currentBufferPointer = BUFFER_SIZE; - - #region Constructors - - /// - /// Creates a multi-threaded random number generator. - /// - /// - /// This constructor uses the user's current local time - /// to derive necessary parameters for the generator. - /// Thus, the results are depending on the time, where - /// the generator was created. - /// - public MultiThreadedRng() - { - // - // Initialize the mW and mZ by using - // the system's time. - // - var now = DateTime.Now; - var ticks = now.Ticks; - this.mW = (uint) (ticks >> 16); - this.mZ = (uint) (ticks % 4_294_967_296); - this.StartProducerThreads(); - } - - /// - /// Creates a multi-threaded random number generator. - /// - /// - /// A multi-threaded random number generator created by this constructor is - /// deterministic. It's behaviour is not depending on the time of its creation.

- /// - /// Please note: Although the number generator and all distributions are deterministic, - /// the behavior of the consuming application might be non-deterministic. This is possible if - /// the application with multiple threads consumes the numbers. The scheduling of the threads - /// is up to the operating system and might not be predictable. - ///
- /// A seed value to generate a deterministic generator. - public MultiThreadedRng(uint seedU) - { - this.mW = seedU; - this.mZ = 362_436_069; - this.StartProducerThreads(); - } - - /// - /// Creates a multi-threaded random number generator. - /// - /// - /// A multi-threaded random number generator created by this constructor is - /// deterministic. It's behaviour is not depending on the time of its creation.

- /// - /// Please note: Although the number generator and all distributions are deterministic, - /// the behavior of the consuming application might be non-deterministic. This is possible if - /// the application with multiple threads consumes the numbers. The scheduling of the threads - /// is up to the operating system and might not be predictable. - ///
- /// The first seed value. - /// The second seed value. - public MultiThreadedRng(uint seedU, uint seedV) - { - this.mW = seedU; - this.mZ = seedV; - this.StartProducerThreads(); - } - - private void StartProducerThreads() - { - this.producerRandomUint = new Thread(() => this.RandomProducerUint(this.producerTokenSource.Token)) {IsBackground = true}; - this.producerRandomUint.Start(); - this.producerRandomUniformDistributedFloat = new Thread(() => this.RandomProducerUniformDistributedFloat(this.producerTokenSource.Token)) {IsBackground = true}; - this.producerRandomUniformDistributedFloat.Start(); - } - - #endregion - - #region Producers - - [ExcludeFromCodeCoverage] - private async void RandomProducerUint(CancellationToken cancellationToken) - { - try - { - while (!cancellationToken.IsCancellationRequested) - { - // A local next buffer, which gets filled next: - var nextBuffer = new uint[BUFFER_SIZE]; - - // Produce the necessary number of random uints: - for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++) - { - this.mZ = 36_969 * (this.mZ & 65_535) + (this.mZ >> 16); - this.mW = 18_000 * (this.mW & 65_535) + (this.mW >> 16); - nextBuffer[n] = (this.mZ << 16) + this.mW; - } - - // Inside this loop, we try to enqueue the produced buffer: - while (!cancellationToken.IsCancellationRequested) - { - try - { - // Ensure, that we do not produce more buffers, as configured: - if (this.queueIntegers.Count < QUEUE_SIZE) - { - this.queueIntegers.Enqueue(nextBuffer); - break; - } - - // The queue was full. Wait a moment and try it again: - await Task.Delay(this.waiter, cancellationToken); - } - catch (TaskCanceledException) - { - // The producers should be stopped: - return; - } - } - } - } - catch (OperationCanceledException) - { - } - } - - [ExcludeFromCodeCoverage] - private async void RandomProducerUniformDistributedFloat(CancellationToken cancellationToken) - { - try - { - while (!cancellationToken.IsCancellationRequested) - { - // A local source buffer of uints: - uint[] bufferSource = null; - - // Try to get the next source buffer: - while (!this.queueIntegers.TryDequeue(out bufferSource) && !cancellationToken.IsCancellationRequested) - await Task.Delay(this.waiter, cancellationToken); - - // Case: The producers should be stopped: - if(bufferSource == null) - return; - - // A local buffer to fill with uniform floats: - var nextBuffer = new float[BUFFER_SIZE]; - - // Generate the necessary number of floats: - for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++) - nextBuffer[n] = (bufferSource[n] + 1.0f) * 2.328306435454494e-10f; - - // Inside this loop, we try to enqueue the generated buffer: - while (!cancellationToken.IsCancellationRequested) - { - try - { - // Ensure, that the queue contains only the configured number of buffers: - if (this.queueFloats.Count < QUEUE_SIZE) - { - this.queueFloats.Enqueue(nextBuffer); - break; - } - - // The queue was full. Wait a moment and try it again: - await Task.Delay(this.waiter, cancellationToken); - } - catch (TaskCanceledException) - { - return; - } - } - } - } - catch (OperationCanceledException) - { - } - } - - #endregion - - #region Implementing interface - - /// - /// Returns a uniform distributed pseudo-random number from the interval (0,1]. - /// This means, the result 0 is impossible, whereas 1 is possible. - /// - /// - /// This method is thread-safe. You can consume numbers from the same generator - /// by using multiple threads at the same time. - /// - /// An optional cancellation token. - public async ValueTask GetUniform(CancellationToken cancel = default) - { - while (!cancel.IsCancellationRequested) - { - // Check, if we need a new buffer to read from: - if (this.currentBufferPointer >= BUFFER_SIZE) - { - // Create a local copy of the current buffer's pointer: - var currentBufferReference = this.currentBuffer; - - // Here, we store the next buffer until we implement it: - var nextBuffer = Array.Empty(); - - // Try to get the next buffer from the queue: - while (this.currentBufferPointer >= BUFFER_SIZE && currentBufferReference == this.currentBuffer && !this.queueFloats.TryDequeue(out nextBuffer)) - { - // - // Case: There is no next buffer available. - // Must wait for producer(s) to provide next. - // - try - { - await Task.Delay(this.waiter, cancel); - } - catch (TaskCanceledException) - { - // - // Case: The consumer cancelled the request. - // - return float.NaN; - } - } - - // - // Note: In general, it does not matter if the following compare-exchange is successful. - // 1st case: It was successful -- everything is fine. But we are responsible to re-set the currentBufferPointer. - // 2nd case: It was not successful. This means, that another thread was successful, though. - // That case is fine as well. But we would loose one buffer of work. Thus, we - // check for this case and preserve the buffer full of work. - // - - // Try to implement the dequeued buffer without locking other threads: - if (Interlocked.CompareExchange(ref this.currentBuffer, nextBuffer, currentBufferReference) != currentBufferReference) - { - // - // Case: Another thread updated the buffer already. - // Thus, we enqueue our copy of the next buffer to preserve it. - // - this.queueFloats.Enqueue(nextBuffer); - - // Next? We can go ahead and yield a random number... - } - else - { - // - // Case: We updated the buffer. - // - this.currentBufferPointer = 0; - - // Next? We can go ahead and yield a random number... - } - } - - // Made a local copy of the current pointer: - var myPointer = this.currentBufferPointer; - - // Increment the pointer for the next thread or call: - var nextPointer = myPointer + 1; - - // Try to update the pointer without locking other threads: - if (Interlocked.CompareExchange(ref this.currentBufferPointer, nextPointer, myPointer) == myPointer) - { - // - // Case: Success. We updated the pointer and, thus, can use the pointer to read a number. - // - return this.currentBuffer[myPointer]; - } - - // - // Case: Another thread updated the pointer already. Must restart the process - // to get a random number. - // - } - - // - // Case: The consumer cancelled the request. - // - return float.NaN; - } - - private void StopProducer() => this.producerTokenSource.Cancel(); - - /// - /// Disposes this generator. It is important to dispose a generator, - /// when it is no longer needed. Otherwise, the background threads - /// are still running. - /// - public void Dispose() => this.StopProducer(); - - #endregion + // + // Initialize the mW and mZ by using + // the system's time. + // + var now = DateTime.Now; + var ticks = now.Ticks; + this.mW = (uint) (ticks >> 16); + this.mZ = (uint) (ticks % 4_294_967_296); + this.StartProducerThreads(); } + + /// + /// Creates a multi-threaded random number generator. + /// + /// + /// A multi-threaded random number generator created by this constructor is + /// deterministic. It's behaviour is not depending on the time of its creation.

+ /// + /// Please note: Although the number generator and all distributions are deterministic, + /// the behavior of the consuming application might be non-deterministic. This is possible if + /// the application with multiple threads consumes the numbers. The scheduling of the threads + /// is up to the operating system and might not be predictable. + ///
+ /// A seed value to generate a deterministic generator. + public MultiThreadedRng(uint seedU) + { + this.mW = seedU; + this.mZ = 362_436_069; + this.StartProducerThreads(); + } + + /// + /// Creates a multi-threaded random number generator. + /// + /// + /// A multi-threaded random number generator created by this constructor is + /// deterministic. It's behaviour is not depending on the time of its creation.

+ /// + /// Please note: Although the number generator and all distributions are deterministic, + /// the behavior of the consuming application might be non-deterministic. This is possible if + /// the application with multiple threads consumes the numbers. The scheduling of the threads + /// is up to the operating system and might not be predictable. + ///
+ /// The first seed value. + /// The second seed value. + public MultiThreadedRng(uint seedU, uint seedV) + { + this.mW = seedU; + this.mZ = seedV; + this.StartProducerThreads(); + } + + private void StartProducerThreads() + { + this.producerRandomUint = new Thread(() => this.RandomProducerUint(this.producerTokenSource.Token)) {IsBackground = true}; + this.producerRandomUint.Start(); + this.producerRandomUniformDistributedFloat = new Thread(() => this.RandomProducerUniformDistributedFloat(this.producerTokenSource.Token)) {IsBackground = true}; + this.producerRandomUniformDistributedFloat.Start(); + } + + #endregion + + #region Producers + + [ExcludeFromCodeCoverage] + private async void RandomProducerUint(CancellationToken cancellationToken) + { + try + { + while (!cancellationToken.IsCancellationRequested) + { + // A local next buffer, which gets filled next: + var nextBuffer = new uint[BUFFER_SIZE]; + + // Produce the necessary number of random uints: + for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++) + { + this.mZ = 36_969 * (this.mZ & 65_535) + (this.mZ >> 16); + this.mW = 18_000 * (this.mW & 65_535) + (this.mW >> 16); + nextBuffer[n] = (this.mZ << 16) + this.mW; + } + + // Inside this loop, we try to enqueue the produced buffer: + while (!cancellationToken.IsCancellationRequested) + { + try + { + // Ensure, that we do not produce more buffers, as configured: + if (this.queueIntegers.Count < QUEUE_SIZE) + { + this.queueIntegers.Enqueue(nextBuffer); + break; + } + + // The queue was full. Wait a moment and try it again: + await Task.Delay(this.waiter, cancellationToken); + } + catch (TaskCanceledException) + { + // The producers should be stopped: + return; + } + } + } + } + catch (OperationCanceledException) + { + } + } + + [ExcludeFromCodeCoverage] + private async void RandomProducerUniformDistributedFloat(CancellationToken cancellationToken) + { + try + { + while (!cancellationToken.IsCancellationRequested) + { + // A local source buffer of uints: + uint[] bufferSource = null; + + // Try to get the next source buffer: + while (!this.queueIntegers.TryDequeue(out bufferSource) && !cancellationToken.IsCancellationRequested) + await Task.Delay(this.waiter, cancellationToken); + + // Case: The producers should be stopped: + if(bufferSource == null) + return; + + // A local buffer to fill with uniform floats: + var nextBuffer = new float[BUFFER_SIZE]; + + // Generate the necessary number of floats: + for (var n = 0; n < nextBuffer.Length && !cancellationToken.IsCancellationRequested; n++) + nextBuffer[n] = (bufferSource[n] + 1.0f) * 2.328306435454494e-10f; + + // Inside this loop, we try to enqueue the generated buffer: + while (!cancellationToken.IsCancellationRequested) + { + try + { + // Ensure, that the queue contains only the configured number of buffers: + if (this.queueFloats.Count < QUEUE_SIZE) + { + this.queueFloats.Enqueue(nextBuffer); + break; + } + + // The queue was full. Wait a moment and try it again: + await Task.Delay(this.waiter, cancellationToken); + } + catch (TaskCanceledException) + { + return; + } + } + } + } + catch (OperationCanceledException) + { + } + } + + #endregion + + #region Implementing interface + + /// + /// Returns a uniform distributed pseudo-random number from the interval (0,1]. + /// This means, the result 0 is impossible, whereas 1 is possible. + /// + /// + /// This method is thread-safe. You can consume numbers from the same generator + /// by using multiple threads at the same time. + /// + /// An optional cancellation token. + public async ValueTask GetUniform(CancellationToken cancel = default) + { + while (!cancel.IsCancellationRequested) + { + // Check, if we need a new buffer to read from: + if (this.currentBufferPointer >= BUFFER_SIZE) + { + // Create a local copy of the current buffer's pointer: + var currentBufferReference = this.currentBuffer; + + // Here, we store the next buffer until we implement it: + var nextBuffer = Array.Empty(); + + // Try to get the next buffer from the queue: + while (this.currentBufferPointer >= BUFFER_SIZE && currentBufferReference == this.currentBuffer && !this.queueFloats.TryDequeue(out nextBuffer)) + { + // + // Case: There is no next buffer available. + // Must wait for producer(s) to provide next. + // + try + { + await Task.Delay(this.waiter, cancel); + } + catch (TaskCanceledException) + { + // + // Case: The consumer cancelled the request. + // + return float.NaN; + } + } + + // + // Note: In general, it does not matter if the following compare-exchange is successful. + // 1st case: It was successful -- everything is fine. But we are responsible to re-set the currentBufferPointer. + // 2nd case: It was not successful. This means, that another thread was successful, though. + // That case is fine as well. But we would loose one buffer of work. Thus, we + // check for this case and preserve the buffer full of work. + // + + // Try to implement the dequeued buffer without locking other threads: + if (Interlocked.CompareExchange(ref this.currentBuffer, nextBuffer, currentBufferReference) != currentBufferReference) + { + // + // Case: Another thread updated the buffer already. + // Thus, we enqueue our copy of the next buffer to preserve it. + // + this.queueFloats.Enqueue(nextBuffer); + + // Next? We can go ahead and yield a random number... + } + else + { + // + // Case: We updated the buffer. + // + this.currentBufferPointer = 0; + + // Next? We can go ahead and yield a random number... + } + } + + // Made a local copy of the current pointer: + var myPointer = this.currentBufferPointer; + + // Increment the pointer for the next thread or call: + var nextPointer = myPointer + 1; + + // Try to update the pointer without locking other threads: + if (Interlocked.CompareExchange(ref this.currentBufferPointer, nextPointer, myPointer) == myPointer) + { + // + // Case: Success. We updated the pointer and, thus, can use the pointer to read a number. + // + return this.currentBuffer[myPointer]; + } + + // + // Case: Another thread updated the pointer already. Must restart the process + // to get a random number. + // + } + + // + // Case: The consumer cancelled the request. + // + return float.NaN; + } + + private void StopProducer() => this.producerTokenSource.Cancel(); + + /// + /// Disposes this generator. It is important to dispose a generator, + /// when it is no longer needed. Otherwise, the background threads + /// are still running. + /// + public void Dispose() => this.StopProducer(); + + #endregion } \ No newline at end of file diff --git a/FastRng/ShapeFitter.cs b/FastRng/ShapeFitter.cs index 8c45da4..07b8397 100644 --- a/FastRng/ShapeFitter.cs +++ b/FastRng/ShapeFitter.cs @@ -3,76 +3,75 @@ using System.Threading; using System.Threading.Tasks; using FastRng.Distributions; -namespace FastRng +namespace FastRng; + +/// +/// ShapeFitter is a rejection sampler, cf. https://en.wikipedia.org/wiki/Rejection_sampling +/// +public sealed class ShapeFitter { + private readonly float[] probabilities; + private readonly IRandom rng; + private readonly float max; + private readonly float sampleSize; + private readonly IDistribution uniform; + /// - /// ShapeFitter is a rejection sampler, cf. https://en.wikipedia.org/wiki/Rejection_sampling + /// Creates a shape fitter instance. /// - public sealed class ShapeFitter + /// The function which describes the desired shape. + /// The random number generator instance to use. + /// The number of sampling steps to sample the given function. + public ShapeFitter(Func shapeFunction, IRandom rng, ushort sampleSize = 50) { - private readonly float[] probabilities; - private readonly IRandom rng; - private readonly float max; - private readonly float sampleSize; - private readonly IDistribution uniform; + this.rng = rng; + this.uniform = new Uniform(rng); + this.sampleSize = sampleSize; + this.probabilities = new float[sampleSize]; - /// - /// Creates a shape fitter instance. - /// - /// The function which describes the desired shape. - /// The random number generator instance to use. - /// The number of sampling steps to sample the given function. - public ShapeFitter(Func shapeFunction, IRandom rng, ushort sampleSize = 50) + var sampleStepSize = 1.0f / sampleSize; + var nextStep = 0.0f + sampleStepSize; + var maxValue = 0.0f; + for (var n = 0; n < sampleSize; n++) { - this.rng = rng; - this.uniform = new Uniform(rng); - this.sampleSize = sampleSize; - this.probabilities = new float[sampleSize]; - - var sampleStepSize = 1.0f / sampleSize; - var nextStep = 0.0f + sampleStepSize; - var maxValue = 0.0f; - for (var n = 0; n < sampleSize; n++) - { - this.probabilities[n] = shapeFunction(nextStep); - if (this.probabilities[n] > maxValue) - maxValue = this.probabilities[n]; + this.probabilities[n] = shapeFunction(nextStep); + if (this.probabilities[n] > maxValue) + maxValue = this.probabilities[n]; - nextStep += sampleStepSize; - } - - this.max = maxValue; + nextStep += sampleStepSize; } - /// - /// Returns a random number regarding the given shape. - /// - /// An optional cancellation token. - /// The next value regarding the given shape. - public async ValueTask NextNumber(CancellationToken token = default) - { - while (!token.IsCancellationRequested) - { - var x = await this.rng.GetUniform(token); - if (float.IsNaN(x)) - return x; - - var nextBucket = (int)MathF.Floor(x * this.sampleSize); - if (nextBucket >= this.probabilities.Length) - nextBucket = this.probabilities.Length - 1; - - var threshold = this.probabilities[nextBucket]; - var y = await this.uniform.NextNumber(0.0f, this.max, token); - if (float.IsNaN(y)) - return y; - - if(y > threshold) - continue; + this.max = maxValue; + } + /// + /// Returns a random number regarding the given shape. + /// + /// An optional cancellation token. + /// The next value regarding the given shape. + public async ValueTask NextNumber(CancellationToken token = default) + { + while (!token.IsCancellationRequested) + { + var x = await this.rng.GetUniform(token); + if (float.IsNaN(x)) return x; - } + + var nextBucket = (int)MathF.Floor(x * this.sampleSize); + if (nextBucket >= this.probabilities.Length) + nextBucket = this.probabilities.Length - 1; + + var threshold = this.probabilities[nextBucket]; + var y = await this.uniform.NextNumber(0.0f, this.max, token); + if (float.IsNaN(y)) + return y; + + if(y > threshold) + continue; - return float.NaN; + return x; } + + return float.NaN; } } \ No newline at end of file diff --git a/FastRngTests/DecisionTester.cs b/FastRngTests/DecisionTester.cs index cddccf4..bc52009 100644 --- a/FastRngTests/DecisionTester.cs +++ b/FastRngTests/DecisionTester.cs @@ -6,57 +6,56 @@ using NUnit.Framework; using Uniform = FastRng.Distributions.Uniform; using WeibullK05La1 = FastRng.Distributions.WeibullK05La1; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +public class DecisionTester { - [ExcludeFromCodeCoverage] - public class DecisionTester + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task DecisionUniform01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task DecisionUniform01() - { - using var rng = new MultiThreadedRng(); - var dist = new Uniform(rng); + using var rng = new MultiThreadedRng(); + var dist = new Uniform(rng); - var neededCoinTossesA = 0; - var neededCoinTossesB = 0; - var neededCoinTossesC = 0; + var neededCoinTossesA = 0; + var neededCoinTossesB = 0; + var neededCoinTossesC = 0; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++; - var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC}; - var max = values.Max(); - var min = values.Min(); + var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC}; + var max = values.Max(); + var min = values.Min(); - TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}"); - Assert.That(max - min, Is.LessThanOrEqualTo(250)); - } + TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}"); + Assert.That(max - min, Is.LessThanOrEqualTo(250)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task DecisionWeibull01() - { - using var rng = new MultiThreadedRng(); - var dist = new WeibullK05La1(rng); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task DecisionWeibull01() + { + using var rng = new MultiThreadedRng(); + var dist = new WeibullK05La1(rng); - var neededCoinTossesA = 0; - var neededCoinTossesB = 0; - var neededCoinTossesC = 0; + var neededCoinTossesA = 0; + var neededCoinTossesB = 0; + var neededCoinTossesC = 0; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++; - for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.0f, 0.1f)) neededCoinTossesA++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.5f, 0.6f)) neededCoinTossesB++; + for(var n = 0; n < 100; n++) while (!await dist.HasDecisionBeenMade(0.8f, 0.9f)) neededCoinTossesC++; - var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC}; - var max = values.Max(); - var min = values.Min(); + var values = new[] {neededCoinTossesA, neededCoinTossesB, neededCoinTossesC}; + var max = values.Max(); + var min = values.Min(); - TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}"); - Assert.That(max - min, Is.LessThanOrEqualTo(2_800)); - } + TestContext.WriteLine($"Coin tosses: a={neededCoinTossesA}, b={neededCoinTossesB}, c={neededCoinTossesC}"); + Assert.That(max - min, Is.LessThanOrEqualTo(2_800)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/BetaA2B2.cs b/FastRngTests/Distributions/BetaA2B2.cs index 28d8e9f..192f395 100644 --- a/FastRngTests/Distributions/BetaA2B2.cs +++ b/FastRngTests/Distributions/BetaA2B2.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class BetaA2B2 { - [ExcludeFromCodeCoverage] - public class BetaA2B2 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.BetaA2B2(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.BetaA2B2(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0396f).Within(0.3f)); - Assert.That(result[1], Is.EqualTo(0.0784f).Within(0.3f)); - Assert.That(result[2], Is.EqualTo(0.1164f).Within(0.3f)); + Assert.That(result[0], Is.EqualTo(0.0396f).Within(0.3f)); + Assert.That(result[1], Is.EqualTo(0.0784f).Within(0.3f)); + Assert.That(result[2], Is.EqualTo(0.1164f).Within(0.3f)); - Assert.That(result[21], Is.EqualTo(0.6864f).Within(0.3f)); - Assert.That(result[22], Is.EqualTo(0.7084f).Within(0.3f)); - Assert.That(result[23], Is.EqualTo(0.7296f).Within(0.3f)); + Assert.That(result[21], Is.EqualTo(0.6864f).Within(0.3f)); + Assert.That(result[22], Is.EqualTo(0.7084f).Within(0.3f)); + Assert.That(result[23], Is.EqualTo(0.7296f).Within(0.3f)); - Assert.That(result[50], Is.EqualTo(0.9996f).Within(0.3f)); + Assert.That(result[50], Is.EqualTo(0.9996f).Within(0.3f)); - Assert.That(result[75], Is.EqualTo(0.7296f).Within(0.3f)); - Assert.That(result[85], Is.EqualTo(0.4816f).Within(0.3f)); - Assert.That(result[90], Is.EqualTo(0.3276f).Within(0.3f)); + Assert.That(result[75], Is.EqualTo(0.7296f).Within(0.3f)); + Assert.That(result[85], Is.EqualTo(0.4816f).Within(0.3f)); + Assert.That(result[90], Is.EqualTo(0.3276f).Within(0.3f)); - Assert.That(result[97], Is.EqualTo(0.0784f).Within(0.3f)); - Assert.That(result[98], Is.EqualTo(0.0396f).Within(0.3f)); - Assert.That(result[99], Is.EqualTo(0.0000f).Within(0.3f)); - } + Assert.That(result[97], Is.EqualTo(0.0784f).Within(0.3f)); + Assert.That(result[98], Is.EqualTo(0.0396f).Within(0.3f)); + Assert.That(result[99], Is.EqualTo(0.0000f).Within(0.3f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA2B2(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA2B2(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA2B2(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA2B2(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.BetaA2B2(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.BetaA2B2(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/BetaA2B5.cs b/FastRngTests/Distributions/BetaA2B5.cs index bf681c9..3ad4867 100644 --- a/FastRngTests/Distributions/BetaA2B5.cs +++ b/FastRngTests/Distributions/BetaA2B5.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class BetaA2B5 { - [ExcludeFromCodeCoverage] - public class BetaA2B5 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.BetaA2B5(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.BetaA2B5(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.11719271f).Within(0.3f)); - Assert.That(result[1], Is.EqualTo(0.22505783f).Within(0.3f)); - Assert.That(result[2], Is.EqualTo(0.32401717f).Within(0.3f)); + Assert.That(result[0], Is.EqualTo(0.11719271f).Within(0.3f)); + Assert.That(result[1], Is.EqualTo(0.22505783f).Within(0.3f)); + Assert.That(result[2], Is.EqualTo(0.32401717f).Within(0.3f)); - Assert.That(result[21], Is.EqualTo(0.99348410f).Within(0.3f)); - Assert.That(result[22], Is.EqualTo(0.98639433f).Within(0.3f)); - Assert.That(result[23], Is.EqualTo(0.97684451f).Within(0.3f)); + Assert.That(result[21], Is.EqualTo(0.99348410f).Within(0.3f)); + Assert.That(result[22], Is.EqualTo(0.98639433f).Within(0.3f)); + Assert.That(result[23], Is.EqualTo(0.97684451f).Within(0.3f)); - Assert.That(result[50], Is.EqualTo(0.35868592f).Within(0.3f)); + Assert.That(result[50], Is.EqualTo(0.35868592f).Within(0.3f)); - Assert.That(result[75], Is.EqualTo(0.03076227f).Within(0.03f)); - Assert.That(result[85], Is.EqualTo(0.00403061f).Within(0.03f)); - Assert.That(result[90], Is.EqualTo(0.00109800f).Within(0.01f)); + Assert.That(result[75], Is.EqualTo(0.03076227f).Within(0.03f)); + Assert.That(result[85], Is.EqualTo(0.00403061f).Within(0.03f)); + Assert.That(result[90], Is.EqualTo(0.00109800f).Within(0.01f)); - Assert.That(result[97], Is.EqualTo(0.00000191f).Within(0.000003f)); - Assert.That(result[98], Is.EqualTo(0.00000012f).Within(0.0000003f)); - Assert.That(result[99], Is.EqualTo(0.00000000f).Within(0.0000003f)); - } + Assert.That(result[97], Is.EqualTo(0.00000191f).Within(0.000003f)); + Assert.That(result[98], Is.EqualTo(0.00000012f).Within(0.0000003f)); + Assert.That(result[99], Is.EqualTo(0.00000000f).Within(0.0000003f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA2B5(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA2B5(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA2B5(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA2B5(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.BetaA2B5(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.BetaA2B5(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/BetaA5B2.cs b/FastRngTests/Distributions/BetaA5B2.cs index 3bfe6fc..ac04112 100644 --- a/FastRngTests/Distributions/BetaA5B2.cs +++ b/FastRngTests/Distributions/BetaA5B2.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class BetaA5B2 { - [ExcludeFromCodeCoverage] - public class BetaA5B2 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.BetaA5B2(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.BetaA5B2(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0000001f).Within(0.0000003f)); - Assert.That(result[1], Is.EqualTo(0.0000019f).Within(0.00001f)); - Assert.That(result[2], Is.EqualTo(0.0000096f).Within(0.0004f)); + Assert.That(result[0], Is.EqualTo(0.0000001f).Within(0.0000003f)); + Assert.That(result[1], Is.EqualTo(0.0000019f).Within(0.00001f)); + Assert.That(result[2], Is.EqualTo(0.0000096f).Within(0.0004f)); - Assert.That(result[21], Is.EqualTo(0.0222918f).Within(0.03f)); - Assert.That(result[22], Is.EqualTo(0.0262883f).Within(0.03f)); - Assert.That(result[23], Is.EqualTo(0.0307623f).Within(0.03f)); + Assert.That(result[21], Is.EqualTo(0.0222918f).Within(0.03f)); + Assert.That(result[22], Is.EqualTo(0.0262883f).Within(0.03f)); + Assert.That(result[23], Is.EqualTo(0.0307623f).Within(0.03f)); - Assert.That(result[50], Is.EqualTo(0.4044237f).Within(0.2f)); + Assert.That(result[50], Is.EqualTo(0.4044237f).Within(0.2f)); - Assert.That(result[75], Is.EqualTo(0.9768445f).Within(0.15f)); - Assert.That(result[85], Is.EqualTo(0.9552714f).Within(0.15f)); - Assert.That(result[90], Is.EqualTo(0.8004420f).Within(0.35f)); + Assert.That(result[75], Is.EqualTo(0.9768445f).Within(0.15f)); + Assert.That(result[85], Is.EqualTo(0.9552714f).Within(0.15f)); + Assert.That(result[90], Is.EqualTo(0.8004420f).Within(0.35f)); - Assert.That(result[97], Is.EqualTo(0.2250578f).Within(0.03f)); - Assert.That(result[98], Is.EqualTo(0.1171927f).Within(0.03f)); - Assert.That(result[99], Is.EqualTo(0f).Within(0.0004f)); - } + Assert.That(result[97], Is.EqualTo(0.2250578f).Within(0.03f)); + Assert.That(result[98], Is.EqualTo(0.1171927f).Within(0.03f)); + Assert.That(result[99], Is.EqualTo(0f).Within(0.0004f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA5B2(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA5B2(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestBetaGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.BetaA5B2(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestBetaGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.BetaA5B2(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.BetaA5B2(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.BetaA5B2(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/CauchyLorentzX0.cs b/FastRngTests/Distributions/CauchyLorentzX0.cs index daf47a3..84458b3 100644 --- a/FastRngTests/Distributions/CauchyLorentzX0.cs +++ b/FastRngTests/Distributions/CauchyLorentzX0.cs @@ -5,83 +5,82 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class CauchyLorentzX0 { - [ExcludeFromCodeCoverage] - public class CauchyLorentzX0 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyDistribution01() - { - // The properties of the cauchy distribution cannot be tested by mean, media or variance, - // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments + // The properties of the cauchy distribution cannot be tested by mean, media or variance, + // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX0(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX0(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.976990739772031f).Within(0.06f)); - Assert.That(result[1], Is.EqualTo(0.948808314586299f).Within(0.06f)); - Assert.That(result[2], Is.EqualTo(0.905284997403441f).Within(0.06f)); + Assert.That(result[0], Is.EqualTo(0.976990739772031f).Within(0.06f)); + Assert.That(result[1], Is.EqualTo(0.948808314586299f).Within(0.06f)); + Assert.That(result[2], Is.EqualTo(0.905284997403441f).Within(0.06f)); - Assert.That(result[21], Is.EqualTo(0.168965864241396f).Within(0.04f)); - Assert.That(result[22], Is.EqualTo(0.156877686354491f).Within(0.04f)); - Assert.That(result[23], Is.EqualTo(0.145970509936354f).Within(0.04f)); + Assert.That(result[21], Is.EqualTo(0.168965864241396f).Within(0.04f)); + Assert.That(result[22], Is.EqualTo(0.156877686354491f).Within(0.04f)); + Assert.That(result[23], Is.EqualTo(0.145970509936354f).Within(0.04f)); - Assert.That(result[50], Is.EqualTo(0.036533159835978f).Within(0.01f)); + Assert.That(result[50], Is.EqualTo(0.036533159835978f).Within(0.01f)); - Assert.That(result[75], Is.EqualTo(0.016793067514802f).Within(0.01f)); - Assert.That(result[85], Is.EqualTo(0.01316382933791f).Within(0.005f)); - Assert.That(result[90], Is.EqualTo(0.011773781734516f).Within(0.005f)); + Assert.That(result[75], Is.EqualTo(0.016793067514802f).Within(0.01f)); + Assert.That(result[85], Is.EqualTo(0.01316382933791f).Within(0.005f)); + Assert.That(result[90], Is.EqualTo(0.011773781734516f).Within(0.005f)); - Assert.That(result[97], Is.EqualTo(0.010168596941156f).Within(0.005f)); - Assert.That(result[98], Is.EqualTo(0.009966272570142f).Within(0.005f)); - Assert.That(result[99], Is.EqualTo(0.00976990739772f).Within(0.005f)); - } + Assert.That(result[97], Is.EqualTo(0.010168596941156f).Within(0.005f)); + Assert.That(result[98], Is.EqualTo(0.009966272570142f).Within(0.005f)); + Assert.That(result[99], Is.EqualTo(0.00976990739772f).Within(0.005f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.CauchyLorentzX0(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.CauchyLorentzX0(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/CauchyLorentzX1.cs b/FastRngTests/Distributions/CauchyLorentzX1.cs index 6d92b05..9b1a7d4 100644 --- a/FastRngTests/Distributions/CauchyLorentzX1.cs +++ b/FastRngTests/Distributions/CauchyLorentzX1.cs @@ -5,83 +5,82 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class CauchyLorentzX1 { - [ExcludeFromCodeCoverage] - public class CauchyLorentzX1 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyDistribution01() - { - // The properties of the cauchy distribution cannot be tested by mean, media or variance, - // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments + // The properties of the cauchy distribution cannot be tested by mean, media or variance, + // cf. https://en.wikipedia.org/wiki/Cauchy_distribution#Explanation_of_undefined_moments - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX1(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX1(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.009966272570142f).Within(0.003f)); - Assert.That(result[1], Is.EqualTo(0.010168596941156f).Within(0.004f)); - Assert.That(result[2], Is.EqualTo(0.010377123221893f).Within(0.005f)); + Assert.That(result[0], Is.EqualTo(0.009966272570142f).Within(0.003f)); + Assert.That(result[1], Is.EqualTo(0.010168596941156f).Within(0.004f)); + Assert.That(result[2], Is.EqualTo(0.010377123221893f).Within(0.005f)); - Assert.That(result[21], Is.EqualTo(0.015956672819692f).Within(0.005f)); - Assert.That(result[22], Is.EqualTo(0.016366904083094f).Within(0.005f)); - Assert.That(result[23], Is.EqualTo(0.016793067514802f).Within(0.005f)); + Assert.That(result[21], Is.EqualTo(0.015956672819692f).Within(0.005f)); + Assert.That(result[22], Is.EqualTo(0.016366904083094f).Within(0.005f)); + Assert.That(result[23], Is.EqualTo(0.016793067514802f).Within(0.005f)); - Assert.That(result[50], Is.EqualTo(0.039454644029179f).Within(0.015f)); + Assert.That(result[50], Is.EqualTo(0.039454644029179f).Within(0.015f)); - Assert.That(result[75], Is.EqualTo(0.145970509936354f).Within(0.03f)); - Assert.That(result[85], Is.EqualTo(0.333365083503296f).Within(0.1f)); - Assert.That(result[90], Is.EqualTo(0.545171628270584f).Within(0.1f)); + Assert.That(result[75], Is.EqualTo(0.145970509936354f).Within(0.03f)); + Assert.That(result[85], Is.EqualTo(0.333365083503296f).Within(0.1f)); + Assert.That(result[90], Is.EqualTo(0.545171628270584f).Within(0.1f)); - Assert.That(result[97], Is.EqualTo(0.948808314586302f).Within(0.06f)); - Assert.That(result[98], Is.EqualTo(0.976990739772032f).Within(0.03f)); - Assert.That(result[99], Is.EqualTo(0.986760647169751f).Within(0.02f)); - } + Assert.That(result[97], Is.EqualTo(0.948808314586302f).Within(0.06f)); + Assert.That(result[98], Is.EqualTo(0.976990739772032f).Within(0.03f)); + Assert.That(result[99], Is.EqualTo(0.986760647169751f).Within(0.02f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCauchyGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.CauchyLorentzX0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCauchyGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.CauchyLorentzX0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.CauchyLorentzX1(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.CauchyLorentzX1(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/ChiSquareK1.cs b/FastRngTests/Distributions/ChiSquareK1.cs index 24c89e6..4d41f52 100644 --- a/FastRngTests/Distributions/ChiSquareK1.cs +++ b/FastRngTests/Distributions/ChiSquareK1.cs @@ -5,83 +5,82 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class ChiSquareK1 { - [ExcludeFromCodeCoverage] - public class ChiSquareK1 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK1(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK1(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - { - var value = await dist.NextNumber(); - fqa.CountThis(value); - } + for (var n = 0; n < 100_000; n++) + { + var value = await dist.NextNumber(); + fqa.CountThis(value); + } - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.00032041964207f).Within(0.004f)); - Assert.That(result[1], Is.EqualTo(0.70380551227703f).Within(0.05f)); - Assert.That(result[2], Is.EqualTo(0.571788691668126f).Within(0.05f)); + Assert.That(result[0], Is.EqualTo(1.00032041964207f).Within(0.004f)); + Assert.That(result[1], Is.EqualTo(0.70380551227703f).Within(0.05f)); + Assert.That(result[2], Is.EqualTo(0.571788691668126f).Within(0.05f)); - Assert.That(result[21], Is.EqualTo(0.192011337664754f).Within(0.07f)); - Assert.That(result[22], Is.EqualTo(0.186854182385981f).Within(0.07f)); - Assert.That(result[23], Is.EqualTo(0.182007652359976f).Within(0.07f)); + Assert.That(result[21], Is.EqualTo(0.192011337664754f).Within(0.07f)); + Assert.That(result[22], Is.EqualTo(0.186854182385981f).Within(0.07f)); + Assert.That(result[23], Is.EqualTo(0.182007652359976f).Within(0.07f)); - Assert.That(result[50], Is.EqualTo(0.109088865614875f).Within(0.06f)); + Assert.That(result[50], Is.EqualTo(0.109088865614875f).Within(0.06f)); - Assert.That(result[75], Is.EqualTo(0.07886274821701f).Within(0.02f)); - Assert.That(result[85], Is.EqualTo(0.070520397849883f).Within(0.02f)); - Assert.That(result[90], Is.EqualTo(0.066863009640287f).Within(0.02f)); + Assert.That(result[75], Is.EqualTo(0.07886274821701f).Within(0.02f)); + Assert.That(result[85], Is.EqualTo(0.070520397849883f).Within(0.02f)); + Assert.That(result[90], Is.EqualTo(0.066863009640287f).Within(0.02f)); - Assert.That(result[97], Is.EqualTo(0.062214737436948f).Within(0.02f)); - Assert.That(result[98], Is.EqualTo(0.061590997922187f).Within(0.02f)); - Assert.That(result[99], Is.EqualTo(0.060976622578824f).Within(0.02f)); - } + Assert.That(result[97], Is.EqualTo(0.062214737436948f).Within(0.02f)); + Assert.That(result[98], Is.EqualTo(0.061590997922187f).Within(0.02f)); + Assert.That(result[99], Is.EqualTo(0.060976622578824f).Within(0.02f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.ChiSquareK1(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.ChiSquareK1(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/ChiSquareK10.cs b/FastRngTests/Distributions/ChiSquareK10.cs index c7961fe..9bd92b7 100644 --- a/FastRngTests/Distributions/ChiSquareK10.cs +++ b/FastRngTests/Distributions/ChiSquareK10.cs @@ -5,83 +5,82 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class ChiSquareK10 { - [ExcludeFromCodeCoverage] - public class ChiSquareK10 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareDistribution01() + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK10(rng); + var fqa = new FrequencyAnalysis(); + + for (var n = 0; n < 100_000; n++) { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK10(rng); - var fqa = new FrequencyAnalysis(); - - for (var n = 0; n < 100_000; n++) - { - var value = await dist.NextNumber(); - fqa.CountThis(value); - } - - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - - Assert.That(result[0], Is.EqualTo(0.0000000164021588f).Within(0.0000002f)); - Assert.That(result[1], Is.EqualTo(0.0000002611256437f).Within(0.000003f)); - Assert.That(result[2], Is.EqualTo(0.0000013153553250f).Within(0.00002f)); - - Assert.That(result[21], Is.EqualTo(0.003459320622874f).Within(0.005f)); - Assert.That(result[22], Is.EqualTo(0.004111875573379f).Within(0.005f)); - Assert.That(result[23], Is.EqualTo(0.004850674298859f).Within(0.005f)); - - Assert.That(result[50], Is.EqualTo(0.086418773275056f).Within(0.05f)); - - Assert.That(result[75], Is.EqualTo(0.376092741436046f).Within(0.08f)); - Assert.That(result[85], Is.EqualTo(0.586569751611096f).Within(0.08f)); - Assert.That(result[90], Is.EqualTo(0.717189736168766f).Within(0.08f)); - - Assert.That(result[97], Is.EqualTo(0.931477764640217f).Within(0.08f)); - Assert.That(result[98], Is.EqualTo(0.965244855212136f).Within(0.08f)); - Assert.That(result[99], Is.EqualTo(0.999827884370044f).Within(0.08f)); + var value = await dist.NextNumber(); + fqa.CountThis(value); } + + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + + Assert.That(result[0], Is.EqualTo(0.0000000164021588f).Within(0.0000002f)); + Assert.That(result[1], Is.EqualTo(0.0000002611256437f).Within(0.000003f)); + Assert.That(result[2], Is.EqualTo(0.0000013153553250f).Within(0.00002f)); + + Assert.That(result[21], Is.EqualTo(0.003459320622874f).Within(0.005f)); + Assert.That(result[22], Is.EqualTo(0.004111875573379f).Within(0.005f)); + Assert.That(result[23], Is.EqualTo(0.004850674298859f).Within(0.005f)); + + Assert.That(result[50], Is.EqualTo(0.086418773275056f).Within(0.05f)); + + Assert.That(result[75], Is.EqualTo(0.376092741436046f).Within(0.08f)); + Assert.That(result[85], Is.EqualTo(0.586569751611096f).Within(0.08f)); + Assert.That(result[90], Is.EqualTo(0.717189736168766f).Within(0.08f)); + + Assert.That(result[97], Is.EqualTo(0.931477764640217f).Within(0.08f)); + Assert.That(result[98], Is.EqualTo(0.965244855212136f).Within(0.08f)); + Assert.That(result[99], Is.EqualTo(0.999827884370044f).Within(0.08f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.ChiSquareK10(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.ChiSquareK10(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/ChiSquareK4.cs b/FastRngTests/Distributions/ChiSquareK4.cs index ca68aba..38efd0c 100644 --- a/FastRngTests/Distributions/ChiSquareK4.cs +++ b/FastRngTests/Distributions/ChiSquareK4.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class ChiSquareK4 { - [ExcludeFromCodeCoverage] - public class ChiSquareK4 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK4(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK4(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.016417705906679f).Within(0.02f)); - Assert.That(result[1], Is.EqualTo(0.032671644513723f).Within(0.02f)); - Assert.That(result[2], Is.EqualTo(0.048763041010352f).Within(0.02f)); + Assert.That(result[0], Is.EqualTo(0.016417705906679f).Within(0.02f)); + Assert.That(result[1], Is.EqualTo(0.032671644513723f).Within(0.02f)); + Assert.That(result[2], Is.EqualTo(0.048763041010352f).Within(0.02f)); - Assert.That(result[21], Is.EqualTo(0.32518779111264f).Within(0.05f)); - Assert.That(result[22], Is.EqualTo(0.338273451612642f).Within(0.05f)); - Assert.That(result[23], Is.EqualTo(0.351220492939994f).Within(0.05f)); + Assert.That(result[21], Is.EqualTo(0.32518779111264f).Within(0.05f)); + Assert.That(result[22], Is.EqualTo(0.338273451612642f).Within(0.05f)); + Assert.That(result[23], Is.EqualTo(0.351220492939994f).Within(0.05f)); - Assert.That(result[50], Is.EqualTo(0.65209223303425f).Within(0.08f)); + Assert.That(result[50], Is.EqualTo(0.65209223303425f).Within(0.08f)); - Assert.That(result[75], Is.EqualTo(0.857562207152294f).Within(0.099f)); - Assert.That(result[85], Is.EqualTo(0.923072405412387f).Within(0.099f)); - Assert.That(result[90], Is.EqualTo(0.952623623874265f).Within(0.099f)); + Assert.That(result[75], Is.EqualTo(0.857562207152294f).Within(0.099f)); + Assert.That(result[85], Is.EqualTo(0.923072405412387f).Within(0.099f)); + Assert.That(result[90], Is.EqualTo(0.952623623874265f).Within(0.099f)); - Assert.That(result[97], Is.EqualTo(0.990616879396201f).Within(0.099f)); - Assert.That(result[98], Is.EqualTo(0.995734077068522f).Within(0.099f)); - Assert.That(result[99], Is.EqualTo(1.00077558852585f).Within(0.1f)); - } + Assert.That(result[97], Is.EqualTo(0.990616879396201f).Within(0.099f)); + Assert.That(result[98], Is.EqualTo(0.995734077068522f).Within(0.099f)); + Assert.That(result[99], Is.EqualTo(1.00077558852585f).Within(0.1f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK4(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK4(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestChiSquareGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ChiSquareK4(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestChiSquareGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ChiSquareK4(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.ChiSquareK4(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.ChiSquareK4(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/ExponentialLa10.cs b/FastRngTests/Distributions/ExponentialLa10.cs index 06fd9e4..51cf379 100644 --- a/FastRngTests/Distributions/ExponentialLa10.cs +++ b/FastRngTests/Distributions/ExponentialLa10.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class ExponentialLa10 { - [ExcludeFromCodeCoverage] - public class ExponentialLa10 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa10(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa10(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.00075018434777f).Within(0.05f)); - Assert.That(result[1], Is.EqualTo(0.905516212904248f).Within(0.05f)); - Assert.That(result[2], Is.EqualTo(0.81934495207398f).Within(0.05f)); + Assert.That(result[0], Is.EqualTo(1.00075018434777f).Within(0.05f)); + Assert.That(result[1], Is.EqualTo(0.905516212904248f).Within(0.05f)); + Assert.That(result[2], Is.EqualTo(0.81934495207398f).Within(0.05f)); - Assert.That(result[21], Is.EqualTo(0.122548293148741f).Within(0.12f)); - Assert.That(result[22], Is.EqualTo(0.110886281157421f).Within(0.12f)); - Assert.That(result[23], Is.EqualTo(0.10033405633809f).Within(0.12f)); + Assert.That(result[21], Is.EqualTo(0.122548293148741f).Within(0.12f)); + Assert.That(result[22], Is.EqualTo(0.110886281157421f).Within(0.12f)); + Assert.That(result[23], Is.EqualTo(0.10033405633809f).Within(0.12f)); - Assert.That(result[50], Is.EqualTo(0.00674300170146f).Within(0.005f)); + Assert.That(result[50], Is.EqualTo(0.00674300170146f).Within(0.005f)); - Assert.That(result[75], Is.EqualTo(0.000553499285385f).Within(0.001f)); - Assert.That(result[85], Is.EqualTo(0.000203621007796f).Within(0.001f)); - Assert.That(result[90], Is.EqualTo(0.00012350238419f).Within(0.001f)); + Assert.That(result[75], Is.EqualTo(0.000553499285385f).Within(0.001f)); + Assert.That(result[85], Is.EqualTo(0.000203621007796f).Within(0.001f)); + Assert.That(result[90], Is.EqualTo(0.00012350238419f).Within(0.001f)); - Assert.That(result[97], Is.EqualTo(0.0000613294689720f).Within(0.0008f)); - Assert.That(result[98], Is.EqualTo(0.0000554931983541f).Within(0.0008f)); - Assert.That(result[99], Is.EqualTo(0.0000502123223173f).Within(0.0008f)); - } + Assert.That(result[97], Is.EqualTo(0.0000613294689720f).Within(0.0008f)); + Assert.That(result[98], Is.EqualTo(0.0000554931983541f).Within(0.0008f)); + Assert.That(result[99], Is.EqualTo(0.0000502123223173f).Within(0.0008f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.ExponentialLa10(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.ExponentialLa10(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/ExponentialLa5.cs b/FastRngTests/Distributions/ExponentialLa5.cs index f325605..66eb16a 100644 --- a/FastRngTests/Distributions/ExponentialLa5.cs +++ b/FastRngTests/Distributions/ExponentialLa5.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class ExponentialLa5 { - [ExcludeFromCodeCoverage] - public class ExponentialLa5 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa5(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa5(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.0002177398625f).Within(0.05f)); - Assert.That(result[1], Is.EqualTo(0.951436545064811f).Within(0.05f)); - Assert.That(result[2], Is.EqualTo(0.905034437210948f).Within(0.05f)); + Assert.That(result[0], Is.EqualTo(1.0002177398625f).Within(0.05f)); + Assert.That(result[1], Is.EqualTo(0.951436545064811f).Within(0.05f)); + Assert.That(result[2], Is.EqualTo(0.905034437210948f).Within(0.05f)); - Assert.That(result[21], Is.EqualTo(0.35001394450853f).Within(0.05f)); - Assert.That(result[22], Is.EqualTo(0.332943563002074f).Within(0.05f)); - Assert.That(result[23], Is.EqualTo(0.31670571382568f).Within(0.05f)); + Assert.That(result[21], Is.EqualTo(0.35001394450853f).Within(0.05f)); + Assert.That(result[22], Is.EqualTo(0.332943563002074f).Within(0.05f)); + Assert.That(result[23], Is.EqualTo(0.31670571382568f).Within(0.05f)); - Assert.That(result[50], Is.EqualTo(0.082102871800213f).Within(0.01f)); + Assert.That(result[50], Is.EqualTo(0.082102871800213f).Within(0.01f)); - Assert.That(result[75], Is.EqualTo(0.023522866606758f).Within(0.01f)); - Assert.That(result[85], Is.EqualTo(0.014267339801329f).Within(0.01f)); - Assert.That(result[90], Is.EqualTo(0.011111415409621f).Within(0.01f)); + Assert.That(result[75], Is.EqualTo(0.023522866606758f).Within(0.01f)); + Assert.That(result[85], Is.EqualTo(0.014267339801329f).Within(0.01f)); + Assert.That(result[90], Is.EqualTo(0.011111415409621f).Within(0.01f)); - Assert.That(result[97], Is.EqualTo(0.007830082099077f).Within(0.008f)); - Assert.That(result[98], Is.EqualTo(0.007448204488898f).Within(0.008f)); - Assert.That(result[99], Is.EqualTo(0.007084951269538f).Within(0.008f)); - } + Assert.That(result[97], Is.EqualTo(0.007830082099077f).Within(0.008f)); + Assert.That(result[98], Is.EqualTo(0.007448204488898f).Within(0.008f)); + Assert.That(result[99], Is.EqualTo(0.007084951269538f).Within(0.008f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa5(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa5(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.ExponentialLa5(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.ExponentialLa5(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.ExponentialLa5(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.ExponentialLa5(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/GammaA5B15.cs b/FastRngTests/Distributions/GammaA5B15.cs index 9fee43c..24ceb0b 100644 --- a/FastRngTests/Distributions/GammaA5B15.cs +++ b/FastRngTests/Distributions/GammaA5B15.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class GammaA5B15 { - [ExcludeFromCodeCoverage] - public class GammaA5B15 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestGammaDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestGammaDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.GammaA5B15(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.GammaA5B15(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0000929594237282f).Within(0.0008f)); - Assert.That(result[1], Is.EqualTo(0.0012801746797876f).Within(0.002f)); - Assert.That(result[2], Is.EqualTo(0.0055781488254349f).Within(0.004f)); + Assert.That(result[0], Is.EqualTo(0.0000929594237282f).Within(0.0008f)); + Assert.That(result[1], Is.EqualTo(0.0012801746797876f).Within(0.002f)); + Assert.That(result[2], Is.EqualTo(0.0055781488254349f).Within(0.004f)); - Assert.That(result[21], Is.EqualTo(0.9331608887752720f).Within(0.09f)); - Assert.That(result[22], Is.EqualTo(0.9594734828891280f).Within(0.09f)); - Assert.That(result[23], Is.EqualTo(0.9790895765535350f).Within(0.09f)); + Assert.That(result[21], Is.EqualTo(0.9331608887752720f).Within(0.09f)); + Assert.That(result[22], Is.EqualTo(0.9594734828891280f).Within(0.09f)); + Assert.That(result[23], Is.EqualTo(0.9790895765535350f).Within(0.09f)); - Assert.That(result[50], Is.EqualTo(0.3478287795336570f).Within(0.06f)); + Assert.That(result[50], Is.EqualTo(0.3478287795336570f).Within(0.06f)); - Assert.That(result[75], Is.EqualTo(0.0403399049422936f).Within(0.009f)); - Assert.That(result[85], Is.EqualTo(0.0163628388658126f).Within(0.009f)); - Assert.That(result[90], Is.EqualTo(0.0097147611446660f).Within(0.005f)); + Assert.That(result[75], Is.EqualTo(0.0403399049422936f).Within(0.009f)); + Assert.That(result[85], Is.EqualTo(0.0163628388658126f).Within(0.009f)); + Assert.That(result[90], Is.EqualTo(0.0097147611446660f).Within(0.005f)); - Assert.That(result[97], Is.EqualTo(0.0041135143233153f).Within(0.008f)); - Assert.That(result[98], Is.EqualTo(0.0036872732029996f).Within(0.008f)); - Assert.That(result[99], Is.EqualTo(0.0033038503429554f).Within(0.008f)); - } + Assert.That(result[97], Is.EqualTo(0.0041135143233153f).Within(0.008f)); + Assert.That(result[98], Is.EqualTo(0.0036872732029996f).Within(0.008f)); + Assert.That(result[99], Is.EqualTo(0.0033038503429554f).Within(0.008f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestGammaGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.GammaA5B15(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestGammaGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.GammaA5B15(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestGammaGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.GammaA5B15(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestGammaGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.GammaA5B15(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.GammaA5B15(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.GammaA5B15(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/InverseExponentialLa10.cs b/FastRngTests/Distributions/InverseExponentialLa10.cs index dc7c7ed..de7271d 100644 --- a/FastRngTests/Distributions/InverseExponentialLa10.cs +++ b/FastRngTests/Distributions/InverseExponentialLa10.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class InverseExponentialLa10 { - [ExcludeFromCodeCoverage] - public class InverseExponentialLa10 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa10(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa10(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0000501746820562f).Within(0.0003f)); - Assert.That(result[1], Is.EqualTo(0.0000554515994322f).Within(0.0003f)); - Assert.That(result[2], Is.EqualTo(0.0000612834950532f).Within(0.0003f)); + Assert.That(result[0], Is.EqualTo(0.0000501746820562f).Within(0.0003f)); + Assert.That(result[1], Is.EqualTo(0.0000554515994322f).Within(0.0003f)); + Assert.That(result[2], Is.EqualTo(0.0000612834950532f).Within(0.0003f)); - Assert.That(result[21], Is.EqualTo(0.00040973497898f).Within(0.00045f)); - Assert.That(result[22], Is.EqualTo(0.000452827182887f).Within(0.00050f)); - Assert.That(result[23], Is.EqualTo(0.000500451433441f).Within(0.0006f)); + Assert.That(result[21], Is.EqualTo(0.00040973497898f).Within(0.00045f)); + Assert.That(result[22], Is.EqualTo(0.000452827182887f).Within(0.00050f)); + Assert.That(result[23], Is.EqualTo(0.000500451433441f).Within(0.0006f)); - Assert.That(result[50], Is.EqualTo(0.007446583070924f).Within(0.003f)); + Assert.That(result[50], Is.EqualTo(0.007446583070924f).Within(0.003f)); - Assert.That(result[75], Is.EqualTo(0.090717953289412f).Within(0.02f)); - Assert.That(result[85], Is.EqualTo(0.246596963941606f).Within(0.05f)); - Assert.That(result[90], Is.EqualTo(0.406569659740598f).Within(0.08f)); + Assert.That(result[75], Is.EqualTo(0.090717953289412f).Within(0.02f)); + Assert.That(result[85], Is.EqualTo(0.246596963941606f).Within(0.05f)); + Assert.That(result[90], Is.EqualTo(0.406569659740598f).Within(0.08f)); - Assert.That(result[97], Is.EqualTo(0.81873075307798f).Within(0.08f)); - Assert.That(result[98], Is.EqualTo(0.904837418035957f).Within(0.08f)); - Assert.That(result[99], Is.EqualTo(0.999999999999999f).Within(0.08f)); - } + Assert.That(result[97], Is.EqualTo(0.81873075307798f).Within(0.08f)); + Assert.That(result[98], Is.EqualTo(0.904837418035957f).Within(0.08f)); + Assert.That(result[99], Is.EqualTo(0.999999999999999f).Within(0.08f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa10(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa10(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.InverseExponentialLa10(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.InverseExponentialLa10(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/InverseExponentialLa5.cs b/FastRngTests/Distributions/InverseExponentialLa5.cs index fec7db4..1fd872a 100644 --- a/FastRngTests/Distributions/InverseExponentialLa5.cs +++ b/FastRngTests/Distributions/InverseExponentialLa5.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class InverseExponentialLa5 { - [ExcludeFromCodeCoverage] - public class InverseExponentialLa5 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa5(rng); - var fqa = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa5(rng); + var fqa = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fqa.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fqa.CountThis(await dist.NextNumber()); - var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fqa.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.007083408929052f).Within(0.008f)); - Assert.That(result[1], Is.EqualTo(0.007446583070924f).Within(0.008f)); - Assert.That(result[2], Is.EqualTo(0.007828377549226f).Within(0.008f)); + Assert.That(result[0], Is.EqualTo(0.007083408929052f).Within(0.008f)); + Assert.That(result[1], Is.EqualTo(0.007446583070924f).Within(0.008f)); + Assert.That(result[2], Is.EqualTo(0.007828377549226f).Within(0.008f)); - Assert.That(result[21], Is.EqualTo(0.020241911445804f).Within(0.05f)); - Assert.That(result[22], Is.EqualTo(0.021279736438377f).Within(0.05f)); - Assert.That(result[23], Is.EqualTo(0.022370771856166f).Within(0.05f)); + Assert.That(result[21], Is.EqualTo(0.020241911445804f).Within(0.05f)); + Assert.That(result[22], Is.EqualTo(0.021279736438377f).Within(0.05f)); + Assert.That(result[23], Is.EqualTo(0.022370771856166f).Within(0.05f)); - Assert.That(result[50], Is.EqualTo(0.08629358649937f).Within(0.02f)); + Assert.That(result[50], Is.EqualTo(0.08629358649937f).Within(0.02f)); - Assert.That(result[75], Is.EqualTo(0.301194211912202f).Within(0.03f)); - Assert.That(result[85], Is.EqualTo(0.496585303791409f).Within(0.05f)); - Assert.That(result[90], Is.EqualTo(0.637628151621772f).Within(0.06f)); + Assert.That(result[75], Is.EqualTo(0.301194211912202f).Within(0.03f)); + Assert.That(result[85], Is.EqualTo(0.496585303791409f).Within(0.05f)); + Assert.That(result[90], Is.EqualTo(0.637628151621772f).Within(0.06f)); - Assert.That(result[97], Is.EqualTo(0.904837418035959f).Within(0.08f)); - Assert.That(result[98], Is.EqualTo(0.951229424500713f).Within(0.08f)); - Assert.That(result[99], Is.EqualTo(1f).Within(0.08f)); - } + Assert.That(result[97], Is.EqualTo(0.904837418035959f).Within(0.08f)); + Assert.That(result[98], Is.EqualTo(0.951229424500713f).Within(0.08f)); + Assert.That(result[99], Is.EqualTo(1f).Within(0.08f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa5(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa5(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestExponentialGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseExponentialLa5(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestExponentialGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseExponentialLa5(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.InverseExponentialLa5(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.InverseExponentialLa5(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/InverseGammaA3B05.cs b/FastRngTests/Distributions/InverseGammaA3B05.cs index b3667da..9027f7f 100644 --- a/FastRngTests/Distributions/InverseGammaA3B05.cs +++ b/FastRngTests/Distributions/InverseGammaA3B05.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class InverseGammaA3B05 { - [ExcludeFromCodeCoverage] - public class InverseGammaA3B05 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestInverseGammaDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestInverseGammaDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseGammaA3B05(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseGammaA3B05(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0000000000000003f).Within(0.0000001f)); - Assert.That(result[1], Is.EqualTo(0.0000011605257228f).Within(0.00001f)); - Assert.That(result[2], Is.EqualTo(0.0009536970016103f).Within(0.0015f)); + Assert.That(result[0], Is.EqualTo(0.0000000000000003f).Within(0.0000001f)); + Assert.That(result[1], Is.EqualTo(0.0000011605257228f).Within(0.00001f)); + Assert.That(result[2], Is.EqualTo(0.0009536970016103f).Within(0.0015f)); - Assert.That(result[21], Is.EqualTo(0.5880485243048120f).Within(0.05f)); - Assert.That(result[22], Is.EqualTo(0.5433842148912880f).Within(0.05f)); - Assert.That(result[23], Is.EqualTo(0.5017780549216030f).Within(0.05f)); + Assert.That(result[21], Is.EqualTo(0.5880485243048120f).Within(0.05f)); + Assert.That(result[22], Is.EqualTo(0.5433842148912880f).Within(0.05f)); + Assert.That(result[23], Is.EqualTo(0.5017780549216030f).Within(0.05f)); - Assert.That(result[50], Is.EqualTo(0.0741442015957425f).Within(0.009f)); + Assert.That(result[50], Is.EqualTo(0.0741442015957425f).Within(0.009f)); - Assert.That(result[75], Is.EqualTo(0.0207568945092484f).Within(0.006f)); - Assert.That(result[85], Is.EqualTo(0.0136661506653688f).Within(0.006f)); - Assert.That(result[90], Is.EqualTo(0.0112550619601327f).Within(0.006f)); + Assert.That(result[75], Is.EqualTo(0.0207568945092484f).Within(0.006f)); + Assert.That(result[85], Is.EqualTo(0.0136661506653688f).Within(0.006f)); + Assert.That(result[90], Is.EqualTo(0.0112550619601327f).Within(0.006f)); - Assert.That(result[97], Is.EqualTo(0.0087026933539773f).Within(0.005f)); - Assert.That(result[98], Is.EqualTo(0.0083995375385004f).Within(0.005f)); - Assert.That(result[99], Is.EqualTo(0.0081094156379928f).Within(0.005f)); - } + Assert.That(result[97], Is.EqualTo(0.0087026933539773f).Within(0.005f)); + Assert.That(result[98], Is.EqualTo(0.0083995375385004f).Within(0.005f)); + Assert.That(result[99], Is.EqualTo(0.0081094156379928f).Within(0.005f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestInverseGammaGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseGammaA3B05(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestInverseGammaGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseGammaA3B05(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestInverseGammaGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.InverseGammaA3B05(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestInverseGammaGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.InverseGammaA3B05(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.InverseGammaA3B05(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.InverseGammaA3B05(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/LaplaceB01M0.cs b/FastRngTests/Distributions/LaplaceB01M0.cs index 5629338..f24132b 100644 --- a/FastRngTests/Distributions/LaplaceB01M0.cs +++ b/FastRngTests/Distributions/LaplaceB01M0.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class LaplaceB01M0 { - [ExcludeFromCodeCoverage] - public class LaplaceB01M0 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M0(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M0(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.0000000000000000f).Within(0.05f)); - Assert.That(result[1], Is.EqualTo(0.9048374180359590f).Within(0.05f)); - Assert.That(result[2], Is.EqualTo(0.8187307530779810f).Within(0.05f)); + Assert.That(result[0], Is.EqualTo(1.0000000000000000f).Within(0.05f)); + Assert.That(result[1], Is.EqualTo(0.9048374180359590f).Within(0.05f)); + Assert.That(result[2], Is.EqualTo(0.8187307530779810f).Within(0.05f)); - Assert.That(result[21], Is.EqualTo(0.1224564282529820f).Within(0.05f)); - Assert.That(result[22], Is.EqualTo(0.1108031583623340f).Within(0.05f)); - Assert.That(result[23], Is.EqualTo(0.1002588437228040f).Within(0.05f)); + Assert.That(result[21], Is.EqualTo(0.1224564282529820f).Within(0.05f)); + Assert.That(result[22], Is.EqualTo(0.1108031583623340f).Within(0.05f)); + Assert.That(result[23], Is.EqualTo(0.1002588437228040f).Within(0.05f)); - Assert.That(result[50], Is.EqualTo(0.0067379469990855f).Within(0.003f)); + Assert.That(result[50], Is.EqualTo(0.0067379469990855f).Within(0.003f)); - Assert.That(result[75], Is.EqualTo(0.0005530843701478f).Within(0.0015f)); - Assert.That(result[85], Is.EqualTo(0.0002034683690106f).Within(0.0015f)); - Assert.That(result[90], Is.EqualTo(0.0001234098040867f).Within(0.0015f)); + Assert.That(result[75], Is.EqualTo(0.0005530843701478f).Within(0.0015f)); + Assert.That(result[85], Is.EqualTo(0.0002034683690106f).Within(0.0015f)); + Assert.That(result[90], Is.EqualTo(0.0001234098040867f).Within(0.0015f)); - Assert.That(result[97], Is.EqualTo(0.0000612834950532f).Within(0.0002f)); - Assert.That(result[98], Is.EqualTo(0.0000554515994322f).Within(0.0002f)); - Assert.That(result[99], Is.EqualTo(0.0000501746820562f).Within(0.0002f)); - } + Assert.That(result[97], Is.EqualTo(0.0000612834950532f).Within(0.0002f)); + Assert.That(result[98], Is.EqualTo(0.0000554515994322f).Within(0.0002f)); + Assert.That(result[99], Is.EqualTo(0.0000501746820562f).Within(0.0002f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.LaplaceB01M0(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.LaplaceB01M0(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/LaplaceB01M05.cs b/FastRngTests/Distributions/LaplaceB01M05.cs index 0acfdde..5cae3bd 100644 --- a/FastRngTests/Distributions/LaplaceB01M05.cs +++ b/FastRngTests/Distributions/LaplaceB01M05.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class LaplaceB01M05 { - [ExcludeFromCodeCoverage] - public class LaplaceB01M05 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M05(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M05(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.0074465830709244f).Within(0.004f)); - Assert.That(result[1], Is.EqualTo(0.0082297470490200f).Within(0.004f)); - Assert.That(result[2], Is.EqualTo(0.0090952771016958f).Within(0.01f)); + Assert.That(result[0], Is.EqualTo(0.0074465830709244f).Within(0.004f)); + Assert.That(result[1], Is.EqualTo(0.0082297470490200f).Within(0.004f)); + Assert.That(result[2], Is.EqualTo(0.0090952771016958f).Within(0.01f)); - Assert.That(result[21], Is.EqualTo(0.0608100626252180f).Within(0.02f)); - Assert.That(result[22], Is.EqualTo(0.0672055127397498f).Within(0.02f)); - Assert.That(result[23], Is.EqualTo(0.0742735782143340f).Within(0.02f)); + Assert.That(result[21], Is.EqualTo(0.0608100626252180f).Within(0.02f)); + Assert.That(result[22], Is.EqualTo(0.0672055127397498f).Within(0.02f)); + Assert.That(result[23], Is.EqualTo(0.0742735782143340f).Within(0.02f)); - Assert.That(result[50], Is.EqualTo(1.0000000000000000f).Within(0.2f)); + Assert.That(result[50], Is.EqualTo(1.0000000000000000f).Within(0.2f)); - Assert.That(result[75], Is.EqualTo(0.0742735782143335f).Within(0.01f)); - Assert.That(result[85], Is.EqualTo(0.0273237224472924f).Within(0.01f)); - Assert.That(result[90], Is.EqualTo(0.0165726754017612f).Within(0.01f)); + Assert.That(result[75], Is.EqualTo(0.0742735782143335f).Within(0.01f)); + Assert.That(result[85], Is.EqualTo(0.0273237224472924f).Within(0.01f)); + Assert.That(result[90], Is.EqualTo(0.0165726754017612f).Within(0.01f)); - Assert.That(result[97], Is.EqualTo(0.0082297470490200f).Within(0.004f)); - Assert.That(result[98], Is.EqualTo(0.0074465830709243f).Within(0.004f)); - Assert.That(result[99], Is.EqualTo(0.0067379469990854f).Within(0.004f)); - } + Assert.That(result[97], Is.EqualTo(0.0082297470490200f).Within(0.004f)); + Assert.That(result[98], Is.EqualTo(0.0074465830709243f).Within(0.004f)); + Assert.That(result[99], Is.EqualTo(0.0067379469990854f).Within(0.004f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M05(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M05(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLaplaceGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LaplaceB01M05(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLaplaceGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LaplaceB01M05(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.LaplaceB01M05(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.LaplaceB01M05(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/LogNormalS1M0.cs b/FastRngTests/Distributions/LogNormalS1M0.cs index c47f506..4b6ad45 100644 --- a/FastRngTests/Distributions/LogNormalS1M0.cs +++ b/FastRngTests/Distributions/LogNormalS1M0.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class LogNormalS1M0 { - [ExcludeFromCodeCoverage] - public class LogNormalS1M0 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLogNormalDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLogNormalDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LogNormalS1M0(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LogNormalS1M0(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(0.001505531f).Within(0.003f)); - Assert.That(result[1], Is.EqualTo(0.014408709f).Within(0.01f)); - Assert.That(result[2], Is.EqualTo(0.043222256f).Within(0.02f)); + Assert.That(result[0], Is.EqualTo(0.001505531f).Within(0.003f)); + Assert.That(result[1], Is.EqualTo(0.014408709f).Within(0.01f)); + Assert.That(result[2], Is.EqualTo(0.043222256f).Within(0.02f)); - Assert.That(result[21], Is.EqualTo(0.876212056f).Within(0.15f)); - Assert.That(result[22], Is.EqualTo(0.895582226f).Within(0.15f)); - Assert.That(result[23], Is.EqualTo(0.912837250f).Within(0.15f)); + Assert.That(result[21], Is.EqualTo(0.876212056f).Within(0.15f)); + Assert.That(result[22], Is.EqualTo(0.895582226f).Within(0.15f)); + Assert.That(result[23], Is.EqualTo(0.912837250f).Within(0.15f)); - Assert.That(result[50], Is.EqualTo(0.948062005f).Within(0.2f)); + Assert.That(result[50], Is.EqualTo(0.948062005f).Within(0.2f)); - Assert.That(result[75], Is.EqualTo(0.768584762f).Within(0.089f)); - Assert.That(result[85], Is.EqualTo(0.697303612f).Within(0.089f)); - Assert.That(result[90], Is.EqualTo(0.663570581f).Within(0.089f)); + Assert.That(result[75], Is.EqualTo(0.768584762f).Within(0.089f)); + Assert.That(result[85], Is.EqualTo(0.697303612f).Within(0.089f)); + Assert.That(result[90], Is.EqualTo(0.663570581f).Within(0.089f)); - Assert.That(result[97], Is.EqualTo(0.618792767f).Within(0.089f)); - Assert.That(result[98], Is.EqualTo(0.612636410f).Within(0.089f)); - Assert.That(result[99], Is.EqualTo(0.606540679f).Within(0.089f)); - } + Assert.That(result[97], Is.EqualTo(0.618792767f).Within(0.089f)); + Assert.That(result[98], Is.EqualTo(0.612636410f).Within(0.089f)); + Assert.That(result[99], Is.EqualTo(0.606540679f).Within(0.089f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLogNormalGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LogNormalS1M0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLogNormalGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LogNormalS1M0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestLogNormalGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.LogNormalS1M0(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestLogNormalGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.LogNormalS1M0(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.LogNormalS1M0(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.LogNormalS1M0(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/NormalS02M05.cs b/FastRngTests/Distributions/NormalS02M05.cs index 877c8ea..4bc88ed 100644 --- a/FastRngTests/Distributions/NormalS02M05.cs +++ b/FastRngTests/Distributions/NormalS02M05.cs @@ -5,76 +5,75 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class NormalS02M05 { - [ExcludeFromCodeCoverage] - public class NormalS02M05 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestNormalDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestNormalDistribution01() + const float MEAN = 0.5f; + const float STANDARD_DEVIATION = 0.2f; + + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.NormalS02M05(rng); + var stats = new RunningStatistics(); + var fra = new FrequencyAnalysis(); + + for (var n = 0; n < 100_000; n++) { - const float MEAN = 0.5f; - const float STANDARD_DEVIATION = 0.2f; - - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.NormalS02M05(rng); - var stats = new RunningStatistics(); - var fra = new FrequencyAnalysis(); - - for (var n = 0; n < 100_000; n++) - { - var nextNumber = await dist.NextNumber(); - stats.Push(nextNumber); - fra.CountThis(nextNumber); - } - - fra.NormalizeAndPlotEvents(TestContext.WriteLine); - - TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}"); - TestContext.WriteLine($"variance={STANDARD_DEVIATION * STANDARD_DEVIATION} vs {stats.Variance}"); - - Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01f), "Mean is out of range"); - Assert.That(stats.Variance, Is.EqualTo(STANDARD_DEVIATION*STANDARD_DEVIATION).Within(0.01f), "Variance is out of range"); + var nextNumber = await dist.NextNumber(); + stats.Push(nextNumber); + fra.CountThis(nextNumber); } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestNormalGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.NormalS02M05(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}"); + TestContext.WriteLine($"variance={STANDARD_DEVIATION * STANDARD_DEVIATION} vs {stats.Variance}"); + + Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01f), "Mean is out of range"); + Assert.That(stats.Variance, Is.EqualTo(STANDARD_DEVIATION*STANDARD_DEVIATION).Within(0.01f), "Variance is out of range"); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestNormalGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.NormalS02M05(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); + + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestNormalGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.NormalS02M05(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestNormalGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.NormalS02M05(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.NormalS02M05(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.NormalS02M05(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/StudentTNu1.cs b/FastRngTests/Distributions/StudentTNu1.cs index cfce282..fcec86a 100644 --- a/FastRngTests/Distributions/StudentTNu1.cs +++ b/FastRngTests/Distributions/StudentTNu1.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class StudentTNu1 { - [ExcludeFromCodeCoverage] - public class StudentTNu1 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestStudentTDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestStudentTDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.StudentTNu1(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.StudentTNu1(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.000000000f).Within(0.2f)); - Assert.That(result[1], Is.EqualTo(0.999700120f).Within(0.2f)); - Assert.That(result[2], Is.EqualTo(0.999200719f).Within(0.2f)); + Assert.That(result[0], Is.EqualTo(1.000000000f).Within(0.2f)); + Assert.That(result[1], Is.EqualTo(0.999700120f).Within(0.2f)); + Assert.That(result[2], Is.EqualTo(0.999200719f).Within(0.2f)); - Assert.That(result[21], Is.EqualTo(0.953929798f).Within(0.2f)); - Assert.That(result[22], Is.EqualTo(0.949852788f).Within(0.2f)); - Assert.That(result[23], Is.EqualTo(0.945631619f).Within(0.2f)); + Assert.That(result[21], Is.EqualTo(0.953929798f).Within(0.2f)); + Assert.That(result[22], Is.EqualTo(0.949852788f).Within(0.2f)); + Assert.That(result[23], Is.EqualTo(0.945631619f).Within(0.2f)); - Assert.That(result[50], Is.EqualTo(0.793667169f).Within(0.095f)); + Assert.That(result[50], Is.EqualTo(0.793667169f).Within(0.095f)); - Assert.That(result[75], Is.EqualTo(0.633937627f).Within(0.09f)); - Assert.That(result[85], Is.EqualTo(0.574902276f).Within(0.09f)); - Assert.That(result[90], Is.EqualTo(0.547070729f).Within(0.09f)); + Assert.That(result[75], Is.EqualTo(0.633937627f).Within(0.09f)); + Assert.That(result[85], Is.EqualTo(0.574902276f).Within(0.09f)); + Assert.That(result[90], Is.EqualTo(0.547070729f).Within(0.09f)); - Assert.That(result[97], Is.EqualTo(0.510150990f).Within(0.09f)); - Assert.That(result[98], Is.EqualTo(0.505075501f).Within(0.09f)); - Assert.That(result[99], Is.EqualTo(0.500050000f).Within(0.09f)); - } + Assert.That(result[97], Is.EqualTo(0.510150990f).Within(0.09f)); + Assert.That(result[98], Is.EqualTo(0.505075501f).Within(0.09f)); + Assert.That(result[99], Is.EqualTo(0.500050000f).Within(0.09f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestStudentTGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.StudentTNu1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestStudentTGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.StudentTNu1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestStudentTGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.StudentTNu1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestStudentTGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.StudentTNu1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.StudentTNu1(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.StudentTNu1(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/Uniform.cs b/FastRngTests/Distributions/Uniform.cs index 4a603ea..ca15280 100644 --- a/FastRngTests/Distributions/Uniform.cs +++ b/FastRngTests/Distributions/Uniform.cs @@ -5,293 +5,292 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class Uniform { - [ExcludeFromCodeCoverage] - public class Uniform + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestUniformDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestUniformDistribution01() + const float A = 0.0f; + const float B = 1.0f; + const float MEAN = 0.5f * (A + B); + const float VARIANCE = (1.0f / 12.0f) * (B - A) * (B - A); + + using var rng = new MultiThreadedRng(); + var stats = new RunningStatistics(); + var fra = new FrequencyAnalysis(); + + for (var n = 0; n < 100_000; n++) { - const float A = 0.0f; - const float B = 1.0f; - const float MEAN = 0.5f * (A + B); - const float VARIANCE = (1.0f / 12.0f) * (B - A) * (B - A); - - using var rng = new MultiThreadedRng(); - var stats = new RunningStatistics(); - var fra = new FrequencyAnalysis(); - - for (var n = 0; n < 100_000; n++) - { - var value = await rng.GetUniform(); - stats.Push(value); - fra.CountThis(value); - } - - fra.NormalizeAndPlotEvents(TestContext.WriteLine); - fra.PlotOccurence(TestContext.WriteLine); - TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}"); - TestContext.WriteLine($"variance={VARIANCE} vs {stats.Variance}"); - - Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01f), "Mean is out of range"); - Assert.That(stats.Variance, Is.EqualTo(VARIANCE).Within(0.001f), "Variance is out of range"); + var value = await rng.GetUniform(); + stats.Push(value); + fra.CountThis(value); } + + fra.NormalizeAndPlotEvents(TestContext.WriteLine); + fra.PlotOccurence(TestContext.WriteLine); + TestContext.WriteLine($"mean={MEAN} vs. {stats.Mean}"); + TestContext.WriteLine($"variance={VARIANCE} vs {stats.Variance}"); + + Assert.That(stats.Mean, Is.EqualTo(MEAN).Within(0.01f), "Mean is out of range"); + Assert.That(stats.Variance, Is.EqualTo(VARIANCE).Within(0.001f), "Variance is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task KolmogorovSmirnovTest() - { - // Kolmogorov-Smirnov test for distributions. - // See Knuth volume 2, page 48-51 (third edition). - // This test should *fail* on average one time in 1000 runs. - // That's life with random number generators: if the test passed all the time, - // the source wouldn't be random enough! If the test were to fail more frequently, - // the most likely explanation would be a bug in the code. + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task KolmogorovSmirnovTest() + { + // Kolmogorov-Smirnov test for distributions. + // See Knuth volume 2, page 48-51 (third edition). + // This test should *fail* on average one time in 1000 runs. + // That's life with random number generators: if the test passed all the time, + // the source wouldn't be random enough! If the test were to fail more frequently, + // the most likely explanation would be a bug in the code. - const int NUM_ROUNDS = 10_000; - const float FAILURE_PROBABILITY = 0.001f; // probability of test failing with normal distributed input - const float P_LOW = 0.25f * FAILURE_PROBABILITY; - const float P_HIGH = 1.0f - 0.25f * FAILURE_PROBABILITY; + const int NUM_ROUNDS = 10_000; + const float FAILURE_PROBABILITY = 0.001f; // probability of test failing with normal distributed input + const float P_LOW = 0.25f * FAILURE_PROBABILITY; + const float P_HIGH = 1.0f - 0.25f * FAILURE_PROBABILITY; - var samples = new float[NUM_ROUNDS]; - using var rng = new MultiThreadedRng(); - int n; + var samples = new float[NUM_ROUNDS]; + using var rng = new MultiThreadedRng(); + int n; - for (n = 0; n != NUM_ROUNDS; ++n) - samples[n] = await rng.GetUniform(); + for (n = 0; n != NUM_ROUNDS; ++n) + samples[n] = await rng.GetUniform(); - Array.Sort(samples); + Array.Sort(samples); - var jMinus = 0; - var jPlus = 0; - var kPlus = -float.MaxValue; - var kMinus = -float.MaxValue; + var jMinus = 0; + var jPlus = 0; + var kPlus = -float.MaxValue; + var kMinus = -float.MaxValue; - for (n = 0; n != NUM_ROUNDS; ++n) + for (n = 0; n != NUM_ROUNDS; ++n) + { + var cdf = samples[n]; + var temp = (n + 1.0f) / NUM_ROUNDS - cdf; + + if (kPlus < temp) { - var cdf = samples[n]; - var temp = (n + 1.0f) / NUM_ROUNDS - cdf; - - if (kPlus < temp) - { - kPlus = temp; - jPlus = n; - } - - temp = cdf - (n + 0.0f) / NUM_ROUNDS; - if (kMinus < temp) - { - kMinus = temp; - jMinus = n; - } + kPlus = temp; + jPlus = n; } + + temp = cdf - (n + 0.0f) / NUM_ROUNDS; + if (kMinus < temp) + { + kMinus = temp; + jMinus = n; + } + } - var sqrtNumReps = MathF.Sqrt(NUM_ROUNDS); - kPlus *= sqrtNumReps; - kMinus *= sqrtNumReps; + var sqrtNumReps = MathF.Sqrt(NUM_ROUNDS); + kPlus *= sqrtNumReps; + kMinus *= sqrtNumReps; - // We divide the failure probability by four because we have four tests: - // left and right tests for K+ and K-. - var cutoffLow = MathF.Sqrt(0.5f * MathF.Log(1.0f / (1.0f - P_LOW))) - 1.0f / (6.0f * sqrtNumReps); - var cutoffHigh = MathF.Sqrt(0.5f * MathF.Log(1.0f / (1.0f - P_HIGH))) - 1.0f / (6.0f * sqrtNumReps); + // We divide the failure probability by four because we have four tests: + // left and right tests for K+ and K-. + var cutoffLow = MathF.Sqrt(0.5f * MathF.Log(1.0f / (1.0f - P_LOW))) - 1.0f / (6.0f * sqrtNumReps); + var cutoffHigh = MathF.Sqrt(0.5f * MathF.Log(1.0f / (1.0f - P_HIGH))) - 1.0f / (6.0f * sqrtNumReps); - TestContext.WriteLine($"K+ = {kPlus} | K- = {kMinus}"); - TestContext.WriteLine($"K+ max at position {jPlus} = {samples[jPlus]}"); - TestContext.WriteLine($"K- max at position {jMinus} = {samples[jMinus]}"); - TestContext.WriteLine($"Acceptable interval: [{cutoffLow}, {cutoffHigh}]"); + TestContext.WriteLine($"K+ = {kPlus} | K- = {kMinus}"); + TestContext.WriteLine($"K+ max at position {jPlus} = {samples[jPlus]}"); + TestContext.WriteLine($"K- max at position {jMinus} = {samples[jMinus]}"); + TestContext.WriteLine($"Acceptable interval: [{cutoffLow}, {cutoffHigh}]"); - Assert.That(kPlus, Is.GreaterThanOrEqualTo(cutoffLow), "K+ is lower than low cutoff"); - Assert.That(kPlus, Is.LessThanOrEqualTo(cutoffHigh), "K+ is higher than high cutoff"); - Assert.That(kMinus, Is.GreaterThanOrEqualTo(cutoffLow), "K- is lower than low cutoff"); - Assert.That(kMinus, Is.LessThanOrEqualTo(cutoffHigh), "K- is lower than high cutoff"); - } + Assert.That(kPlus, Is.GreaterThanOrEqualTo(cutoffLow), "K+ is lower than low cutoff"); + Assert.That(kPlus, Is.LessThanOrEqualTo(cutoffHigh), "K+ is higher than high cutoff"); + Assert.That(kMinus, Is.GreaterThanOrEqualTo(cutoffLow), "K- is lower than low cutoff"); + Assert.That(kMinus, Is.LessThanOrEqualTo(cutoffHigh), "K- is lower than high cutoff"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestUniformGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.Uniform(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestUniformGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.Uniform(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestUniformGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - var dist = new FastRng.Distributions.Uniform(rng); - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestUniformGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + var dist = new FastRng.Distributions.Uniform(rng); + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestUniformGeneratorWithRange04() - { - using var rng = new MultiThreadedRng(); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await rng.GetUniform(); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestUniformGeneratorWithRange04() + { + using var rng = new MultiThreadedRng(); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await rng.GetUniform(); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange05Uint() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0, 100)]++; + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange05Uint() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0, 100)]++; - for (var n = 0; n < distribution.Length - 1; n++) - Assert.That(distribution[n], Is.GreaterThan(0)); - } + for (var n = 0; n < distribution.Length - 1; n++) + Assert.That(distribution[n], Is.GreaterThan(0)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange05Ulong() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0UL, 100)]++; + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange05Ulong() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0UL, 100)]++; - for (var n = 0; n < distribution.Length - 1; n++) - Assert.That(distribution[n], Is.GreaterThan(0)); - } + for (var n = 0; n < distribution.Length - 1; n++) + Assert.That(distribution[n], Is.GreaterThan(0)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange05Float() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange05Float() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; - for (var n = 0; n < distribution.Length - 1; n++) - Assert.That(distribution[n], Is.GreaterThan(0)); - } + for (var n = 0; n < distribution.Length - 1; n++) + Assert.That(distribution[n], Is.GreaterThan(0)); + } - [Test] - [Category(TestCategories.NORMAL)] - public async Task TestDistribution001Uint() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0, 100)]++; + [Test] + [Category(TestCategories.NORMAL)] + public async Task TestDistribution001Uint() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0, 100)]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); + } - [Test] - [Category(TestCategories.NORMAL)] - public async Task TestDistribution001Ulong() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0UL, 100)]++; + [Test] + [Category(TestCategories.NORMAL)] + public async Task TestDistribution001Ulong() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0UL, 100)]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); + } - [Test] - [Category(TestCategories.NORMAL)] - public async Task TestDistribution001Float() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 1_000_000; - for (var n = 0; n < runs; n++) - distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; + [Test] + [Category(TestCategories.NORMAL)] + public async Task TestDistribution001Float() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 1_000_000; + for (var n = 0; n < runs; n++) + distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 600)); + } - [Test] - [Category(TestCategories.LONG_RUNNING)] - public async Task TestDistribution002Uint() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 100_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0, 100)]++; + [Test] + [Category(TestCategories.LONG_RUNNING)] + public async Task TestDistribution002Uint() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 100_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0, 100)]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); + } - [Test] - [Category(TestCategories.LONG_RUNNING)] - public async Task TestDistribution002Ulong() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 100_000_000; - for (var n = 0; n < runs; n++) - distribution[await dist.NextNumber(0UL, 100)]++; + [Test] + [Category(TestCategories.LONG_RUNNING)] + public async Task TestDistribution002Ulong() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 100_000_000; + for (var n = 0; n < runs; n++) + distribution[await dist.NextNumber(0UL, 100)]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); + } - [Test] - [Category(TestCategories.LONG_RUNNING)] - public async Task TestDistribution002Float() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.Uniform(rng); - var distribution = new uint[101]; - var runs = 100_000_000; - for (var n = 0; n < runs; n++) - distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; + [Test] + [Category(TestCategories.LONG_RUNNING)] + public async Task TestDistribution002Float() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.Uniform(rng); + var distribution = new uint[101]; + var runs = 100_000_000; + for (var n = 0; n < runs; n++) + distribution[(uint)MathF.Floor(await dist.NextNumber(0.0f, 100.0f))]++; - Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); - } + Assert.That(distribution[..^1].Max() - distribution[..^1].Min(), Is.InRange(0, 6_000)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.Uniform(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.Uniform(null)); } } \ No newline at end of file diff --git a/FastRngTests/Distributions/WeibullK05La1.cs b/FastRngTests/Distributions/WeibullK05La1.cs index 06fca55..89fa45c 100644 --- a/FastRngTests/Distributions/WeibullK05La1.cs +++ b/FastRngTests/Distributions/WeibullK05La1.cs @@ -5,80 +5,79 @@ using System.Threading.Tasks; using FastRng; using NUnit.Framework; -namespace FastRngTests.Distributions +namespace FastRngTests.Distributions; + +[ExcludeFromCodeCoverage] +public class WeibullK05La1 { - [ExcludeFromCodeCoverage] - public class WeibullK05La1 + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestWeibullDistribution01() { - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestWeibullDistribution01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.WeibullK05La1(rng); - var fra = new FrequencyAnalysis(); + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.WeibullK05La1(rng); + var fra = new FrequencyAnalysis(); - for (var n = 0; n < 100_000; n++) - fra.CountThis(await dist.NextNumber()); + for (var n = 0; n < 100_000; n++) + fra.CountThis(await dist.NextNumber()); - var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); + var result = fra.NormalizeAndPlotEvents(TestContext.WriteLine); - Assert.That(result[0], Is.EqualTo(1.000000000f).Within(0.2f)); - Assert.That(result[1], Is.EqualTo(0.678415772f).Within(0.09f)); - Assert.That(result[2], Is.EqualTo(0.536595233f).Within(0.09f)); + Assert.That(result[0], Is.EqualTo(1.000000000f).Within(0.2f)); + Assert.That(result[1], Is.EqualTo(0.678415772f).Within(0.09f)); + Assert.That(result[2], Is.EqualTo(0.536595233f).Within(0.09f)); - Assert.That(result[21], Is.EqualTo(0.147406264f).Within(0.02f)); - Assert.That(result[22], Is.EqualTo(0.142654414f).Within(0.02f)); - Assert.That(result[23], Is.EqualTo(0.138217760f).Within(0.02f)); + Assert.That(result[21], Is.EqualTo(0.147406264f).Within(0.02f)); + Assert.That(result[22], Is.EqualTo(0.142654414f).Within(0.02f)); + Assert.That(result[23], Is.EqualTo(0.138217760f).Within(0.02f)); - Assert.That(result[50], Is.EqualTo(0.075769787f).Within(0.095f)); + Assert.That(result[50], Is.EqualTo(0.075769787f).Within(0.095f)); - Assert.That(result[75], Is.EqualTo(0.053016799f).Within(0.05f)); - Assert.That(result[85], Is.EqualTo(0.047144614f).Within(0.05f)); - Assert.That(result[90], Is.EqualTo(0.044629109f).Within(0.05f)); + Assert.That(result[75], Is.EqualTo(0.053016799f).Within(0.05f)); + Assert.That(result[85], Is.EqualTo(0.047144614f).Within(0.05f)); + Assert.That(result[90], Is.EqualTo(0.044629109f).Within(0.05f)); - Assert.That(result[97], Is.EqualTo(0.041484591f).Within(0.05f)); - Assert.That(result[98], Is.EqualTo(0.041067125f).Within(0.05f)); - Assert.That(result[99], Is.EqualTo(0.040656966f).Within(0.05f)); - } + Assert.That(result[97], Is.EqualTo(0.041484591f).Within(0.05f)); + Assert.That(result[98], Is.EqualTo(0.041067125f).Within(0.05f)); + Assert.That(result[99], Is.EqualTo(0.040656966f).Within(0.05f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestWeibullGeneratorWithRange01() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.WeibullK05La1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(-1.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestWeibullGeneratorWithRange01() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.WeibullK05La1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(-1.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(-1.0f), "Min out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestWeibullGeneratorWithRange02() - { - using var rng = new MultiThreadedRng(); - var dist = new FastRng.Distributions.WeibullK05La1(rng); - var samples = new float[1_000]; - for (var n = 0; n < samples.Length; n++) - samples[n] = await dist.NextNumber(0.0f, 1.0f); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestWeibullGeneratorWithRange02() + { + using var rng = new MultiThreadedRng(); + var dist = new FastRng.Distributions.WeibullK05La1(rng); + var samples = new float[1_000]; + for (var n = 0; n < samples.Length; n++) + samples[n] = await dist.NextNumber(0.0f, 1.0f); - Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); - Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); - } + Assert.That(samples.Min(), Is.GreaterThanOrEqualTo(0.0f), "Min is out of range"); + Assert.That(samples.Max(), Is.LessThanOrEqualTo(1.0f), "Max is out of range"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void NoRandomNumberGenerator01() - { - Assert.Throws(() => new FastRng.Distributions.WeibullK05La1(null)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void NoRandomNumberGenerator01() + { + Assert.Throws(() => new FastRng.Distributions.WeibullK05La1(null)); } } \ No newline at end of file diff --git a/FastRngTests/FrequencyAnalysis.cs b/FastRngTests/FrequencyAnalysis.cs index e0b4e7a..64c7b4d 100644 --- a/FastRngTests/FrequencyAnalysis.cs +++ b/FastRngTests/FrequencyAnalysis.cs @@ -3,82 +3,81 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +public sealed class FrequencyAnalysis { - [ExcludeFromCodeCoverage] - public sealed class FrequencyAnalysis + private readonly uint[] data; + + public FrequencyAnalysis(int samples = 100) { - private readonly uint[] data; - - public FrequencyAnalysis(int samples = 100) + this.data = new uint[samples]; + } + + public void CountThis(float value) + { + var bucket = (int)MathF.Floor(value * this.data.Length); + this.data[bucket]++; + } + + public float[] GetNormalizedEvents() + { + var max = (float) this.data.Max(); + var result = new float[this.data.Length]; + for (var n = 0; n < this.data.Length; n++) { - this.data = new uint[samples]; + result[n] = this.data[n] / max; } - public void CountThis(float value) - { - var bucket = (int)MathF.Floor(value * this.data.Length); - this.data[bucket]++; - } + return result; + } - public float[] GetNormalizedEvents() - { - var max = (float) this.data.Max(); - var result = new float[this.data.Length]; - for (var n = 0; n < this.data.Length; n++) - { - result[n] = this.data[n] / max; - } + private float[] Normalize() + { + var max = (float)this.data.Max(); + var result = new float[this.data.Length]; + for (var n = 0; n < this.data.Length; n++) + result[n] = this.data[n] / max; - return result; - } + return result; + } - private float[] Normalize() - { - var max = (float)this.data.Max(); - var result = new float[this.data.Length]; - for (var n = 0; n < this.data.Length; n++) - result[n] = this.data[n] / max; - - return result; - } - - public float[] NormalizeAndPlotEvents(Action writer) - { - var result = this.Normalize(); - FrequencyAnalysis.Plot(result, writer, "Event Distribution"); + public float[] NormalizeAndPlotEvents(Action writer) + { + var result = this.Normalize(); + Plot(result, writer, "Event Distribution"); - return result; - } + return result; + } - public void PlotOccurence(Action writer) + public void PlotOccurence(Action writer) + { + var data = this.data.Select(n => n > 0f ? 1.0f : 0.0f).ToArray(); + Plot(data, writer, "Occurrence Distribution"); + } + + private static void Plot(float[] data, Action writer, string name) + { + const int HEIGHT = 16; + + var values = new float[data.Length]; + for (var n = 0; n < data.Length; n++) { - var data = this.data.Select(n => n > 0f ? 1.0f : 0.0f).ToArray(); - FrequencyAnalysis.Plot(data, writer, "Occurrence Distribution"); + values[n] = data[n] * HEIGHT; } - private static void Plot(float[] data, Action writer, string name) + var sb = new StringBuilder(); + for (var line = HEIGHT; line > 0; line--) { - const int HEIGHT = 16; - - var values = new float[data.Length]; - for (var n = 0; n < data.Length; n++) - { - values[n] = data[n] * HEIGHT; - } - - var sb = new StringBuilder(); - for (var line = HEIGHT; line > 0; line--) - { - for (var column = 0; column < data.Length; column++) - sb.Append(values[column] >= line ? 'â–ˆ' : 'â–‘'); + for (var column = 0; column < data.Length; column++) + sb.Append(values[column] >= line ? 'â–ˆ' : 'â–‘'); - writer.Invoke(sb.ToString()); - sb.Clear(); - } - - writer.Invoke(name); - writer.Invoke(string.Empty); + writer.Invoke(sb.ToString()); + sb.Clear(); } + + writer.Invoke(name); + writer.Invoke(string.Empty); } } \ No newline at end of file diff --git a/FastRngTests/MathToolsTests.cs b/FastRngTests/MathToolsTests.cs index f32b25b..46d297e 100644 --- a/FastRngTests/MathToolsTests.cs +++ b/FastRngTests/MathToolsTests.cs @@ -3,339 +3,338 @@ using System.Diagnostics.CodeAnalysis; using FastRng; using NUnit.Framework; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +public class MathToolsTests { - [ExcludeFromCodeCoverage] - public class MathToolsTests + #region Gamma + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest01() { - #region Gamma - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest01() - { - Assert.That(MathTools.Gamma(-0.5f), Is.EqualTo(-3.544907701811087f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest02() - { - Assert.That(MathTools.Gamma(0.1f), Is.EqualTo(9.51350975f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest03() - { - Assert.That(MathTools.Gamma(0.5f), Is.EqualTo(1.772453850905517f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest04() - { - Assert.That(MathTools.Gamma(1.0f), Is.EqualTo(1.0f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest05() - { - Assert.That(MathTools.Gamma(1.5f), Is.EqualTo(0.8862269254527587f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest06() - { - Assert.That(MathTools.Gamma(2.0f), Is.EqualTo(1.0f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest07() - { - Assert.That(MathTools.Gamma(3.0f), Is.EqualTo(2.0f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest08() - { - Assert.That(MathTools.Gamma(10.0f), Is.EqualTo(362_880.719f).Within(1e-6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest09() - { - Assert.That(MathTools.Gamma(140.0f), Is.EqualTo(float.NaN)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void GammaTest10() - { - Assert.That(MathTools.Gamma(170.0f), Is.EqualTo(float.NaN)); - } - - #endregion - - #region Factorial (integer) - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger01() - { - Assert.That(MathTools.Factorial(0), Is.EqualTo(1)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger02() - { - Assert.That(MathTools.Factorial(1), Is.EqualTo(1)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger03() - { - Assert.That(MathTools.Factorial(2), Is.EqualTo(2)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger04() - { - Assert.That(MathTools.Factorial(3), Is.EqualTo(6)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger05() - { - Assert.That(MathTools.Factorial(4), Is.EqualTo(24)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger06() - { - Assert.That(MathTools.Factorial(5), Is.EqualTo(120)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger07() - { - Assert.That(MathTools.Factorial(6), Is.EqualTo(720)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger08() - { - Assert.That(MathTools.Factorial(7), Is.EqualTo(5_040)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger09() - { - Assert.That(MathTools.Factorial(8), Is.EqualTo(40_320)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger10() - { - Assert.That(MathTools.Factorial(9), Is.EqualTo(362_880)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger11() - { - Assert.That(MathTools.Factorial(10), Is.EqualTo(3_628_800)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger12() - { - Assert.That(MathTools.Factorial(11), Is.EqualTo(39_916_800)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger13() - { - Assert.That(MathTools.Factorial(12), Is.EqualTo(479_001_600)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger14() - { - Assert.That(MathTools.Factorial(13), Is.EqualTo(6_227_020_800)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger15() - { - Assert.That(MathTools.Factorial(14), Is.EqualTo(87_178_291_200)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger16() - { - Assert.That(MathTools.Factorial(15), Is.EqualTo(1_307_674_368_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger17() - { - Assert.That(MathTools.Factorial(16), Is.EqualTo(20_922_789_888_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger18() - { - Assert.That(MathTools.Factorial(17), Is.EqualTo(355_687_428_096_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger19() - { - Assert.That(MathTools.Factorial(18), Is.EqualTo(6_402_373_705_728_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger20() - { - Assert.That(MathTools.Factorial(19), Is.EqualTo(121_645_100_408_832_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger21() - { - Assert.That(MathTools.Factorial(20), Is.EqualTo(2_432_902_008_176_640_000)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger22() - { - Assert.Throws(() => MathTools.Factorial(21)); - - // Note: 21! is not possible in C# until we got 128 bit integers, since: - // ulong.max == 18_446_744_073_709_551_615 < 51_090_942_171_709_400_000 - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger23() - { - Assert.Throws(() => MathTools.Factorial(45_646)); - - // Note: 45_646! is not possible in C# since: - // ulong.max == 18_446_744_073_709_551_615 - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger24() - { - Assert.Throws(() => MathTools.Factorial(-1)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialInteger25() - { - Assert.Throws(() => MathTools.Factorial(-6_565)); - } - - #endregion - - #region Factorial (floating point) - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialFloatingPoint01() - { - Assert.That(MathTools.Factorial(0.5f), Is.EqualTo(0.886226925f).Within(1e6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialFloatingPoint02() - { - Assert.That(MathTools.Factorial(1.5f), Is.EqualTo(1.329340388f).Within(1e6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialFloatingPoint03() - { - Assert.That(MathTools.Factorial(-1.5f), Is.EqualTo(-1.329340388f).Within(1e6f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public void FactorialFloatingPoint04() - { - Assert.That(MathTools.Factorial(7.5f), Is.EqualTo(14_034.407293483f).Within(1e6f)); - } - - #endregion + Assert.That(MathTools.Gamma(-0.5f), Is.EqualTo(-3.544907701811087f).Within(1e-6f)); } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest02() + { + Assert.That(MathTools.Gamma(0.1f), Is.EqualTo(9.51350975f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest03() + { + Assert.That(MathTools.Gamma(0.5f), Is.EqualTo(1.772453850905517f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest04() + { + Assert.That(MathTools.Gamma(1.0f), Is.EqualTo(1.0f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest05() + { + Assert.That(MathTools.Gamma(1.5f), Is.EqualTo(0.8862269254527587f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest06() + { + Assert.That(MathTools.Gamma(2.0f), Is.EqualTo(1.0f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest07() + { + Assert.That(MathTools.Gamma(3.0f), Is.EqualTo(2.0f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest08() + { + Assert.That(MathTools.Gamma(10.0f), Is.EqualTo(362_880.719f).Within(1e-6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest09() + { + Assert.That(MathTools.Gamma(140.0f), Is.EqualTo(float.NaN)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void GammaTest10() + { + Assert.That(MathTools.Gamma(170.0f), Is.EqualTo(float.NaN)); + } + + #endregion + + #region Factorial (integer) + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger01() + { + Assert.That(MathTools.Factorial(0), Is.EqualTo(1)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger02() + { + Assert.That(MathTools.Factorial(1), Is.EqualTo(1)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger03() + { + Assert.That(MathTools.Factorial(2), Is.EqualTo(2)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger04() + { + Assert.That(MathTools.Factorial(3), Is.EqualTo(6)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger05() + { + Assert.That(MathTools.Factorial(4), Is.EqualTo(24)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger06() + { + Assert.That(MathTools.Factorial(5), Is.EqualTo(120)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger07() + { + Assert.That(MathTools.Factorial(6), Is.EqualTo(720)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger08() + { + Assert.That(MathTools.Factorial(7), Is.EqualTo(5_040)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger09() + { + Assert.That(MathTools.Factorial(8), Is.EqualTo(40_320)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger10() + { + Assert.That(MathTools.Factorial(9), Is.EqualTo(362_880)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger11() + { + Assert.That(MathTools.Factorial(10), Is.EqualTo(3_628_800)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger12() + { + Assert.That(MathTools.Factorial(11), Is.EqualTo(39_916_800)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger13() + { + Assert.That(MathTools.Factorial(12), Is.EqualTo(479_001_600)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger14() + { + Assert.That(MathTools.Factorial(13), Is.EqualTo(6_227_020_800)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger15() + { + Assert.That(MathTools.Factorial(14), Is.EqualTo(87_178_291_200)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger16() + { + Assert.That(MathTools.Factorial(15), Is.EqualTo(1_307_674_368_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger17() + { + Assert.That(MathTools.Factorial(16), Is.EqualTo(20_922_789_888_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger18() + { + Assert.That(MathTools.Factorial(17), Is.EqualTo(355_687_428_096_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger19() + { + Assert.That(MathTools.Factorial(18), Is.EqualTo(6_402_373_705_728_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger20() + { + Assert.That(MathTools.Factorial(19), Is.EqualTo(121_645_100_408_832_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger21() + { + Assert.That(MathTools.Factorial(20), Is.EqualTo(2_432_902_008_176_640_000)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger22() + { + Assert.Throws(() => MathTools.Factorial(21)); + + // Note: 21! is not possible in C# until we got 128 bit integers, since: + // ulong.max == 18_446_744_073_709_551_615 < 51_090_942_171_709_400_000 + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger23() + { + Assert.Throws(() => MathTools.Factorial(45_646)); + + // Note: 45_646! is not possible in C# since: + // ulong.max == 18_446_744_073_709_551_615 + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger24() + { + Assert.Throws(() => MathTools.Factorial(-1)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialInteger25() + { + Assert.Throws(() => MathTools.Factorial(-6_565)); + } + + #endregion + + #region Factorial (floating point) + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialFloatingPoint01() + { + Assert.That(MathTools.Factorial(0.5f), Is.EqualTo(0.886226925f).Within(1e6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialFloatingPoint02() + { + Assert.That(MathTools.Factorial(1.5f), Is.EqualTo(1.329340388f).Within(1e6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialFloatingPoint03() + { + Assert.That(MathTools.Factorial(-1.5f), Is.EqualTo(-1.329340388f).Within(1e6f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public void FactorialFloatingPoint04() + { + Assert.That(MathTools.Factorial(7.5f), Is.EqualTo(14_034.407293483f).Within(1e6f)); + } + + #endregion } \ No newline at end of file diff --git a/FastRngTests/MultiThreadedRngTests.cs b/FastRngTests/MultiThreadedRngTests.cs index 8924fd3..280aac6 100644 --- a/FastRngTests/MultiThreadedRngTests.cs +++ b/FastRngTests/MultiThreadedRngTests.cs @@ -6,620 +6,619 @@ using FastRng; using FastRng.Distributions; using NUnit.Framework; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +public class MultiThreadedRngTests { - [ExcludeFromCodeCoverage] - public class MultiThreadedRngTests + private readonly IRandom rng = new MultiThreadedRng(); + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange01Uint() { - private readonly IRandom rng = new MultiThreadedRng(); + var dist = new Uniform(this.rng); + for (uint n = 0; n < 1_000_000; n++) + Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange01Uint() - { - var dist = new Uniform(this.rng); - for (uint n = 0; n < 1_000_000; n++) - Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange01Ulong() + { + var dist = new Uniform(this.rng); + for (ulong n = 0; n < 1_000_000; n++) + Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange01Ulong() - { - var dist = new Uniform(this.rng); - for (ulong n = 0; n < 1_000_000; n++) - Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange01Float() + { + var dist = new Uniform(this.rng); + for (var n = 0.0f; n < 1e6f; n++) + Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange01Float() - { - var dist = new Uniform(this.rng); - for (var n = 0.0f; n < 1e6f; n++) - Assert.That(await dist.NextNumber(n, 100_000 + n), Is.InRange(n, 100_000 + n)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange02Uint() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5, 5), Is.EqualTo(5)); + Assert.That(await dist.NextNumber(0, 0), Is.EqualTo(0)); + Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_000), Is.EqualTo(3_000_000_000)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange02Uint() - { - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(5, 5), Is.EqualTo(5)); - Assert.That(await dist.NextNumber(0, 0), Is.EqualTo(0)); - Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_000), Is.EqualTo(3_000_000_000)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange02Ulong() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5UL, 5), Is.EqualTo(5)); + Assert.That(await dist.NextNumber(0UL, 0), Is.EqualTo(0)); + Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_000), Is.EqualTo(3_000_000_000)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange02Ulong() - { - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(5UL, 5), Is.EqualTo(5)); - Assert.That(await dist.NextNumber(0UL, 0), Is.EqualTo(0)); - Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_000), Is.EqualTo(3_000_000_000)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange02Float() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5f, 5f), Is.EqualTo(5)); + Assert.That(await dist.NextNumber(0f, 0f), Is.EqualTo(0)); + Assert.That(await dist.NextNumber(3e9f, 3e9f), Is.EqualTo(3e9f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange02Float() - { - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(5f, 5f), Is.EqualTo(5)); - Assert.That(await dist.NextNumber(0f, 0f), Is.EqualTo(0)); - Assert.That(await dist.NextNumber(3e9f, 3e9f), Is.EqualTo(3e9f)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange03Uint() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5, 6), Is.InRange(5, 6)); + Assert.That(await dist.NextNumber(0, 1), Is.InRange(0, 1)); + Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange03Uint() - { - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(5, 6), Is.InRange(5, 6)); - Assert.That(await dist.NextNumber(0, 1), Is.InRange(0, 1)); - Assert.That(await dist.NextNumber(3_000_000_000, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange03Ulong() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5UL, 6), Is.InRange(5, 6)); + Assert.That(await dist.NextNumber(0UL, 1), Is.InRange(0, 1)); + Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange03Ulong() - { - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(5UL, 6), Is.InRange(5, 6)); - Assert.That(await dist.NextNumber(0UL, 1), Is.InRange(0, 1)); - Assert.That(await dist.NextNumber(3_000_000_000UL, 3_000_000_002), Is.InRange(3_000_000_000, 3_000_000_002)); - } + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange03Float() + { + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(5f, 6f), Is.InRange(5f, 6f)); + Assert.That(await dist.NextNumber(0f, 1f), Is.InRange(0f, 1f)); + Assert.That(await dist.NextNumber(3e9f, 3e9f+2f), Is.InRange(3e9f, 3e9f+2f)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange03Float() - { - var dist = new Uniform(this.rng); - 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(3e9f, 3e9f+2f), Is.InRange(3e9f, 3e9f+2f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange04Uint() - { - var distUniform = new Uniform(this.rng); - var distNormal = new NormalS02M05(this.rng); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange04Uint() + { + var distUniform = new Uniform(this.rng); + var distNormal = new NormalS02M05(this.rng); - Assert.That(await distUniform.NextNumber(10, 1), Is.InRange(1, 10)); - Assert.That(await distNormal.NextNumber(10, 1), Is.InRange(1, 10)); + Assert.That(await distUniform.NextNumber(10, 1), Is.InRange(1, 10)); + Assert.That(await distNormal.NextNumber(10, 1), Is.InRange(1, 10)); - Assert.That(await distUniform.NextNumber(20, 1), Is.InRange(1, 20)); - Assert.That(await distNormal.NextNumber(20, 1), Is.InRange(1, 20)); - } + Assert.That(await distUniform.NextNumber(20, 1), Is.InRange(1, 20)); + Assert.That(await distNormal.NextNumber(20, 1), Is.InRange(1, 20)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange04Ulong() - { - var distUniform = new Uniform(this.rng); - var distNormal = new NormalS02M05(this.rng); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange04Ulong() + { + var distUniform = new Uniform(this.rng); + var distNormal = new NormalS02M05(this.rng); - Assert.That(await distUniform.NextNumber(10UL, 1), Is.InRange(1, 10)); - Assert.That(await distNormal.NextNumber(10UL, 1), Is.InRange(1, 10)); + Assert.That(await distUniform.NextNumber(10UL, 1), Is.InRange(1, 10)); + Assert.That(await distNormal.NextNumber(10UL, 1), Is.InRange(1, 10)); - Assert.That(await distUniform.NextNumber(20UL, 1), Is.InRange(1, 20)); - Assert.That(await distNormal.NextNumber(20UL, 1), Is.InRange(1, 20)); - } + Assert.That(await distUniform.NextNumber(20UL, 1), Is.InRange(1, 20)); + Assert.That(await distNormal.NextNumber(20UL, 1), Is.InRange(1, 20)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestRange04Float() - { - var distUniform = new Uniform(this.rng); - var distNormal = new NormalS02M05(this.rng); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestRange04Float() + { + var distUniform = new Uniform(this.rng); + var distNormal = new NormalS02M05(this.rng); - Assert.That(await distUniform.NextNumber(10.0f, 1), Is.InRange(1, 10)); - Assert.That(await distNormal.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 distUniform.NextNumber(20.0f, 1), Is.InRange(1, 20)); - Assert.That(await distNormal.NextNumber(20.0f, 1), Is.InRange(1, 20)); - } + Assert.That(await distUniform.NextNumber(20.0f, 1), Is.InRange(1, 20)); + Assert.That(await distNormal.NextNumber(20.0f, 1), Is.InRange(1, 20)); + } - [Test] - [Category(TestCategories.LONG_RUNNING)] - public async Task TestRange05() - { - var distUniform = new Uniform(this.rng); - var distLorentz = new CauchyLorentzX1(this.rng); + [Test] + [Category(TestCategories.LONG_RUNNING)] + public async Task TestRange05() + { + var distUniform = new Uniform(this.rng); + var distLorentz = new CauchyLorentzX1(this.rng); - var rngContains0 = false; - var rngContains1 = false; + var rngContains0 = false; + var rngContains1 = false; - var uniformContains0 = false; - var uniformContains1 = false; + var uniformContains0 = false; + var uniformContains1 = false; - var lorentzContains0 = false; - var lorentzContains1 = false; + var lorentzContains0 = false; + var lorentzContains1 = false; - for (int i = 0; i < 100_000_000; i++) + for (int i = 0; i < 100_000_000; i++) + { + var rngValue = await this.rng.GetUniform(); + var uniform = await distUniform.NextNumber(); + var lorentz = await distLorentz.NextNumber(); + + switch (rngValue) { - var rngValue = await this.rng.GetUniform(); - var uniform = await distUniform.NextNumber(); - var lorentz = await distLorentz.NextNumber(); - - switch (rngValue) - { - case 0.0f: - rngContains0 = true; - break; - case 1.0f: - rngContains1 = true; - break; - } - - switch (uniform) - { - case 0.0f: - uniformContains0 = true; - break; - case 1.0f: - uniformContains1 = true; - break; - } - - switch (lorentz) - { - case 0.0f: - lorentzContains0 = true; - break; - case 1.0f: - lorentzContains1 = true; - break; - } + case 0.0f: + rngContains0 = true; + break; + case 1.0f: + rngContains1 = true; + break; } - - TestContext.WriteLine($"Uniform generator contained 0? {rngContains0} (expected=false)"); - TestContext.WriteLine($"Uniform generator contained 1? {rngContains1} (expected=true)"); - TestContext.WriteLine($"Uniform distribution contained 0? {uniformContains0} (expected=false)"); - TestContext.WriteLine($"Uniform distribution contained 1? {uniformContains1} (expected=true)"); - TestContext.WriteLine($"Lorentz distribution contained 0? {lorentzContains0} (expected=false)"); - TestContext.WriteLine($"Lorentz distribution contained 1? {lorentzContains1} (expected=true)"); - - Assert.That(rngContains0, Is.False, "Uniform generator contained 0"); - Assert.That(rngContains1, Is.True, "Uniform generator does not contained 1"); - - Assert.That(uniformContains0, Is.False, "Uniform distribution contained 0"); - Assert.That(uniformContains1, Is.True, "Uniform distribution does not contained 1"); - - Assert.That(lorentzContains0, Is.False, "Lorentz distribution contained 0"); - Assert.That(lorentzContains1, Is.True, "Lorentz distribution does not contained 1"); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestStoppingProducers01() - { - var rng2 = new MultiThreadedRng(); - rng2.Dispose(); - - var masterToken = new CancellationTokenSource(TimeSpan.FromSeconds(16)).Token; - var wasCanceled = false; - - while(true) + + switch (uniform) { - var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - await rng2.GetUniform(tokenSource.Token); - if (tokenSource.IsCancellationRequested) - { - wasCanceled = true; + case 0.0f: + uniformContains0 = true; break; - } - - if (masterToken.IsCancellationRequested) - { + case 1.0f: + uniformContains1 = true; + break; + } + + switch (lorentz) + { + case 0.0f: + lorentzContains0 = true; + break; + case 1.0f: + lorentzContains1 = true; break; - } } - - Assert.That(masterToken.IsCancellationRequested, Is.False, "Master token was used to stop test"); - Assert.That(wasCanceled, Is.True, "The consumer was not canceled"); - - var tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - await new NormalS02M05(rng2).NextNumber(tokenSource2.Token); - Assert.That(tokenSource2.IsCancellationRequested, Is.True); - - tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - await new NormalS02M05(rng2).NextNumber(-1f, 1f, tokenSource2.Token); - Assert.That(tokenSource2.IsCancellationRequested, Is.True); - - tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - await new NormalS02M05(rng2).NextNumber(0u, 6u, tokenSource2.Token); - Assert.That(tokenSource2.IsCancellationRequested, Is.True); - - tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - await new NormalS02M05(rng2).NextNumber(0ul, 6ul, tokenSource2.Token); - Assert.That(tokenSource2.IsCancellationRequested, Is.True); } + + TestContext.WriteLine($"Uniform generator contained 0? {rngContains0} (expected=false)"); + TestContext.WriteLine($"Uniform generator contained 1? {rngContains1} (expected=true)"); + TestContext.WriteLine($"Uniform distribution contained 0? {uniformContains0} (expected=false)"); + TestContext.WriteLine($"Uniform distribution contained 1? {uniformContains1} (expected=true)"); + TestContext.WriteLine($"Lorentz distribution contained 0? {lorentzContains0} (expected=false)"); + TestContext.WriteLine($"Lorentz distribution contained 1? {lorentzContains1} (expected=true)"); + + Assert.That(rngContains0, Is.False, "Uniform generator contained 0"); + Assert.That(rngContains1, Is.True, "Uniform generator does not contained 1"); + + Assert.That(uniformContains0, Is.False, "Uniform distribution contained 0"); + Assert.That(uniformContains1, Is.True, "Uniform distribution does not contained 1"); + + Assert.That(lorentzContains0, Is.False, "Lorentz distribution contained 0"); + Assert.That(lorentzContains1, Is.True, "Lorentz distribution does not contained 1"); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task OneSeed01() - { - using var rng1 = new MultiThreadedRng(6); - using var rng2 = new MultiThreadedRng(6); - using var rng3 = new MultiThreadedRng(7); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestStoppingProducers01() + { + var rng2 = new MultiThreadedRng(); + rng2.Dispose(); - var rng1Sample = new float[10]; - for (var n = 0; n < rng1Sample.Length; n++) - rng1Sample[n] = await rng1.GetUniform(); + var masterToken = new CancellationTokenSource(TimeSpan.FromSeconds(16)).Token; + var wasCanceled = false; - var rng2Sample = new float[10]; - for (var n = 0; n < rng2Sample.Length; n++) - rng2Sample[n] = await rng2.GetUniform(); - - var rng3Sample = new float[10]; - for (var n = 0; n < rng3Sample.Length; n++) - rng3Sample[n] = await rng3.GetUniform(); + while(true) + { + var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await rng2.GetUniform(tokenSource.Token); + if (tokenSource.IsCancellationRequested) + { + wasCanceled = true; + break; + } - Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample)); - Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); - Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); + if (masterToken.IsCancellationRequested) + { + break; + } } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TwoSeeds01() - { - using var rng1 = new MultiThreadedRng(3, 6); - using var rng2 = new MultiThreadedRng(3, 6); - using var rng3 = new MultiThreadedRng(3, 7); - using var rng4 = new MultiThreadedRng(6, 3); + + Assert.That(masterToken.IsCancellationRequested, Is.False, "Master token was used to stop test"); + Assert.That(wasCanceled, Is.True, "The consumer was not canceled"); + + var tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await new NormalS02M05(rng2).NextNumber(tokenSource2.Token); + Assert.That(tokenSource2.IsCancellationRequested, Is.True); + + tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await new NormalS02M05(rng2).NextNumber(-1f, 1f, tokenSource2.Token); + Assert.That(tokenSource2.IsCancellationRequested, Is.True); + + tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await new NormalS02M05(rng2).NextNumber(0u, 6u, tokenSource2.Token); + Assert.That(tokenSource2.IsCancellationRequested, Is.True); + + tokenSource2 = new CancellationTokenSource(TimeSpan.FromSeconds(3)); + await new NormalS02M05(rng2).NextNumber(0ul, 6ul, tokenSource2.Token); + Assert.That(tokenSource2.IsCancellationRequested, Is.True); + } - var rng1Sample = new float[10]; - for (var n = 0; n < rng1Sample.Length; n++) - rng1Sample[n] = await rng1.GetUniform(); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task OneSeed01() + { + using var rng1 = new MultiThreadedRng(6); + using var rng2 = new MultiThreadedRng(6); + using var rng3 = new MultiThreadedRng(7); - var rng2Sample = new float[10]; - for (var n = 0; n < rng2Sample.Length; n++) - rng2Sample[n] = await rng2.GetUniform(); + var rng1Sample = new float[10]; + for (var n = 0; n < rng1Sample.Length; n++) + rng1Sample[n] = await rng1.GetUniform(); - var rng3Sample = new float[10]; - for (var n = 0; n < rng3Sample.Length; n++) - rng3Sample[n] = await rng3.GetUniform(); + var rng2Sample = new float[10]; + for (var n = 0; n < rng2Sample.Length; n++) + rng2Sample[n] = await rng2.GetUniform(); - var rng4Sample = new float[10]; - for (var n = 0; n < rng4Sample.Length; n++) - rng4Sample[n] = await rng4.GetUniform(); + var rng3Sample = new float[10]; + for (var n = 0; n < rng3Sample.Length; n++) + rng3Sample[n] = await rng3.GetUniform(); - Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample)); - Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); - Assert.That(rng1Sample, Is.Not.EquivalentTo(rng4Sample)); - Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); - Assert.That(rng2Sample, Is.Not.EquivalentTo(rng4Sample)); - Assert.That(rng3Sample, Is.Not.EquivalentTo(rng4Sample)); - } + Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample)); + Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); + Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task NoSeed01() - { - using var rng1 = new MultiThreadedRng(); - using var rng2 = new MultiThreadedRng(); - using var rng3 = new MultiThreadedRng(); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TwoSeeds01() + { + using var rng1 = new MultiThreadedRng(3, 6); + using var rng2 = new MultiThreadedRng(3, 6); + using var rng3 = new MultiThreadedRng(3, 7); + using var rng4 = new MultiThreadedRng(6, 3); - var rng1Sample = new float[10]; - for (var n = 0; n < rng1Sample.Length; n++) - rng1Sample[n] = await rng1.GetUniform(); - - var rng2Sample = new float[10]; - for (var n = 0; n < rng2Sample.Length; n++) - rng2Sample[n] = await rng2.GetUniform(); - - var rng3Sample = new float[10]; - for (var n = 0; n < rng3Sample.Length; n++) - rng3Sample[n] = await rng3.GetUniform(); + var rng1Sample = new float[10]; + for (var n = 0; n < rng1Sample.Length; n++) + rng1Sample[n] = await rng1.GetUniform(); - Assert.That(rng1Sample, Is.Not.EquivalentTo(rng2Sample)); - Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); - Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCancellation01() - { - var tokenSource = new CancellationTokenSource(); - var token = tokenSource.Token; - tokenSource.Cancel(); + var rng2Sample = new float[10]; + for (var n = 0; n < rng2Sample.Length; n++) + rng2Sample[n] = await rng2.GetUniform(); - using var rng2 = new MultiThreadedRng(); - var dist = new Uniform(this.rng); - Assert.That(await dist.NextNumber(1, 100_000, token), Is.EqualTo(0)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestCancellation02() - { - var tokenSource = new CancellationTokenSource(); - var token = tokenSource.Token; - tokenSource.Cancel(); + var rng3Sample = new float[10]; + for (var n = 0; n < rng3Sample.Length; n++) + rng3Sample[n] = await rng3.GetUniform(); - using var rng2 = new MultiThreadedRng(); - Assert.That(await rng2.GetUniform(token), Is.NaN); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic01() - { - using var rng2 = new MultiThreadedRng(16); - - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic02() - { - using var rng2 = new MultiThreadedRng(16); - var dist = new Uniform(rng2); - - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic03() - { - using var rng2 = new MultiThreadedRng(16); - var dist = new CauchyLorentzX0(rng2); + var rng4Sample = new float[10]; + for (var n = 0; n < rng4Sample.Length; n++) + rng4Sample[n] = await rng4.GetUniform(); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); - } + Assert.That(rng1Sample, Is.EquivalentTo(rng2Sample)); + Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); + Assert.That(rng1Sample, Is.Not.EquivalentTo(rng4Sample)); + Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); + Assert.That(rng2Sample, Is.Not.EquivalentTo(rng4Sample)); + Assert.That(rng3Sample, Is.Not.EquivalentTo(rng4Sample)); + } - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic01b() - { - using var rng2 = new MultiThreadedRng(16, 362_436_069); - - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f)); - Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic02b() - { - using var rng2 = new MultiThreadedRng(16, 362_436_069); - var dist = new Uniform(rng2); - - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83)); - } - - [Test] - [Category(TestCategories.COVER)] - [Category(TestCategories.NORMAL)] - public async Task TestDeterministic03b() - { - using var rng2 = new MultiThreadedRng(16, 362_436_069); - var dist = new CauchyLorentzX0(rng2); + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task NoSeed01() + { + using var rng1 = new MultiThreadedRng(); + using var rng2 = new MultiThreadedRng(); + using var rng3 = new MultiThreadedRng(); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); - Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); - } + var rng1Sample = new float[10]; + for (var n = 0; n < rng1Sample.Length; n++) + rng1Sample[n] = await rng1.GetUniform(); + + var rng2Sample = new float[10]; + for (var n = 0; n < rng2Sample.Length; n++) + rng2Sample[n] = await rng2.GetUniform(); + + var rng3Sample = new float[10]; + for (var n = 0; n < rng3Sample.Length; n++) + rng3Sample[n] = await rng3.GetUniform(); + + Assert.That(rng1Sample, Is.Not.EquivalentTo(rng2Sample)); + Assert.That(rng1Sample, Is.Not.EquivalentTo(rng3Sample)); + Assert.That(rng2Sample, Is.Not.EquivalentTo(rng3Sample)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCancellation01() + { + var tokenSource = new CancellationTokenSource(); + var token = tokenSource.Token; + tokenSource.Cancel(); + + using var rng2 = new MultiThreadedRng(); + var dist = new Uniform(this.rng); + Assert.That(await dist.NextNumber(1, 100_000, token), Is.EqualTo(0)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestCancellation02() + { + var tokenSource = new CancellationTokenSource(); + var token = tokenSource.Token; + tokenSource.Cancel(); + + using var rng2 = new MultiThreadedRng(); + Assert.That(await rng2.GetUniform(token), Is.NaN); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic01() + { + using var rng2 = new MultiThreadedRng(16); + + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic02() + { + using var rng2 = new MultiThreadedRng(16); + var dist = new Uniform(rng2); + + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic03() + { + using var rng2 = new MultiThreadedRng(16); + var dist = new CauchyLorentzX0(rng2); + + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic01b() + { + using var rng2 = new MultiThreadedRng(16, 362_436_069); + + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12712699).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.5764246).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.06033641).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.6822646).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.61201024).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.17746393).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.33456334).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.96167856).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.12944269).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.64489424).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.109665975).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.18188846).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.36097932).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.48192585).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.1617974).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.24791045).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.43913218).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.3343723).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9428737).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55195147).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.027495692).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.9621458).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.55794334).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.69002056).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.86020225).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.88220626).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.68816894).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.8583311).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.003915685).Within(1e-7f)); + Assert.That(await rng2.GetUniform(), Is.EqualTo(0.83575225).Within(1e-7f)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic02b() + { + using var rng2 = new MultiThreadedRng(16, 362_436_069); + var dist = new Uniform(rng2); + + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(58)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(6)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(68)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(61)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(13)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(64)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(36)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(48)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(25)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(44)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(34)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(94)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(55)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(96)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(86)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(88)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(69)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(85)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(83)); + } + + [Test] + [Category(TestCategories.COVER)] + [Category(TestCategories.NORMAL)] + public async Task TestDeterministic03b() + { + using var rng2 = new MultiThreadedRng(16, 362_436_069); + var dist = new CauchyLorentzX0(rng2); + + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(17)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(18)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(14)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(65)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(11)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(37)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(12)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(8)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(22)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(3)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(20)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(84)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(9)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(19)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(2)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(1)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(10)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(4)); + Assert.That(await dist.NextNumber(1, 100), Is.EqualTo(56)); } } \ No newline at end of file diff --git a/FastRngTests/PerformanceTests.cs b/FastRngTests/PerformanceTests.cs index f086117..6226945 100644 --- a/FastRngTests/PerformanceTests.cs +++ b/FastRngTests/PerformanceTests.cs @@ -9,129 +9,128 @@ using MathNet.Numerics.Distributions; using MathNet.Numerics.Random; using NUnit.Framework; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +public class PerformanceTests { - [ExcludeFromCodeCoverage] - public class PerformanceTests + #region FastRng + + [Test] + [Category(TestCategories.PERFORMANCE)] + public async Task Generate1MUniform() { - #region FastRng + using var rng = new MultiThreadedRng(); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = await rng.GetUniform(); + + stopwatch.Stop(); - [Test] - [Category(TestCategories.PERFORMANCE)] - public async Task Generate1MUniform() - { - using var rng = new MultiThreadedRng(); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = await rng.GetUniform(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M uniform distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - [Test] - [Category(TestCategories.PERFORMANCE)] - public async Task Generate1MNormal() - { - using var rng = new MultiThreadedRng(); - var dist = new NormalS02M05(rng); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = await dist.NextNumber(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M normal distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - [Test] - [Category(TestCategories.PERFORMANCE)] - public async Task Generate1MChiSquare() - { - using var rng = new MultiThreadedRng(); - var dist = new ChiSquareK4(rng); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = await dist.NextNumber(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M chi-square distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - #endregion - - #region Math.NET - - [Test] - [Category(TestCategories.PERFORMANCE)] - public void ComparisonMathNet1MUniform() - { - var rng = new Xorshift(true); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = (float) rng.NextDouble(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M uniform distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - [Test] - [Category(TestCategories.PERFORMANCE)] - public void ComparisonMathNet1MNormal() - { - var rng = new Xorshift(true); - var dist = new Normal(stddev: 0.2f, mean: 0.5f, randomSource: rng); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = (float) dist.Sample(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M normal distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - [Test] - [Category(TestCategories.PERFORMANCE)] - public void ComparisonMathNet1MChiSquare() - { - var rng = new Xorshift(true); - var dist = new ChiSquared(4); - var data = new float[1_000_000]; - var stopwatch = new Stopwatch(); - Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator - - stopwatch.Start(); - for (uint n = 0; n < data.Length; n++) - data[n] = (float) dist.Sample(); - - stopwatch.Stop(); - - TestContext.WriteLine($"Generated 1M chi-squared distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); - } - - #endregion + TestContext.WriteLine($"Generated 1M uniform distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); } + + [Test] + [Category(TestCategories.PERFORMANCE)] + public async Task Generate1MNormal() + { + using var rng = new MultiThreadedRng(); + var dist = new NormalS02M05(rng); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = await dist.NextNumber(); + + stopwatch.Stop(); + + TestContext.WriteLine($"Generated 1M normal distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); + } + + [Test] + [Category(TestCategories.PERFORMANCE)] + public async Task Generate1MChiSquare() + { + using var rng = new MultiThreadedRng(); + var dist = new ChiSquareK4(rng); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = await dist.NextNumber(); + + stopwatch.Stop(); + + TestContext.WriteLine($"Generated 1M chi-square distributed random numbers in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); + } + + #endregion + + #region Math.NET + + [Test] + [Category(TestCategories.PERFORMANCE)] + public void ComparisonMathNet1MUniform() + { + var rng = new Xorshift(true); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = (float) rng.NextDouble(); + + stopwatch.Stop(); + + TestContext.WriteLine($"Generated 1M uniform distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); + } + + [Test] + [Category(TestCategories.PERFORMANCE)] + public void ComparisonMathNet1MNormal() + { + var rng = new Xorshift(true); + var dist = new Normal(stddev: 0.2f, mean: 0.5f, randomSource: rng); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = (float) dist.Sample(); + + stopwatch.Stop(); + + TestContext.WriteLine($"Generated 1M normal distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); + } + + [Test] + [Category(TestCategories.PERFORMANCE)] + public void ComparisonMathNet1MChiSquare() + { + var rng = new Xorshift(true); + var dist = new ChiSquared(4); + var data = new float[1_000_000]; + var stopwatch = new Stopwatch(); + Thread.Sleep(TimeSpan.FromSeconds(10)); // Warm-up phase of generator + + stopwatch.Start(); + for (uint n = 0; n < data.Length; n++) + data[n] = (float) dist.Sample(); + + stopwatch.Stop(); + + TestContext.WriteLine($"Generated 1M chi-squared distributed random numbers by means of Math.NET in {stopwatch.Elapsed.Minutes} minute(s), {stopwatch.Elapsed.Seconds} second(s), and {stopwatch.Elapsed.Milliseconds} milliseconds."); + } + + #endregion } \ No newline at end of file diff --git a/FastRngTests/RunningStatistics.cs b/FastRngTests/RunningStatistics.cs index afe9626..3bd51fe 100644 --- a/FastRngTests/RunningStatistics.cs +++ b/FastRngTests/RunningStatistics.cs @@ -1,49 +1,44 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace FastRngTests +namespace FastRngTests; + +[ExcludeFromCodeCoverage] +internal sealed class RunningStatistics { - [ExcludeFromCodeCoverage] - internal sealed class RunningStatistics - { - private float previousM; - private float previousS; - private float nextM; - private float nextS; - - public RunningStatistics() - { - } - - public int NumberRecords { get; private set; } = 0; + private float previousM; + private float previousS; + private float nextM; + private float nextS; + + private int NumberRecords { get; set; } = 0; - public void Clear() => this.NumberRecords = 0; + public void Clear() => this.NumberRecords = 0; - public void Push(float x) - { - this.NumberRecords++; + public void Push(float x) + { + this.NumberRecords++; - // See Knuth TAOCP vol 2, 3rd edition, page 232 - if (this.NumberRecords == 1) - { - this.previousM = this.nextM = x; - this.previousS = 0.0f; - } - else - { - this.nextM = this.previousM + (x - this.previousM) / this.NumberRecords; - this.nextS = this.previousS + (x - this.previousM) * (x - this.nextM); - - // set up for next iteration - this.previousM = this.nextM; - this.previousS = this.nextS; - } + // See Knuth TAOCP vol 2, 3rd edition, page 232 + if (this.NumberRecords == 1) + { + this.previousM = this.nextM = x; + this.previousS = 0.0f; + } + else + { + this.nextM = this.previousM + (x - this.previousM) / this.NumberRecords; + this.nextS = this.previousS + (x - this.previousM) * (x - this.nextM); + + // set up for next iteration + this.previousM = this.nextM; + this.previousS = this.nextS; } - - public float Mean => this.NumberRecords > 0 ? this.nextM : 0.0f; - - public float Variance => this.NumberRecords > 1 ? this.nextS / (this.NumberRecords - 1f) : 0.0f; - - public float StandardDeviation => MathF.Sqrt(this.Variance); } + + public float Mean => this.NumberRecords > 0 ? this.nextM : 0.0f; + + public float Variance => this.NumberRecords > 1 ? this.nextS / (this.NumberRecords - 1f) : 0.0f; + + public float StandardDeviation => MathF.Sqrt(this.Variance); } \ No newline at end of file diff --git a/FastRngTests/TestCategories.cs b/FastRngTests/TestCategories.cs index d23fb4b..a523612 100644 --- a/FastRngTests/TestCategories.cs +++ b/FastRngTests/TestCategories.cs @@ -1,11 +1,10 @@ -namespace FastRngTests +namespace FastRngTests; + +public static class TestCategories { - public class TestCategories - { - public const string COVER = "cover"; - public const string PERFORMANCE = "performance"; - public const string NORMAL = "normal"; - public const string EXAMPLE = "example"; - public const string LONG_RUNNING = "long running"; - } + public const string COVER = "cover"; + public const string PERFORMANCE = "performance"; + public const string NORMAL = "normal"; + public const string EXAMPLE = "example"; + public const string LONG_RUNNING = "long running"; } \ No newline at end of file