akreon-linalg
Fixed-size linear algebra and numerical methods in C++26.
Loading...
Searching...
No Matches
linalg_ops.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2025-2026 Akreon LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
10#include "vector/vector.hpp"
11
12namespace linalg {
13
24template <VectorContainer Vec>
25constexpr auto add(const Vec& A, const Vec& B) {
26 // (dakre) below is safeguard against non-square matrix acting as vector with
27 // duck type T as Vector<Vector<...>>
28 using T = vector_element_t<Vec>;
29 constexpr auto N = vector_dim_v<Vec>;
31 for (std::size_t i = 0; i < N; ++i) C(i) = A(i) + B(i);
32 return C;
33}
34
40template <VectorContainer Vec>
41constexpr auto operator+(const Vec& A, const Vec& B) {
42 return add(A, B);
43}
44
51template <MatrixContainer Mat>
52constexpr auto add(const Mat& A, const Mat& B) {
53 using T = matrix_scalar_t<Mat>;
54 constexpr auto Rows = mat_rows_v<Mat>;
55 constexpr auto Cols = mat_cols_v<Mat>;
57 for (std::size_t row = 0; row < Rows; ++row)
58 for (std::size_t col = 0; col < Cols; ++col)
59 result(row, col) = A(row, col) + B(row, col);
60 return result;
61}
62
64template <MatrixContainer Mat>
65constexpr auto operator+(const Mat& A, const Mat& B) {
66 return add(A, B);
67}
68
79template <VectorContainer Vec, Field Alpha>
80constexpr auto scalar_multiplication(const Alpha& alpha, const Vec& A) {
81 using T = vector_element_t<Vec>;
82 constexpr auto N = vector_dim_v<Vec>;
84 for (std::size_t i = 0; i < N; ++i) C(i) = alpha * A(i);
85 return C;
86}
87
93template <VectorContainer Vec, Field Alpha>
94constexpr auto operator*(const Alpha& alpha, const Vec& A) {
96}
97
104template <MatrixContainer Mat, Field Alpha>
105constexpr auto scalar_multiplication(const Alpha& alpha, const Mat& A) {
106 using T = matrix_scalar_t<Mat>;
107 constexpr auto Rows = mat_rows_v<Mat>;
108 constexpr auto Cols = mat_cols_v<Mat>;
110 for (std::size_t row = 0; row < Rows; ++row)
111 for (std::size_t col = 0; col < Cols; ++col)
112 result(row, col) = alpha * A(row, col);
113 return result;
114}
115
117template <MatrixContainer Mat, Field Alpha>
118constexpr auto operator*(const Alpha& alpha, const Mat& A) {
120}
121
128template <VectorContainer Vec>
129constexpr auto operator-(const Vec& A, const Vec& B) {
130 return A + vector_scalar_t<Vec>(-1) * B;
131}
132
134template <MatrixContainer Mat>
135constexpr auto operator-(const Mat& A, const Mat& B) {
136 return A + matrix_scalar_t<Mat>(-1) * B;
137}
138
149template <FieldVector Vec>
150constexpr auto transpose(const Vec& x) {
151 using T = vector_element_t<Vec>;
152 constexpr auto N = vector_dim_v<Vec>;
154 for (std::size_t i = 0; i < N; ++i) x_t(i, 0) = x(i);
155 return x_t;
156}
157
165template <ComplexVector Vec>
166constexpr auto conjugate(const Vec& x) {
167 using T = vector_element_t<Vec>;
168 constexpr auto N = vector_dim_v<Vec>;
170 for (std::size_t i = 0; i < N; ++i) result(i) = std::conj(x(i));
171 return result;
172}
173
182template <FieldVector Vec>
183 requires(vector_dim_v<Vec> == 3)
184constexpr auto cross(const Vec& x, const Vec& y) {
185 return Vec{x(1) * y(2) - x(2) * y(1), -(x(0) * y(2) - x(2) * y(0)),
186 x(0) * y(1) - x(1) * y(0)};
187}
188
197template <FieldVector Vec>
198 requires(vector_dim_v<Vec> > 0)
199constexpr bool all_zero(const Vec& x) {
200 using T = vector_element_t<Vec>;
201 constexpr auto N = vector_dim_v<Vec>;
202 int cnt = 0;
203 for (std::size_t i = 0; i < N; ++i) cnt += x(i) == T(0);
204 return cnt == N;
205}
206
214template <std::size_t idx, FieldVector Vec>
216constexpr auto splice(const Vec& x) {
217 using T = vector_element_t<Vec>;
218 constexpr auto N = vector_dim_v<Vec>;
220 std::size_t i = 0;
221 for (; i < idx; ++i) a(i) = x(i);
222 Vector<T, N - idx> b;
223 for (std::size_t j = 0; i < N; ++i, ++j) b(j) = x(i);
224 return std::tuple(a, b);
225}
226
239template <MatrixContainer MatA, MatrixContainer MatB>
241constexpr auto outer_product(const MatA& A, const MatB& B) {
242 using T = matrix_scalar_t<MatA>;
243 constexpr auto Rows = mat_rows_v<MatA>;
244 constexpr auto Cols = mat_cols_v<MatB>;
246 for (std::size_t i = 0; i < Rows; ++i)
247 for (std::size_t j = 0; j < Cols; ++j) result(i, j) = A(i, 0) * B(0, j);
248 return result;
249}
250
260template <MatrixContainer Mat>
261constexpr auto transpose(const Mat& A) {
262 using T = matrix_scalar_t<Mat>;
263 constexpr auto Cols = mat_cols_v<Mat>;
264 constexpr auto Rows = mat_rows_v<Mat>;
266 for (std::size_t i = 0; i < Rows; ++i)
267 for (std::size_t j = 0; j < Cols; ++j) result(j, i) = A(i, j);
268 return result;
269}
270
280template <SquareMatrix Mat>
281 requires(mat_rows_v<Mat> > 0)
282constexpr auto trace(const Mat& A) {
283 using T = matrix_scalar_t<Mat>;
284 constexpr auto Rows = mat_rows_v<Mat>;
285 T sum = 0;
286 for (std::size_t i = 0; i < Rows; ++i) sum += A(i, i);
287 return sum;
288}
289
299template <MatrixContainer Mat>
300constexpr auto conjugate_transpose(const Mat& A)
302{
303 constexpr auto Rows = mat_rows_v<Mat>;
304 constexpr auto Cols = mat_cols_v<Mat>;
305 auto A_t = transpose(A);
306 for (std::size_t i = 0; i < Cols; ++i)
307 for (std::size_t j = 0; j < Rows; ++j) A_t(i, j) = std::conj(A_t(i, j));
308 return A_t;
309}
310
319template <MatrixContainer MatA, MatrixContainer MatB>
321constexpr auto operator*(const MatA& A, const MatB& B) {
322 using T = matrix_scalar_t<MatA>;
323 constexpr auto Rows = mat_rows_v<MatA>;
324 constexpr auto Cols = mat_cols_v<MatB>;
326 constexpr auto Inner = mat_cols_v<MatA>;
327 for (std::size_t i = 0; i < Rows; ++i) {
328 for (std::size_t j = 0; j < Cols; ++j) {
329 T value{};
330 for (std::size_t k = 0; k < Inner; ++k) value += A(i, k) * B(k, j);
331 result(i, j) = value;
332 }
333 }
334 return result;
335}
336
345template <MatrixContainer Mat, VectorContainer Vec>
347constexpr auto operator*(const Mat& A, const Vec& X) {
348 using T = matrix_scalar_t<Mat>;
349 constexpr auto Rows = mat_rows_v<Mat>;
351 constexpr auto Cols = mat_cols_v<Mat>;
352 for (std::size_t i = 0; i < Rows; ++i) {
353 T value{};
354 for (std::size_t j = 0; j < Cols; ++j) value += A(i, j) * X(j);
355 result(i) = value;
356 }
357 return result;
358}
359
367template <VectorContainer Vec>
368 requires(vector_dim_v<Vec> > 0)
369constexpr auto min(const Vec& x) {
370 using T = vector_element_t<Vec>;
371 constexpr std::size_t N = vector_dim_v<Vec>;
372 T mn = x(0);
373 for (std::size_t i = 1; i < N; ++i) mn = x(i) < mn ? x(i) : mn;
374 return mn;
375}
376
384template <VectorContainer Vec>
385 requires(vector_dim_v<Vec> > 0)
386constexpr auto max(const Vec& x) {
387 using T = vector_element_t<Vec>;
388 constexpr std::size_t N = vector_dim_v<Vec>;
389 T mx = x(0);
390 for (std::size_t i = 1; i < N; ++i) mx = x(i) > mx ? x(i) : mx;
391 return mx;
392}
393
401template <VectorContainer Vec>
402 requires(vector_dim_v<Vec> > 0)
403constexpr std::size_t arg_min(const Vec& x) {
404 using T = vector_element_t<Vec>;
405 constexpr std::size_t N = vector_dim_v<Vec>;
406 T mn = x(0);
407 std::size_t idx{0};
408 for (std::size_t i = 1; i < N; ++i)
409 if (x(i) < mn) mn = x(i), idx = i;
410 return idx;
411}
412
420template <VectorContainer Vec>
421 requires(vector_dim_v<Vec> > 0)
422constexpr std::size_t arg_max(const Vec& x) {
423 using T = vector_element_t<Vec>;
424 constexpr std::size_t N = vector_dim_v<Vec>;
425 T mx = x(0);
426 std::size_t idx{0};
427 for (std::size_t i = 1; i < N; ++i)
428 if (x(i) > mx) mx = x(i), idx = i;
429 return idx;
430}
431
432} // namespace linalg
Field classified by scalar_traits as complex.
constexpr auto splice(const Vec &x)
splice operator
typename vector_traits_t< Vec >::element_type vector_element_t
Registered vector coordinate type.
constexpr auto operator+(const Vec &A, const Vec &B)
operator overload for add
constexpr auto conjugate_transpose(const Mat &A)
conjugate transpose of a matrix
constexpr auto add(const Vec &A, const Vec &B)
add two vectors together to get a third
constexpr auto outer_product(const MatA &A, const MatB &B)
Multiply matrix-shaped column and row operands as an outer product.
constexpr auto transpose(const Vec &x)
tranpose of a vector
constexpr std::size_t arg_max(const Vec &x)
max element
constexpr auto operator*(const Alpha &alpha, const Vec &A)
operator overload for scalar multiplication
constexpr std::size_t mat_rows_v
Registered compile-time row count after cv/ref normalization.
constexpr auto scalar_multiplication(const Alpha &alpha, const Vec &A)
multiply a vector A with a scalar alpha
constexpr auto min(const Vec &x)
min element
constexpr auto max(const Vec &x)
max element
constexpr auto conjugate(const Vec &x)
conjugate a vector
constexpr std::size_t arg_min(const Vec &x)
min element
constexpr bool all_zero(const Vec &x)
simple function that checks if a vector contains only zeros (hence spans nullspace)
constexpr auto trace(const Mat &A)
trace of a matrix
typename mat_traits< remove_cvref_t< Mat > >::value_type matrix_scalar_t
Registered matrix scalar type after cv/ref normalization.
constexpr auto cross(const Vec &x, const Vec &y)
cross product between x x y = Z
constexpr auto operator-(const Vec &A, const Vec &B)
operator overload for subtraction
Owning, fixed-size, row-major matrix container over a scalar field.
Definition matrix.hpp:44
Owning, fixed-size vector container.
Definition vector.hpp:36