Browse Source

Distributions: discrete distribution Median should be double; multiple modes #189 #187

provider
Christoph Ruegg 13 years ago
parent
commit
fb4e4e0195
  1. 12
      src/Numerics/Distributions/Bernoulli.cs
  2. 22
      src/Numerics/Distributions/Binomial.cs
  3. 4
      src/Numerics/Distributions/Categorical.cs
  4. 3
      src/Numerics/Distributions/Cauchy.cs
  5. 2
      src/Numerics/Distributions/ConwayMaxwellPoisson.cs
  6. 4
      src/Numerics/Distributions/DiscreteUniform.cs
  7. 4
      src/Numerics/Distributions/Geometric.cs
  8. 2
      src/Numerics/Distributions/Hypergeometric.cs
  9. 5
      src/Numerics/Distributions/IContinuousDistribution.cs
  10. 5
      src/Numerics/Distributions/IDiscreteDistribution.cs
  11. 5
      src/Numerics/Distributions/IUnivariateDistribution.cs
  12. 1
      src/Numerics/Distributions/Laplace.cs
  13. 2
      src/Numerics/Distributions/NegativeBinomial.cs
  14. 4
      src/Numerics/Distributions/Poisson.cs
  15. 1
      src/Numerics/Distributions/Rayleigh.cs
  16. 3
      src/Numerics/Distributions/Triangular.cs
  17. 2
      src/Numerics/Distributions/Weibull.cs
  18. 2
      src/Numerics/Distributions/Zipf.cs
  19. 14
      src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs
  20. 18
      src/UnitTests/DistributionTests/Discrete/GeometricTests.cs

12
src/Numerics/Distributions/Bernoulli.cs

@ -176,12 +176,20 @@ namespace MathNet.Numerics.Distributions
get { return _p > 0.5 ? 1 : 0; } get { return _p > 0.5 ? 1 : 0; }
} }
/// <summary>
/// Gets all modes of the distribution.
/// </summary>
public int[] Modes
{
get { return _p < 0.5 ? new[] { 0 } : P > 0.5 ? new[] { 1 } : new[] { 0, 1 }; }
}
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
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; }
} }
/// <summary> /// <summary>

22
src/Numerics/Distributions/Binomial.cs

@ -213,12 +213,28 @@ namespace MathNet.Numerics.Distributions
} }
} }
/// <summary>
/// Gets all modes of the distribution.
/// </summary>
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 };
}
}
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { return (int)Math.Floor(_p*_trials); } get { return Math.Floor(_p*_trials); }
} }
/// <summary> /// <summary>
@ -371,7 +387,6 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Samples a binomially distributed random variable. /// Samples a binomially distributed random variable.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param>
/// <param name="p">The success probability (p) in each trial. Range: 0 ≤ p ≤ 1.</param> /// <param name="p">The success probability (p) in each trial. Range: 0 ≤ p ≤ 1.</param>
/// <param name="n">The number of trials (n). Range: n ≥ 0.</param> /// <param name="n">The number of trials (n). Range: n ≥ 0.</param>
/// <returns>The number of successes in <paramref name="n"/> trials.</returns> /// <returns>The number of successes in <paramref name="n"/> trials.</returns>
@ -384,7 +399,6 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Samples a sequence of binomially distributed random variable. /// Samples a sequence of binomially distributed random variable.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param>
/// <param name="p">The success probability (p) in each trial. Range: 0 ≤ p ≤ 1.</param> /// <param name="p">The success probability (p) in each trial. Range: 0 ≤ p ≤ 1.</param>
/// <param name="n">The number of trials (n). Range: n ≥ 0.</param> /// <param name="n">The number of trials (n). Range: n ≥ 0.</param>
/// <returns>a sequence of successes in <paramref name="n"/> trials.</returns> /// <returns>a sequence of successes in <paramref name="n"/> trials.</returns>

4
src/Numerics/Distributions/Categorical.cs

@ -277,9 +277,9 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { return (int) _pmfNormalized.Median(); } get { return _pmfNormalized.Median(); }
} }
/// <summary> /// <summary>

3
src/Numerics/Distributions/Cauchy.cs

@ -386,6 +386,7 @@ namespace MathNet.Numerics.Distributions
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param> /// <param name="rnd">The random number generator to use.</param>
/// <param name="values">The array to fill with the samples.</param>
/// <param name="location">The location (x0) of the distribution.</param> /// <param name="location">The location (x0) of the distribution.</param>
/// <param name="scale">The scale (γ) of the distribution. Range: γ > 0.</param> /// <param name="scale">The scale (γ) of the distribution. Range: γ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>
@ -425,7 +426,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param> /// <param name="values">The array to fill with the samples.</param>
/// <param name="location">The location (x0) of the distribution.</param> /// <param name="location">The location (x0) of the distribution.</param>
/// <param name="scale">The scale (γ) of the distribution. Range: γ > 0.</param> /// <param name="scale">The scale (γ) of the distribution. Range: γ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>

