# Summator

Output range for summation. Precise, KB2, KBN and Kahan algorithms are supported.

struct Summator (
T
Summation summation = Summation.Precise
) if (
isMutable!T &&
(
summation == Summation.Precise &&
isFloatingPoint!T
||
summation == Summation.Kahan &&
isSummable!T
||
(
summation == Summation.KBN ||
summation == Summation.KB2
)
&&
(
isFloatingPoint!T ||
isComplex!T
)
)
) {
F s;
F cs;
F ccs;
F s;
F c;
F s;
F c;
F y;
F t;
}

this
this(T n)

~this
~this()

## Postblit

A postblit is present on this object, but not explicitly documented in the source.

## Members

### Functions

isFinite
bool isFinite()

Returns true if current sum is finite (not infinite or NaN).

isFinite
bool isFinite()

Returns true if current sum is finite (not infinite or NaN).

isInfinity
bool isInfinity()

Returns true if current sum is ±∞.

isInfinity
bool isInfinity()

Returns true if current sum is ±∞.

isNaN
bool isNaN()

Returns true if current sum is a NaN.

isNaN
bool isNaN()

Returns true if current sum is a NaN.

opAssign
void opAssign(T rhs)

opCast
C opCast()

Returns Summator with extended internal partial sums.

opCast
C opCast()

opOpAssign
void opOpAssign(T rhs)
void opOpAssign(ref Summator rhs)
void opOpAssign(T rhs)
void opOpAssign(ref Summator rhs)

put
void put(T n)

Adds x to the internal partial sums.

sum
T sum()

Returns the value of the sum.

unsafePut
void unsafePut(F x)

Adds x to the internal partial sums. This operation doesn't re-establish special value semantics across iterations (i.e. handling -inf + inf). Preconditions: isFinite(x).

## Examples

```1 import std.range;
2 import std.algorithm: swap;
3
4 ///Moving mean
5 class MovingAverage
6 {
7     Summator!double summator;
8     double[] circularBuffer;
9     size_t frontIndex;
10
11     double avg() @property
12     {
13         return summator.sum() / circularBuffer.length;
14     }
15
16     this(double[] buffer)
17     {
18         assert(!buffer.empty);
19         circularBuffer = buffer;
20         summator = 0;
21         .put(summator, buffer);
22     }
23
24     ///operation without rounding
25     void put(double x)
26     {
27         summator += x;
28         swap(circularBuffer[frontIndex++], x);
29         summator -= x;
30         frontIndex %= circularBuffer.length;
31     }
32 }
33
34 /// ma always keeps pricese average of last 1000 elements
35 auto ma = new MovingAverage(iota(0.0, 1000.0).array);
36 assert(ma.avg == (1000*999/2) / 1000.0);
37 /// move by 10 elements
38 put(ma, iota(1000.0, 1010.0));
39 assert(ma.avg == (1010*1009/2 - 10*9/2) / 1000.0);```

move by 10 elements

```1 Summator!double d;
2 assert(d.isNaN());
3 assert(d.sum().isNaN());
4 d += 100;
5 assert(d.isNaN());
6 assert(d.sum().isNaN());
7 d = 1;
8 d += 1000;
9 assert(d.sum == 1001);```