Class Sum

java.lang.Object
org.apache.commons.numbers.core.Sum
All Implemented Interfaces:
DoubleConsumer, DoubleSupplier

public final class Sum extends Object implements DoubleSupplier, DoubleConsumer
Class providing accurate floating-point sums and linear combinations. This class uses techniques to mitigate round off errors resulting from standard floating-point operations, increasing the overall accuracy of results at the cost of a moderate increase in the number of computations. This functionality can be viewed as filling the gap between standard floating point operations (fast but prone to round off errors) and BigDecimal (perfectly accurate but slow).

Usage

This class use a builder pattern in order to maximize the flexibility of the API. Typical use involves constructing an instance from one of the factory methods, adding any number of single value terms and/or products, and then extracting the computed sum. Convenience methods exist for adding multiple values or products at once. The examples below demonstrate some simple use cases.

 // compute the sum a1 + a2 + a3 + a4
 Sum sum = Sum.of(a1);
      .add(a2)
      .add(a3)
      .add(a4);
 double result = sum.getAsDouble();

 // same as above but using the varargs factory method
 double result = Sum.of(a1, a2, a3, a4).getAsDouble();

 // compute the dot product of two arrays of the same length, a and b
 Sum sum = Sum.create();
 for (int i = 0; i < a.length; ++i) {
      sum.addProduct(a[i], b[i]);
 }
 double result = sum.getAsDouble();

 // same as above but using a convenience factory method
 double result = Sum.ofProducts(a, b).getAsDouble();
 

It is worth noting that this class is designed to reduce floating point errors across a sequence of operations and not just a single add or multiply. The standard IEEE floating point operations already produce the most accurate results possible given two arguments and this class does not improve on them. Rather, it tracks the errors inherent with each operation and uses them to reduce the error of the overall result. Therefore, this class is only beneficial in cases involving 3 or more floating point operations. Code such as Sum.of(a, b).getAsDouble() and Sum.create().addProduct(a, b).getAsDouble() only adds overhead with no benefit.

Implementation Notes

This class internally uses the Sum2S and Dot2S algorithms described in Accurate Sum and Dot Product by Takeshi Ogita, Siegfried M. Rump, and Shin'ichi Oishi (SIAM J. Sci. Comput, 2005). These are compensated summation and multiplication algorithms chosen here for their good balance of precision and performance. Future releases may choose to use different algorithms.

Results follow the IEEE 754 rules for addition: For example, if any input value is Double.NaN, the result is Double.NaN.

Instances of this class are mutable and not safe for use by multiple threads.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private double
    Compensation value.
    private double
    Standard sum.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Sum(double initialValue)
    Constructs a new instance with the given initial value.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    accept(double value)
    Adds a single term to this sum.
    add(double t)
    Adds a single term to this sum.
    add(double... terms)
    Adds values from the given array to the sum.
    add(Sum other)
    Adds another sum to this sum.
    addProduct(double a, double b)
    Adds the high-accuracy product \( a b \) to this sum.
    addProducts(double[] a, double[] b)
    Adds \( \sum_i a_i b_i \) to this sum.
    static Sum
    Creates a new instance with an initial value of zero.
    double
    Gets the sum value.
    static Sum
    of(double a)
    Creates an instance initialized to the given value.
    static Sum
    of(double... values)
    Creates an instance containing the sum of the given values.
    static Sum
    ofProducts(double[] a, double[] b)
    Creates a new instance containing \( \sum_i a_i b_i \).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface java.util.function.DoubleConsumer

    andThen
  • Field Details

    • sum

      private double sum
      Standard sum.
    • comp

      private double comp
      Compensation value.
  • Constructor Details

    • Sum

      private Sum(double initialValue)
      Constructs a new instance with the given initial value.
      Parameters:
      initialValue - Initial value.
  • Method Details

    • add

      public Sum add(double t)
      Adds a single term to this sum.
      Parameters:
      t - Value to add.
      Returns:
      this instance.
    • add

      public Sum add(double... terms)
      Adds values from the given array to the sum.
      Parameters:
      terms - Terms to add.
      Returns:
      this instance.
    • addProduct

      public Sum addProduct(double a, double b)
      Adds the high-accuracy product \( a b \) to this sum.
      Parameters:
      a - Factor
      b - Factor.
      Returns:
      this instance
    • addProducts

      public Sum addProducts(double[] a, double[] b)
      Adds \( \sum_i a_i b_i \) to this sum.
      Parameters:
      a - Factors.
      b - Factors.
      Returns:
      this instance.
      Throws:
      IllegalArgumentException - if the arrays do not have the same length.
    • add

      public Sum add(Sum other)
      Adds another sum to this sum.
      Parameters:
      other - Sum to add.
      Returns:
      this instance.
    • accept

      public void accept(double value)
      Adds a single term to this sum. This is equivalent to add(double).
      Specified by:
      accept in interface DoubleConsumer
      Parameters:
      value - Value to add.
      See Also:
    • getAsDouble

      public double getAsDouble()
      Gets the sum value.
      Specified by:
      getAsDouble in interface DoubleSupplier
      Returns:
      the sum value.
    • create

      public static Sum create()
      Creates a new instance with an initial value of zero.
      Returns:
      a new instance.
    • of

      public static Sum of(double a)
      Creates an instance initialized to the given value.
      Parameters:
      a - Initial value.
      Returns:
      a new instance.
    • of

      public static Sum of(double... values)
      Creates an instance containing the sum of the given values.
      Parameters:
      values - Values to add.
      Returns:
      a new instance.
    • ofProducts

      public static Sum ofProducts(double[] a, double[] b)
      Creates a new instance containing \( \sum_i a_i b_i \).
      Parameters:
      a - Factors.
      b - Factors.
      Returns:
      a new instance.