akreon-linalg
Fixed-size linear algebra and numerical methods in C++26.
Loading...
Searching...
No Matches
matrix_inverse.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
8#include "ldl.hpp"
11
12namespace linalg {
13
19template <MatrixContainer MatIn>
23 static constexpr std::size_t N = mat_rows_v<Mat>;
24 static_assert(N >= 1, "inverse requires matrix dim of at least 1");
25
33 constexpr auto operator()(const Mat& A) const { return apply(A); }
34
42 constexpr auto apply(const Mat& A) const {
43 // Factor once, then solve A*x_i = e_i for each inverse column.
44 const auto qr = QR(A);
45 Mat A_inv{};
46 for (std::size_t i = 0; i < N; ++i) {
48 I_vec(i) = T(1);
49 const auto [a_col, event] = qr.solve(I_vec);
51 return std::tuple(A_inv, event);
52
53 for (std::size_t j = 0; j < N; ++j) A_inv(j, i) = a_col(j);
54 }
55 return std::tuple(A_inv, linalg::NumericalEvent::NONE);
56 }
57};
58
64template <SquareMatrix MatIn>
68 static constexpr std::size_t N = mat_rows_v<Mat>;
69 static_assert(N >= 1, "inverse requires matrix dim of at least 1");
70
78 constexpr auto operator()(const Mat& A) const { return apply(A); }
79
87 constexpr auto apply(const Mat& A) const {
88 Mat A_inv{};
89 if constexpr (N == 1) {
90 if (constexpr_abs(A(0, 0)) == T(0))
92 A_inv(0, 0) = T(1) / A(0, 0);
93 return std::tuple(A_inv, linalg::NumericalEvent::NONE);
94 } else {
95 // Reuse LDL^T for the identity-column solves A*x_i = e_i.
96 const auto ldl = LDL(A);
97
98 if (!ldl.is_valid())
100
101 for (std::size_t i = 0; i < N; ++i) {
103 I_vec(i) = T(1);
104 const auto [a_col, event] = ldl.solve(I_vec);
105 if (linalg::is_fatal_event(event)) return std::tuple(A_inv, event);
106 for (std::size_t j = 0; j < N; ++j) A_inv(j, i) = a_col(j);
107 }
108 return std::tuple(A_inv, linalg::NumericalEvent::NONE);
109 }
110 }
111};
112
113} // namespace linalg
std::remove_cvref_t< T > remove_cvref_t
Remove top-level const, volatile, and reference qualification.
constexpr T constexpr_abs(T x)
Compute real absolute value or complex magnitude.
constexpr std::size_t mat_rows_v
Registered compile-time row count after cv/ref normalization.
constexpr bool is_fatal_event(NumericalEvent event)
is_fatal_event
typename mat_traits< remove_cvref_t< Mat > >::value_type matrix_scalar_t
Registered matrix scalar type after cv/ref normalization.
Factors a real symmetric matrix as A = L D L^T without pivoting.
Definition ldl.hpp:22
Matrix inverse via QR.
matrix_scalar_t< Mat > T
static constexpr std::size_t N
linalg::remove_cvref_t< MatIn > Mat
constexpr auto operator()(const Mat &A) const
Compute the inverse by solving against identity columns.
constexpr auto apply(const Mat &A) const
Compute the inverse by solving against identity columns.
Factors A = Q R using Householder reflections.
Definition qr.hpp:24
Symmetric matrix inverse via LDL^T.
constexpr auto apply(const Mat &A) const
Compute the inverse by solving against identity columns.
static constexpr std::size_t N
linalg::remove_cvref_t< MatIn > Mat
constexpr auto operator()(const Mat &A) const
Compute the inverse by solving against identity columns.
Owning, fixed-size vector container.
Definition vector.hpp:36