AmpGen 2.1
Loading...
Searching...
No Matches
KahanSum.h
Go to the documentation of this file.
1#ifndef AMPGEN_KAHANSUM_H
2#define AMPGEN_KAHANSUM_H
3
4#ifdef __FAST_MATH__
5#error Compensated summation is unsafe with -ffast-math (/fp:fast)
6#endif
7#include "AmpGen/simd/utils.h"
8
9namespace AmpGen {
13 template <typename T> struct KahanSum {
14 T sum = 0.;
15 T cor = 0.;
16 KahanSum &operator+=(const T &var) {
17 T t = sum + var;
19 cor += select(abs(sum) >= abs(var), (sum - t) + var, (var - t) + sum);
20 } else {
21 cor += std::abs(sum) >= std::abs(var) ? (sum - t) + var : (var - t) + sum;
22 }
23 sum = t;
24 return *this;
25 }
26 T operator()() const { return sum + cor; }
27 };
28 template <typename T> KahanSum<T> operator+(const KahanSum<T> &l, const T &var) {
29 KahanSum<T> rt;
30 T y = var - l.cor;
31 T t = l.sum + y;
32 rt.cor = (t - l.sum) - y;
33 rt.sum = t;
34 return rt;
35 }
36
37 template <typename T> T KahanBabushkaKleinSum(const std::vector<T> &container) {
38 T sum = 0.0;
39 T cs = 0.0;
40 T ccs = 0.0;
41 T c = 0.0;
42 T cc = 0.0;
43
44 for(auto &input : container) {
45 T t = sum + input;
46 if(std::fabs(sum) >= std::fabs(input)) {
47 c = (sum - t) + input;
48 } else
49 c = (input - t) + sum;
50 sum = t;
51 t = cs + c;
52 if(std::fabs(cs) >= std::fabs(c))
53 cc = (cs - t) + c;
54 else
55 cc = (c - t) + cs;
56 cs = t;
57 ccs = ccs + cc;
58 }
59 return sum + cs + ccs;
60 }
61}
62
63#endif
real_t abs(const Complex< real_t > &v)
Definition Complex.h:39
Complex< real_t > operator+(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:43
T KahanBabushkaKleinSum(const std::vector< T > &container)
Definition KahanSum.h:37
Implements Kahan summation for better precision with (repeated) floating point addition.
Definition KahanSum.h:13
T operator()() const
Definition KahanSum.h:26
KahanSum & operator+=(const T &var)
Definition KahanSum.h:16