From 7306226559c667097ee76f6da678d369884058fd Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 24 May 2020 11:20:56 +0200 Subject: [PATCH] Distributions: fix sampling wiring of new Skewed Generalized distributions Related to #654 --- .../Distributions/SkewedGeneralizedError.cs | 110 +++++++++++++---- .../Distributions/SkewedGeneralizedT.cs | 114 ++++++++++++++---- 2 files changed, 176 insertions(+), 48 deletions(-) diff --git a/src/Numerics/Distributions/SkewedGeneralizedError.cs b/src/Numerics/Distributions/SkewedGeneralizedError.cs index 33579d86..700fd10f 100644 --- a/src/Numerics/Distributions/SkewedGeneralizedError.cs +++ b/src/Numerics/Distributions/SkewedGeneralizedError.cs @@ -3,7 +3,7 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // -// Copyright (c) 2009-2019 Math.NET +// Copyright (c) 2009-2020 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -313,6 +313,43 @@ namespace MathNet.Numerics.Distributions return PDFLn(Location, Scale, Skew, P, x); } + public double Sample() + { + return SampleUnchecked(_random, Location, Scale, Skew, P); + } + + public void Samples(double[] values) + { + SamplesUnchecked(_random, values, Location, Scale, Skew, P); + } + + public IEnumerable Samples() + { + return SamplesUnchecked(_random, Location, Scale, Skew, P); + } + + static double SampleUnchecked(System.Random rnd, double location, double scale, double skew, double p) + { + var u = ContinuousUniform.Sample(rnd, 0, 1); + return InvCDF(location, scale, skew, p, u); + } + + static void SamplesUnchecked(System.Random rnd, double[] values, double location, double scale, double skew, double p) + { + for (int i = 0; i < values.Length; i++) + { + values[i] = SampleUnchecked(rnd, location, scale, skew, p); + } + } + + static IEnumerable SamplesUnchecked(System.Random rnd, double location, double scale, double skew, double p) + { + while (true) + { + yield return SampleUnchecked(rnd, location, scale, skew, p); + } + } + /// /// Generates a sample from the Skew Generalized Error distribution. /// @@ -348,22 +385,37 @@ namespace MathNet.Numerics.Distributions throw new ArgumentException(Resources.InvalidDistributionParameters); } - while (true) - { - yield return SampleUnchecked(rnd, location, scale, skew, p); - } + return SamplesUnchecked(rnd, location, scale, skew, p); } - public static IEnumerable Samples(double location, double scale, double skew, double p) + /// + /// Fills an array with samples from the Skew Generalized Error distribution using inverse transform. + /// + /// The random number generator to use. + /// The array to fill with the samples. + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// Parameter that controls kurtosis. Range: p > 0 + /// a sequence of samples from the distribution. + public static void Samples(System.Random rnd, double[] values, double location, double scale, double skew, double p) { if (!IsValidParameterSet(location, scale, skew, p)) { throw new ArgumentException(Resources.InvalidDistributionParameters); } - return Samples(SystemRandomSource.Default, location, scale, skew, p); + SamplesUnchecked(rnd, values, location, scale, skew, p); } + /// + /// Generates a sample from the Skew Generalized Error distribution. + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// Parameter that controls kurtosis. Range: p > 0 + /// a sample from the distribution. public static double Sample(double location, double scale, double skew, double p) { if (!IsValidParameterSet(location, scale, skew, p)) @@ -374,31 +426,41 @@ namespace MathNet.Numerics.Distributions return SampleUnchecked(SystemRandomSource.Default, location, scale, skew, p); } - static double SampleUnchecked(System.Random rnd, double location, double scale, double skew, double p) + /// + /// Generates a sequence of samples from the Skew Generalized Error distribution using inverse transform. + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// Parameter that controls kurtosis. Range: p > 0 + /// a sequence of samples from the distribution. + public static IEnumerable Samples(double location, double scale, double skew, double p) { - var u = ContinuousUniform.Sample(rnd, 0, 1); - return InvCDF(location, scale, skew, p, u); - } + if (!IsValidParameterSet(location, scale, skew, p)) + { + throw new ArgumentException(Resources.InvalidDistributionParameters); + } - public double Sample() - { - return SampleUnchecked(SystemRandomSource.Default, Location, Scale, Skew, P); + return SamplesUnchecked(SystemRandomSource.Default, location, scale, skew, p); } - public void Samples(double[] values) + /// + /// Fills an array with samples from the Skew Generalized Error distribution using inverse transform. + /// + /// The array to fill with the samples. + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// Parameter that controls kurtosis. Range: p > 0 + /// a sequence of samples from the distribution. + public static void Samples(double[] values, double location, double scale, double skew, double p) { - if (values == null) - return; - - for (int i = 0; i < values.Length; i++) + if (!IsValidParameterSet(location, scale, skew, p)) { - values[i] = Sample(); + throw new ArgumentException(Resources.InvalidDistributionParameters); } - } - public IEnumerable Samples() - { - return Samples(); + SamplesUnchecked(SystemRandomSource.Default, values, location, scale, skew, p); } } } diff --git a/src/Numerics/Distributions/SkewedGeneralizedT.cs b/src/Numerics/Distributions/SkewedGeneralizedT.cs index 72724b4b..c6cef174 100644 --- a/src/Numerics/Distributions/SkewedGeneralizedT.cs +++ b/src/Numerics/Distributions/SkewedGeneralizedT.cs @@ -3,7 +3,7 @@ // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // -// Copyright (c) 2009-2019 Math.NET +// Copyright (c) 2009-2020 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -482,6 +482,43 @@ namespace MathNet.Numerics.Distributions return _d?.DensityLn(x) ?? PDFLn(Location, Scale, Skew, P, Q, x); } + public double Sample() + { + return SampleUnchecked(_random, Location, Scale, Skew, P, Q); + } + + public void Samples(double[] values) + { + SamplesUnchecked(_random, values, Location, Scale, Skew, P, Q); + } + + public IEnumerable Samples() + { + return SamplesUnchecked(_random, Location, Scale, Skew, P, Q); + } + + static double SampleUnchecked(System.Random rnd, double location, double scale, double skew, double p, double q) + { + var u = ContinuousUniform.Sample(rnd, 0, 1); + return InvCDF(location, scale, skew, p, q, u); + } + + static void SamplesUnchecked(System.Random rnd, double[] values, double location, double scale, double skew, double p, double q) + { + for (int i = 0; i < values.Length; i++) + { + values[i] = SampleUnchecked(rnd, location, scale, skew, p, q); + } + } + + static IEnumerable SamplesUnchecked(System.Random rnd, double location, double scale, double skew, double p, double q) + { + while (true) + { + yield return SampleUnchecked(rnd, location, scale, skew, p, q); + } + } + /// /// Generates a sample from the Skew Generalized t-distribution. /// @@ -519,22 +556,39 @@ namespace MathNet.Numerics.Distributions throw new ArgumentException(Resources.InvalidDistributionParameters); } - while (true) - { - yield return SampleUnchecked(rnd, location, scale, skew, p, q); - } + return SamplesUnchecked(rnd, location, scale, skew, p, q); } - public static IEnumerable Samples(double location, double scale, double skew, double p, double q) + /// + /// Fills an array with samples from the Skew Generalized t-distribution using inverse transform. + /// + /// The random number generator to use. + /// The array to fill with the samples. + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// First parameter that controls kurtosis. Range: p > 0 + /// Second parameter that controls kurtosis. Range: q > 0 + /// a sequence of samples from the distribution. + public static void Samples(System.Random rnd, double[] values, double location, double scale, double skew, double p, double q) { if (!IsValidParameterSet(location, scale, skew, p, q)) { throw new ArgumentException(Resources.InvalidDistributionParameters); } - return Samples(SystemRandomSource.Default, location, scale, skew, p, q); + SamplesUnchecked(rnd, values, location, scale, skew, p, q); } + /// + /// Generates a sample from the Skew Generalized t-distribution. + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// First parameter that controls kurtosis. Range: p > 0 + /// Second parameter that controls kurtosis. Range: q > 0 + /// a sample from the distribution. public static double Sample(double location, double scale, double skew, double p, double q) { if (!IsValidParameterSet(location, scale, skew, p, q)) @@ -545,31 +599,43 @@ namespace MathNet.Numerics.Distributions return SampleUnchecked(SystemRandomSource.Default, location, scale, skew, p, q); } - static double SampleUnchecked(System.Random rnd, double location, double scale, double skew, double p, double q) + /// + /// Generates a sequence of samples from the Skew Generalized t-distribution using inverse transform. + /// + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// First parameter that controls kurtosis. Range: p > 0 + /// Second parameter that controls kurtosis. Range: q > 0 + /// a sequence of samples from the distribution. + public static IEnumerable Samples(double location, double scale, double skew, double p, double q) { - var u = ContinuousUniform.Sample(rnd, 0, 1); - return InvCDF(location, scale, skew, p, q, u); - } + if (!IsValidParameterSet(location, scale, skew, p, q)) + { + throw new ArgumentException(Resources.InvalidDistributionParameters); + } - public double Sample() - { - return SampleUnchecked(SystemRandomSource.Default, Location, Scale, Skew, P, Q); + return SamplesUnchecked(SystemRandomSource.Default, location, scale, skew, p, q); } - public void Samples(double[] values) + /// + /// Fills an array with samples from the Skew Generalized t-distribution using inverse transform. + /// + /// The array to fill with the samples. + /// The location (μ) of the distribution. + /// The scale (σ) of the distribution. Range: σ > 0. + /// The skew, 1 > λ > -1 + /// First parameter that controls kurtosis. Range: p > 0 + /// Second parameter that controls kurtosis. Range: q > 0 + /// a sequence of samples from the distribution. + public static void Samples(double[] values, double location, double scale, double skew, double p, double q) { - if (values == null) - return; - - for (int i = 0; i < values.Length; i++) + if (!IsValidParameterSet(location, scale, skew, p, q)) { - values[i] = Sample(); + throw new ArgumentException(Resources.InvalidDistributionParameters); } - } - public IEnumerable Samples() - { - return Samples(); + SamplesUnchecked(SystemRandomSource.Default, values, location, scale, skew, p, q); } } }