Skip to content

Commit

Permalink
Fixed inverse cumulative probability for uniform distribution.
Browse files Browse the repository at this point in the history
JIRA: MATH-957

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1462018 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Luc Maisonobe committed Mar 28, 2013
1 parent 06c0af5 commit 9aabf58
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/changes/changes.xml
Expand Up @@ -55,6 +55,9 @@ This is a minor release: It combines bug fixes and new features.
Changes to existing features were made in a backwards-compatible
way such as to allow drop-in replacement of the v3.1[.1] JAR file.
">
<action dev="luc" type="fix" issue="MATH-957" due-to="Dennis Hendriks">
Fixed inverse cumulative probability for uniform distribution.
</action>
<action dev="tn" type="change" issue="MATH-917,MATH-918,MATH-919,MATH-920" due-to="Reid Hochstedler">
All contents of package "o.a.c.m.stat.clustering" refactored into
new package "o.a.c.m.ml.clustering" and added support for additional
Expand Down
Expand Up @@ -18,6 +18,7 @@
package org.apache.commons.math3.distribution;

import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.Well19937c;
Expand All @@ -32,16 +33,17 @@
* @since 3.0
*/
public class UniformRealDistribution extends AbstractRealDistribution {
/** Default inverse cumulative probability accuracy. */
/** Default inverse cumulative probability accuracy.
* @deprecated as of 3.2 not used anymore, will be removed in 4.0
*/
@Deprecated
public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
/** Serializable version identifier. */
private static final long serialVersionUID = 20120109L;
/** Lower bound of this distribution (inclusive). */
private final double lower;
/** Upper bound of this distribution (exclusive). */
private final double upper;
/** Inverse cumulative probability accuracy. */
private final double solverAbsoluteAccuracy;

/**
* Create a standard uniform real distribution with lower bound (inclusive)
Expand All @@ -61,7 +63,7 @@ public UniformRealDistribution() {
*/
public UniformRealDistribution(double lower, double upper)
throws NumberIsTooLargeException {
this(lower, upper, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
this(new Well19937c(), lower, upper);
}

/**
Expand All @@ -71,10 +73,13 @@ public UniformRealDistribution(double lower, double upper)
* @param upper Upper bound of this distribution (exclusive).
* @param inverseCumAccuracy Inverse cumulative probability accuracy.
* @throws NumberIsTooLargeException if {@code lower >= upper}.
* @deprecated as of 3.2, inverse CDF is now calculated analytically, use
* {@link #UniformRealDistribution(double, double)} instead.
*/
@Deprecated
public UniformRealDistribution(double lower, double upper, double inverseCumAccuracy)
throws NumberIsTooLargeException {
this(new Well19937c(), lower, upper, inverseCumAccuracy);
this(new Well19937c(), lower, upper);
}

/**
Expand All @@ -86,11 +91,30 @@ public UniformRealDistribution(double lower, double upper, double inverseCumAccu
* @param inverseCumAccuracy Inverse cumulative probability accuracy.
* @throws NumberIsTooLargeException if {@code lower >= upper}.
* @since 3.1
* @deprecated as of 3.2, inverse CDF is now calculated analytically, use
* {@link #UniformRealDistribution(RandomGenerator, double, double)}
* instead.
*/
@Deprecated
public UniformRealDistribution(RandomGenerator rng,
double lower,
double upper,
double inverseCumAccuracy)
double inverseCumAccuracy){
this(rng, lower, upper);
}

/**
* Creates a uniform distribution.
*
* @param rng Random number generator.
* @param lower Lower bound of this distribution (inclusive).
* @param upper Upper bound of this distribution (exclusive).
* @throws NumberIsTooLargeException if {@code lower >= upper}.
* @since 3.1
*/
public UniformRealDistribution(RandomGenerator rng,
double lower,
double upper)
throws NumberIsTooLargeException {
super(rng);
if (lower >= upper) {
Expand All @@ -101,7 +125,6 @@ public UniformRealDistribution(RandomGenerator rng,

this.lower = lower;
this.upper = upper;
solverAbsoluteAccuracy = inverseCumAccuracy;
}

/** {@inheritDoc} */
Expand All @@ -123,10 +146,13 @@ public double cumulativeProbability(double x) {
return (x - lower) / (upper - lower);
}

/** {@inheritDoc} */
@Override
protected double getSolverAbsoluteAccuracy() {
return solverAbsoluteAccuracy;
public double inverseCumulativeProbability(final double p)
throws OutOfRangeException {
if (p < 0.0 || p > 1.0) {
throw new OutOfRangeException(p, 0, 1);
}
return p * (upper - lower) + lower;
}

/**
Expand Down
Expand Up @@ -110,4 +110,15 @@ public void testMeanVariance() {
Assert.assertEquals(dist.getNumericalMean(), 0.375, 0);
Assert.assertEquals(dist.getNumericalVariance(), 0.2552083333333333, 0);
}

/**
* Check accuracy of analytical inverse CDF. Fails if a solver is used
* with the default accuracy.
*/
@Test
public void testInverseCumulativeDistribution() {
UniformRealDistribution dist = new UniformRealDistribution(0, 1e-9);

Assert.assertEquals(2.5e-10, dist.inverseCumulativeProbability(0.25), 0);
}
}

0 comments on commit 9aabf58

Please sign in to comment.