7#include "aligator/tracy.hpp"
12template <
typename MatrixType>
13typename MatrixType::PlainObject
15 const std::vector<MatrixType> &diagonal,
16 const std::vector<MatrixType> &superdiagonal) {
17 if (subdiagonal.size() != superdiagonal.size() ||
18 diagonal.size() != superdiagonal.size() + 1) {
19 throw std::invalid_argument(
"Wrong lengths");
22 using PlainObjectType =
typename MatrixType::PlainObject;
24 const size_t N = subdiagonal.size();
26 for (
size_t i = 0; i <= N; i++) {
27 dim += diagonal[i].cols();
30 PlainObjectType out(dim, dim);
33 for (
size_t i = 0; i <= N; i++) {
34 Eigen::Index d = diagonal[i].cols();
35 out.block(i0, i0, d, d) = diagonal[i];
38 Eigen::Index dn = superdiagonal[i].cols();
39 out.block(i0, i0 + d, d, dn) = superdiagonal[i];
40 out.block(i0 + d, i0, dn, d) = subdiagonal[i];
48template <
typename MatrixType,
typename InputType,
typename OutType,
49 typename Scalar =
typename MatrixType::Scalar>
51 const std::vector<MatrixType> &Adiag,
52 const std::vector<MatrixType> &Asuper,
56 const size_t N = Asuper.size();
60 c[0].noalias() += Adiag[0] * b[0];
61 c[0].noalias() += Asuper[0] * b[1];
63 for (
size_t i = 1; i < N; i++) {
64 c[i].noalias() += Asub[i - 1] * b[i - 1];
65 c[i].noalias() += Adiag[i] * b[i];
66 c[i].noalias() += Asuper[i] * b[i + 1];
69 c[N].noalias() += Asub[N - 1] * b[N - 1];
70 c[N].noalias() += Adiag[N] * b[N];
78template <
typename MatrixType,
typename RhsType,
typename DecType>
80 std::vector<MatrixType> &diagonal,
81 const std::vector<MatrixType> &superdiagonal,
83 std::vector<DecType> &facs) {
84 ALIGATOR_TRACY_ZONE_SCOPED;
87 if (subdiagonal.size() != superdiagonal.size() ||
88 diagonal.size() != superdiagonal.size() + 1 ||
89 rhs.
rowDims().size() != diagonal.size()) {
94 const size_t N = superdiagonal.size();
98 DecType &ldl = facs[i + 1];
99 ldl.compute(diagonal[i + 1]);
100 if (ldl.info() != Eigen::Success)
103 Eigen::Ref<RhsType> r = rhs[i + 1];
107 const auto &Bip1 = superdiagonal[i];
108 auto &Cip1 = subdiagonal[i];
110 rhs[i].noalias() -= Bip1 * rhs[i + 1];
111 ldl.solveInPlace(Cip1);
113 diagonal[i].noalias() -= Bip1 * Cip1;
121 DecType &ldl = facs[0];
122 ldl.compute(diagonal[0]);
123 if (ldl.info() != Eigen::Success)
125 Eigen::Ref<RhsType> r = rhs[0];
129 for (
size_t i = 0; i < N; i++) {
130 const auto &Uip1t = subdiagonal[i];
131 rhs[i + 1].noalias() -= Uip1t * rhs[i];
142template <
typename MatrixType,
typename RhsType,
typename DecType>
144 const std::vector<MatrixType> &superdiagonal,
145 const std::vector<DecType> &diagonalFacs,
149 const size_t N = superdiagonal.size();
153 const DecType &ldl = diagonalFacs[i + 1];
154 Eigen::Ref<RhsType> r = rhs[i + 1];
158 const auto &Bip1 = superdiagonal[i];
160 rhs[i].noalias() -= Bip1 * rhs[i + 1];
167 const DecType &ldl = diagonalFacs[0];
168 Eigen::Ref<RhsType> r = rhs[0];
171 for (
size_t i = 0; i < N; i++) {
172 const auto &Uip1t = transposedUfacs[i];
173 rhs[i + 1].noalias() -= Uip1t * rhs[i];
181template <
typename MatrixType,
typename RhsType,
typename DecType>
183 std::vector<MatrixType> &subdiagonal, std::vector<MatrixType> &diagonal,
185 std::vector<DecType> &facs) {
186 ALIGATOR_TRACY_ZONE_SCOPED;
189 if (subdiagonal.size() != superdiagonal.size() ||
190 diagonal.size() != superdiagonal.size() + 1 ||
191 rhs.
rowDims().size() != diagonal.size()) {
196 const size_t N = superdiagonal.size();
198 for (
size_t i = 0; i < N; i++) {
199 DecType &ldl = facs[i];
200 ldl.compute(diagonal[i]);
201 if (ldl.info() != Eigen::Success)
204 Eigen::Ref<RhsType> r = rhs[i];
208 auto &Bip1 = superdiagonal[i];
209 const auto &Cip1 = subdiagonal[i];
211 rhs[i + 1].noalias() -= Cip1 * rhs[i];
212 ldl.solveInPlace(Bip1);
215 diagonal[i + 1].noalias() -= Cip1 * Bip1;
219 DecType &ldl = facs[N];
220 ldl.compute(diagonal[N]);
221 if (ldl.info() != Eigen::Success)
223 Eigen::Ref<RhsType> r = rhs[N];
229 const auto &Lim1t = superdiagonal[i];
230 rhs[i].noalias() -= Lim1t * rhs[i + 1];
Block matrix class, with a fixed-size number of row and column blocks.
const row_dim_t & rowDims() const
#define ALIGATOR_NOMALLOC_SCOPED
bool symmetricBlockTridiagSolveDownLooking(std::vector< MatrixType > &subdiagonal, std::vector< MatrixType > &diagonal, std::vector< MatrixType > &superdiagonal, BlkMatrix< RhsType, -1, 1 > &rhs, std::vector< DecType > &facs)
Solve a symmetric block-tridiagonal problem by in-place factorization. The subdiagonal will be used ...
MatrixType::PlainObject blockTridiagToDenseMatrix(const std::vector< MatrixType > &subdiagonal, const std::vector< MatrixType > &diagonal, const std::vector< MatrixType > &superdiagonal)
bool blockTridiagMatMul(const std::vector< MatrixType > &Asub, const std::vector< MatrixType > &Adiag, const std::vector< MatrixType > &Asuper, const BlkMatrix< InputType, -1, 1 > &b, BlkMatrix< OutType, -1, 1 > &c, const Scalar beta)
bool symmetricBlockTridiagSolve(std::vector< MatrixType > &subdiagonal, std::vector< MatrixType > &diagonal, const std::vector< MatrixType > &superdiagonal, BlkMatrix< RhsType, -1, 1 > &rhs, std::vector< DecType > &facs)
Solve a symmetric block-tridiagonal problem by in-place factorization. The subdiagonal will be used ...
bool blockTridiagRefinementStep(const std::vector< MatrixType > &transposedUfacs, const std::vector< MatrixType > &superdiagonal, const std::vector< DecType > &diagonalFacs, BlkMatrix< RhsType, -1, 1 > &rhs)
Given the decomposed matrix data, just perform the backward-forward step of the algorithm.