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

Reply via email to