50 auto [sw, sx, sxx] = state;
51 return load_state(sw, sx, sxx);
54 void operator()(T x)
noexcept
56 if constexpr (Stats == stats::variance) {
57 T dx = (sum_w * x) - sum_x;
61 T denom = sum_w * sum_w_old;
62 sum_xx += eve::if_else(denom != T{0}, (dx * dx) / denom, T{0});
64 }
else if constexpr (Stats == stats::mean) {
72 void operator()(T x, T w)
noexcept
74 if constexpr (Stats == stats::variance) {
76 T dx = (sum_w * x) - (sum_x * w);
79 T denom = w * sum_w * sum_w_old;
80 sum_xx += eve::if_else(denom != T{0}, (dx * dx) / denom, T{0});
82 }
else if constexpr (Stats == stats::mean) {
91 requires eve::simd_value<T> && eve::simd_compatible_ptr<U, T>
92 void operator()(U
const* x)
noexcept
98 requires eve::simd_value<T> && eve::simd_compatible_ptr<U, T>
99 void operator()(U
const* x, U
const* w)
noexcept
101 (*this)(T {x}, T {w});
106 [[nodiscard]]
auto stats()
const noexcept -> std::tuple<double, double, double>
108 if constexpr (std::is_floating_point_v<T>) {
109 return {sum_w, sum_x, sum_xx};
110 }
else if constexpr (Stats == stats::variance) {
111 return {eve::reduce(sum_w), eve::reduce(sum_x), combine(sum_w, sum_x, sum_xx)};
112 }
else if constexpr (Stats == stats::mean) {
113 return {eve::reduce(sum_w), eve::reduce(sum_x), 0.0};
116 return {0.0, eve::reduce(sum_x), 0.0};
137 double sample_variance;
139 template<
typename T, stats Stats>
142 auto [sw, sx, sxx] = accumulator.stats();
143 if constexpr (Stats == stats::sum) {
144 count = std::numeric_limits<double>::quiet_NaN();
150 if constexpr (Stats != stats::sum) {
153 mean = std::numeric_limits<double>::quiet_NaN();
155 if constexpr (Stats == stats::variance) {
157 sample_variance = sxx / (sw - 1);
159 variance = std::numeric_limits<double>::quiet_NaN();
160 sample_variance = std::numeric_limits<double>::quiet_NaN();