fsum

Computes sum of range.

template fsum(F, Summation summation = Summation.Precise)
F
fsum
(
Range
)
(
Range r
)
if (
isSummable!(Range, F)
)
if (
isFloatingPoint!F &&
isMutable!F
)

Examples

1 import std.algorithm;
2 auto ar = [1, 1e100, 1, -1e100].map!(a => a*10000);
3 const r = 20000;
4 assert(r == ar.fsum!(Summation.KBN));
5 assert(r == ar.fsum!(Summation.KB2));
6 assert(r == ar.fsum); //Summation.Precise
1 import std.math, std.algorithm, std.range;
2 auto ar = 1000
3     .iota
4     .map!(n => 1.7L.pow(n+1) - 1.7L.pow(n))
5     .array
6     ;
7 //Summation.Precise is default
8 real d = 1.7L.pow(1000);
9 assert(fsum(ar.chain([-d])) == -1);
10 assert(fsum(-d, ar.retro) == -1);

Naive, Pairwise and Kahan algorithms can be used for user defined types.

1 static struct Quaternion(F)
2     if (isFloatingPoint!F)
3 {
4     F[3] array;
5 
6     /// + and - operator overloading
7     Quaternion opBinary(string op)(auto ref Quaternion rhs) const
8         if (op == "+" || op == "-")
9     {
10         Quaternion ret = void;
11         foreach (i, ref e; ret.array)
12             mixin("e = array[i] "~op~" rhs.array[i];");
13         return ret;
14     }
15 
16     /// += and -= operator overloading
17     Quaternion opOpAssign(string op)(auto ref Quaternion rhs)
18         if (op == "+" || op == "-")
19     {
20         foreach (i, ref e; array)
21             mixin("e "~op~"= rhs.array[i];");
22         return this;
23     }
24 
25     ///constructor with single FP argument
26     this(F f)
27     {
28         array[] = f;
29     }
30 
31     ///assigment with single FP argument
32     void opAssign(F f)
33     {
34         array[] = f;
35     }
36 }
37 
38 Quaternion!double q, p, r;
39 q.array = [0, 1, 2];
40 p.array = [3, 4, 5];
41 r.array = [3, 5, 7];
42 
43 assert(r == [p, q].fsum!(Summation.Naive));
44 assert(r == [p, q].fsum!(Summation.Pairwise));
45 assert(r == [p, q].fsum!(Summation.Kahan));

All summation algorithms available for complex numbers.

1 import std.complex;
2 Complex!double[] ar = [complex(1.0, 2), complex(2, 3), complex(3, 4), complex(4, 5)];
3 Complex!double r = complex(10, 14);
4 assert(r == ar.fsum!(Summation.Fast));
5 assert(r == ar.fsum!(Summation.Naive));
6 assert(r == ar.fsum!(Summation.Pairwise));
7 assert(r == ar.fsum!(Summation.Kahan));
8 assert(r == ar.fsum!(Summation.KBN));
9 assert(r == ar.fsum!(Summation.KB2));
10 assert(r == ar.fsum); //Summation.Precise

Meta