You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2021/06/20 02:30:26 UTC

[commons-numbers] 02/02: NUMBERS-163: Nits.

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

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

commit 93c45e9dcde7f283c620508daacaf36383925596
Author: Gilles Sadowski <gi...@gmail.com>
AuthorDate: Sun Jun 20 04:10:59 2021 +0200

    NUMBERS-163: Nits.
    
    Javadoc style to match style in (most) other files.
    Removed factory methods that were just one-liner replacements.
    Added "varargs" (any number of terms) methods.
    Explicit initialization of "comp" instance variable.
    
    Closes #97.
---
 .../java/org/apache/commons/numbers/core/Norm.java |   7 +-
 .../java/org/apache/commons/numbers/core/Sum.java  | 239 ++++++++-------------
 .../org/apache/commons/numbers/core/SumTest.java   |  16 +-
 3 files changed, 99 insertions(+), 163 deletions(-)

diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java
index 255215a..92587fc 100644
--- a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java
@@ -219,9 +219,10 @@ public enum Norm {
     private static double manhattan(final double x,
                                     final double y,
                                     final double z) {
-        return Sum.of(Math.abs(x),
-                      Math.abs(y),
-                      Math.abs(z)).getAsDouble();
+        return Sum.of(Math.abs(x))
+            .add(Math.abs(y))
+            .add(Math.abs(z))
+            .getAsDouble();
     }
 
     /** Computes the Manhattan norm.
diff --git a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
index 9939e62..390649a 100644
--- a/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
+++ b/commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Sum.java
@@ -19,40 +19,42 @@ package org.apache.commons.numbers.core;
 import java.util.function.DoubleConsumer;
 import java.util.function.DoubleSupplier;
 
-/** Class providing accurate floating-point sums and linear combinations. The methods
- * provided use compensated summation and multiplication techniques to reduce numerical errors.
- * The approach is based on the <em>Sum2S</em> and <em>Dot2S</em> algorithms described in the
- * 2005 paper <a href="https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
+/**
+ * Class providing accurate floating-point sums and linear combinations.
+ *
+ * In order to reduce errors, compensated summations and multiplications
+ * are performed according to the <em>Sum2S</em> and <em>Dot2S</em>
+ * algorithms described in
+ * <a href="https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
  * Accurate Sum and Dot Product</a> by Takeshi Ogita, Siegfried M. Rump,
- * and Shin'ichi Oishi published in <em>SIAM J. Sci. Comput</em>.
+ * and Shin'ichi Oishi (<em>SIAM J. Sci. Comput</em>, 2005).
  *
- * <p>Method results follow the standard rules for IEEE 754 addition. For example,
- * if any input value is NaN, the result is NaN.
+ * <p>Results follow the IEEE 754 rules for addition: For example, if any
+ * input value is {@link Double#NaN}, the result is {@link Double#NaN}.
  */
-public final class Sum implements DoubleSupplier, DoubleConsumer {
-
+public final class Sum
+    implements DoubleSupplier,
+               DoubleConsumer {
     /** Standard sum. */
     private double sum;
-
     /** Compensation value. */
     private double comp;
 
-    /** Construct a new instance with an initial value of zero.
-     */
-    private Sum() {
-        this(0d);
-    }
-
-    /** Construct a new instance with the given initial value.
-     * @param initialValue initial value
+    /**
+     * Constructs a new instance with the given initial value.
+     *
+     * @param initialValue Initial value.
      */
     private Sum(final double initialValue) {
-        this.sum = initialValue;
+        sum = initialValue;
+        comp = 0d;
     }
 
-    /** Add a single term to this sum.
-     * @param t value to add
-     * @return this instance
+    /**
+     * Adds a single term to this sum.
+     *
+     * @param t Value to add.
+     * @return this instance.
      */
     public Sum add(final double t) {
         final double newSum = sum + t;
@@ -62,11 +64,13 @@ public final class Sum implements DoubleSupplier, DoubleConsumer {
         return this;
     }
 
-    /** Add an array of value to the sum.
-     * @param terms terms to add
-     * @return this instance
+    /**
+     * Adds values from the given array to the sum.
+     *
+     * @param terms Terms to add.
+     * @return this instance.
      */
-    public Sum add(final double[] terms) {
+    public Sum add(final double... terms) {
         for (double t : terms) {
             add(t);
         }
@@ -74,12 +78,15 @@ public final class Sum implements DoubleSupplier, DoubleConsumer {
         return this;
     }
 
-    /** Add the high-accuracy product \(a b\) to this sum.
-     * @param a first factor
-     * @param b second factor
+    /**
+     * Adds the high-accuracy product \( a b \) to this sum.
+     *
+     * @param a Factor
+     * @param b Factor.
      * @return this instance
      */
-    public Sum addProduct(final double a, final double b) {
+    public Sum addProduct(final double a,
+                          final double b) {
         final double ab = a * b;
         final double pLow = ExtendedPrecision.productLow(a, b, ab);
 
@@ -90,18 +97,20 @@ public final class Sum implements DoubleSupplier, DoubleConsumer {
         return this;
     }
 
-    /** Add \( \sum_i a_i b_i \). In other words, multiply each element
-     * in {@code a} with its corresponding element in {@code b} and add the product
-     * to the sum.
-     * @param a factors
-     * @param b factors
-     * @return this instance
-     * @throws IllegalArgumentException if the arrays do not have the same length
+    /**
+     * Adds \( \sum_i a_i b_i \) to this sum.
+     *
+     * @param a Factors.
+     * @param b Factors.
+     * @return this instance.
+     * @throws IllegalArgumentException if the arrays do not have the same length.
      */
-    public Sum addProducts(final double[] a, final double[] b) {
+    public Sum addProducts(final double[] a,
+                           final double[] b) {
         final int len = a.length;
         if (len != b.length) {
-            throw new IllegalArgumentException("Dimension mismatch: " + a.length + " != " + b.length);
+            throw new IllegalArgumentException("Dimension mismatch: " +
+                                               a.length + " != " + b.length);
         }
 
         for (int i = 0; i < len; ++i) {
@@ -111,22 +120,27 @@ public final class Sum implements DoubleSupplier, DoubleConsumer {
         return this;
     }
 
-    /** Add another sum to this sum.
-     * @param other sum to add
-     * @return this instance
+    /**
+     * Adds another sum to this sum.
+     *
+     * @param other Sum to add.
+     * @return this instance.
      */
     public Sum add(final Sum other) {
-        // pull both values first to ensure there are
-        // no issues when adding a sum to itself
+        // Pull both values first to ensure there are
+        // no issues when adding a sum to itself.
         final double s = other.sum;
         final double c = other.comp;
 
-        return add(s)
-                .add(c);
+        return add(s).add(c);
     }
 
-    /** Add a single term to this sum. This is equivalent to {@link #add(double)}.
-     * @param value value to add
+    /**
+     * Adds a single term to this sum.
+     * This is equivalent to {@link #add(double)}.
+     *
+     * @param value Value to add.
+     *
      * @see #add(double)
      */
     @Override
@@ -134,125 +148,58 @@ public final class Sum implements DoubleSupplier, DoubleConsumer {
         add(value);
     }
 
-    /** Get the sum value.
-     * @return sum value as a double
+    /**
+     * Gets the sum value.
+     *
+     * @return the sum value.
      */
     @Override
     public double getAsDouble() {
-        // compute and return the high precision sum if it is finite; otherwise,
-        // return the standard IEEE754 result
+        // High-precision value if it is finite, standard IEEE754 result otherwise.
         final double hpsum = sum + comp;
         return Double.isFinite(hpsum) ?
                 hpsum :
                 sum;
     }
 
-    /** Create a new sum instance with an initial value of zero.
-     * @return new sum instance
+    /**
+     * Creates a new instance with an initial value of zero.
+     *
+     * @return a new instance.
      */
     public static Sum create() {
-        return new Sum();
+        return new Sum(0d);
     }
 
-    /** Return a new sum instance containing a single value.
-     * @param a value
-     * @return new sum instance
-     * @see #add(double)
+    /**
+     * Creates an instance initialized to the given value.
+     *
+     * @param a Initial value.
+     * @return a new instance.
      */
     public static Sum of(final double a) {
         return new Sum(a);
     }
 
-    /** Return a new sum instance containing the value \(a + b\).
-     * @param a first term
-     * @param b second term
-     * @return new sum instance
-     * @see #add(double)
-     */
-    public static Sum of(final double a, final double b) {
-        return new Sum(a).add(b);
-    }
-
-    /** Return a new sum instance containing the value \(a + b + c\).
-     * @param a first term
-     * @param b second term
-     * @param c third term
-     * @return new sum instance
-     * @see #add(double)
-     */
-    public static Sum of(final double a, final double b, final double c) {
-        return new Sum(a)
-                .add(b)
-                .add(c);
-    }
-
-    /** Return a new sum instance containing the value \(a + b + c + d\).
-     * @param a first term
-     * @param b second term
-     * @param c third term
-     * @param d fourth term
-     * @return new sum instance
-     * @see #add(double)
-     */
-    public static Sum of(final double a, final double b, final double c, final double d) {
-        return new Sum(a)
-                .add(b)
-                .add(c)
-                .add(d);
-    }
-
-    /** Return a new sum instance containing the sum of the given values.
-     * @param values input values
-     * @return new sum instance
-     * @see #add(double[])
-     */
-    public static Sum of(final double[] values) {
-        return new Sum().add(values);
-    }
-
-    /** Return a new sum instance containing the linear combination
-     * \(a_1 b_1 + a_2 b_2\).
-     * @param a1 first factor of first term
-     * @param b1 second factor of first term
-     * @param a2 first factor of second term
-     * @param b2 second factor of second term
-     * @return new sum instance
-     * @see #addProduct(double, double)
-     */
-    public static Sum ofProducts(final double a1, final double b1,
-                                 final double a2, final double b2) {
-        return new Sum()
-                .addProduct(a1, b1)
-                .addProduct(a2, b2);
-    }
-
-    /** Return a new sum instance containing the linear combination
-     * \(a_1 b_1 + a_2 b_2 + a_3 b_3\).
-     * @param a1 first factor of first term
-     * @param b1 second factor of first term
-     * @param a2 first factor of second term
-     * @param b2 second factor of second term
-     * @param a3 first factor of third term
-     * @param b3 second factor of third term
-     * @return new sum instance
-     * @see #addProduct(double, double)
+    /**
+     * Creates an instance containing the sum of the given values.
+     *
+     * @param values Values to add.
+     * @return a new instance.
      */
-    public static Sum ofProducts(final double a1, final double b1,
-                                 final double a2, final double b2,
-                                 final double a3, final double b3) {
-        return new Sum()
-                .addProduct(a1, b1)
-                .addProduct(a2, b2)
-                .addProduct(a3, b3);
+    public static Sum of(final double... values) {
+        return create().add(values);
     }
 
-    /** Return a new sum instance containing \( \sum_i a_i b_i \).
-     * @param a first set of factors
-     * @param b second set of factors
-     * @return new sum instance
-     * @see #addProducts(double[], double[])
+    /**
+     * Creates a new instance containing \( \sum_i a_i b_i \).
+     *
+     * @param a Factors.
+     * @param b Factors.
+     * @return a new instance.
      */
-    public static Sum ofProducts(final double[] a, final double[] b) {
-        return new Sum().addProducts(a, b);
+    public static Sum ofProducts(final double[] a,
+                                 final double[] b) {
+        return create().addProducts(a, b);
     }
 }
diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/SumTest.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/SumTest.java
index 70afcd5..5d38260 100644
--- a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/SumTest.java
+++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/SumTest.java
@@ -193,9 +193,7 @@ class SumTest {
         }
 
         // act
-        final double sum = Sum.ofProducts(scaledA[0], scaledB[0],
-                                          scaledA[1], scaledB[1],
-                                          scaledA[2], scaledB[2]).getAsDouble();
+        final double sum = Sum.ofProducts(scaledA, scaledB).getAsDouble();
 
         // assert
         Assertions.assertEquals(-1.8551294182586248737720779899, sum, 1e-15);
@@ -352,7 +350,7 @@ class SumTest {
         final double x = Math.nextDown(2.0);
         final double y = -Math.nextDown(x);
         final double xxMxy = x * x + x * y;
-        final double xxMxyHighPrecision = Sum.ofProducts(x, x, x, y).getAsDouble();
+        final double xxMxyHighPrecision = Sum.create().addProduct(x, x).addProduct(x, y).getAsDouble();
         Assertions.assertNotEquals(xxMxy, xxMxyHighPrecision, "High precision result should be different");
 
         // Scale it close to max value.
@@ -510,16 +508,6 @@ class SumTest {
     private static void assertSumOfProducts(final double expected, final double[] a, final double[] b) {
         final int len = a.length;
 
-        // check non-array method variants
-        if (len == 2) {
-            Assertions.assertEquals(expected, Sum.ofProducts(a[0], b[0],
-                                                             a[1], b[1]).getAsDouble());
-        } else if (len == 3) {
-            Assertions.assertEquals(expected, Sum.ofProducts(a[0], b[0],
-                                                             a[1], b[1],
-                                                             a[2], b[2]).getAsDouble());
-        }
-
         // check use of addProduct()
         final Sum accumulator = Sum.create();
         for (int i = 0; i < len; ++i) {