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) andBigDecimal
(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/orproducts
, 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()
andSum.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 isDouble.NaN
.Instances of this class are mutable and not safe for use by multiple threads.
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
accept(double value)
Adds a single term to this sum.Sum
add(double t)
Adds a single term to this sum.Sum
add(double... terms)
Adds values from the given array to the sum.Sum
add(Sum other)
Adds another sum to this sum.Sum
addProduct(double a, double b)
Adds the high-accuracy product \( a b \) to this sum.Sum
addProducts(double[] a, double[] b)
Adds \( \sum_i a_i b_i \) to this sum.static Sum
create()
Creates a new instance with an initial value of zero.double
getAsDouble()
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 \).Sum
subtract(Sum other)
Subtracts another sum from this sum.-
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
-
-
-
-
Method Detail
-
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
- Factorb
- 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.
-
subtract
public Sum subtract(Sum other)
Subtracts another sum from this sum.- Parameters:
other
- Sum to subtract.- Returns:
- this instance.
- Since:
- 1.2
-
accept
public void accept(double value)
Adds a single term to this sum. This is equivalent toadd(double)
.- Specified by:
accept
in interfaceDoubleConsumer
- Parameters:
value
- Value to add.- See Also:
add(double)
-
getAsDouble
public double getAsDouble()
Gets the sum value.- Specified by:
getAsDouble
in interfaceDoubleSupplier
- 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.
-
-