Browse Source

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

pull/222/head
Christoph Ruegg 12 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; }
}
/// <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>
/// Gets the median of the distribution.
/// </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>

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>
/// Gets the median of the distribution.
/// </summary>
public int Median
public double Median
{
get { return (int)Math.Floor(_p*_trials); }
get { return Math.Floor(_p*_trials); }
}
/// <summary>
@ -371,7 +387,6 @@ namespace MathNet.Numerics.Distributions
/// <summary>
/// Samples a binomially distributed random variable.
/// </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="n">The number of trials (n). Range: n ≥ 0.</param>
/// <returns>The number of successes in <paramref name="n"/> trials.</returns>
@ -384,7 +399,6 @@ namespace MathNet.Numerics.Distributions
/// <summary>
/// Samples a sequence of binomially distributed random variable.
/// </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="n">The number of trials (n). Range: n ≥ 0.</param>
/// <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>
/// Gets the median of the distribution.
/// </summary>
public int Median
public double Median
{
get { return (int) _pmfNormalized.Median(); }
get { return _pmfNormalized.Median(); }
}
/// <summary>

3
src/Numerics/Distributions/Cauchy.cs

@ -386,6 +386,7 @@ namespace MathNet.Numerics.Distributions
/// Fills an array with samples generated from the distribution.
/// </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="scale">The scale (γ) of the distribution. Range: γ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns>
@ -425,7 +426,7 @@ namespace MathNet.Numerics.Distributions
/// <summary>
/// Fills an array with samples generated from the distribution.
/// </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="scale">The scale (γ) of the distribution. Range: γ > 0.</param>
/// <returns>a sequence of samples from the distribution.</returns>

2
src/Numerics/Distributions/ConwayMaxwellPoisson.cs

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

4
src/Numerics/Distributions/DiscreteUniform.cs

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

4
src/Numerics/Distributions/Geometric.cs

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

2
src/Numerics/Distributions/Hypergeometric.cs

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

5
src/Numerics/Distributions/IContinuousDistribution.cs

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

5
src/Numerics/Distributions/IDiscreteDistribution.cs

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

5
src/Numerics/Distributions/IUnivariateDistribution.cs

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

1
src/Numerics/Distributions/Laplace.cs

@ -407,7 +407,6 @@ namespace MathNet.Numerics.Distributions
/// <summary>
/// Fills an array with samples generated from the distribution.
/// </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 (μ) of the distribution.</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>
/// Gets the median of the distribution.
/// </summary>
public int Median
public double Median
{
get { throw new NotSupportedException(); }
}

4
src/Numerics/Distributions/Poisson.cs

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

1
src/Numerics/Distributions/Rayleigh.cs

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

2
src/Numerics/Distributions/Zipf.cs

@ -211,7 +211,7 @@ namespace MathNet.Numerics.Distributions
/// <summary>
/// Gets the median of the distribution.
/// </summary>
public int Median
public double Median
{
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);
}
/// <summary>
/// Validate median throws <c>NotSupportedException</c>.
/// </summary>
[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<NotSupportedException>(() => { double m = b.Median; });
Assert.That(new Bernoulli(p).Median, Is.EqualTo(expected));
}
/// <summary>

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

@ -143,17 +143,15 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Discrete
Assert.AreEqual(1, d.Mode);
}
/// <summary>
/// Validate median.
/// </summary>
/// <param name="p">Probability of generating a one.</param>
[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));
}
/// <summary>

Loading…
Cancel
Save