7#include "bivariate.hpp"
8#include "univariate.hpp"
15#include <eve/module/math.hpp>
16#include <eve/module/special.hpp>
18namespace VSTAT_NAMESPACE {
22 template<eve::simd_value T, std::input_iterator I,
typename F>
23 requires std::is_invocable_v<F, std::iter_value_t<I>>
24 auto inline load(I iter, F&& func) {
25 return [&]<std::size_t ...Idx>(std::index_sequence<Idx...>){
26 return T{ std::forward<F>(func)(*(iter + Idx))... };
27 }(std::make_index_sequence<T::size()>{});
31 template<
typename Distance,
typename... Iters>
32 auto inline advance(Distance d, Iters&... iters) ->
void {
33 (std::advance(iters, d), ...);
39 concept arithmetic = std::is_arithmetic_v<T>;
41 template<
typename F,
typename... Args>
42 concept arithmetic_projection =
requires(F&&) {
43 { std::is_invocable_v<F, Args...> };
44 { arithmetic<std::remove_reference_t<std::invoke_result_t<F, Args...>>> };
66template<std::
floating_po
int T, std::input_iterator I,
typename F = std::
identity>
67requires concepts::arithmetic_projection<F, std::iter_value_t<I>>
70 using wide = eve::wide<T>;
71 auto constexpr s{ wide::size() };
72 auto const n{ std::distance(first, last) };
73 auto const m = n - n % s;
76 univariate_accumulator<T> scalar_acc;
77 for (; first < last; ++first) {
78 scalar_acc(std::invoke(std::forward<F>(f), *first));
80 return univariate_statistics(scalar_acc);
83 univariate_accumulator<wide> acc;
84 for (
size_t i = 0; i < m; i += s) {
85 acc(detail::load<wide>(first, std::forward<F>(f)));
86 detail::advance(s, first);
91 auto [sw, sx, sxx] = acc.stats();
92 auto scalar_acc = univariate_accumulator<T>::load_state(sw, sx, sxx);
93 for (; first < last; ++first) {
94 scalar_acc(std::invoke(std::forward<F>(f), *first));
96 return univariate_statistics(scalar_acc);
98 return univariate_statistics(acc);
113template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J,
typename F = std::
identity>
114requires concepts::arithmetic_projection<F, std::iter_value_t<I>> and std::is_arithmetic_v<std::iter_value_t<J>>
117 using wide = eve::wide<T>;
118 auto constexpr s{ wide::size() };
119 auto const n { std::distance(first1, last1) };
120 const size_t m = n - n % s;
123 univariate_accumulator<T> scalar_acc;
124 for (; first1 < last1; ++first1, ++first2) {
125 scalar_acc(std::invoke(std::forward<F>(f), *first1), *first2);
127 return univariate_statistics(scalar_acc);
130 univariate_accumulator<wide> acc;
131 for (
size_t i = 0; i < m; i += s) {
132 acc(detail::load<wide>(first1, std::forward<F>(f)), wide(first2, first2 + s));
133 detail::advance(s, first1, first2);
138 auto [sw, sx, sxx] = acc.stats();
139 auto scalar_acc = univariate_accumulator<T>::load_state(sw, sx, sxx);
140 for (; first1 < last1; ++first1, ++first2) {
141 scalar_acc(std::invoke(std::forward<F>(f), *first1), *first2);
143 return univariate_statistics(scalar_acc);
145 return univariate_statistics(acc);
165template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J,
typename BinaryOp,
typename F1 = std::
identity,
typename F2 = std::
identity>
166requires std::is_invocable_v<F1, std::iter_value_t<I>> and
167 std::is_invocable_v<F2, std::iter_value_t<J>> and
170 std::invoke_result_t<F1, std::iter_value_t<I>>,
171 std::invoke_result_t<F2, std::iter_value_t<J>>
173 concepts::arithmetic_projection<
175 std::invoke_result_t<F1, std::iter_value_t<I>>,
176 std::invoke_result_t<F2, std::iter_value_t<J>>
178inline auto accumulate(I first1, std::sized_sentinel_for<I>
auto last1, J first2, BinaryOp&& op = BinaryOp{}, F1&& f1 = F1{}, F2&& f2 = F2{})
noexcept -> univariate_statistics
180 using wide = eve::wide<T>;
181 auto constexpr s{ wide::size() };
182 auto const n{ std::distance(first1, last1) };
183 auto const m = n - n % s;
185 auto f = [&](
auto a,
auto b){
186 return std::invoke(std::forward<BinaryOp>(op), std::invoke(std::forward<F1>(f1), a), std::invoke(std::forward<F2>(f2), b));
190 univariate_accumulator<T> scalar_acc;
191 for (; first1 < last1; ++first1, ++first2) {
192 scalar_acc(f(*first1, *first2));
194 return univariate_statistics(scalar_acc);
198 univariate_accumulator<wide> acc;
199 for (
size_t i = 0; i < m; i += s) {
200 std::transform(first1, first1 + s, first2, x.begin(), f);
202 detail::advance(s, first1, first2);
207 auto [sw, sx, sxx] = acc.stats();
208 auto scalar_acc = univariate_accumulator<T>::load_state(sw, sx, sxx);
209 for (; first1 < last1; ++first1, ++first2) {
210 scalar_acc(f(*first1, *first2));
212 return univariate_statistics(scalar_acc);
214 return univariate_statistics(acc);
235template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K,
typename BinaryOp,
typename F1 = std::
identity,
typename F2 = std::
identity>
236requires std::is_arithmetic_v<std::iter_value_t<K>> &&
237 std::is_invocable_v<F1, std::iter_value_t<I>> &&
238 std::is_invocable_v<F2, std::iter_value_t<J>> &&
241 std::invoke_result_t<F1, std::iter_value_t<I>>,
242 std::invoke_result_t<F2, std::iter_value_t<J>>
244 concepts::arithmetic_projection<
246 std::invoke_result_t<F1, std::iter_value_t<I>>,
247 std::invoke_result_t<F2, std::iter_value_t<J>>
249inline auto accumulate(I first1, std::sized_sentinel_for<I>
auto last1, J first2, K first3, BinaryOp&& op = BinaryOp{}, F1&& f1 = F1{}, F2&& f2 = F2{})
noexcept -> univariate_statistics
251 using wide = eve::wide<T>;
252 auto constexpr s{ wide::size() };
253 auto const n{ std::distance(first1, last1) };
254 auto const m = n - n % s;
256 auto f = [&](
auto a,
auto b){
257 return std::invoke(std::forward<BinaryOp>(op), std::invoke(std::forward<F1>(f1), a), std::invoke(std::forward<F2>(f2), b));
261 univariate_accumulator<T> scalar_acc;
262 for (; first1 < last1; ++first1, ++first2, ++first3) {
263 scalar_acc(f(*first1, *first2), *first3);
265 return univariate_statistics(scalar_acc);
269 univariate_accumulator<wide> acc;
270 for (
size_t i = 0; i < m; i += s) {
271 std::transform(first1, first1 + s, first2, x.begin(), f);
272 acc(wide(x), wide(first3, first3 + s));
273 detail::advance(s, first1, first2, first3);
278 auto [sw, sx, sxx] = acc.stats();
279 auto scalar_acc = univariate_accumulator<T>::load_state(sw, sx, sxx);
280 for (; first1 < last1; ++first1, ++first2, ++first3) {
281 scalar_acc(f(*first1, *first2), *first3);
283 return univariate_statistics(scalar_acc);
285 return univariate_statistics(acc);
333template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J,
typename F1 = std::
identity,
typename F2 = std::
identity>
334requires concepts::arithmetic_projection<F1, std::iter_value_t<I>> and
335 concepts::arithmetic_projection<F2, std::iter_value_t<J>>
336inline auto accumulate(I first1, std::sized_sentinel_for<I>
auto last1, J first2, F1&& f1 = F1{}, F2&& f2 = F2{})
338 using wide = eve::wide<T>;
339 auto constexpr s { wide::size() };
340 auto const n { std::distance(first1, last1) };
341 auto const m = n - n % s;
344 bivariate_accumulator<T> scalar_acc;
345 for (; first1 < last1; ++first1, ++first2) {
346 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2));
348 return bivariate_statistics(scalar_acc);
351 bivariate_accumulator<wide> acc;
352 for (
size_t i = 0; i < m; i += s) {
353 acc(detail::load<wide>(first1, std::forward<F1>(f1)), detail::load<wide>(first2, std::forward<F2>(f2)));
354 detail::advance(s, first1, first2);
358 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
359 auto scalar_acc = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
360 for (; first1 < last1; ++first1, ++first2) {
361 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2));
363 return bivariate_statistics(scalar_acc);
366 return bivariate_statistics(acc);
369template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K,
typename F1 = std::
identity,
typename F2 = std::
identity>
370requires concepts::arithmetic_projection<F1, std::iter_value_t<I>> and
371 concepts::arithmetic_projection<F2, std::iter_value_t<J>> and
372 std::is_arithmetic_v<std::iter_value_t<K>>
373inline auto accumulate(I first1, std::sized_sentinel_for<I>
auto last1, J first2, K first3, F1&& f1 = F1{}, F2&& f2 = F2{})
noexcept -> bivariate_statistics
375 using wide = eve::wide<T>;
376 auto constexpr s { wide::size() };
377 auto const n = std::distance(first1, last1);
378 auto const m = n - n % s;
381 bivariate_accumulator<T> scalar_acc;
382 for (; first1 < last1; ++first1, ++first2, ++first3) {
383 scalar_acc(std::invoke(std::forward<F1>(f1), *first1++), std::invoke(std::forward<F2>(f2), *first2++), *first3++);
385 return bivariate_statistics(scalar_acc);
388 bivariate_accumulator<wide> acc;
389 for (
size_t i = 0; i < m; i += s) {
391 detail::load<wide>(first1, std::forward<F1>(f1)),
392 detail::load<wide>(first2, std::forward<F2>(f2)),
393 wide(first3, first3 + s)
395 detail::advance(s, first1, first2, first3);
399 auto [sw, sx, sy, sxx, syy, sxy] = acc.stats();
400 auto scalar_acc = bivariate_accumulator<T>::load_state(sx, sy, sw, sxx, syy, sxy);
401 for (; first1 < last1; ++first1, ++first2, ++first3) {
402 scalar_acc(std::invoke(std::forward<F1>(f1), *first1), std::invoke(std::forward<F2>(f2), *first2), *first3);
404 return bivariate_statistics(scalar_acc);
406 return bivariate_statistics(acc);
430template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
431inline auto r2_score(I first1, std::sentinel_for<I>
auto last1, J first2)
noexcept ->
double {
432 using wide = eve::wide<T>;
433 auto constexpr s{ wide::size() };
434 auto const n{ std::distance(first1, last1) };
435 auto const m{ n - n % s };
439 for (
auto i = 0; i < m; i += s) {
440 wide y_true{first1, first1+s};
441 wide y_pred{first2, first2+s};
442 wx(eve::sqr(y_true-y_pred));
444 detail::advance(s, first1, first2);
451 for(; first1 < last1; ++first1, ++first2) {
452 sx(eve::sqr(*first1 - *first2));
459 return tss < std::numeric_limits<double>::epsilon()
460 ? std::numeric_limits<double>::lowest()
475template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
476inline auto r2_score(I first1, std::sentinel_for<I>
auto last1, J first2, K first3)
noexcept ->
double {
477 using wide = eve::wide<T>;
478 auto constexpr s{ wide::size() };
479 auto const n{ std::distance(first1, last1) };
480 auto const m{ n - n % s };
484 for (
auto i = 0; i < m; i += s) {
485 wide y_true{first1, first1+s};
486 wide y_pred{first2, first2+s};
487 wide weight{first3, first3+s};
488 wx(eve::sqr(y_true-y_pred), weight);
490 detail::advance(s, first1, first2, first3);
497 for(; first1 < last1; ++first1, ++first2, ++first3) {
498 sx(eve::sqr(*first1 - *first2), *first3);
499 sy(*first1, *first3);
505 return tss < std::numeric_limits<double>::epsilon()
506 ? std::numeric_limits<double>::lowest()
519template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
520inline auto mean_squared_error(I first1, std::sentinel_for<I>
auto last1, J first2)
noexcept ->
double {
521 using wide = eve::wide<T>;
522 auto constexpr s{ wide::size() };
523 auto const n{ std::distance(first1, last1) };
524 auto const m{ n - n % s };
527 for (
auto i = 0; i < m; i += s) {
528 wide y_true{first1, first1+s};
529 wide y_pred{first2, first2+s};
530 we(eve::sqr(y_true-y_pred));
531 detail::advance(s, first1, first2);
536 for(; first1 < last1; ++first1, ++first2) {
537 se(eve::sqr(*first1 - *first2));
551template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
552inline auto mean_squared_error(I first1, std::sentinel_for<I>
auto last1, J first2, K first3)
noexcept ->
double {
553 using wide = eve::wide<T>;
554 auto constexpr s{ wide::size() };
555 auto const n{ std::distance(first1, last1) };
556 auto const m{ n - n % s };
559 for (
auto i = 0; i < m; i += s) {
560 wide y_true{first1, first1+s};
561 wide y_pred{first2, first2+s};
562 wide weight{first3, first3+s};
563 we(eve::sqr(y_true-y_pred), weight);
564 detail::advance(s, first1, first2, first3);
569 for(; first1 < last1; ++first1, ++first2, ++first3) {
570 se(eve::sqr(*first1 - *first2), *first3);
584template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
586 using wide = eve::wide<T>;
587 auto constexpr s{ wide::size() };
588 auto const n{ std::distance(first1, last1) };
589 auto const m{ n - n % s };
592 for (
auto i = 0; i < m; i += s) {
593 wide y_true{first1, first1+s};
594 wide y_pred{first2, first2+s};
595 we(eve::sqr(eve::log1p(y_true)-eve::log1p(y_pred)));
596 detail::advance(s, first1, first2);
601 for(; first1 < last1; ++first1, ++first2) {
602 se(eve::sqr(eve::log1p(*first1) - eve::log1p(*first2)));
616template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
618 using wide = eve::wide<T>;
619 auto constexpr s{ wide::size() };
620 auto const n{ std::distance(first1, last1) };
621 auto const m{ n - n % s };
624 for (
auto i = 0; i < m; i += s) {
625 wide y_true{first1, first1+s};
626 wide y_pred{first2, first2+s};
627 wide weight{first3, first3+s};
628 we(eve::sqr(eve::log1p(y_true)-eve::log1p(y_pred)), weight);
629 detail::advance(s, first1, first2, first3);
634 for(; first1 < last1; ++first1, ++first2, ++first3) {
635 se(eve::sqr(eve::log1p(*first1) - eve::log1p(*first2)), *first3);
649template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
651 using wide = eve::wide<T>;
652 auto constexpr s{ wide::size() };
653 auto const n{ std::distance(first1, last1) };
654 auto const m{ n - n % s };
657 for (
auto i = 0; i < m; i += s) {
658 wide y_true{first1, first1+s};
659 wide y_pred{first2, first2+s};
660 we(eve::abs(y_true-y_pred));
661 detail::advance(s, first1, first2);
666 for(; first1 < last1; ++first1, ++first2) {
667 se(eve::abs(*first1 - *first2));
681template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
682inline auto mean_absolute_error(I first1, std::sentinel_for<I>
auto last1, J first2, K first3)
noexcept ->
double {
683 using wide = eve::wide<T>;
684 auto constexpr s{ wide::size() };
685 auto const n{ std::distance(first1, last1) };
686 auto const m{ n - n % s };
689 for (
auto i = 0; i < m; i += s) {
690 wide y_true{first1, first1+s};
691 wide y_pred{first2, first2+s};
692 wide weight{first3, first3+s};
693 we(eve::abs(y_true-y_pred), weight);
694 detail::advance(s, first1, first2, first3);
699 for(; first1 < last1; ++first1, ++first2, ++first3) {
700 se(eve::abs(*first1 - *first2), *first3);
717template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
719 using wide = eve::wide<T>;
720 auto constexpr s{ wide::size() };
721 auto const n{ std::distance(first1, last1) };
722 auto const m{ n - n % s };
724 auto constexpr eps{ std::numeric_limits<T>::epsilon() };
727 for (
auto i = 0; i < m; i += s) {
728 wide y_true{first1, first1+s};
729 wide y_pred{first2, first2+s};
730 we(eve::abs(y_true-y_pred) / eve::max(eps, eve::abs(y_true)));
731 detail::advance(s, first1, first2);
736 for(; first1 < last1; ++first1, ++first2) {
737 se(eve::abs(*first1 - *first2) / eve::max(eps, eve::abs(*first1)));
751template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
753 using wide = eve::wide<T>;
754 auto constexpr s{ wide::size() };
755 auto const n{ std::distance(first1, last1) };
756 auto const m{ n - n % s };
759 for (
auto i = 0; i < m; i += s) {
760 wide y_true{first1, first1+s};
761 wide y_pred{first2, first2+s};
762 wide weight{first3, first3+s};
763 we(eve::abs(y_true-y_pred), weight);
764 detail::advance(s, first1, first2, first3);
769 for(; first1 < last1; ++first1, ++first2, ++first3) {
770 se(eve::abs(*first1 - *first2), *first3);
784template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J>
786 using wide = eve::wide<T>;
787 auto constexpr s{ wide::size() };
788 auto const n{ std::distance(first1, last1) };
789 auto const m{ n - n % s };
791 auto constexpr eps{ std::numeric_limits<T>::epsilon() };
794 for (
auto i = 0; i < m; i += s) {
795 wide y_true{first1, first1+s};
796 wide y_pred{first2, first2+s};
797 we(y_pred - y_true * eve::log(y_pred) + eve::log_abs_gamma(T{1} + y_true));
798 detail::advance(s, first1, first2);
803 for(; first1 < last1; ++first1, ++first2) {
804 se(*first2 - *first1 * eve::log(*first2) + eve::log_abs_gamma(T{1} + *first1));
818template<std::
floating_po
int T, std::input_iterator I, std::input_iterator J, std::input_iterator K>
820 using wide = eve::wide<T>;
821 auto constexpr s{ wide::size() };
822 auto const n{ std::distance(first1, last1) };
823 auto const m{ n - n % s };
825 auto constexpr eps{ std::numeric_limits<T>::epsilon() };
828 for (
auto i = 0; i < m; i += s) {
829 wide y_true{first1, first1+s};
830 wide y_pred = eve::mul(wide{first2, first2+s}, wide{first3, first3+s});
831 we(y_pred - y_true * eve::log(y_pred) + eve::log_abs_gamma(T{1} + y_true));
832 detail::advance(s, first1, first2, first3);
837 for(; first1 < last1; ++first1, ++first2, ++first3) {
838 se(*first2 * *first3 - *first1 * eve::log(*first2 * *first3) + eve::log_abs_gamma(T{1} + *first1));
auto poisson_neg_likelihood_loss(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Negative log likelihood loss with Poisson distribution of target.
Definition vstat.hpp:785
auto mean_absolute_error(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Computes the mean absolute error.
Definition vstat.hpp:650
auto mean_absolute_percentage_error(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Computes the mean absolute error.
Definition vstat.hpp:718
auto r2_score(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Computes the coefficient of determination .
Definition vstat.hpp:431
auto mean_squared_log_error(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Computes the mean squared logarithmic error.
Definition vstat.hpp:585
auto mean_squared_error(I first1, std::sentinel_for< I > auto last1, J first2) noexcept -> double
Computes the mean squared error.
Definition vstat.hpp:520
auto accumulate(I first, std::sized_sentinel_for< I > auto last, F &&f=F{}) noexcept -> univariate_statistics
Accumulates a sequence of (projected) values.
Definition vstat.hpp:68
Univariate accumulator object.
Definition univariate.hpp:14
Univariate statistics.
Definition univariate.hpp:84