Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
compensated_sum.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <uni20/core/math.hpp>
6
7#include <cmath>
8
9namespace uni20::linalg::backends::cpu::detail
10{
11
13template <uni20::Real Real> class CompensatedRealSum {
14 public:
15 void add(Real value)
16 {
17 using std::abs;
18
19 Real const next = sum_ + value;
20 if (!uni20::isfinite(next))
21 {
22 sum_ = next;
23 correction_ = Real{};
24 return;
25 }
26 if (abs(sum_) >= abs(value))
27 {
28 correction_ += (sum_ - next) + value;
29 }
30 else
31 {
32 correction_ += (value - next) + sum_;
33 }
34 sum_ = next;
35 }
36
37 [[nodiscard]] Real value() const { return sum_ + correction_; }
38
39 private:
40 Real sum_{};
41 Real correction_{};
42};
43
45template <uni20::RealOrComplex Scalar> class CompensatedSum {
46 public:
47 using real_type = uni20::make_real_t<Scalar>;
48
49 void add(Scalar value)
50 {
51 if constexpr (uni20::Complex<Scalar>)
52 {
53 real_.add(value.real());
54 imaginary_.add(value.imag());
55 }
56 else
57 {
58 real_.add(value);
59 }
60 }
61
62 [[nodiscard]] Scalar value() const
63 {
64 if constexpr (uni20::Complex<Scalar>)
65 {
66 return Scalar{real_.value(), imaginary_.value()};
67 }
68 else
69 {
70 return real_.value();
71 }
72 }
73
74 private:
75 CompensatedRealSum<real_type> real_;
76 CompensatedRealSum<real_type> imaginary_;
77};
78
79} // namespace uni20::linalg::backends::cpu::detail
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
locale_t value
Definition data_table.cpp:49
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
Scalar math helper utilities.
constexpr auto abs(basic_half_int< T > value) -> basic_half_int< T >
Return the absolute value of a half-integer.
Definition half_int.hpp:431
Return the sum of two element values.
Definition elementwise_functions.hpp:102