EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Triangularization.h
Go to the documentation of this file.
1#pragma once
2
10
11#include <algorithm>
12#include <concepts>
13#include <type_traits>
14
15#include <Eigen/Core>
16#include <Eigen/Householder>
17
19
20namespace Emrys
21{
22
48template <typename M, typename Derived = std::remove_cvref_t<M>>
49 requires std::derived_from<Derived, Eigen::MatrixBase<Derived>> && (!std::is_const_v<std::remove_reference_t<M>>)
50 && ((Derived::Flags & Eigen::LvalueBit) != 0)
51void
53{
54 Derived & matrix = m;
55 using Scalar = typename Derived::Scalar;
56 using RealScalar = typename Eigen::NumTraits<Scalar>::Real;
57 using Workspace =
58 Eigen::Matrix<Scalar, Derived::ColsAtCompileTime, 1, Eigen::ColMajor, Derived::MaxColsAtCompileTime, 1>;
59 Eigen::Index const rows = matrix.rows();
60 Eigen::Index const cols = matrix.cols();
61 Workspace workspace(cols);
62 for (Eigen::Index k = 0; k < std::min(rows, cols); ++k)
63 {
64 Eigen::Index const below = rows - k - 1;
65 Eigen::Index const right = cols - k - 1;
66 if (below > 0)
67 {
68 auto tau = Scalar{};
69 auto beta = RealScalar{};
70 matrix.col(k).tail(below + 1).makeHouseholderInPlace(tau, beta);
71 if (right > 0)
72 {
73 matrix.bottomRightCorner(below + 1, right)
74 .applyHouseholderOnTheLeft(matrix.col(k).tail(below), tau, workspace.data());
75 }
76 matrix(k, k) = beta;
77 matrix.col(k).tail(below).setZero();
78 }
79 if (matrix(k, k) < Scalar(0))
80 {
81 matrix.row(k).tail(cols - k) *= Scalar(-1);
82 }
83 }
84}
85
86namespace internal
87{
88
94template <typename Derived>
95[[nodiscard]] Eigen::Matrix<
96 typename Derived::Scalar,
97 Derived::RowsAtCompileTime,
98 Derived::RowsAtCompileTime,
99 Eigen::ColMajor,
100 Derived::MaxRowsAtCompileTime,
101 Derived::MaxRowsAtCompileTime>
102lowerTriangularRoot(Eigen::MatrixBase<Derived> const & a)
103{
104 using Scalar = typename Derived::Scalar;
105 using Transposed = Eigen::Matrix<
106 Scalar,
107 Derived::ColsAtCompileTime,
108 Derived::RowsAtCompileTime,
109 Eigen::ColMajor,
110 Derived::MaxColsAtCompileTime,
111 Derived::MaxRowsAtCompileTime>;
112 using Result = Eigen::Matrix<
113 Scalar,
114 Derived::RowsAtCompileTime,
115 Derived::RowsAtCompileTime,
116 Eigen::ColMajor,
117 Derived::MaxRowsAtCompileTime,
118 Derived::MaxRowsAtCompileTime>;
119 Transposed buffer = a.transpose();
120 triangularize(buffer);
121 Eigen::Index const n = a.rows();
122 Eigen::Index const k = std::min(a.rows(), a.cols());
123 Result factor = Result::Zero(n, n);
124 factor.leftCols(k) = buffer.topRows(k).transpose();
125 return factor;
126}
127
128} // namespace internal
129
130} // namespace Emrys
The macros every header includes first.
A type usable as the scalar of a distribution: a real number type such as float, double,...
Definition Math.h:80
void triangularize(M &&m)
Reduces m to upper-triangular form in place by Householder reflections from the left,...
Definition Triangularization.h:52