This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git


The following commit(s) were added to refs/heads/master by this push:
     new bd30c3b  Cache another constant in the large mean Poisson sampler
bd30c3b is described below

commit bd30c3bcb73daec9c1d9298f26363c268d6c46e8
Author: Alex Herbert <[email protected]>
AuthorDate: Sat Oct 23 21:33:39 2021 +0100

    Cache another constant in the large mean Poisson sampler
    
    This avoids evaluating a constant sqrt expression in the sampling loop.
---
 .../distribution/LargeMeanPoissonSampler.java      | 23 +++++++++++++++++++---
 src/main/resources/pmd/pmd-ruleset.xml             |  6 ++++++
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git 
a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
 
b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
index 66fe104..a0e746e 100644
--- 
a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
+++ 
b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
@@ -91,6 +91,8 @@ public class LargeMeanPoissonSampler
     private final double delta;
     /** Algorithm constant: {@code delta / 2}. */
     private final double halfDelta;
+    /** Algorithm constant: {@code Math.sqrt(lambda + halfDelta)}. */
+    private final double sqrtLambdaPlusHalfDelta;
     /** Algorithm constant: {@code 2 * lambda + delta}. */
     private final double twolpd;
     /**
@@ -143,6 +145,7 @@ public class LargeMeanPoissonSampler
         logLambdaFactorial = getFactorialLog((int) lambda);
         delta = Math.sqrt(lambda * Math.log(32 * lambda / Math.PI + 1));
         halfDelta = delta / 2;
+        sqrtLambdaPlusHalfDelta = Math.sqrt(lambda + halfDelta);
         twolpd = 2 * lambda + delta;
         c1 = 1 / (8 * lambda);
         final double a1 = Math.sqrt(Math.PI * twolpd) * Math.exp(c1);
@@ -188,6 +191,7 @@ public class LargeMeanPoissonSampler
         logLambdaFactorial = state.getLogLambdaFactorial();
         delta = state.getDelta();
         halfDelta = state.getHalfDelta();
+        sqrtLambdaPlusHalfDelta = state.getSqrtLambdaPlusHalfDelta();
         twolpd = state.getTwolpd();
         p1 = state.getP1();
         p2 = state.getP2();
@@ -217,6 +221,7 @@ public class LargeMeanPoissonSampler
         logLambdaFactorial = source.logLambdaFactorial;
         delta = source.delta;
         halfDelta = source.halfDelta;
+        sqrtLambdaPlusHalfDelta = source.sqrtLambdaPlusHalfDelta;
         twolpd = source.twolpd;
         p1 = source.p1;
         p2 = source.p2;
@@ -245,7 +250,7 @@ public class LargeMeanPoissonSampler
             if (u <= p1) {
                 // Step 2:
                 final double n = gaussian.sample();
-                x = n * Math.sqrt(lambda + halfDelta) - 0.5d;
+                x = n * sqrtLambdaPlusHalfDelta - 0.5d;
                 if (x > delta || x < -lambda) {
                     continue;
                 }
@@ -349,7 +354,7 @@ public class LargeMeanPoissonSampler
      */
     LargeMeanPoissonSamplerState getState() {
         return new LargeMeanPoissonSamplerState(lambda, logLambda, 
logLambdaFactorial,
-                delta, halfDelta, twolpd, p1, p2, c1);
+                delta, halfDelta, sqrtLambdaPlusHalfDelta, twolpd, p1, p2, c1);
     }
 
     /**
@@ -371,6 +376,8 @@ public class LargeMeanPoissonSampler
         private final double delta;
         /** Algorithm constant {@code halfDelta}. */
         private final double halfDelta;
+        /** Algorithm constant {@code sqrtLambdaPlusHalfDelta}. */
+        private final double sqrtLambdaPlusHalfDelta;
         /** Algorithm constant {@code twolpd}. */
         private final double twolpd;
         /** Algorithm constant {@code p1}. */
@@ -391,19 +398,22 @@ public class LargeMeanPoissonSampler
          * @param logLambdaFactorial the log lambda factorial
          * @param delta the delta
          * @param halfDelta the half delta
+         * @param sqrtLambdaPlusHalfDelta the sqrt(lambda+half delta)
          * @param twolpd the two lambda plus delta
          * @param p1 the p1 constant
          * @param p2 the p2 constant
          * @param c1 the c1 constant
          */
         LargeMeanPoissonSamplerState(double lambda, double logLambda,
-                double logLambdaFactorial, double delta, double halfDelta, 
double twolpd,
+                double logLambdaFactorial, double delta, double halfDelta,
+                double sqrtLambdaPlusHalfDelta, double twolpd,
                 double p1, double p2, double c1) {
             this.lambda = lambda;
             this.logLambda = logLambda;
             this.logLambdaFactorial = logLambdaFactorial;
             this.delta = delta;
             this.halfDelta = halfDelta;
+            this.sqrtLambdaPlusHalfDelta = sqrtLambdaPlusHalfDelta;
             this.twolpd = twolpd;
             this.p1 = p1;
             this.p2 = p2;
@@ -456,6 +466,13 @@ public class LargeMeanPoissonSampler
         }
 
         /**
+         * @return algorithm constant {@code sqrtLambdaPlusHalfDelta}
+         */
+        double getSqrtLambdaPlusHalfDelta() {
+            return sqrtLambdaPlusHalfDelta;
+        }
+
+        /**
          * @return algorithm constant {@code twolpd}
          */
         double getTwolpd() {
diff --git a/src/main/resources/pmd/pmd-ruleset.xml 
b/src/main/resources/pmd/pmd-ruleset.xml
index ae7f871..0a6775a 100644
--- a/src/main/resources/pmd/pmd-ruleset.xml
+++ b/src/main/resources/pmd/pmd-ruleset.xml
@@ -164,6 +164,12 @@
         or @SimpleName='CompositeSamplers' or @SimpleName='StableSampler' or 
@SimpleName='ZigguratSampler']"/>
     </properties>
   </rule>
+  <rule ref="category/java/design.xml/ExcessiveParameterList">
+    <properties>
+      <!-- The length is due to the size of the internal state saved in the 
state object -->
+      <property name="violationSuppressXPath" 
value="//ClassOrInterfaceDeclaration[@SimpleName='LargeMeanPoissonSampler']"/>
+    </properties>
+  </rule>
   <rule ref="category/java/design.xml/LogicInversion">
     <properties>
       <!-- Logic inversion allows detection of NaN for parameters that are 
expected in a range -->

Reply via email to