Class Sum
- All Implemented Interfaces:
DoubleConsumer
,DoubleSupplier
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 -
Constructor Summary
ConstructorsModifierConstructorDescriptionprivate
Sum
(double initialValue) Constructs a new instance with the given initial value. -
Method Summary
Modifier and TypeMethodDescriptionvoid
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.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
create()
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 sumStandard sum. -
comp
private double compCompensation value.
-
-
Constructor Details
-
Sum
private Sum(double initialValue) Constructs a new instance with the given initial value.- Parameters:
initialValue
- Initial value.
-
-
Method Details
-
add
Adds a single term to this sum.- Parameters:
t
- Value to add.- Returns:
- this instance.
-
add
Adds values from the given array to the sum.- Parameters:
terms
- Terms to add.- Returns:
- this instance.
-
addProduct
Adds the high-accuracy product \( a b \) to this sum.- Parameters:
a
- Factorb
- Factor.- Returns:
- this instance
-
addProducts
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
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 toadd(double)
.- Specified by:
accept
in interfaceDoubleConsumer
- Parameters:
value
- Value to add.- See Also:
-
getAsDouble
public double getAsDouble()Gets the sum value.- Specified by:
getAsDouble
in interfaceDoubleSupplier
- Returns:
- the sum value.
-
create
Creates a new instance with an initial value of zero.- Returns:
- a new instance.
-
of
Creates an instance initialized to the given value.- Parameters:
a
- Initial value.- Returns:
- a new instance.
-
of
Creates an instance containing the sum of the given values.- Parameters:
values
- Values to add.- Returns:
- a new instance.
-
ofProducts
Creates a new instance containing \( \sum_i a_i b_i \).- Parameters:
a
- Factors.b
- Factors.- Returns:
- a new instance.
-