aligator  0.6.1
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
Loading...
Searching...
No Matches
block-tridiagonal.hpp
Go to the documentation of this file.
1
3#pragma once
4
7#include <tracy/Tracy.hpp>
8
9namespace aligator {
10namespace gar {
11
12template <typename MatrixType>
13typename MatrixType::PlainObject
14blockTridiagToDenseMatrix(const std::vector<MatrixType> &subdiagonal,
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");
20 }
21
22 using PlainObjectType = typename MatrixType::PlainObject;
23
24 const size_t N = subdiagonal.size();
25 Eigen::Index dim = 0;
26 for (size_t i = 0; i <= N; i++) {
27 dim += diagonal[i].cols();
28 }
29
30 PlainObjectType out(dim, dim);
31 out.setZero();
32 Eigen::Index i0 = 0;
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];
36
37 if (i != N) {
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];
41 }
42
43 i0 += d;
44 }
45 return out;
46}
47
48template <typename MatrixType, typename InputType, typename OutType,
49 typename Scalar = typename MatrixType::Scalar>
50bool blockTridiagMatMul(const std::vector<MatrixType> &Asub,
51 const std::vector<MatrixType> &Adiag,
52 const std::vector<MatrixType> &Asuper,
53 const BlkMatrix<InputType, -1, 1> &b,
54 BlkMatrix<OutType, -1, 1> &c, const Scalar beta) {
56 const size_t N = Asuper.size();
57
58 c.matrix() *= beta;
59
60 c[0].noalias() += Adiag[0] * b[0];
61 c[0].noalias() += Asuper[0] * b[1];
62
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];
67 }
68
69 c[N].noalias() += Asub[N - 1] * b[N - 1];
70 c[N].noalias() += Adiag[N] * b[N];
71
72 return true;
73}
74
78template <typename MatrixType, typename RhsType, typename DecType>
79bool symmetricBlockTridiagSolve(std::vector<MatrixType> &subdiagonal,
80 std::vector<MatrixType> &diagonal,
81 const std::vector<MatrixType> &superdiagonal,
82 BlkMatrix<RhsType, -1, 1> &rhs,
83 std::vector<DecType> &facs) {
84 ZoneScoped;
86
87 if (subdiagonal.size() != superdiagonal.size() ||
88 diagonal.size() != superdiagonal.size() + 1 ||
89 rhs.rowDims().size() != diagonal.size()) {
90 return false;
91 }
92
93 // size of problem
94 const size_t N = superdiagonal.size();
95
96 size_t i = N - 1;
97 while (true) {
98 DecType &ldl = facs[i + 1];
99 ldl.compute(diagonal[i + 1]);
100 if (ldl.info() != Eigen::Success)
101 return false;
102
103 Eigen::Ref<RhsType> r = rhs[i + 1];
104 ldl.solveInPlace(r);
105
106 // the math has index of B starting at 1, array starts at 0
107 const auto &Bip1 = superdiagonal[i];
108 auto &Cip1 = subdiagonal[i]; // should be Bi.transpose()
109
110 rhs[i].noalias() -= Bip1 * rhs[i + 1];
111 ldl.solveInPlace(Cip1); // contains U.T = D[i+1]^-1 * B[i+1].transpose()
112
113 diagonal[i].noalias() -= Bip1 * Cip1;
114
115 if (i == 0)
116 break;
117 i--;
118 }
119
120 {
121 DecType &ldl = facs[0];
122 ldl.compute(diagonal[0]);
123 if (ldl.info() != Eigen::Success)
124 return false;
125 Eigen::Ref<RhsType> r = rhs[0];
126 ldl.solveInPlace(r);
127 }
128
129 for (size_t i = 0; i < N; i++) {
130 const auto &Uip1t = subdiagonal[i];
131 rhs[i + 1].noalias() -= Uip1t * rhs[i];
132 }
133
134 return true;
135}
136
142template <typename MatrixType, typename RhsType, typename DecType>
143bool blockTridiagRefinementStep(const std::vector<MatrixType> &transposedUfacs,
144 const std::vector<MatrixType> &superdiagonal,
145 const std::vector<DecType> &diagonalFacs,
146 BlkMatrix<RhsType, -1, 1> &rhs) {
148 // size of problem
149 const size_t N = superdiagonal.size();
150
151 size_t i = N - 1;
152 while (true) {
153 const DecType &ldl = diagonalFacs[i + 1];
154 Eigen::Ref<RhsType> r = rhs[i + 1];
155 ldl.solveInPlace(r);
156
157 // the math has index of B starting at 1, array starts at 0
158 const auto &Bip1 = superdiagonal[i];
159
160 rhs[i].noalias() -= Bip1 * rhs[i + 1];
161
162 if (i == 0)
163 break;
164 i--;
165 }
166
167 const DecType &ldl = diagonalFacs[0];
168 Eigen::Ref<RhsType> r = rhs[0];
169 ldl.solveInPlace(r);
170
171 for (size_t i = 0; i < N; i++) {
172 const auto &Uip1t = transposedUfacs[i];
173 rhs[i + 1].noalias() -= Uip1t * rhs[i];
174 }
175
176 return true;
177}
178
181template <typename MatrixType, typename RhsType, typename DecType>
183 std::vector<MatrixType> &subdiagonal, std::vector<MatrixType> &diagonal,
184 std::vector<MatrixType> &superdiagonal, BlkMatrix<RhsType, -1, 1> &rhs,
185 std::vector<DecType> &facs) {
186 ZoneScoped;
188
189 if (subdiagonal.size() != superdiagonal.size() ||
190 diagonal.size() != superdiagonal.size() + 1 ||
191 rhs.rowDims().size() != diagonal.size()) {
192 return false;
193 }
194
195 // size of problem
196 const size_t N = superdiagonal.size();
197
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)
202 return false;
203
204 Eigen::Ref<RhsType> r = rhs[i];
205 ldl.solveInPlace(r);
206
207 // the math has index of B starting at 1, array starts at 0
208 auto &Bip1 = superdiagonal[i];
209 const auto &Cip1 = subdiagonal[i]; // should be B[i+1].transpose()
210
211 rhs[i + 1].noalias() -= Cip1 * rhs[i];
212 ldl.solveInPlace(Bip1); // contains L.T = D[i]^-1 * B[i+1]
213
214 // substract B[i+1].T * L.T
215 diagonal[i + 1].noalias() -= Cip1 * Bip1;
216 }
217
218 {
219 DecType &ldl = facs[N];
220 ldl.compute(diagonal[N]);
221 if (ldl.info() != Eigen::Success)
222 return false;
223 Eigen::Ref<RhsType> r = rhs[N];
224 ldl.solveInPlace(r);
225 }
226
227 size_t i = N - 1;
228 while (true) {
229 const auto &Lim1t = superdiagonal[i];
230 rhs[i].noalias() -= Lim1t * rhs[i + 1];
231
232 if (i == 0)
233 break;
234 i--;
235 }
236 return true;
237}
238
239} // namespace gar
240} // namespace aligator
#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.
Main package namespace.