Search
View source code
Display the source code in std/algorithm/iteration.d from which this page was generated on github.
Report a bug
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

# Function `std.algorithm.iteration.sum`

Sums elements of `r`, which must be a finite input range. Although conceptually `sum(r)` is equivalent to `fold`!((a, b) => a + b)(r, 0), `sum` uses specialized algorithms to maximize accuracy, as follows.

``` auto sum(R) (   R r ) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))); auto sum(R, E) (   R r,   E seed ) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front))); ```

• If `ElementType`!R is a floating-point type and `R` is a random-access range with length and slicing, then `sum` uses the pairwise summation algorithm.
• If `ElementType!R` is a floating-point type and `R` is a finite input range (but not a random-access range with slicing), then `sum` uses the Kahan summation algorithm.
• In all other cases, a simple element by element addition is done.

For floating point inputs, calculations are made in `real` precision for `real` inputs and in `double` precision otherwise (Note this is a special case that deviates from `fold`'s behavior, which would have kept `float` precision for a `float` range). For all other types, the calculations are done in the same type obtained from from adding two elements of the range, which may be a different type from the elements themselves (for example, in case of integral promotion).

A seed may be passed to `sum`. Not only will this seed be used as an initial value, but its type will override all the above, and determine the algorithm and precision used for summation. If a seed is not passed, one is created with the value of `typeof(r.front + r.front)(0)`, or `typeof(r.front + r.front).zero` if no constructor exists that takes an int.

Note that these specialized summing algorithms execute more primitive operations than vanilla summation. Therefore, if in certain cases maximum speed is required at expense of precision, one can use `fold!((a, b) => a + b)(r, 0)`, which is not specialized for summation.

## Parameters

NameDescription
seed the initial value of the summation
r a finite input range

## Returns

The sum of all the elements in the range r.

## Example

Ditto

``````import std.range;

//simple integral sumation
writeln(sum([1, 2, 3, 4])); // 10

//with integral promotion
writeln(sum([false, true, true, false, true])); // 3
writeln(sum(ubyte.max.repeat(100))); // 25500

//The result may overflow
writeln(uint.max.repeat(3).sum()); // 4294967293U
//But a seed can be used to change the sumation primitive
writeln(uint.max.repeat(3).sum(ulong.init)); // 12884901885UL

//Floating point sumation
writeln(sum([1.0, 2.0, 3.0, 4.0])); // 10

//Floating point operations have double precision minimum
static assert(is(typeof(sum([1F, 2F, 3F, 4F])) == double));
writeln(sum([1F, 2, 3, 4])); // 10

//Force pair-wise floating point sumation on large integers
import std.math.operations : isClose;
assert(iota(ulong.max / 2, ulong.max / 2 + 4096).sum(0.0)
.isClose((ulong.max / 2) * 4096.0 + 4096^^2 / 2));
``````