Fixed inverse cumulative probability for uniform distribution.

JIRA: MATH-957

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1462018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2013-03-28 10:20:30 +00:00
parent 06c0af5514
commit 9aabf587ca
3 changed files with 50 additions and 10 deletions

View File

@ -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 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. 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"> <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 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 new package "o.a.c.m.ml.clustering" and added support for additional

View File

@ -18,6 +18,7 @@
package org.apache.commons.math3.distribution; package org.apache.commons.math3.distribution;
import org.apache.commons.math3.exception.NumberIsTooLargeException; 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.exception.util.LocalizedFormats;
import org.apache.commons.math3.random.RandomGenerator; import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.Well19937c; import org.apache.commons.math3.random.Well19937c;
@ -32,7 +33,10 @@ import org.apache.commons.math3.random.Well19937c;
* @since 3.0 * @since 3.0
*/ */
public class UniformRealDistribution extends AbstractRealDistribution { 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; public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
/** Serializable version identifier. */ /** Serializable version identifier. */
private static final long serialVersionUID = 20120109L; private static final long serialVersionUID = 20120109L;
@ -40,8 +44,6 @@ public class UniformRealDistribution extends AbstractRealDistribution {
private final double lower; private final double lower;
/** Upper bound of this distribution (exclusive). */ /** Upper bound of this distribution (exclusive). */
private final double upper; private final double upper;
/** Inverse cumulative probability accuracy. */
private final double solverAbsoluteAccuracy;
/** /**
* Create a standard uniform real distribution with lower bound (inclusive) * Create a standard uniform real distribution with lower bound (inclusive)
@ -61,7 +63,7 @@ public class UniformRealDistribution extends AbstractRealDistribution {
*/ */
public UniformRealDistribution(double lower, double upper) public UniformRealDistribution(double lower, double upper)
throws NumberIsTooLargeException { throws NumberIsTooLargeException {
this(lower, upper, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); this(new Well19937c(), lower, upper);
} }
/** /**
@ -71,10 +73,13 @@ public class UniformRealDistribution extends AbstractRealDistribution {
* @param upper Upper bound of this distribution (exclusive). * @param upper Upper bound of this distribution (exclusive).
* @param inverseCumAccuracy Inverse cumulative probability accuracy. * @param inverseCumAccuracy Inverse cumulative probability accuracy.
* @throws NumberIsTooLargeException if {@code lower >= upper}. * @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) public UniformRealDistribution(double lower, double upper, double inverseCumAccuracy)
throws NumberIsTooLargeException { throws NumberIsTooLargeException {
this(new Well19937c(), lower, upper, inverseCumAccuracy); this(new Well19937c(), lower, upper);
} }
/** /**
@ -86,11 +91,30 @@ public class UniformRealDistribution extends AbstractRealDistribution {
* @param inverseCumAccuracy Inverse cumulative probability accuracy. * @param inverseCumAccuracy Inverse cumulative probability accuracy.
* @throws NumberIsTooLargeException if {@code lower >= upper}. * @throws NumberIsTooLargeException if {@code lower >= upper}.
* @since 3.1 * @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, public UniformRealDistribution(RandomGenerator rng,
double lower, double lower,
double upper, 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 { throws NumberIsTooLargeException {
super(rng); super(rng);
if (lower >= upper) { if (lower >= upper) {
@ -101,7 +125,6 @@ public class UniformRealDistribution extends AbstractRealDistribution {
this.lower = lower; this.lower = lower;
this.upper = upper; this.upper = upper;
solverAbsoluteAccuracy = inverseCumAccuracy;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@ -123,10 +146,13 @@ public class UniformRealDistribution extends AbstractRealDistribution {
return (x - lower) / (upper - lower); return (x - lower) / (upper - lower);
} }
/** {@inheritDoc} */
@Override @Override
protected double getSolverAbsoluteAccuracy() { public double inverseCumulativeProbability(final double p)
return solverAbsoluteAccuracy; throws OutOfRangeException {
if (p < 0.0 || p > 1.0) {
throw new OutOfRangeException(p, 0, 1);
}
return p * (upper - lower) + lower;
} }
/** /**

View File

@ -110,4 +110,15 @@ public class UniformRealDistributionTest extends RealDistributionAbstractTest {
Assert.assertEquals(dist.getNumericalMean(), 0.375, 0); Assert.assertEquals(dist.getNumericalMean(), 0.375, 0);
Assert.assertEquals(dist.getNumericalVariance(), 0.2552083333333333, 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);
}
} }