15#include <eve/module/math.hpp>
16#include <eve/module/special.hpp>
18#include "bivariate.hpp"
19#include "compensated_sum.hpp"
20#include "univariate.hpp"
22namespace VSTAT_NAMESPACE
34enum class nan_policy { propagate, omit };
39template<eve::simd_value T, std::random_access_iterator I,
typename F>
40 requires std::is_invocable_v<F, std::iter_value_t<I>>
41auto inline load(I iter, F&& func)
43 return [&]<std::size_t... Idx>(std::index_sequence<Idx...>) ->
auto
44 {
return T {std::forward<F>(func)(*(iter + Idx))...}; }(std::make_index_sequence<T::size()> {});
48template<eve::simd_value T, std::random_access_iterator I, std::random_access_iterator J,
typename F>
49 requires std::is_invocable_v<F, std::iter_value_t<I>, std::iter_value_t<J>>
50auto inline load(I iter1, J iter2, F&& func)
52 return [&]<std::size_t... Idx>(std::index_sequence<Idx...>) ->
auto
53 {
return T {std::forward<F>(func)(*(iter1 + Idx), *(iter2 + Idx))...}; }(std::make_index_sequence<T::size()> {});
57template<
typename Distance,
typename... Iters>
58auto inline advance(Distance d, Iters&... iters) ->
void
60 (std::advance(iters, d), ...);
67concept arithmetic = std::is_arithmetic_v<T>;
69template<
typename F,
typename... Args>
70concept arithmetic_projection =
requires(F&&) {
71 { std::is_invocable_v<F, Args...> };
72 { arithmetic<std::remove_reference_t<std::invoke_result_t<F, Args...>>> };
95template<std::
floating_po
int T, stats Stats = stats::variance, std::random_access_iterator I,
typename F = std::
identity>
96 requires concepts::arithmetic_projection<F, std::iter_value_t<I>>
99 using wide = eve::wide<T>;
100 auto constexpr s {wide::size()};
101 auto const n {std::distance(first, last)};
102 auto const m = n - (n % s);
105 univariate_accumulator<T, Stats> scalar_acc;
106 for (; first < last; ++first) {
107 scalar_acc(std::invoke(std::forward<F>(f), *first));
109 return univariate_statistics(scalar_acc);
112 univariate_accumulator<wide, Stats> acc;
113 for (
size_t i = 0; i < m; i += s) {
114 acc(detail::load<wide>(first, std::forward<F>(f)));
115 detail::advance(s, first);
120 auto [sw, sx, sxx] = acc.stats();
121 auto scalar_acc = univariate_accumulator<T, Stats>::load_state(sw, sx, sxx);
122 for (; first < last; ++first) {
123 scalar_acc(std::invoke(std::forward<F>(f), *first));
125 return univariate_statistics(scalar_acc);
127 return univariate_statistics(acc);
143template<std::floating_point T,
144 stats Stats = stats::variance,
145 std::random_access_iterator I,
146 std::random_access_iterator J,
147 typename F = std::identity>
148 requires concepts::arithmetic_projection<F, std::iter_value_t<I>> and std::is_arithmetic_v<std::iter_value_t<J>>
149inline auto accumulate(I first1, I last1, J first2, F&& f = F {})
noexcept
152 using wide = eve::wide<T>;
153 auto constexpr s {wide::size()};
154 auto const n {std::distance(first1, last1)};
155 const size_t m = n - n % s;
158 univariate_accumulator<T, Stats> scalar_acc;
159 for (; first1 < last1; ++first1, ++first2) {
160 scalar_acc(std::invoke(std::forward<F>(f), *first1), *first2);
162 return univariate_statistics(scalar_acc);
165 univariate_accumulator<wide, Stats> acc;
166 for (
size_t i = 0; i < m; i += s) {
167 acc(detail::load<wide>(first1, std::forward<F>(f)), wide {first2});
168 detail::advance(s, first1, first2);
173 auto [sw, sx, sxx] = acc.stats();
174 auto scalar_acc = univariate_accumulator<T, Stats>::load_state(sw, sx, sxx);
175 for (; first1 < last1; ++first1, ++first2) {
176 scalar_acc(std::invoke(std::forward<F>(f), *first1), *first2);
178 return univariate_statistics(scalar_acc);
180 return univariate_statistics(acc);
213template<std::floating_point T,
214 stats Stats = stats::variance,
215 nan_policy Policy = nan_policy::propagate,
216 std::random_access_iterator I,
217 std::random_access_iterator J,
219 typename F1 = std::identity,
220 typename F2 = std::identity>
221 requires std::is_invocable_v<F1, std::iter_value_t<I>> and std::is_invocable_v<F2, std::iter_value_t<J>>
222 and std::is_invocable_v<BinaryOp,
223 std::invoke_result_t<F1, std::iter_value_t<I>>,
224 std::invoke_result_t<F2, std::iter_value_t<J>>>
225 and concepts::arithmetic_projection<BinaryOp,
226 std::invoke_result_t<F1, std::iter_value_t<I>>,
227 std::invoke_result_t<F2, std::iter_value_t<J>>>
231 BinaryOp&& op = BinaryOp {},
233 F2&& f2 = F2 {})
noexcept
234 -> std::conditional_t<Policy == nan_policy::omit, std::pair<univariate_statistics, std::size_t>, univariate_statistics>
236 using wide = eve::wide<T>;
237 auto constexpr s {wide::size()};
238 auto const n {std::distance(first1, last1)};
239 auto const m = n - n % s;
241 auto f = [&](
auto a,
auto b)
244 std::forward<BinaryOp>(op), std::invoke(std::forward<F1>(f1), a), std::invoke(std::forward<F2>(f2), b));
247 if constexpr (Policy == nan_policy::propagate) {
249 univariate_accumulator<T, Stats> scalar_acc;
250 for (; first1 < last1; ++first1, ++first2) {
251 scalar_acc(f(*first1, *first2));
253 return univariate_statistics(scalar_acc);
256 univariate_accumulator<wide, Stats> acc;
257 for (
size_t i = 0; i < m; i += s) {
258 acc(detail::load<wide>(first1, first2, f));
259 detail::advance(s, first1, first2);
264 auto [sw, sx, sxx] = acc.stats();
265 auto scalar_acc = univariate_accumulator<T, Stats>::load_state(sw, sx, sxx);
266 for (; first1 < last1; ++first1, ++first2) {
267 scalar_acc(f(*first1, *first2));
269 return univariate_statistics(scalar_acc);
271 return univariate_statistics(acc);
273 univariate_accumulator<wide, Stats> acc;
275 for (
size_t i = 0; i < m; i += s) {
281 auto finite = eve::is_finite((a - a) + (b - b));
282 if (eve::all(finite)) [[likely]] {
286 wide sa = eve::if_else(finite, a, wide {0});
287 wide sb = eve::if_else(finite, b, wide {0});
288 wide w = eve::if_else(finite, wide {1}, wide {0});
290 skipped += eve::if_else(finite, wide {0}, wide {1});
292 detail::advance(s, first1, first2);
295 auto se = univariate_accumulator<T, Stats>::load_state(acc.stats());
296 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
297 for (; first1 < last1; ++first1, ++first2) {
298 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
300 se(f(*first1, *first2));
308 return {univariate_statistics(se), skipped_count};
321template<std::floating_point T,
322 stats Stats = stats::variance,
323 nan_policy Policy = nan_policy::propagate,
324 std::random_access_iterator I,
325 std::random_access_iterator J,
326 std::random_access_iterator K,
328 typename F1 = std::identity,
329 typename F2 = std::identity>
330 requires std::is_arithmetic_v<std::iter_value_t<K>> && std::is_invocable_v<F1, std::iter_value_t<I>>
331 && std::is_invocable_v<F2, std::iter_value_t<J>>
332 && std::is_invocable_v<BinaryOp,
333 std::invoke_result_t<F1, std::iter_value_t<I>>,
334 std::invoke_result_t<F2, std::iter_value_t<J>>>
335 && concepts::arithmetic_projection<BinaryOp,
336 std::invoke_result_t<F1, std::iter_value_t<I>>,
337 std::invoke_result_t<F2, std::iter_value_t<J>>>
342 BinaryOp&& op = BinaryOp {},
344 F2&& f2 = F2 {})
noexcept
345 -> std::conditional_t<Policy == nan_policy::omit, std::pair<univariate_statistics, std::size_t>, univariate_statistics>
347 using wide = eve::wide<T>;
348 auto constexpr s {wide::size()};
349 auto const n {std::distance(first1, last1)};
350 auto const m = n - n % s;
352 auto f = [&](
auto a,
auto b)
355 std::forward<BinaryOp>(op), std::invoke(std::forward<F1>(f1), a), std::invoke(std::forward<F2>(f2), b));
358 if constexpr (Policy == nan_policy::propagate) {
360 univariate_accumulator<T, Stats> scalar_acc;
361 for (; first1 < last1; ++first1, ++first2, ++first3) {
362 scalar_acc(f(*first1, *first2), *first3);
364 return univariate_statistics(scalar_acc);
367 univariate_accumulator<wide, Stats> acc;
368 for (
size_t i = 0; i < m; i += s) {
369 acc(detail::load<wide>(first1, first2, f), wide {std::to_address(first3)});
370 detail::advance(s, first1, first2, first3);
375 auto [sw, sx, sxx] = acc.stats();
376 auto scalar_acc = univariate_accumulator<T, Stats>::load_state(sw, sx, sxx);
377 for (; first1 < last1; ++first1, ++first2, ++first3) {
378 scalar_acc(f(*first1, *first2), *first3);
380 return univariate_statistics(scalar_acc);
382 return univariate_statistics(acc);
384 univariate_accumulator<wide, Stats> acc;
386 for (
size_t i = 0; i < m; i += s) {
389 wide weight {first3};
390 auto finite = eve::is_finite((a - a) + (b - b));
391 if (eve::all(finite)) [[likely]] {
392 acc(f(a, b), weight);
395 wide sa = eve::if_else(finite, a, wide {0});
396 wide sb = eve::if_else(finite, b, wide {0});
397 wide w = eve::if_else(finite, weight, wide {0});
399 skipped += eve::if_else(finite, wide {0}, wide {1});
401 detail::advance(s, first1, first2, first3);
404 auto se = univariate_accumulator<T, Stats>::load_state(acc.stats());
405 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
406 for (; first1 < last1; ++first1, ++first2, ++first3) {
407 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
408 se(f(*first1, *first2), *first3);
415 return {univariate_statistics(se), skipped_count};
475template<std::floating_point T,
476 nan_policy Policy = nan_policy::propagate,
477 std::random_access_iterator I,
478 std::random_access_iterator J,
479 typename F1 = std::identity,
480 typename F2 = std::identity>
481 requires concepts::arithmetic_projection<F1, std::iter_value_t<I>>
482 and concepts::arithmetic_projection<F2, std::iter_value_t<J>>
483inline auto accumulate(I first1, I last1, J first2, F1&& f1 = F1 {}, F2&& f2 = F2 {})
noexcept
484 -> std::conditional_t<Policy == nan_policy::omit, std::pair<bivariate_statistics, std::size_t>, bivariate_statistics>
486 using wide = eve::wide<T>;
487 auto constexpr s {wide::size()};
488 auto const n {std::distance(first1, last1)};
489 auto const m = n - n % s;
491 if constexpr (Policy == nan_policy::propagate) {
493 bivariate_accumulator<T> scalar_acc;
494 for (; first1 < last1; ++first1, ++first2) {
495 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2));
497 return bivariate_statistics(scalar_acc);
500 bivariate_accumulator<wide> acc;
501 for (
size_t i = 0; i < m; i += s) {
502 acc(detail::load<wide>(first1, std::forward<F1>(f1)), detail::load<wide>(first2, std::forward<F2>(f2)));
503 detail::advance(s, first1, first2);
507 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
508 auto scalar_acc = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
509 for (; first1 < last1; ++first1, ++first2) {
510 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2));
512 return bivariate_statistics(scalar_acc);
515 return bivariate_statistics(acc);
517 bivariate_accumulator<wide> acc;
519 for (
size_t i = 0; i < m; i += s) {
522 auto finite = eve::is_finite((a - a) + (b - b));
523 if (eve::all(finite)) [[likely]] {
527 acc(std::invoke(f1, a), std::invoke(f2, b));
529 wide sa = eve::if_else(finite, a, wide {0});
530 wide sb = eve::if_else(finite, b, wide {0});
531 wide w = eve::if_else(finite, wide {1}, wide {0});
532 acc(std::invoke(f1, sa), std::invoke(f2, sb), w);
533 skipped += eve::if_else(finite, wide {0}, wide {1});
535 detail::advance(s, first1, first2);
538 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
539 auto be = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
540 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
541 for (; first1 < last1; ++first1, ++first2) {
542 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
543 be(std::invoke(f1, *first1), std::invoke(f2, *first2));
550 return {bivariate_statistics(be), skipped_count};
561template<std::floating_point T,
562 nan_policy Policy = nan_policy::propagate,
563 std::random_access_iterator I,
564 std::random_access_iterator J,
565 std::random_access_iterator K,
566 typename F1 = std::identity,
567 typename F2 = std::identity>
568 requires concepts::arithmetic_projection<F1, std::iter_value_t<I>>
569 and concepts::arithmetic_projection<F2, std::iter_value_t<J>> and std::is_arithmetic_v<std::iter_value_t<K>>
570inline auto accumulate(
571 I first1, I last1, J first2, K first3, F1&& f1 = F1 {}, F2&& f2 = F2 {})
noexcept
572 -> std::conditional_t<Policy == nan_policy::omit, std::pair<bivariate_statistics, std::size_t>, bivariate_statistics>
574 using wide = eve::wide<T>;
575 auto constexpr s {wide::size()};
576 auto const n = std::distance(first1, last1);
577 auto const m = n - n % s;
579 if constexpr (Policy == nan_policy::propagate) {
581 bivariate_accumulator<T> scalar_acc;
582 for (; first1 < last1; ++first1, ++first2, ++first3) {
584 std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2), *first3);
586 return bivariate_statistics(scalar_acc);
589 bivariate_accumulator<wide> acc;
590 for (
size_t i = 0; i < m; i += s) {
591 acc(detail::load<wide>(first1, std::forward<F1>(f1)),
592 detail::load<wide>(first2, std::forward<F2>(f2)),
594 detail::advance(s, first1, first2, first3);
598 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
599 auto scalar_acc = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
600 for (; first1 < last1; ++first1, ++first2, ++first3) {
601 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2), *first3);
603 return bivariate_statistics(scalar_acc);
605 return bivariate_statistics(acc);
607 bivariate_accumulator<wide> acc;
609 for (
size_t i = 0; i < m; i += s) {
612 wide weight {first3};
613 auto finite = eve::is_finite((a - a) + (b - b));
614 if (eve::all(finite)) [[likely]] {
615 acc(std::invoke(f1, a), std::invoke(f2, b), weight);
617 wide sa = eve::if_else(finite, a, wide {0});
618 wide sb = eve::if_else(finite, b, wide {0});
619 wide w = eve::if_else(finite, weight, wide {0});
620 acc(std::invoke(f1, sa), std::invoke(f2, sb), w);
621 skipped += eve::if_else(finite, wide {0}, wide {1});
623 detail::advance(s, first1, first2, first3);
626 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
627 auto be = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
628 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
629 for (; first1 < last1; ++first1, ++first2, ++first3) {
630 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
631 be(std::invoke(f1, *first1), std::invoke(f2, *first2), *first3);
638 return {bivariate_statistics(be), skipped_count};
665template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
666inline auto r2_score(I first1, I last1, J first2)
noexcept ->
double
668 using wide = eve::wide<T>;
669 auto constexpr s {wide::size()};
670 auto const n {std::distance(first1, last1)};
671 auto const m {n - (n % s)};
675 for (
auto i = 0; i < m; i += s) {
676 wide y_true {first1};
677 wide y_pred {first2};
678 wx(eve::sqr(y_true - y_pred));
680 detail::advance(s, first1, first2);
687 for (; first1 < last1; ++first1, ++first2) {
688 sx(eve::sqr(*first1 - *first2));
695 return tss < std::numeric_limits<double>::epsilon() ? std::numeric_limits<double>::lowest() : 1.0 - (rss / tss);
709template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
710inline auto r2_score(I first1, I last1, J first2, K first3)
noexcept ->
double
712 using wide = eve::wide<T>;
713 auto constexpr s {wide::size()};
714 auto const n {std::distance(first1, last1)};
715 auto const m {n - (n % s)};
719 for (
auto i = 0; i < m; i += s) {
720 wide y_true {first1};
721 wide y_pred {first2};
722 wide weight {first3};
723 wx(eve::sqr(y_true - y_pred), weight);
725 detail::advance(s, first1, first2, first3);
732 for (; first1 < last1; ++first1, ++first2, ++first3) {
733 sx(eve::sqr(*first1 - *first2), *first3);
734 sy(*first1, *first3);
740 return tss < std::numeric_limits<double>::epsilon() ? std::numeric_limits<double>::lowest() : 1.0 - rss / tss;
760template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J>
762 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
764 if constexpr (Policy == nan_policy::propagate) {
765 using wide = eve::wide<T>;
766 auto constexpr s {wide::size()};
767 auto const n {std::distance(first1, last1)};
768 auto const m {n - n % s};
771 for (
auto i = 0; i < m; i += s) {
772 wide y_true {first1};
773 wide y_pred {first2};
774 we(eve::sqr(y_true - y_pred));
775 detail::advance(s, first1, first2);
780 for (; first1 < last1; ++first1, ++first2) {
781 se(eve::sqr(*first1 - *first2));
785 auto [st, skipped] = univariate::accumulate<T, stats::mean, nan_policy::omit>(
786 first1, last1, first2, [](
auto a,
auto b) {
return eve::sqr(a - b); });
787 return {st.mean, skipped};
801template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
803 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
805 if constexpr (Policy == nan_policy::propagate) {
806 using wide = eve::wide<T>;
807 auto constexpr s {wide::size()};
808 auto const n {std::distance(first1, last1)};
809 auto const m {n - n % s};
812 for (
auto i = 0; i < m; i += s) {
813 wide y_true {first1};
814 wide y_pred {first2};
815 wide weight {first3};
816 we(eve::sqr(y_true - y_pred), weight);
817 detail::advance(s, first1, first2, first3);
822 for (; first1 < last1; ++first1, ++first2, ++first3) {
823 se(eve::sqr(*first1 - *first2), *first3);
827 auto [st, skipped] = univariate::accumulate<T, stats::mean, nan_policy::omit>(
828 first1, last1, first2, first3, [](
auto a,
auto b) {
return eve::sqr(a - b); });
829 return {st.mean, skipped};
859template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J>
861 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
863 using wide = eve::wide<T>;
864 auto constexpr s {wide::size()};
865 auto const n {std::distance(first1, last1)};
866 auto const m = n - n % s;
871 if constexpr (Policy == nan_policy::propagate) {
872 for (
size_t i = 0; i < m; i += s) {
877 detail::advance(s, first1, first2);
882 for (; first1 < last1; ++first1, ++first2) {
883 se(eve::sqr(*first1 - *first2));
889 return var > 0.0 ? mean / var : 0.0;
892 for (
size_t i = 0; i < m; i += s) {
895 auto finite = eve::is_finite((a - a) + (b - b));
896 if (eve::all(finite)) [[likely]] {
900 wide sa = eve::if_else(finite, a, wide {0});
901 wide sb = eve::if_else(finite, b, wide {0});
902 wide w = eve::if_else(finite, wide {1}, wide {0});
907 we(eve::sqr(sa - sb), w);
909 skipped += eve::if_else(finite, wide {0}, wide {1});
911 detail::advance(s, first1, first2);
916 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
917 for (; first1 < last1; ++first1, ++first2) {
918 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
919 se(eve::sqr(*first1 - *first2));
930 return {var > 0.0 ? mean / var : 0.0, skipped_count};
939template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
941 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
943 using wide = eve::wide<T>;
944 auto constexpr s {wide::size()};
945 auto const n {std::distance(first1, last1)};
946 auto const m = n - n % s;
951 if constexpr (Policy == nan_policy::propagate) {
952 for (
size_t i = 0; i < m; i += s) {
955 wide weight {first3};
956 we(eve::sqr(a - b), weight);
958 detail::advance(s, first1, first2, first3);
963 for (; first1 < last1; ++first1, ++first2, ++first3) {
964 se(eve::sqr(*first1 - *first2), *first3);
965 sv(*first2, *first3);
970 return var > 0.0 ? mean / var : 0.0;
973 for (
size_t i = 0; i < m; i += s) {
976 wide weight {first3};
977 auto finite = eve::is_finite((a - a) + (b - b));
978 if (eve::all(finite)) [[likely]] {
979 we(eve::sqr(a - b), weight);
982 wide sa = eve::if_else(finite, a, wide {0});
983 wide sb = eve::if_else(finite, b, wide {0});
984 wide w = eve::if_else(finite, weight, wide {0});
985 we(eve::sqr(sa - sb), w);
987 skipped += eve::if_else(finite, wide {0}, wide {1});
989 detail::advance(s, first1, first2, first3);
994 auto skipped_count =
static_cast<std::size_t
>(eve::reduce(skipped));
995 for (; first1 < last1; ++first1, ++first2, ++first3) {
996 if (std::isfinite(*first1) && std::isfinite(*first2)) [[likely]] {
997 se(eve::sqr(*first1 - *first2), *first3);
998 sv(*first2, *first3);
1008 return {var > 0.0 ? mean / var : 0.0, skipped_count};
1022template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
1025 using wide = eve::wide<T>;
1026 auto constexpr s {wide::size()};
1027 auto const n {std::distance(first1, last1)};
1028 auto const m {n - n % s};
1031 for (
auto i = 0; i < m; i += s) {
1032 wide y_true {first1};
1033 wide y_pred {first2};
1034 we(eve::sqr(eve::log1p(y_true) - eve::log1p(y_pred)));
1035 detail::advance(s, first1, first2);
1040 for (; first1 < last1; ++first1, ++first2) {
1041 se(eve::sqr(eve::log1p(*first1) - eve::log1p(*first2)));
1056template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
1059 using wide = eve::wide<T>;
1060 auto constexpr s {wide::size()};
1061 auto const n {std::distance(first1, last1)};
1062 auto const m {n - n % s};
1065 for (
auto i = 0; i < m; i += s) {
1066 wide y_true {first1};
1067 wide y_pred {first2};
1068 wide weight {first3};
1069 we(eve::sqr(eve::log1p(y_true) - eve::log1p(y_pred)), weight);
1070 detail::advance(s, first1, first2, first3);
1075 for (; first1 < last1; ++first1, ++first2, ++first3) {
1076 se(eve::sqr(eve::log1p(*first1) - eve::log1p(*first2)), *first3);
1098template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J>
1100 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
1102 if constexpr (Policy == nan_policy::propagate) {
1103 using wide = eve::wide<T>;
1104 auto constexpr s {wide::size()};
1105 auto const n {std::distance(first1, last1)};
1106 auto const m {n - n % s};
1109 for (
auto i = 0; i < m; i += s) {
1110 wide y_true {first1};
1111 wide y_pred {first2};
1112 we(eve::abs(y_true - y_pred));
1113 detail::advance(s, first1, first2);
1118 for (; first1 < last1; ++first1, ++first2) {
1119 se(eve::abs(*first1 - *first2));
1123 auto [st, skipped] = univariate::accumulate<T, stats::mean, nan_policy::omit>(
1124 first1, last1, first2, [](
auto a,
auto b) {
return eve::abs(a - b); });
1125 return {st.mean, skipped};
1139template<std::
floating_po
int T, nan_policy Policy = nan_policy::propagate, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
1141 -> std::conditional_t<Policy == nan_policy::omit, std::pair<double, std::size_t>,
double>
1143 if constexpr (Policy == nan_policy::propagate) {
1144 using wide = eve::wide<T>;
1145 auto constexpr s {wide::size()};
1146 auto const n {std::distance(first1, last1)};
1147 auto const m {n - n % s};
1150 for (
auto i = 0; i < m; i += s) {
1151 wide y_true {first1};
1152 wide y_pred {first2};
1153 wide weight {first3};
1154 we(eve::abs(y_true - y_pred), weight);
1155 detail::advance(s, first1, first2, first3);
1160 for (; first1 < last1; ++first1, ++first2, ++first3) {
1161 se(eve::abs(*first1 - *first2), *first3);
1165 auto [st, skipped] = univariate::accumulate<T, stats::mean, nan_policy::omit>(
1166 first1, last1, first2, first3, [](
auto a,
auto b) {
return eve::abs(a - b); });
1167 return {st.mean, skipped};
1185template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
1188 using wide = eve::wide<T>;
1189 auto constexpr s {wide::size()};
1190 auto const n {std::distance(first1, last1)};
1191 auto const m {n - n % s};
1193 auto constexpr eps {std::numeric_limits<T>::epsilon()};
1196 for (
auto i = 0; i < m; i += s) {
1197 wide y_true {first1};
1198 wide y_pred {first2};
1199 we(eve::abs(y_true - y_pred) / eve::max(eps, eve::abs(y_true)));
1200 detail::advance(s, first1, first2);
1205 for (; first1 < last1; ++first1, ++first2) {
1206 se(eve::abs(*first1 - *first2) / eve::max(eps, eve::abs(*first1)));
1221template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
1225 using wide = eve::wide<T>;
1226 auto constexpr s {wide::size()};
1227 auto const n {std::distance(first1, last1)};
1228 auto const m {n - n % s};
1230 auto constexpr eps {std::numeric_limits<T>::epsilon()};
1233 for (
auto i = 0; i < m; i += s) {
1234 wide y_true {first1};
1235 wide y_pred {first2};
1236 wide weight {first3};
1237 we(eve::abs(y_true - y_pred) / eve::max(eps, eve::abs(y_true)), weight);
1238 detail::advance(s, first1, first2, first3);
1243 for (; first1 < last1; ++first1, ++first2, ++first3) {
1244 se(eve::abs(*first1 - *first2) / eve::max(eps, eve::abs(*first1)), *first3);
1260template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
1263 using wide = eve::wide<T>;
1264 auto constexpr s {wide::size()};
1265 auto const n {std::distance(first1, last1)};
1266 auto const m {n - n % s};
1269 for (
auto i = 0; i < m; i += s) {
1270 wide y_true {first1};
1271 wide y_pred {first2};
1272 we(y_pred - y_true * eve::log(y_pred) + eve::log_abs_gamma(T {1} + y_true));
1273 detail::advance(s, first1, first2);
1278 for (; first1 < last1; ++first1, ++first2) {
1279 se(*first2 - *first1 * eve::log(*first2) + eve::log_abs_gamma(T {1} + *first1));
1297template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J, std::contiguous_iterator K>
1301 using wide = eve::wide<T>;
1302 auto constexpr s {wide::size()};
1303 auto const n {std::distance(first1, last1)};
1304 auto const m {n - n % s};
1307 for (
auto i = 0; i < m; i += s) {
1308 wide y_true {first1};
1309 wide y_pred = wide {first2} * wide {first3};
1310 we(y_pred - y_true * eve::log(y_pred) + eve::log_abs_gamma(T {1} + y_true));
1311 detail::advance(s, first1, first2, first3);
1316 for (; first1 < last1; ++first1, ++first2, ++first3) {
1317 se(*first2 * *first3 - *first1 * eve::log(*first2 * *first3) + eve::log_abs_gamma(T {1} + *first1));
1336template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
1340 using wide = eve::wide<T>;
1341 auto constexpr s {wide::size()};
1342 auto const n {std::distance(first1, last1)};
1343 auto const m {n - n % s};
1346 for (
auto i = 0; i < m; i += s) {
1347 wide y_true {first1};
1348 wide y_pred {first2};
1349 we(eve::sqr(y_true - y_pred));
1350 detail::advance(s, first1, first2);
1355 for (; first1 < last1; ++first1, ++first2) {
1356 se(eve::sqr(*first1 - *first2));
1359 auto const pi = std::numbers::pi_v<double>;
1360 return 0.5 *
static_cast<double>(n) * std::log(2.0 * pi)
1361 +
static_cast<double>(n) * std::log(
static_cast<double>(sigma))
1362 + ssr / (2.0 *
static_cast<double>(sigma) *
static_cast<double>(sigma));
1377template<std::
floating_po
int T, std::contiguous_iterator I, std::contiguous_iterator J>
1380 using wide = eve::wide<T>;
1381 auto constexpr s {wide::size()};
1382 auto const n {std::distance(first1, last1)};
1383 auto const m {n - n % s};
1386 for (
auto i = 0; i < m; i += s) {
1387 wide y_true {first1};
1388 wide y_pred {first2};
1389 we(eve::exp(y_pred) - y_true * y_pred + eve::log_abs_gamma(T {1} + y_true));
1390 detail::advance(s, first1, first2);
1395 for (; first1 < last1; ++first1, ++first2) {
1396 se(eve::exp(*first2) - *first1 * *first2 + eve::log_abs_gamma(T {1} + *first1));
auto normalized_mean_squared_error(I first1, I last1, J first2) noexcept -> std::conditional_t< Policy==nan_policy::omit, std::pair< double, std::size_t >, double >
Normalized mean squared error over (estimated, target) pairs.
Definition vstat.hpp:860
auto mean_absolute_error(I first1, I last1, J first2) noexcept -> std::conditional_t< Policy==nan_policy::omit, std::pair< double, std::size_t >, double >
Computes the mean absolute error.
Definition vstat.hpp:1099
auto gaussian_neg_likelihood_loss(I first1, I last1, J first2, T sigma) noexcept -> double
Negative log likelihood loss under a Gaussian with known scalar noise level .
Definition vstat.hpp:1337
auto mean_squared_error(I first1, I last1, J first2) noexcept -> std::conditional_t< Policy==nan_policy::omit, std::pair< double, std::size_t >, double >
Computes the mean squared error.
Definition vstat.hpp:761
auto mean_squared_log_error(I first1, I last1, J first2) noexcept -> double
Computes the mean squared logarithmic error.
Definition vstat.hpp:1023
auto poisson_log_neg_likelihood_loss(I first1, I last1, J first2) noexcept -> double
Negative log likelihood loss with Poisson distribution of target, where the model outputs (the natur...
Definition vstat.hpp:1378
auto r2_score(I first1, I last1, J first2) noexcept -> double
Computes the coefficient of determination .
Definition vstat.hpp:666
auto poisson_neg_likelihood_loss(I first1, I last1, J first2) noexcept -> double
Negative log likelihood loss with Poisson distribution of target.
Definition vstat.hpp:1261
auto mean_absolute_percentage_error(I first1, I last1, J first2) noexcept -> double
Computes the mean absolute percentage error.
Definition vstat.hpp:1186
auto accumulate(I first, I last, F &&f=F {}) noexcept -> univariate_statistics
Accumulates a sequence of (projected) values.
Definition vstat.hpp:97
Univariate accumulator object.
Definition univariate.hpp:37
Univariate statistics.
Definition univariate.hpp:131