31 lines
861 B
C++
31 lines
861 B
C++
#ifndef FESA_MATH_COMPENSATED_SUM_H_
|
|
#define FESA_MATH_COMPENSATED_SUM_H_
|
|
|
|
#include <cmath>
|
|
|
|
namespace fesa::math_internal {
|
|
|
|
/// @brief Preserves the compensated scalar accumulation graph and caller order.
|
|
inline void AddCompensated(const double term, double* sum, double* correction) {
|
|
const double next = *sum + term;
|
|
*correction += std::abs(*sum) >= std::abs(term)
|
|
? (*sum - next) + term
|
|
: (term - next) + *sum;
|
|
*sum = next;
|
|
}
|
|
|
|
/// @brief Owns one sum and its correction without changing reduction order.
|
|
class CompensatedSum {
|
|
public:
|
|
void Add(const double term) { AddCompensated(term, &sum_, &correction_); }
|
|
double Value() const { return sum_ + correction_; }
|
|
|
|
private:
|
|
double sum_ = 0.0;
|
|
double correction_ = 0.0;
|
|
};
|
|
|
|
} // namespace fesa::math_internal
|
|
|
|
#endif // FESA_MATH_COMPENSATED_SUM_H_
|