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>
14 struct KahanSum {
15 T sum = 0.;
16 T cor = 0.;
17 KahanSum& operator+=( const T& var )
18 {
19
20 T t = sum + var;
22 {
23 cor += select( abs(sum) >= abs(var), (sum-t)+var, (var-t) + sum );
24 }
25 else {
26
27 cor += std::abs(sum) >= std::abs(var) ? (sum-t)+var : (var-t) + sum;
28 }
29 sum = t;
30 return *this;
31 }
32 T operator()() const { return sum + cor; }
33 };
34 template <typename T>
35 KahanSum<T> operator+( const KahanSum<T>& l, const T& var )
36 {
37 KahanSum<T> rt;
38 T y = var - l.cor;
39 T t = l.sum + y;
40 rt.cor = (t-l.sum)-y;
41 rt.sum = t;
42 return rt;
43 }
44
45
46 template <typename T> T KahanBabushkaKleinSum(const std::vector<T>& container)
47 {
48 T sum = 0.0;
49 T cs = 0.0;
50 T ccs = 0.0;
51 T c = 0.0;
52 T cc = 0.0;
53
54 for( auto& input : container )
55 {
56 T t = sum + input;
57 if ( std::fabs(sum) >= std::fabs(input) )
58 {
59 c = (sum - t) + input;
60 }
61 else c = (input - t) + sum;
62 sum = t;
63 t = cs + c;
64 if ( std::fabs(cs) >= std::fabs(c) )
65 cc = (cs - t) + c;
66 else
67 cc = (c - t) + cs;
68 cs = t;
69 ccs = ccs + cc;
70 }
71 return sum + cs + ccs;
72 }
73}
74
75#endif
real_t abs(const Complex< real_t > &v)
Definition Complex.h:45
Complex< real_t > operator+(const Complex< real_t > &lhs, const R2_t &rhs)
Definition Complex.h:50
T KahanBabushkaKleinSum(const std::vector< T > &container)
Definition KahanSum.h:46
Implements Kahan summation for better precision with (repeated) floating point addition.
Definition KahanSum.h:14
T operator()() const
Definition KahanSum.h:32
KahanSum & operator+=(const T &var)
Definition KahanSum.h:17