And here’s a floating-point implementation with compensated summation:
extension Sequence where Element: FloatingPoint {
func sum() -> Element {
var result: Element = 0
var excess: Element = 0
for x in self {
let large = Element.maximumMagnitude(result, x)
let small = Element.minimumMagnitude(result, x)
result += x
excess += (result - large) - small
}
return result - excess
}
}
Although for Float
(and Float16
) it’s probably better to just sum as Double
:
extension Sequence where Element == Float {
func sum() -> Float {
return Float(self.reduce(0 as Double){ $0 + Double($1) })
}
}
• • •
I have more thoughts on this, and I’ll work on writing them up, but the top-line is that I think sum()
belongs in either the standard library or perhaps Numerics, rather than Algorithms.
There’s also some consideration for whether we ought to make Sequence.sum()
trampoline off a customization point in AdditiveArithmetic
to enable dynamic dispatch. That has both benefits and drawbacks, which I’ll try to cover when I get the chance.