Refactored common code into abstract class

This commit is contained in:
Thorsten Sommer 2020-10-31 23:44:23 +01:00
parent c340635c4a
commit 706f2552bc
21 changed files with 76 additions and 478 deletions

View File

@ -4,37 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA2B2 : IDistribution
public sealed class BetaA2B2 : Distribution
{
private const double ALPHA = 2;
private const double BETA = 2;
private const double CONSTANT = 4;
private ShapeFitter fitter;
private IRandom random;
public BetaA2B2()
{
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(BetaA2B2.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -4,37 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA2B5 : IDistribution
public sealed class BetaA2B5 : Distribution
{
private const double ALPHA = 2;
private const double BETA = 5;
private const double CONSTANT = 12.2;
private ShapeFitter fitter;
private IRandom random;
public BetaA2B5()
{
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(BetaA2B5.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -4,37 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class BetaA5B2 : IDistribution
public sealed class BetaA5B2 : Distribution
{
private const double ALPHA = 5;
private const double BETA = 2;
private const double CONSTANT = 12.2;
private ShapeFitter fitter;
private IRandom random;
public BetaA5B2()
{
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(BetaA5B2.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * Math.Pow(x, ALPHA - 1) * Math.Pow(1 - x, BETA - 1);
}
}

View File

@ -4,33 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class CauchyLorentzX0 : IDistribution
public sealed class CauchyLorentzX0 : Distribution
{
private const double CONSTANT = 0.31;
private const double SCALE = 0.1;
private const double MEDIAN = 0.0;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(CauchyLorentzX0.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
}
}

View File

@ -4,33 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class CauchyLorentzX1 : IDistribution
public sealed class CauchyLorentzX1 : Distribution
{
private const double CONSTANT = 0.31;
private const double SCALE = 0.1;
private const double MEDIAN = 1.0;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(CauchyLorentzX1.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * (1.0 / (Math.PI * SCALE)) * ((SCALE * SCALE) / (Math.Pow(x - MEDIAN, 2) + (SCALE * SCALE)));
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK1 : IDistribution
public sealed class ChiSquareK1 : Distribution
{
private const double K = 1.0;
private const double K_HALF = K * 0.5d;
@ -13,34 +13,13 @@ namespace FastRng.Double.Distributions
private static readonly double DIVISOR;
private ShapeFitter fitter;
private IRandom random;
static ChiSquareK1()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(ChiSquareK1.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK10 : IDistribution
public sealed class ChiSquareK10 : Distribution
{
private const double K = 10.0;
private const double K_HALF = K * 0.5d;
@ -13,34 +13,13 @@ namespace FastRng.Double.Distributions
private static readonly double DIVISOR;
private ShapeFitter fitter;
private IRandom random;
static ChiSquareK10()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(ChiSquareK10.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ChiSquareK4 : IDistribution
public sealed class ChiSquareK4 : Distribution
{
private const double K = 4.0;
private const double K_HALF = K * 0.5d;
@ -13,34 +13,13 @@ namespace FastRng.Double.Distributions
private static readonly double DIVISOR;
private ShapeFitter fitter;
private IRandom random;
static ChiSquareK4()
{
var twoToTheKHalf = Math.Pow(2, K_HALF);
var gammaKHalf = MathTools.Gamma(K_HALF);
DIVISOR = twoToTheKHalf * gammaKHalf;
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(ChiSquareK4.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * ((Math.Pow(x, K_HALF_MINUS_ONE) * Math.Exp(-x * 0.5d)) / DIVISOR);
}
}

View File

@ -0,0 +1,34 @@
using System.Threading;
using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public abstract class Distribution : IDistribution
{
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
if(this.random != null)
return;
this.random = value;
this.fitter = new ShapeFitter(this.ShapeFunction, this.random, 100);
}
}
protected abstract double ShapeFunction(double x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
}
}

View File

@ -4,32 +4,11 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ExponentialLa10 : IDistribution
public sealed class ExponentialLa10 : Distribution
{
private const double LAMBDA = 10.0;
private const double CONSTANT = 0.1106;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(ExponentialLa10.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
}
}

View File

@ -4,32 +4,11 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class ExponentialLa5 : IDistribution
public sealed class ExponentialLa5 : Distribution
{
private const double LAMBDA = 5.0;
private const double CONSTANT = 0.2103;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(ExponentialLa5.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(-LAMBDA * x);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class GammaA5B15 : IDistribution
public sealed class GammaA5B15 : Distribution
{
private const double ALPHA = 5.0;
private const double BETA = 15.0;
@ -13,33 +13,12 @@ namespace FastRng.Double.Distributions
private static readonly double GAMMA_ALPHA;
private static readonly double BETA_TO_THE_ALPHA;
private ShapeFitter fitter;
private IRandom random;
static GammaA5B15()
{
GAMMA_ALPHA = MathTools.Gamma(ALPHA);
BETA_TO_THE_ALPHA = Math.Pow(BETA, ALPHA);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(GammaA5B15.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * ((BETA_TO_THE_ALPHA * Math.Pow(x, ALPHA - 1.0d) * Math.Exp(-BETA * x)) / GAMMA_ALPHA);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * ((BETA_TO_THE_ALPHA * Math.Pow(x, ALPHA - 1.0d) * Math.Exp(-BETA * x)) / GAMMA_ALPHA);
}
}

View File

@ -4,32 +4,11 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseExponentialLa10 : IDistribution
public sealed class InverseExponentialLa10 : Distribution
{
private const double LAMBDA = 10.0;
private const double CONSTANT = 4.539992976248453e-06;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(InverseExponentialLa10.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
}
}

View File

@ -4,32 +4,11 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseExponentialLa5 : IDistribution
public sealed class InverseExponentialLa5 : Distribution
{
private const double LAMBDA = 5.0;
private const double CONSTANT = 0.001347589399817;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(InverseExponentialLa5.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * LAMBDA * Math.Exp(LAMBDA * x);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class InverseGammaA3B05 : IDistribution
public sealed class InverseGammaA3B05 : Distribution
{
private const double ALPHA = 3.0;
private const double BETA = 0.5;
@ -12,9 +12,6 @@ namespace FastRng.Double.Distributions
private static readonly double FACTOR_LEFT;
private ShapeFitter fitter;
private IRandom random;
static InverseGammaA3B05()
{
var gammaAlpha = MathTools.Gamma(ALPHA);
@ -22,25 +19,7 @@ namespace FastRng.Double.Distributions
FACTOR_LEFT = CONSTANT * (betaToTheAlpha / gammaAlpha);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(InverseGammaA3B05.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => FACTOR_LEFT * Math.Pow(x, -ALPHA - 1.0d) * Math.Exp(-BETA / x);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Pow(x, -ALPHA - 1.0d) * Math.Exp(-BETA / x);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LaplaceB01M0 : IDistribution
public sealed class LaplaceB01M0 : Distribution
{
private const double B = 0.1;
private const double MU = 0.0;
@ -12,32 +12,11 @@ namespace FastRng.Double.Distributions
private static readonly double FACTOR_LEFT;
private ShapeFitter fitter;
private IRandom random;
static LaplaceB01M0()
{
FACTOR_LEFT = CONSTANT / (2.0d * B);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(LaplaceB01M0.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LaplaceB01M05 : IDistribution
public sealed class LaplaceB01M05 : Distribution
{
private const double B = 0.1;
private const double MU = 0.5;
@ -12,32 +12,11 @@ namespace FastRng.Double.Distributions
private static readonly double FACTOR_LEFT;
private ShapeFitter fitter;
private IRandom random;
static LaplaceB01M05()
{
FACTOR_LEFT = CONSTANT / (2.0d * B);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(LaplaceB01M05.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => FACTOR_LEFT * Math.Exp(-Math.Abs(x - MU) / B);
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class LogNormalS1M0 : IDistribution
public sealed class LogNormalS1M0 : Distribution
{
private const double SIGMA = 1.0;
private const double MU = 0.0;
@ -12,32 +12,11 @@ namespace FastRng.Double.Distributions
private static readonly double FACTOR;
private ShapeFitter fitter;
private IRandom random;
static LogNormalS1M0()
{
FACTOR = SIGMA * Math.Sqrt(2 * Math.PI);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(LogNormalS1M0.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => (CONSTANT / (x * FACTOR)) * Math.Exp( -(Math.Pow(Math.Log(x) - MU, 2) / (2 * Math.Pow(SIGMA, 2))));
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => (CONSTANT / (x * FACTOR)) * Math.Exp( -(Math.Pow(Math.Log(x) - MU, 2) / (2 * Math.Pow(SIGMA, 2))));
}
}

View File

@ -5,37 +5,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class NormalS02M05 : IDistribution
public sealed class NormalS02M05 : Distribution
{
private const double SQRT_2_PI = 2.506628275;
private const double STDDEV = 0.2;
private const double MEAN = 0.5;
private ShapeFitter fitter;
private IRandom random;
public NormalS02M05()
{
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(NormalS02M05.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => 1.0 / (STDDEV * SQRT_2_PI) * Math.Exp(-0.5 * Math.Pow((x - MEAN) / STDDEV, 2.0));
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => 1.0 / (STDDEV * SQRT_2_PI) * Math.Exp(-0.5 * Math.Pow((x - MEAN) / STDDEV, 2.0));
}
}

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class StudentTNu1 : IDistribution
public sealed class StudentTNu1 : Distribution
{
private const double NU = 1.0;
private const double START = 0.0;
@ -15,34 +15,13 @@ namespace FastRng.Double.Distributions
private static readonly double DIVISOR;
private static readonly double EXPONENT;
private ShapeFitter fitter;
private IRandom random;
static StudentTNu1()
{
DIVIDEND = MathTools.Gamma((NU + 1.0d) * 0.5d);
DIVISOR = Math.Sqrt(NU * Math.PI) * MathTools.Gamma(NU * 0.5d);
EXPONENT = -((NU + 1.0d) * 0.5d);
}
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(StudentTNu1.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * Math.Pow((DIVIDEND / DIVISOR) * Math.Pow(1.0d + Math.Pow(START + x * COMPRESS, 2) / NU, EXPONENT), COMPRESS);
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * Math.Pow((DIVIDEND / DIVISOR) * Math.Pow(1.0d + Math.Pow(START + x * COMPRESS, 2) / NU, EXPONENT), COMPRESS);
}
}

View File

@ -4,33 +4,12 @@ using System.Threading.Tasks;
namespace FastRng.Double.Distributions
{
public sealed class WeibullK05La1 : IDistribution
public sealed class WeibullK05La1 : Distribution
{
private const double K = 0.5;
private const double LAMBDA = 1.0;
private const double CONSTANT = 0.221034183615129;
private ShapeFitter fitter;
private IRandom random;
public IRandom Random
{
get => this.random;
set
{
this.random = value;
this.fitter = new ShapeFitter(WeibullK05La1.ShapeFunction, this.random, 100);
}
}
private static double ShapeFunction(double x) => CONSTANT * ( (K / LAMBDA) * Math.Pow(x / LAMBDA, K - 1.0d) * Math.Exp(-Math.Pow(x/LAMBDA, K)));
public async ValueTask<double> GetDistributedValue(CancellationToken token = default)
{
if (this.Random == null)
return double.NaN;
return await this.fitter.NextNumber(token);
}
protected override double ShapeFunction(double x) => CONSTANT * ( (K / LAMBDA) * Math.Pow(x / LAMBDA, K - 1.0d) * Math.Exp(-Math.Pow(x/LAMBDA, K)));
}
}