From adfa016f3ef7ff262643e0f0a5a54d3ddb7d7e1d Mon Sep 17 00:00:00 2001 From: Gilles Date: Sat, 12 Mar 2016 03:12:06 +0100 Subject: [PATCH] MATH-1158. Method "createSampler" overridden in "ExponentialDistribution". --- .../distribution/ExponentialDistribution.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) 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 95b24e70e..133321e36 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} + * + *

Sampling algorithm uses the + * + * inversion method to generate exponentially distributed + * random values from uniform deviates. + *

+ */ + @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]); + } + }; + } }