View source code Display the source code in std/algorithm/iteration.d from which this page was generated on github. Improve this page 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. Page wiki View or edit the community-maintained wiki page associated with this page.

Function std.algorithm.iteration.sum

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

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 reduce'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 sumation.

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 reduce!((a, b) => a + b)(0, r), which is not specialized for summation.

Prototypes

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)));

Returns

The sum of all the elements in the range r.

Example

Ditto

import std.range;

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

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

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

//Floating point sumation
assert(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));
assert(sum([1F, 2, 3, 4]) == 10);

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

Authors

Andrei Alexandrescu

License

Boost License 1.0.

Comments