MATH-1158. Method "createSampler" overridden in "ExponentialDistribution".
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/adfa016f Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/adfa016f Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/adfa016f Branch: refs/heads/feature-MATH-1158 Commit: adfa016f3ef7ff262643e0f0a5a54d3ddb7d7e1d Parents: 228b49f Author: Gilles <er...@apache.org> Authored: Sat Mar 12 03:12:06 2016 +0100 Committer: Gilles <er...@apache.org> Committed: Sat Mar 12 03:12:06 2016 +0100 ---------------------------------------------------------------------- .../distribution/ExponentialDistribution.java | 59 ++++++++++++++++++++ 1 file changed, 59 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/adfa016f/src/main/java/org/apache/commons/math4/distribution/ExponentialDistribution.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/distribution/ExponentialDistribution.java b/src/main/java/org/apache/commons/math4/distribution/ExponentialDistribution.java index 95b24e7..133321e 100644 --- a/src/main/java/org/apache/commons/math4/distribution/ExponentialDistribution.java +++ b/src/main/java/org/apache/commons/math4/distribution/ExponentialDistribution.java @@ -21,6 +21,7 @@ import org.apache.commons.math4.exception.OutOfRangeException; import org.apache.commons.math4.exception.util.LocalizedFormats; import org.apache.commons.math4.random.RandomGenerator; import org.apache.commons.math4.random.Well19937c; +import org.apache.commons.math4.rng.UniformRandomProvider; import org.apache.commons.math4.util.CombinatoricsUtils; import org.apache.commons.math4.util.FastMath; import org.apache.commons.math4.util.ResizableDoubleArray; @@ -134,6 +135,7 @@ public class ExponentialDistribution extends AbstractRealDistribution { * @throws NotStrictlyPositiveException if {@code mean <= 0}. * @since 3.3 */ + @Deprecated public ExponentialDistribution(RandomGenerator rng, double mean) throws NotStrictlyPositiveException { this(rng, mean, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); @@ -150,6 +152,7 @@ public class ExponentialDistribution extends AbstractRealDistribution { * @throws NotStrictlyPositiveException if {@code mean <= 0}. * @since 3.1 */ + @Deprecated public ExponentialDistribution(RandomGenerator rng, double mean, double inverseCumAccuracy) @@ -243,6 +246,7 @@ public class ExponentialDistribution extends AbstractRealDistribution { * @since 2.2 */ @Override + @Deprecated public double sample() { // Step 1: double a = 0; @@ -345,4 +349,59 @@ public class ExponentialDistribution extends AbstractRealDistribution { public boolean isSupportConnected() { return true; } + + /** + * {@inheritDoc} + * + * <p>Sampling algorithm uses the + * <a href="http://www.jesus.ox.ac.uk/~clifford/a5/chap1/node5.html"> + * inversion method</a> to generate exponentially distributed + * random values from uniform deviates. + * </p> + */ + @Override + public RealDistribution.Sampler createSampler(final UniformRandomProvider rng) { + return new RealDistribution.Sampler() { + /** {@inheritDoc} */ + @Override + public double sample() { + // Step 1: + double a = 0; + double u = rng.nextDouble(); + + // Step 2 and 3: + while (u < 0.5) { + a += EXPONENTIAL_SA_QI[0]; + u *= 2; + } + + // Step 4 (now u >= 0.5): + u += u - 1; + + // Step 5: + if (u <= EXPONENTIAL_SA_QI[0]) { + return mean * (a + u); + } + + // Step 6: + int i = 0; // Should be 1, be we iterate before it in while using 0 + double u2 = rng.nextDouble(); + double umin = u2; + + // Step 7 and 8: + do { + ++i; + u2 = rng.nextDouble(); + + if (u2 < umin) { + umin = u2; + } + + // Step 8: + } while (u > EXPONENTIAL_SA_QI[i]); // Ensured to exit since EXPONENTIAL_SA_QI[MAX] = 1 + + return mean * (a + umin * EXPONENTIAL_SA_QI[0]); + } + }; + } }