cyqlone develop
Fast, parallel and vectorized solver for linear systems with optimal control structure.
Loading...
Searching...
No Matches
reduce.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// Vector reductions.
5/// @ingroup topic-utilities
6
7#include <cyqlone/config.hpp>
8#include <batmat/simd.hpp>
9#include <cmath>
10
11namespace cyqlone {
12
13/// @addtogroup topic-utilities
14/// @{
15
16/// Utilities for computing vector norms.
17/// @tparam T Scalar type.
18/// @tparam simd SIMD type. Void for scalar-only.
19template <class T, class simd = void>
20struct norms;
21
22template <class T>
23struct norms<T>;
24
25template <class T, class simd>
26struct norms : norms<T> {
27 /// Accumulator.
28 using result = typename norms<T>::result;
29 /// Lane-wise accumulators.
30 struct result_simd {
31 simd amax;
32 simd asum;
33 simd sumsq;
34 };
35
36 using norms<T>::operator();
37
38 /// Update the accumulator with a new value.
39 result_simd operator()(result_simd accum, simd t) const {
40 using std::abs;
41 using std::max;
42 auto at = abs(t);
43 return {.amax = max(at, accum.amax), .asum = at + accum.asum, .sumsq = t * t + accum.sumsq};
44 }
45
46 /// Reduce the SIMD accumulator to a scalar result.
48#if BATMAT_WITH_GSI_HPC_SIMD
49 using batmat::datapar::hmax;
50#endif
51 return {hmax(accum.amax), reduce(accum.asum), reduce(accum.sumsq)};
52 }
53
54 using norms<T>::zero;
55 static result_simd zero_simd() { return {}; }
56};
57
58template <class T>
59struct norms<T, void> {
60 /// Accumulator.
61 struct result {
62 T amax; ///< Maximum absolute value (ignoring NaNs).
65
66 /// ℓ₁ norm.
67 [[nodiscard]] T norm_1() const { return asum; }
68 /// ℓ₂ norm.
69 [[nodiscard]] T norm_2() const {
70 using std::sqrt;
71 return sqrt(sumsq);
72 }
73 [[nodiscard]] T norm_inf() const {
74 using std::isfinite;
75 return isfinite(asum) ? amax : asum;
76 }
77 };
78
79 /// Update the accumulator with a new value.
80 result operator()(result accum, T t) const {
81 using std::abs;
82 using std::max;
83 auto at = abs(t);
84 return {.amax = max(at, accum.amax), .asum = at + accum.asum, .sumsq = t * t + accum.sumsq};
85 }
86
87 /// Combine two accumulators.
88 result operator()(result accum, result t) const {
89 using std::max;
90 return {max(accum.amax, t.amax), accum.asum + t.asum, accum.sumsq + t.sumsq};
91 }
92
93 /// Identity element for the reduction.
94 static result zero() { return {}; }
95};
96
97/// @}
98
99} // namespace cyqlone
T amax
Maximum absolute value (ignoring NaNs).
Definition reduce.hpp:62
T norm_2() const
ℓ₂ norm.
Definition reduce.hpp:69
T norm_1() const
ℓ₁ norm.
Definition reduce.hpp:67
result operator()(result accum, result t) const
Combine two accumulators.
Definition reduce.hpp:88
result operator()(result accum, T t) const
Update the accumulator with a new value.
Definition reduce.hpp:80
static result zero()
Identity element for the reduction.
Definition reduce.hpp:94
Utilities for computing vector norms.
Definition reduce.hpp:26
static result_simd zero_simd()
Definition reduce.hpp:55
result operator()(result_simd accum) const
Reduce the SIMD accumulator to a scalar result.
Definition reduce.hpp:47
result_simd operator()(result_simd accum, simd t) const
Update the accumulator with a new value.
Definition reduce.hpp:39
typename norms< T >::result result
Accumulator.
Definition reduce.hpp:28
Lane-wise accumulators.
Definition reduce.hpp:30