[MATH-1065] Fix EnumeratedRealDistribution.inverseCumulativeProbability. Thanks to matteodg and Phil.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1566274 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3f59a81a15
commit
996c0c164a
|
@ -51,6 +51,11 @@ If the output is not quite correct, check for invisible trailing spaces!
|
|||
</properties>
|
||||
<body>
|
||||
<release version="3.3" date="TBD" description="TBD">
|
||||
<action dev="tn" type="fix" issue="MATH-1065" due-to="matteodg">
|
||||
Calculating the inverse cumulative probability of an "EnumeratedRealDistribution"
|
||||
will now return the correct result according to the selected enumerated probability
|
||||
mass function.
|
||||
</action>
|
||||
<action dev="erans" type="update" issue="MATH-1050">
|
||||
Deprecated "ArithmeticUtils#pow(int, long)" and "ArithmeticUtils#pow(long, long)"
|
||||
in favor of corresponding methods "ArithmeticUtils#pow(..., int)".
|
||||
|
|
|
@ -18,11 +18,13 @@ package org.apache.commons.math3.distribution;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math3.exception.DimensionMismatchException;
|
||||
import org.apache.commons.math3.exception.MathArithmeticException;
|
||||
import org.apache.commons.math3.exception.NotANumberException;
|
||||
import org.apache.commons.math3.exception.NotFiniteNumberException;
|
||||
import org.apache.commons.math3.exception.NotPositiveException;
|
||||
import org.apache.commons.math3.exception.OutOfRangeException;
|
||||
import org.apache.commons.math3.random.RandomGenerator;
|
||||
import org.apache.commons.math3.random.Well19937c;
|
||||
import org.apache.commons.math3.util.Pair;
|
||||
|
@ -136,6 +138,33 @@ public class EnumeratedRealDistribution extends AbstractRealDistribution {
|
|||
return probability;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public double inverseCumulativeProbability(final double p) throws OutOfRangeException {
|
||||
if (p < 0.0 || p > 1.0) {
|
||||
throw new OutOfRangeException(p, 0, 1);
|
||||
}
|
||||
|
||||
double probability = 0;
|
||||
double x = getSupportLowerBound();
|
||||
for (final Pair<Double, Double> sample : innerDistribution.getPmf()) {
|
||||
if (sample.getValue() == 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
probability += sample.getValue();
|
||||
x = sample.getKey();
|
||||
|
||||
if (probability >= p) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.commons.math3.distribution;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -213,4 +215,46 @@ public class EnumeratedRealDistributionTest {
|
|||
Assert.assertEquals(1, new EnumeratedDistribution<Object>(list).sample(1).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssue1065() {
|
||||
// Test Distribution for inverseCumulativeProbability
|
||||
//
|
||||
// ^
|
||||
// |
|
||||
// 1.000 +--------------------------------o===============
|
||||
// | 3|
|
||||
// | |
|
||||
// | 1o=
|
||||
// 0.750 +-------------------------> o== .
|
||||
// | 3| . .
|
||||
// | 0 | . .
|
||||
// 0.5625 +---------------> o==o====== . .
|
||||
// | | . . . .
|
||||
// | | . . . .
|
||||
// | 5| . . . .
|
||||
// | | . . . .
|
||||
// | o=== . . . .
|
||||
// | | . . . . .
|
||||
// | 4| . . . . .
|
||||
// | | . . . . .
|
||||
// 0.000 +=============----+--+------+--+-+--------------->
|
||||
// 14 18 21 28 31 33
|
||||
//
|
||||
// sum = 4+5+0+3+1+3 = 16
|
||||
|
||||
EnumeratedRealDistribution distribution = new EnumeratedRealDistribution(
|
||||
new double[] { 14.0, 18.0, 21.0, 28.0, 31.0, 33.0 },
|
||||
new double[] { 4.0 / 16.0, 5.0 / 16.0, 0.0 / 16.0, 3.0 / 16.0, 1.0 / 16.0, 3.0 / 16.0 });
|
||||
|
||||
assertEquals(14.0, distribution.inverseCumulativeProbability(0.0000), 0.0);
|
||||
assertEquals(14.0, distribution.inverseCumulativeProbability(0.2500), 0.0);
|
||||
assertEquals(33.0, distribution.inverseCumulativeProbability(1.0000), 0.0);
|
||||
|
||||
assertEquals(18.0, distribution.inverseCumulativeProbability(0.5000), 0.0);
|
||||
assertEquals(18.0, distribution.inverseCumulativeProbability(0.5624), 0.0);
|
||||
assertEquals(28.0, distribution.inverseCumulativeProbability(0.5626), 0.0);
|
||||
assertEquals(31.0, distribution.inverseCumulativeProbability(0.7600), 0.0);
|
||||
assertEquals(18.0, distribution.inverseCumulativeProbability(0.5625), 0.0);
|
||||
assertEquals(28.0, distribution.inverseCumulativeProbability(0.7500), 0.0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue