cyqlone develop
Fast, parallel and vectorized solver for linear systems with optimal control structure.
Loading...
Searching...
No Matches
neumaier.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// Kahan-Babuška-Neumaier compensated summation.
5/// @ingroup topic-utilities
6
7#include <cyqlone/config.hpp>
8#include <cmath>
9#include <type_traits>
10
11namespace cyqlone {
12
13/// Kahan-Babuška-Neumaier compensated summation.
14/// @ingroup topic-utilities
15template <class T>
17 public:
20 NeumaierSum(T value = {}) : sum(value) {}
21 operator T() const { return sum + compensation; }
22
23 NeumaierSum operator-() const { return {-sum, -compensation}; }
25 using std::abs;
26 T t = sum + v;
27 if constexpr (std::is_floating_point_v<T>) {
28 if (abs(sum) >= abs(v))
29 compensation += (sum - t) + v;
30 else
31 compensation += (v - t) + sum;
32 } else {
33 auto m = abs(sum) >= abs(v);
34#if BATMAT_WITH_GSI_HPC_SIMD
36 select(m, compensation + ((sum - t) + v), compensation + ((v - t) + sum));
37#else
38 where(m, compensation) += (sum - t) + v;
39 where(!m, compensation) += (v - t) + sum;
40#endif
41 }
42 sum = t;
43 return *this;
44 }
46 *this += other.sum;
47 *this += other.compensation;
48 return *this;
49 }
50 NeumaierSum &operator-=(T v) { return *this += -v; }
52 *this -= other.sum;
53 *this -= other.compensation;
54 return *this;
55 }
56
57 friend NeumaierSum operator+(NeumaierSum lhs, T rhs) {
58 lhs += rhs;
59 return lhs;
60 }
61 friend NeumaierSum operator+(T lhs, NeumaierSum rhs) {
62 rhs += lhs;
63 return rhs;
64 }
66 lhs += rhs;
67 return lhs;
68 }
69
70 friend NeumaierSum operator-(NeumaierSum lhs, T rhs) {
71 lhs -= rhs;
72 return lhs;
73 }
74 friend NeumaierSum operator-(T lhs, NeumaierSum rhs) { return lhs + (-rhs); }
75 friend NeumaierSum operator-(NeumaierSum lhs, const NeumaierSum &rhs) {
76 lhs -= rhs;
77 return lhs;
78 }
80 NeumaierSum res = lhs.sum * rhs.sum;
81 res += lhs.sum * rhs.compensation;
82 res += lhs.compensation * rhs.sum;
83 res += lhs.compensation * rhs.compensation;
84 return res;
85 }
86 friend NeumaierSum operator*(NeumaierSum lhs, T rhs) {
87 return {lhs.sum * rhs, lhs.compensation * rhs};
88 }
89 friend NeumaierSum operator*(T lhs, NeumaierSum rhs) {
90 return {rhs.sum * lhs, rhs.compensation * lhs};
91 }
92};
93
94} // namespace cyqlone
NeumaierSum(T sum, T compensation)
Definition neumaier.hpp:19
friend NeumaierSum operator*(NeumaierSum lhs, NeumaierSum rhs)
Definition neumaier.hpp:79
friend NeumaierSum operator*(NeumaierSum lhs, T rhs)
Definition neumaier.hpp:86
friend NeumaierSum operator-(T lhs, NeumaierSum rhs)
Definition neumaier.hpp:74
friend NeumaierSum operator-(NeumaierSum lhs, T rhs)
Definition neumaier.hpp:70
friend NeumaierSum operator*(T lhs, NeumaierSum rhs)
Definition neumaier.hpp:89
friend NeumaierSum operator+(T lhs, NeumaierSum rhs)
Definition neumaier.hpp:61
NeumaierSum & operator+=(T v)
Definition neumaier.hpp:24
NeumaierSum(T value={})
Definition neumaier.hpp:20
friend NeumaierSum operator-(NeumaierSum lhs, const NeumaierSum &rhs)
Definition neumaier.hpp:75
friend NeumaierSum operator+(NeumaierSum lhs, NeumaierSum rhs)
Definition neumaier.hpp:65
friend NeumaierSum operator+(NeumaierSum lhs, T rhs)
Definition neumaier.hpp:57
NeumaierSum & operator+=(const NeumaierSum &other)
Definition neumaier.hpp:45
NeumaierSum & operator-=(T v)
Definition neumaier.hpp:50
NeumaierSum & operator-=(const NeumaierSum &other)
Definition neumaier.hpp:51
NeumaierSum operator-() const
Definition neumaier.hpp:23
constexpr index_t v