2
src/Numerics/Distributions/ConwayMaxwellPoisson.cs

@ -309,7 +309,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { throw new NotSupportedException(); } get { throw new NotSupportedException(); }
} }

4
src/Numerics/Distributions/DiscreteUniform.cs

@ -193,9 +193,9 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { return (int)Math.Floor((_lower + _upper)/2.0); } get { return (_lower + _upper)/2.0; }
} }
/// <summary> /// <summary>

4
src/Numerics/Distributions/Geometric.cs

@ -162,9 +162,9 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
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)); }
} }
/// <summary> /// <summary>

2
src/Numerics/Distributions/Hypergeometric.cs

@ -222,7 +222,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { throw new NotSupportedException(); } get { throw new NotSupportedException(); }
} }

5
src/Numerics/Distributions/IContinuousDistribution.cs

@ -43,11 +43,6 @@ namespace MathNet.Numerics.Distributions
/// </summary> /// </summary>
double Mode { get; } double Mode { get; }
/// <summary>
/// Gets the median of the distribution.
/// </summary>
double Median { get; }
/// <summary> /// <summary>
/// Gets the smallest element in the domain of the distribution which can be represented by a double. /// Gets the smallest element in the domain of the distribution which can be represented by a double.
/// </summary> /// </summary>

5
src/Numerics/Distributions/IDiscreteDistribution.cs

@ -43,11 +43,6 @@ namespace MathNet.Numerics.Distributions
/// </summary> /// </summary>
int Mode { get; } int Mode { get; }
/// <summary>
/// Gets the median of the distribution.
/// </summary>
int Median { get; }
/// <summary> /// <summary>
/// Gets the smallest element in the domain of the distribution which can be represented by an integer. /// Gets the smallest element in the domain of the distribution which can be represented by an integer.
/// </summary> /// </summary>

5
src/Numerics/Distributions/IUnivariateDistribution.cs

@ -62,6 +62,11 @@ namespace MathNet.Numerics.Distributions
/// </summary> /// </summary>
double Skewness { get; } double Skewness { get; }
/// <summary>
/// Gets the median of the distribution.
/// </summary>
double Median { get; }
/// <summary> /// <summary>
/// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x). /// Computes the cumulative distribution (CDF) of the distribution at x, i.e. P(X ≤ x).
/// </summary> /// </summary>

1
src/Numerics/Distributions/Laplace.cs

@ -407,7 +407,6 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param>
/// <param name="values">The array to fill with the samples.</param> /// <param name="values">The array to fill with the samples.</param>
/// <param name="location">The location (μ) of the distribution.</param> /// <param name="location">The location (μ) of the distribution.</param>
/// <param name="scale">The scale (b) of the distribution. Range: b > 0.</param> /// <param name="scale">The scale (b) of the distribution. Range: b > 0.</param>

2
src/Numerics/Distributions/NegativeBinomial.cs

@ -178,7 +178,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { throw new NotSupportedException(); } get { throw new NotSupportedException(); }
} }

4
src/Numerics/Distributions/Poisson.cs

@ -185,9 +185,9 @@ namespace MathNet.Numerics.Distributions
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
/// <remarks>Approximation, see Wikipedia <a href="http://en.wikipedia.org/wiki/Poisson_distribution">Poisson distribution</a></remarks> /// <remarks>Approximation, see Wikipedia <a href="http://en.wikipedia.org/wiki/Poisson_distribution">Poisson distribution</a></remarks>
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)); }
} }
/// <summary> /// <summary>

1
src/Numerics/Distributions/Rayleigh.cs

@ -397,7 +397,6 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param>
/// <param name="values">The array to fill with the samples.</param> /// <param name="values">The array to fill with the samples.</param>
/// <param name="scale">The scale (σ) of the distribution. Range: σ > 0.</param> /// <param name="scale">The scale (σ) of the distribution. Range: σ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>

3
src/Numerics/Distributions/Triangular.cs

