numerics 0.1.0
Loading...
Searching...
No Matches
small_matrix.hpp
Go to the documentation of this file.
1/// @file small_matrix.hpp
2/// @brief Constexpr fixed-size vector, matrix, and Givens rotation helpers.
3#pragma once
4
5#include "core/types.hpp"
6#include <array>
7#include <cmath>
8
9namespace num {
10
11template<idx N>
12struct SmallVec {
13 std::array<real, N> data{};
14
15 constexpr real& operator[](idx i) noexcept { return data[i]; }
16 constexpr const real& operator[](idx i) const noexcept { return data[i]; }
17 static constexpr idx size() noexcept { return N; }
18
19 constexpr SmallVec& operator+=(const SmallVec& o) noexcept {
20 for (idx i = 0; i < N; ++i) {
21 data[i] += o.data[i];
22 }
23 return *this;
24 }
25
26 constexpr SmallVec& operator-=(const SmallVec& o) noexcept {
27 for (idx i = 0; i < N; ++i) {
28 data[i] -= o.data[i];
29 }
30 return *this;
31 }
32
33 constexpr SmallVec& operator*=(real s) noexcept {
34 for (idx i = 0; i < N; ++i) {
35 data[i] *= s;
36 }
37 return *this;
38 }
39
40 constexpr real dot(const SmallVec& o) const noexcept {
41 real s = 0;
42 for (idx i = 0; i < N; ++i) {
43 s += data[i] * o.data[i];
44 }
45 return s;
46 }
47
48 [[nodiscard]] constexpr real norm_sq() const noexcept { return dot(*this); }
49};
50
51template<idx N>
52constexpr SmallVec<N> operator+(SmallVec<N> a, const SmallVec<N>& b) noexcept {
53 return a += b;
54}
55
56template<idx N>
57constexpr SmallVec<N> operator*(real s, SmallVec<N> v) noexcept {
58 return v *= s;
59}
60
61template<idx M, idx N>
63 std::array<real, M * N> data{};
64
65 constexpr real& operator()(idx i, idx j) noexcept { return data[i * N + j]; }
66
67 constexpr const real& operator()(idx i, idx j) const noexcept {
68 return data[i * N + j];
69 }
70
71 static constexpr idx rows() noexcept { return M; }
72 static constexpr idx cols() noexcept { return N; }
73
74 constexpr void fill(real v) noexcept { data.fill(v); }
75
76 static constexpr SmallMatrix zeros() noexcept { return SmallMatrix{}; }
77
78 static constexpr SmallMatrix identity() noexcept {
79 static_assert(M == N, "identity() requires a square matrix");
80 SmallMatrix m{};
81 for (idx i = 0; i < M; ++i) {
82 m(i, i) = 1;
83 }
84 return m;
85 }
86
87 constexpr SmallMatrix<N, M> transposed() const noexcept {
89 for (idx i = 0; i < M; ++i) {
90 for (idx j = 0; j < N; ++j) {
91 t(j, i) = (*this)(i, j);
92 }
93 }
94 return t;
95 }
96
97 template<idx K>
98 constexpr SmallMatrix<M, K> operator*(const SmallMatrix<N, K>& B) const noexcept {
100 for (idx i = 0; i < M; ++i) {
101 for (idx k = 0; k < N; ++k) {
102 for (idx j = 0; j < K; ++j) {
103 C(i, j) += (*this)(i, k) * B(k, j);
104 }
105 }
106 }
107 return C;
108 }
109
110 constexpr SmallVec<M> operator*(const SmallVec<N>& x) const noexcept {
111 SmallVec<M> y{};
112 for (idx i = 0; i < M; ++i) {
113 for (idx j = 0; j < N; ++j) {
114 y[i] += (*this)(i, j) * x[j];
115 }
116 }
117 return y;
118 }
119
120 constexpr SmallMatrix& operator+=(const SmallMatrix& o) noexcept {
121 for (idx k = 0; k < M * N; ++k) {
122 data[k] += o.data[k];
123 }
124 return *this;
125 }
126
127 constexpr SmallMatrix& operator*=(real s) noexcept {
128 for (idx k = 0; k < M * N; ++k) {
129 data[k] *= s;
130 }
131 return *this;
132 }
133};
134
136 real c = 1;
137 real s = 0;
138
139 /// @brief Construct \f$G=\begin{bmatrix}c&s\\-s&c\end{bmatrix}\f$.
140 static constexpr GivensRotation from(real a, real b) noexcept {
141 if (b == 0) {
142 return {};
143 }
144 const real r = std::sqrt(a * a + b * b);
145 return {a / r, b / r};
146 }
147
148 constexpr void apply(real& x, real& y) const noexcept {
149 const real tmp = c * x + s * y;
150 y = -s * x + c * y;
151 x = tmp;
152 }
153
154 constexpr void apply_t(real& x, real& y) const noexcept {
155 const real tmp = c * x - s * y;
156 y = s * x + c * y;
157 x = tmp;
158 }
159
160 constexpr SmallMatrix<2, 2> matrix() const noexcept {
162 G(0, 0) = c;
163 G(0, 1) = s;
164 G(1, 0) = -s;
165 G(1, 1) = c;
166 return G;
167 }
168};
169
170} // namespace num
Core type definitions.
double real
Definition types.hpp:10
constexpr SmallVec< N > operator*(real s, SmallVec< N > v) noexcept
constexpr SmallVec< N > operator+(SmallVec< N > a, const SmallVec< N > &b) noexcept
std::size_t idx
Definition types.hpp:11
constexpr void apply(real &x, real &y) const noexcept
constexpr void apply_t(real &x, real &y) const noexcept
constexpr SmallMatrix< 2, 2 > matrix() const noexcept
static constexpr GivensRotation from(real a, real b) noexcept
Construct .
static constexpr SmallMatrix identity() noexcept
static constexpr idx cols() noexcept
constexpr SmallMatrix & operator+=(const SmallMatrix &o) noexcept
constexpr SmallMatrix< N, M > transposed() const noexcept
static constexpr SmallMatrix zeros() noexcept
constexpr real & operator()(idx i, idx j) noexcept
constexpr SmallVec< M > operator*(const SmallVec< N > &x) const noexcept
constexpr void fill(real v) noexcept
static constexpr idx rows() noexcept
constexpr SmallMatrix & operator*=(real s) noexcept
std::array< real, M *N > data
constexpr const real & operator()(idx i, idx j) const noexcept
constexpr SmallMatrix< M, K > operator*(const SmallMatrix< N, K > &B) const noexcept
static constexpr idx size() noexcept
constexpr real norm_sq() const noexcept
constexpr SmallVec & operator+=(const SmallVec &o) noexcept
constexpr real dot(const SmallVec &o) const noexcept
constexpr SmallVec & operator-=(const SmallVec &o) noexcept
constexpr const real & operator[](idx i) const noexcept
constexpr real & operator[](idx i) noexcept
std::array< real, N > data
constexpr SmallVec & operator*=(real s) noexcept