diff --git a/src/Numerics/Distributions/Bernoulli.cs b/src/Numerics/Distributions/Bernoulli.cs index 1a0fa11f..3820a4e1 100644 --- a/src/Numerics/Distributions/Bernoulli.cs +++ b/src/Numerics/Distributions/Bernoulli.cs @@ -176,12 +176,20 @@ namespace MathNet.Numerics.Distributions get { return _p > 0.5 ? 1 : 0; } } + /// + /// Gets all modes of the distribution. + /// + public int[] Modes + { + get { return _p < 0.5 ? new[] { 0 } : P > 0.5 ? new[] { 1 } : new[] { 0, 1 }; } + } + /// /// Gets the median of the distribution. /// - public int Median + public double Median { - get { throw new NotSupportedException("The median of the Bernoulli distribution is undefined."); } + get { return _p < 0.5 ? 0.0 : _p > 0.5 ? 1.0 : 0.5; } } /// diff --git a/src/Numerics/Distributions/Binomial.cs b/src/Numerics/Distributions/Binomial.cs index b6d3e75e..a069ca1e 100644 --- a/src/Numerics/Distributions/Binomial.cs +++ b/src/Numerics/Distributions/Binomial.cs @@ -213,12 +213,28 @@ namespace MathNet.Numerics.Distributions } } + /// + /// Gets all modes of the distribution. + /// + public int[] Modes + { + get + { + if (_p == 1.0) return new [] {_trials}; + if (_p == 0.0) return new [] {0}; + + double td = (_trials + 1)*_p; + int t = (int)Math.Floor(td); + return t != td ? new[] { t } : new[] { t, t - 1 }; + } + } + /// /// Gets the median of the distribution. /// - public int Median + public double Median { - get { return (int)Math.Floor(_p*_trials); } + get { return Math.Floor(_p*_trials); } } /// @@ -371,7 +387,6 @@ namespace MathNet.Numerics.Distributions /// /// Samples a binomially distributed random variable. /// - /// The random number generator to use. /// The success probability (p) in each trial. Range: 0 ≤ p ≤ 1. /// The number of trials (n). Range: n ≥ 0. /// The number of successes in trials. @@ -384,7 +399,6 @@ namespace MathNet.Numerics.Distributions /// /// Samples a sequence of binomially distributed random variable. /// - /// The random number generator to use. /// The success probability (p) in each trial. Range: 0 ≤ p ≤ 1. /// The number of trials (n). Range: n ≥ 0. /// a sequence of successes in trials. diff --git a/src/Numerics/Distributions/Categorical.cs b/src/Numerics/Distributions/Categorical.cs index 6360fccf..5084c966 100644 --- a/src/Numerics/Distributions/Categorical.cs +++ b/src/Numerics/Distributions/Categorical.cs @@ -277,9 +277,9 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { - get { return (int) _pmfNormalized.Median(); } + get { return _pmfNormalized.Median(); } } /// diff --git a/src/Numerics/Distributions/Cauchy.cs b/src/Numerics/Distributions/Cauchy.cs index ed1acaec..045b38d9 100644 --- a/src/Numerics/Distributions/Cauchy.cs +++ b/src/Numerics/Distributions/Cauchy.cs @@ -386,6 +386,7 @@ namespace MathNet.Numerics.Distributions /// Fills an array with samples generated from the distribution. /// /// The random number generator to use. + /// The array to fill with the samples. /// The location (x0) of the distribution. /// The scale (γ) of the distribution. Range: γ > 0. /// a sequence of samples from the distribution. @@ -425,7 +426,7 @@ namespace MathNet.Numerics.Distributions /// /// Fills an array with samples generated from the distribution. /// - /// The random number generator to use. + /// The array to fill with the samples. /// The location (x0) of the distribution. /// The scale (γ) of the distribution. Range: γ > 0. /// a sequence of samples from the distribution. diff --git a/src/Numerics/Distributions/ConwayMaxwellPoisson.cs b/src/Numerics/Distributions/ConwayMaxwellPoisson.cs index 977439cc..cc87f23c 100644 --- a/src/Numerics/Distributions/ConwayMaxwellPoisson.cs +++ b/src/Numerics/Distributions/ConwayMaxwellPoisson.cs @@ -309,7 +309,7 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { get { throw new NotSupportedException(); } } diff --git a/src/Numerics/Distributions/DiscreteUniform.cs b/src/Numerics/Distributions/DiscreteUniform.cs index cbafa02c..852da707 100644 --- a/src/Numerics/Distributions/DiscreteUniform.cs +++ b/src/Numerics/Distributions/DiscreteUniform.cs @@ -193,9 +193,9 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { - get { return (int)Math.Floor((_lower + _upper)/2.0); } + get { return (_lower + _upper)/2.0; } } /// diff --git a/src/Numerics/Distributions/Geometric.cs b/src/Numerics/Distributions/Geometric.cs index f402ec4d..dc1cf91f 100644 --- a/src/Numerics/Distributions/Geometric.cs +++ b/src/Numerics/Distributions/Geometric.cs @@ -162,9 +162,9 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { - get { return (int)Math.Ceiling(-Constants.Ln2/Math.Log(1 - _p)); } + get { return _p == 0.0 ? double.PositiveInfinity : _p == 1.0 ? 1.0 : Math.Ceiling(-Constants.Ln2/Math.Log(1 - _p)); } } /// diff --git a/src/Numerics/Distributions/Hypergeometric.cs b/src/Numerics/Distributions/Hypergeometric.cs index 895b2055..13a9b3e2 100644 --- a/src/Numerics/Distributions/Hypergeometric.cs +++ b/src/Numerics/Distributions/Hypergeometric.cs @@ -222,7 +222,7 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { get { throw new NotSupportedException(); } } diff --git a/src/Numerics/Distributions/IContinuousDistribution.cs b/src/Numerics/Distributions/IContinuousDistribution.cs index 3f496795..28802418 100644 --- a/src/Numerics/Distributions/IContinuousDistribution.cs +++ b/src/Numerics/Distributions/IContinuousDistribution.cs @@ -43,11 +43,6 @@ namespace MathNet.Numerics.Distributions /// double Mode { get; } - /// - /// Gets the median of the distribution. - /// - double Median { get; } - /// /// Gets the smallest element in the domain of the distribution which can be represented by a double. /// diff --git a/src/Numerics/Distributions/IDiscreteDistribution.cs b/src/Numerics/Distributions/IDiscreteDistribution.cs index cb2f3201..1949e23c 100644 --- a/src/Numerics/Distributions/IDiscreteDistribution.cs +++ b/src/Numerics/Distributions/IDiscreteDistribution.cs @@ -43,11 +43,6 @@ namespace MathNet.Numerics.Distributions /// int Mode { get; } - /// - /// Gets the median of the distribution. - /// - int Median { get; } - /// /// Gets the smallest element in the domain of the distribution which can be represented by an integer. /// diff --git a/src/Numerics/Distributions/IUnivariateDistribution.cs b/src/Numerics/Distributions/IUnivariateDistribution.cs index df481737..a6981fab 100644 --- a/src/Numerics/Distributions/IUnivariateDistribution.cs +++ b/src/Numerics/Distributions/IUnivariateDistribution.cs @@ -62,6 +62,11 @@ namespace MathNet.Numerics.Distributions /// double Skewness { get; } + /// + /// Gets the median of the distribution. + /// + double Median { get; } + /// /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). /// diff --git a/src/Numerics/Distributions/Laplace.cs b/src/Numerics/Distributions/Laplace.cs index eafe9c7e..ed68ecd7 100644 --- a/src/Numerics/Distributions/Laplace.cs +++ b/src/Numerics/Distributions/Laplace.cs @@ -407,7 +407,6 @@ namespace MathNet.Numerics.Distributions /// /// Fills an array with samples generated from the distribution. /// - /// The random number generator to use. /// The array to fill with the samples. /// The location (μ) of the distribution. /// The scale (b) of the distribution. Range: b > 0. diff --git a/src/Numerics/Distributions/NegativeBinomial.cs b/src/Numerics/Distributions/NegativeBinomial.cs index 1ef6fa22..73f38547 100644 --- a/src/Numerics/Distributions/NegativeBinomial.cs +++ b/src/Numerics/Distributions/NegativeBinomial.cs @@ -178,7 +178,7 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { get { throw new NotSupportedException(); } } diff --git a/src/Numerics/Distributions/Poisson.cs b/src/Numerics/Distributions/Poisson.cs index 4bbca97d..886641e0 100644 --- a/src/Numerics/Distributions/Poisson.cs +++ b/src/Numerics/Distributions/Poisson.cs @@ -185,9 +185,9 @@ namespace MathNet.Numerics.Distributions /// Gets the median of the distribution. /// /// Approximation, see Wikipedia Poisson distribution - public int Median + public double Median { - get { return (int)Math.Floor(_lambda + (1.0/3.0) - (0.02/_lambda)); } + get { return Math.Floor(_lambda + (1.0/3.0) - (0.02/_lambda)); } } /// diff --git a/src/Numerics/Distributions/Rayleigh.cs b/src/Numerics/Distributions/Rayleigh.cs index d6e0c205..2ee2e8ef 100644 --- a/src/Numerics/Distributions/Rayleigh.cs +++ b/src/Numerics/Distributions/Rayleigh.cs @@ -397,7 +397,6 @@ namespace MathNet.Numerics.Distributions /// /// Fills an array with samples generated from the distribution. /// - /// The random number generator to use. /// The array to fill with the samples. /// The scale (σ) of the distribution. Range: σ > 0. /// a sequence of samples from the distribution. diff --git a/src/Numerics/Distributions/Triangular.cs b/src/Numerics/Distributions/Triangular.cs index cb070b52..1e85fd9e 100644 --- a/src/Numerics/Distributions/Triangular.cs +++ b/src/Numerics/Distributions/Triangular.cs @@ -448,6 +448,7 @@ namespace MathNet.Numerics.Distributions /// Fills an array with samples generated from the distribution. /// /// The random number generator to use. + /// The array to fill with the samples. /// Lower bound. Range: lower ≤ mode ≤ upper /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper @@ -490,7 +491,7 @@ namespace MathNet.Numerics.Distributions /// /// Fills an array with samples generated from the distribution. /// - /// The random number generator to use. + /// The array to fill with the samples. /// Lower bound. Range: lower ≤ mode ≤ upper /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper diff --git a/src/Numerics/Distributions/Weibull.cs b/src/Numerics/Distributions/Weibull.cs index cbcfae15..fec31cf5 100644 --- a/src/Numerics/Distributions/Weibull.cs +++ b/src/Numerics/Distributions/Weibull.cs @@ -425,6 +425,7 @@ namespace MathNet.Numerics.Distributions /// Fills an array with samples generated from the distribution. /// /// The random number generator to use. + /// The array to fill with the samples. /// The shape (k) of the Weibull distribution. Range: k > 0. /// The scale (λ) of the Weibull distribution. Range: λ > 0. /// a sequence of samples from the distribution. @@ -464,6 +465,7 @@ namespace MathNet.Numerics.Distributions /// /// Fills an array with samples generated from the distribution. /// + /// The array to fill with the samples. /// The shape (k) of the Weibull distribution. Range: k > 0. /// The scale (λ) of the Weibull distribution. Range: λ > 0. /// a sequence of samples from the distribution. diff --git a/src/Numerics/Distributions/Zipf.cs b/src/Numerics/Distributions/Zipf.cs index 41991f22..3009088f 100644 --- a/src/Numerics/Distributions/Zipf.cs +++ b/src/Numerics/Distributions/Zipf.cs @@ -211,7 +211,7 @@ namespace MathNet.Numerics.Distributions /// /// Gets the median of the distribution. /// - public int Median + public double Median { get { throw new NotSupportedException(); } } diff --git a/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs b/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs index d0194150..0a0e77cd 100644 --- a/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs @@ -144,14 +144,14 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete Assert.AreEqual(m, b.Mode); } - /// - /// Validate median throws NotSupportedException. - /// - [Test] - public void ValidateMedianThrowsNotSupportedException() + [TestCase(0.0, 0.0)] + [TestCase(0.4, 0.0)] + [TestCase(0.5, 0.5)] + [TestCase(0.6, 1.0)] + [TestCase(1.0, 1.0)] + public void ValidateMedian(double p, double expected) { - var b = new Bernoulli(0.3); - Assert.Throws(() => { double m = b.Median; }); + Assert.That(new Bernoulli(p).Median, Is.EqualTo(expected)); } /// diff --git a/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs b/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs index abf869e5..9b62a4d2 100644 --- a/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs +++ b/src/UnitTests/DistributionTests/Discrete/GeometricTests.cs @@ -143,17 +143,15 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete Assert.AreEqual(1, d.Mode); } - /// - /// Validate median. - /// - /// Probability of generating a one. - [TestCase(0.0)] - [TestCase(0.3)] - [TestCase(1.0)] - public void ValidateMedian(double p) + [TestCase(0.0, double.PositiveInfinity)] + [TestCase(0.0001, 6932.0)] + [TestCase(0.1, 7.0)] + [TestCase(0.3, 2.0)] + [TestCase(0.9, 1.0)] + [TestCase(1.0, 1.0)] + public void ValidateMedian(double p, double expected) { - var d = new Geometric(p); - Assert.AreEqual((int)Math.Ceiling(-Math.Log(2.0) / Math.Log(1 - p)), d.Median); + Assert.That(new Geometric(p).Median, Is.EqualTo(expected)); } ///