@ -448,6 +448,7 @@ namespace MathNet.Numerics.Distributions
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param> /// <param name="rnd">The random number generator to use.</param>
/// <param name="values">The array to fill with the samples.</param>
/// <param name="lower">Lower bound. Range: lower ≤ mode ≤ upper</param> /// <param name="lower">Lower bound. Range: lower ≤ mode ≤ upper</param>
/// <param name="upper">Upper bound. Range: lower ≤ mode ≤ upper</param> /// <param name="upper">Upper bound. Range: lower ≤ mode ≤ upper</param>
/// <param name="mode">Mode (most frequent value). Range: lower ≤ mode ≤ upper</param> /// <param name="mode">Mode (most frequent value). Range: lower ≤ mode ≤ upper</param>
@ -490,7 +491,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param> /// <param name="values">The array to fill with the samples.</param>
/// <param name="lower">Lower bound. Range: lower ≤ mode ≤ upper</param> /// <param name="lower">Lower bound. Range: lower ≤ mode ≤ upper</param>
/// <param name="upper">Upper bound. Range: lower ≤ mode ≤ upper</param> /// <param name="upper">Upper bound. Range: lower ≤ mode ≤ upper</param>
/// <param name="mode">Mode (most frequent value). Range: lower ≤ mode ≤ upper</param> /// <param name="mode">Mode (most frequent value). Range: lower ≤ mode ≤ upper</param>

2
src/Numerics/Distributions/Weibull.cs

@ -425,6 +425,7 @@ namespace MathNet.Numerics.Distributions
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="rnd">The random number generator to use.</param> /// <param name="rnd">The random number generator to use.</param>
/// <param name="values">The array to fill with the samples.</param>
/// <param name="shape">The shape (k) of the Weibull distribution. Range: k > 0.</param> /// <param name="shape">The shape (k) of the Weibull distribution. Range: k > 0.</param>
/// <param name="scale">The scale (λ) of the Weibull distribution. Range: λ > 0.</param> /// <param name="scale">The scale (λ) of the Weibull distribution. Range: λ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>
@ -464,6 +465,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Fills an array with samples generated from the distribution. /// Fills an array with samples generated from the distribution.
/// </summary> /// </summary>
/// <param name="values">The array to fill with the samples.</param>
/// <param name="shape">The shape (k) of the Weibull distribution. Range: k > 0.</param> /// <param name="shape">The shape (k) of the Weibull distribution. Range: k > 0.</param>
/// <param name="scale">The scale (λ) of the Weibull distribution. Range: λ > 0.</param> /// <param name="scale">The scale (λ) of the Weibull distribution. Range: λ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns> /// <returns>a sequence of samples from the distribution.</returns>

2
src/Numerics/Distributions/Zipf.cs

@ -211,7 +211,7 @@ namespace MathNet.Numerics.Distributions
/// <summary> /// <summary>
/// Gets the median of the distribution. /// Gets the median of the distribution.
/// </summary> /// </summary>
public int Median public double Median
{ {
get { throw new NotSupportedException(); } get { throw new NotSupportedException(); }
} }

14
src/UnitTests/DistributionTests/Discrete/BernoulliTests.cs

@ -144,14 +144,14 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete
Assert.AreEqual(m, b.Mode); Assert.AreEqual(m, b.Mode);
} }
/// <summary> [TestCase(0.0, 0.0)]
/// Validate median throws <c>NotSupportedException</c>. [TestCase(0.4, 0.0)]
/// </summary> [TestCase(0.5, 0.5)]
[Test] [TestCase(0.6, 1.0)]
public void ValidateMedianThrowsNotSupportedException() [TestCase(1.0, 1.0)]
public void ValidateMedian(double p, double expected)
{ {
var b = new Bernoulli(0.3); Assert.That(new Bernoulli(p).Median, Is.EqualTo(expected));
Assert.Throws<NotSupportedException>(() => { double m = b.Median; });
} }
/// <summary> /// <summary>

18
src/UnitTests/DistributionTests/Discrete/GeometricTests.cs

@ -143,17 +143,15 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete
Assert.AreEqual(1, d.Mode); Assert.AreEqual(1, d.Mode);
} }
/// <summary> [TestCase(0.0, double.PositiveInfinity)]
/// Validate median. [TestCase(0.0001, 6932.0)]
/// </summary> [TestCase(0.1, 7.0)]
/// <param name="p">Probability of generating a one.</param> [TestCase(0.3, 2.0)]
[TestCase(0.0)] [TestCase(0.9, 1.0)]
[TestCase(0.3)] [TestCase(1.0, 1.0)]
[TestCase(1.0)] public void ValidateMedian(double p, double expected)
public void ValidateMedian(double p)
{ {
var d = new Geometric(p); Assert.That(new Geometric(p).Median, Is.EqualTo(expected));
Assert.AreEqual((int)Math.Ceiling(-Math.Log(2.0) / Math.Log(1 - p)), d.Median);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save