5#include "../concepts/concepts.hpp"
10using concepts::Accumulator;
32 constexpr operator T() const noexcept {
return sum_; }
34 constexpr void reset() noexcept { sum_ = T{}; }
50 T y = value - correction_;
52 correction_ = (t - sum_) - y;
58 constexpr operator T() const noexcept {
return sum_; }
60 constexpr T
error() const noexcept {
return correction_; }
61 constexpr T
correction() const noexcept {
return correction_; }
63 constexpr void reset() noexcept {
84 if (std::abs(sum_) >= std::abs(value)) {
85 correction_ += (sum_ - t) + value;
87 correction_ += (value - t) + sum_;
93 constexpr T
operator()() const noexcept {
return sum_ + correction_; }
94 constexpr operator T() const noexcept {
return sum_ + correction_; }
96 constexpr T
error() const noexcept {
return correction_; }
97 constexpr T
correction() const noexcept {
return correction_; }
99 constexpr void reset() noexcept {
122 if (std::abs(sum_) >= std::abs(value)) {
123 c = (sum_ - t) + value;
125 c = (value - t) + sum_;
131 if (std::abs(cs_) >= std::abs(c)) {
132 ccs_ += (cs_ - t) + c;
134 ccs_ += (c - t) + cs_;
141 constexpr T
operator()() const noexcept {
return sum_ + cs_ + ccs_; }
142 constexpr operator T() const noexcept {
return sum_ + cs_ + ccs_; }
144 constexpr T
error() const noexcept {
return cs_ + ccs_; }
161template<Field T, std::
size_t ChunkSize = 128>
169 if (count_ < ChunkSize) {
170 buffer_[count_++] = value;
172 sum_ += pairwise_sum(buffer_, ChunkSize);
180 if (count_ == 0)
return sum_;
181 return sum_ + pairwise_sum(buffer_, count_);
184 constexpr operator T() const noexcept {
return operator()(); }
192 T buffer_[ChunkSize];
196 static constexpr T pairwise_sum(
const T* data, std::size_t n)
noexcept {
197 if (n <= 1)
return n ? data[0] : T{};
198 if (n == 2)
return data[0] + data[1];
200 std::size_t mid = n / 2;
201 return pairwise_sum(data, mid) + pairwise_sum(data + mid, n - mid);
211 template<Accumulator<T> A>
213 : impl_{std::make_unique<accumulator_impl<A>>(std::move(acc))} {}
216 : impl_{other.impl_->clone()} {}
219 impl_ = other.impl_->clone();
229 operator T()
const {
return impl_->get(); }
234 struct accumulator_base {
235 virtual ~accumulator_base() =
default;
236 virtual void add(T value) = 0;
237 virtual T get()
const = 0;
238 virtual void reset() = 0;
239 virtual std::unique_ptr<accumulator_base> clone()
const = 0;
243 struct accumulator_impl : accumulator_base {
246 explicit accumulator_impl(A a) : acc{std::move(a)} {}
248 void add(T value)
override { acc += value; }
249 T get()
const override {
return acc(); }
250 void reset()
override { acc.reset(); }
252 std::unique_ptr<accumulator_base> clone()
const override {
253 return std::make_unique<accumulator_impl>(acc);
257 std::unique_ptr<accumulator_base> impl_;
any_accumulator & operator=(const any_accumulator &other)
any_accumulator(const any_accumulator &other)
any_accumulator & operator+=(T value)
constexpr T error() const noexcept
constexpr T correction() const noexcept
constexpr void reset() noexcept
constexpr T operator()() const noexcept
constexpr kahan_accumulator(T init) noexcept
constexpr kahan_accumulator & operator+=(T value) noexcept
constexpr kahan_accumulator() noexcept
constexpr T second_correction() const noexcept
constexpr T correction() const noexcept
constexpr void reset() noexcept
constexpr klein_accumulator(T init) noexcept
constexpr klein_accumulator() noexcept
constexpr T error() const noexcept
constexpr T operator()() const noexcept
constexpr klein_accumulator & operator+=(T value) noexcept
constexpr T error() const noexcept
constexpr void reset() noexcept
constexpr neumaier_accumulator & operator+=(T value) noexcept
constexpr neumaier_accumulator() noexcept
constexpr neumaier_accumulator(T init) noexcept
constexpr T correction() const noexcept
constexpr T operator()() const noexcept
constexpr pairwise_accumulator() noexcept
constexpr void reset() noexcept
constexpr T operator()() const noexcept
constexpr pairwise_accumulator & operator+=(T value) noexcept
constexpr simple_accumulator & operator-=(T value) noexcept
constexpr simple_accumulator(T init) noexcept
constexpr simple_accumulator & operator+=(T value) noexcept
constexpr T operator()() const noexcept
constexpr simple_accumulator() noexcept
constexpr void reset() noexcept