Directory: | ./ |
---|---|
File: | include/pinocchio/math/tridiagonal-matrix.hpp |
Date: | 2025-02-12 21:03:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 162 | 172 | 94.2% |
Branches: | 88 | 372 | 23.7% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2024 INRIA | ||
3 | // | ||
4 | |||
5 | #ifndef __pinocchio_math_tridiagonal_matrix_hpp__ | ||
6 | #define __pinocchio_math_tridiagonal_matrix_hpp__ | ||
7 | |||
8 | #include "pinocchio/fwd.hpp" | ||
9 | #include <Eigen/Dense> | ||
10 | |||
11 | namespace pinocchio | ||
12 | { | ||
13 | template<typename Scalar, int Options = 0> | ||
14 | struct TridiagonalSymmetricMatrixTpl; | ||
15 | |||
16 | template<typename _Scalar, int _Options> | ||
17 | struct traits<TridiagonalSymmetricMatrixTpl<_Scalar, _Options>> | ||
18 | { | ||
19 | typedef _Scalar Scalar; | ||
20 | enum | ||
21 | { | ||
22 | Options = _Options | ||
23 | }; | ||
24 | typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Options> PlainMatrixType; | ||
25 | }; | ||
26 | |||
27 | template<typename TridiagonalSymmetricMatrix, typename MatrixDerived> | ||
28 | struct TridiagonalSymmetricMatrixApplyOnTheRightReturnType; | ||
29 | |||
30 | template<typename TridiagonalSymmetricMatrix, typename MatrixDerived> | ||
31 | struct traits< | ||
32 | TridiagonalSymmetricMatrixApplyOnTheRightReturnType<TridiagonalSymmetricMatrix, MatrixDerived>> | ||
33 | : public traits<TridiagonalSymmetricMatrix> | ||
34 | { | ||
35 | }; | ||
36 | |||
37 | template<typename MatrixDerived, typename TridiagonalSymmetricMatrix> | ||
38 | struct TridiagonalSymmetricMatrixApplyOnTheLeftReturnType; | ||
39 | |||
40 | template<typename MatrixDerived, typename TridiagonalSymmetricMatrix> | ||
41 | struct traits< | ||
42 | TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<MatrixDerived, TridiagonalSymmetricMatrix>> | ||
43 | : public traits<TridiagonalSymmetricMatrix> | ||
44 | { | ||
45 | }; | ||
46 | |||
47 | template<typename TridiagonalSymmetricMatrix> | ||
48 | struct TridiagonalSymmetricMatrixInverse; | ||
49 | |||
50 | template<typename TridiagonalSymmetricMatrix> | ||
51 | struct traits<TridiagonalSymmetricMatrixInverse<TridiagonalSymmetricMatrix>> | ||
52 | : public traits<TridiagonalSymmetricMatrix> | ||
53 | { | ||
54 | }; | ||
55 | |||
56 | template<typename TridiagonalSymmetricMatrixInverse, typename MatrixDerived> | ||
57 | struct TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType; | ||
58 | |||
59 | template<typename TridiagonalSymmetricMatrixInverse, typename MatrixDerived> | ||
60 | struct traits<TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType< | ||
61 | TridiagonalSymmetricMatrixInverse, | ||
62 | MatrixDerived>> : public traits<TridiagonalSymmetricMatrixInverse> | ||
63 | { | ||
64 | }; | ||
65 | } // namespace pinocchio | ||
66 | |||
67 | namespace Eigen | ||
68 | { | ||
69 | namespace internal | ||
70 | { | ||
71 | |||
72 | template<typename Scalar, int Options> | ||
73 | struct traits<pinocchio::TridiagonalSymmetricMatrixTpl<Scalar, Options>> | ||
74 | : public traits<typename pinocchio::traits< | ||
75 | pinocchio::TridiagonalSymmetricMatrixTpl<Scalar, Options>>::PlainMatrixType> | ||
76 | { | ||
77 | typedef pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixTpl<Scalar, Options>> Base; | ||
78 | typedef typename Base::PlainMatrixType ReturnType; | ||
79 | enum | ||
80 | { | ||
81 | Flags = 0 | ||
82 | }; | ||
83 | }; | ||
84 | |||
85 | template<typename TridiagonalSymmetricMatrix, typename MatrixDerived> | ||
86 | struct traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheRightReturnType< | ||
87 | TridiagonalSymmetricMatrix, | ||
88 | MatrixDerived>> | ||
89 | : public traits< | ||
90 | typename pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheRightReturnType< | ||
91 | TridiagonalSymmetricMatrix, | ||
92 | MatrixDerived>>::PlainMatrixType> | ||
93 | { | ||
94 | typedef pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheRightReturnType< | ||
95 | TridiagonalSymmetricMatrix, | ||
96 | MatrixDerived>> | ||
97 | Base; | ||
98 | typedef typename Base::PlainMatrixType ReturnType; | ||
99 | enum | ||
100 | { | ||
101 | Flags = 0 | ||
102 | }; | ||
103 | }; | ||
104 | |||
105 | template<typename MatrixDerived, typename TridiagonalSymmetricMatrix> | ||
106 | struct traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheLeftReturnType< | ||
107 | MatrixDerived, | ||
108 | TridiagonalSymmetricMatrix>> | ||
109 | : public traits< | ||
110 | typename pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheLeftReturnType< | ||
111 | MatrixDerived, | ||
112 | TridiagonalSymmetricMatrix>>::PlainMatrixType> | ||
113 | { | ||
114 | typedef pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheLeftReturnType< | ||
115 | MatrixDerived, | ||
116 | TridiagonalSymmetricMatrix>> | ||
117 | Base; | ||
118 | typedef typename Base::PlainMatrixType ReturnType; | ||
119 | enum | ||
120 | { | ||
121 | Flags = 0 | ||
122 | }; | ||
123 | }; | ||
124 | |||
125 | template<typename TridiagonalSymmetricMatrix> | ||
126 | struct traits<pinocchio::TridiagonalSymmetricMatrixInverse<TridiagonalSymmetricMatrix>> | ||
127 | : public traits<TridiagonalSymmetricMatrix> | ||
128 | { | ||
129 | }; | ||
130 | |||
131 | template<typename TridiagonalSymmetricMatrixInverse, typename MatrixDerived> | ||
132 | struct traits<pinocchio::TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType< | ||
133 | TridiagonalSymmetricMatrixInverse, | ||
134 | MatrixDerived>> | ||
135 | : public traits<typename pinocchio::traits< | ||
136 | pinocchio::TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType< | ||
137 | TridiagonalSymmetricMatrixInverse, | ||
138 | MatrixDerived>>::PlainMatrixType> | ||
139 | { | ||
140 | typedef pinocchio::traits< | ||
141 | pinocchio::TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType< | ||
142 | TridiagonalSymmetricMatrixInverse, | ||
143 | MatrixDerived>> | ||
144 | Base; | ||
145 | typedef typename Base::PlainMatrixType ReturnType; | ||
146 | enum | ||
147 | { | ||
148 | Flags = 0 | ||
149 | }; | ||
150 | }; | ||
151 | |||
152 | } // namespace internal | ||
153 | } // namespace Eigen | ||
154 | |||
155 | namespace pinocchio | ||
156 | { | ||
157 | |||
158 | /// \brief Dynamic size Tridiagonal symmetric matrix type | ||
159 | /// This class is in practice used in Lanczos decomposition | ||
160 | template<typename _Scalar, int _Options> | ||
161 | struct TridiagonalSymmetricMatrixTpl | ||
162 | : public Eigen::ReturnByValue<TridiagonalSymmetricMatrixTpl<_Scalar, _Options>> | ||
163 | { | ||
164 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
165 | typedef TridiagonalSymmetricMatrixTpl Self; | ||
166 | typedef _Scalar Scalar; | ||
167 | enum | ||
168 | { | ||
169 | Options = _Options | ||
170 | }; | ||
171 | |||
172 | typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> CoeffVectorType; | ||
173 | typedef typename traits<Self>::PlainMatrixType PlainMatrixType; | ||
174 | |||
175 | /// \brief Default constructor from a given size | ||
176 | 4 | explicit TridiagonalSymmetricMatrixTpl(const Eigen::DenseIndex size) | |
177 | 4 | : m_size(size) | |
178 | 4 | , m_diagonal(size) | |
179 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | , m_sub_diagonal(size - 1) |
180 | { | ||
181 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | assert(size > 0 && "size should be greater than 0."); |
182 | 4 | } | |
183 | |||
184 | ✗ | bool operator==(const TridiagonalSymmetricMatrixTpl & other) const | |
185 | { | ||
186 | ✗ | if (this == &other) | |
187 | ✗ | return true; | |
188 | ✗ | return diagonal() == other.diagonal() && subDiagonal() == other.subDiagonal(); | |
189 | } | ||
190 | |||
191 | ✗ | bool operator!=(const TridiagonalSymmetricMatrixTpl & other) const | |
192 | { | ||
193 | ✗ | return !(*this == other); | |
194 | } | ||
195 | |||
196 | 1 | TridiagonalSymmetricMatrixInverse<Self> inverse() const | |
197 | { | ||
198 | 1 | return TridiagonalSymmetricMatrixInverse<Self>(*this); | |
199 | } | ||
200 | |||
201 | 8 | CoeffVectorType & diagonal() | |
202 | { | ||
203 | 8 | return m_diagonal; | |
204 | } | ||
205 | 7009 | const CoeffVectorType & diagonal() const | |
206 | { | ||
207 | 7009 | return m_diagonal; | |
208 | } | ||
209 | 9 | CoeffVectorType & subDiagonal() | |
210 | { | ||
211 | 9 | return m_sub_diagonal; | |
212 | } | ||
213 | 14020 | const CoeffVectorType & subDiagonal() const | |
214 | { | ||
215 | 14020 | return m_sub_diagonal; | |
216 | } | ||
217 | |||
218 | 1 | void setIdentity() | |
219 | { | ||
220 | 1 | diagonal().setOnes(); | |
221 | 1 | subDiagonal().setZero(); | |
222 | 1 | } | |
223 | |||
224 | 1 | bool isIdentity(const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision()) const | |
225 | { | ||
226 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | return subDiagonal().isZero(prec) && diagonal().isOnes(prec); |
227 | } | ||
228 | |||
229 | 1 | void setZero() | |
230 | { | ||
231 | 1 | diagonal().setZero(); | |
232 | 1 | subDiagonal().setZero(); | |
233 | 1 | } | |
234 | |||
235 | 1 | bool isZero(const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision()) const | |
236 | { | ||
237 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | return subDiagonal().isZero(prec) && diagonal().isZero(prec); |
238 | } | ||
239 | |||
240 | 2 | void setRandom() | |
241 | { | ||
242 | 2 | diagonal().setRandom(); | |
243 | 2 | subDiagonal().setRandom(); | |
244 | 2 | } | |
245 | |||
246 | 2 | bool isDiagonal(const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision()) const | |
247 | { | ||
248 | 2 | return subDiagonal().isZero(prec); | |
249 | } | ||
250 | |||
251 | template<typename VectorCoeffType> | ||
252 | ✗ | void setDiagonal(const Eigen::MatrixBase<VectorCoeffType> & diagonal_coefficients) | |
253 | { | ||
254 | ✗ | PINOCCHIO_CHECK_ARGUMENT_SIZE(diagonal_coefficients.size(), cols()); | |
255 | static_assert( | ||
256 | VectorCoeffType::IsVectorAtCompileTime, | ||
257 | "VectorCoeffType should be a vector type at compile time"); | ||
258 | |||
259 | ✗ | diagonal() = diagonal_coefficients; | |
260 | ✗ | subDiagonal().setZero(); | |
261 | } | ||
262 | |||
263 | 12012 | EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT | |
264 | { | ||
265 | 12012 | return m_size; | |
266 | } | ||
267 | 7008 | EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT | |
268 | { | ||
269 | 7008 | return m_size; | |
270 | } | ||
271 | |||
272 | 1002 | PlainMatrixType matrix() const | |
273 | { | ||
274 | 1002 | return PlainMatrixType(*this); | |
275 | } | ||
276 | |||
277 | template<typename ResultType> | ||
278 | 3005 | inline void evalTo(ResultType & result) const | |
279 | { | ||
280 | 3005 | result.setZero(); | |
281 |
1/2✓ Branch 4 taken 3005 times.
✗ Branch 5 not taken.
|
3005 | result.template diagonal<1>() = subDiagonal().conjugate(); |
282 |
1/2✓ Branch 3 taken 3005 times.
✗ Branch 4 not taken.
|
3005 | result.diagonal() = diagonal(); |
283 |
1/2✓ Branch 3 taken 3005 times.
✗ Branch 4 not taken.
|
3005 | result.template diagonal<-1>() = subDiagonal(); |
284 | 3005 | } | |
285 | |||
286 | template<typename MatrixDerived> | ||
287 | TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived> | ||
288 | 6002 | applyOnTheRight(const Eigen::MatrixBase<MatrixDerived> & mat) const | |
289 | { | ||
290 | typedef TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived> ReturnType; | ||
291 | 6002 | return ReturnType(*this, mat.derived()); | |
292 | } | ||
293 | |||
294 | template<typename MatrixDerived> | ||
295 | TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<MatrixDerived, Self> | ||
296 | 1000 | applyOnTheLeft(const Eigen::MatrixBase<MatrixDerived> & mat) const | |
297 | { | ||
298 | typedef TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<MatrixDerived, Self> ReturnType; | ||
299 | 1000 | return ReturnType(mat.derived(), *this); | |
300 | } | ||
301 | |||
302 | template<typename MatrixDerived> | ||
303 | inline TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived> | ||
304 | 6002 | operator*(const Eigen::MatrixBase<MatrixDerived> & mat) const | |
305 | { | ||
306 | 6002 | return this->applyOnTheRight(mat.derived()); | |
307 | } | ||
308 | |||
309 | protected: | ||
310 | Eigen::DenseIndex m_size; | ||
311 | CoeffVectorType m_diagonal; | ||
312 | CoeffVectorType m_sub_diagonal; | ||
313 | }; | ||
314 | |||
315 | template<typename LhsMatrixType, typename S, int O> | ||
316 | TridiagonalSymmetricMatrixApplyOnTheLeftReturnType< | ||
317 | LhsMatrixType, | ||
318 | TridiagonalSymmetricMatrixTpl<S, O>> | ||
319 | 1000 | operator*( | |
320 | const Eigen::MatrixBase<LhsMatrixType> & lhs, const TridiagonalSymmetricMatrixTpl<S, O> & rhs) | ||
321 | { | ||
322 | 1000 | return rhs.applyOnTheLeft(lhs); | |
323 | } | ||
324 | |||
325 | template<typename TridiagonalSymmetricMatrix, typename RhsMatrixType> | ||
326 | struct TridiagonalSymmetricMatrixApplyOnTheRightReturnType | ||
327 | : public Eigen::ReturnByValue<TridiagonalSymmetricMatrixApplyOnTheRightReturnType< | ||
328 | TridiagonalSymmetricMatrix, | ||
329 | RhsMatrixType>> | ||
330 | { | ||
331 | typedef TridiagonalSymmetricMatrixApplyOnTheRightReturnType Self; | ||
332 | typedef typename traits<Self>::PlainMatrixType PlainMatrixType; | ||
333 | |||
334 | 6002 | TridiagonalSymmetricMatrixApplyOnTheRightReturnType( | |
335 | const TridiagonalSymmetricMatrix & lhs, const RhsMatrixType & rhs) | ||
336 | 6002 | : m_lhs(lhs) | |
337 | 6002 | , m_rhs(rhs) | |
338 | { | ||
339 | 6002 | } | |
340 | |||
341 | template<typename ResultType> | ||
342 | 6002 | inline void evalTo(ResultType & result) const | |
343 | { | ||
344 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 3001 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
6002 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows()); |
345 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 3001 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
6002 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols()); |
346 | |||
347 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3001 times.
|
6002 | assert(cols() >= 1); |
348 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3001 times.
|
6002 | assert(rows() >= 1); |
349 | |||
350 | 6002 | const Eigen::DenseIndex reduced_size = cols() - 1; | |
351 | // Main diagonal | ||
352 |
3/6✓ Branch 3 taken 3001 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3001 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3001 times.
✗ Branch 10 not taken.
|
6002 | result.noalias() = m_lhs.diagonal().asDiagonal() * m_rhs; |
353 | // Upper diagonal | ||
354 |
4/8✓ Branch 1 taken 3001 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3001 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3001 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1000 times.
✗ Branch 11 not taken.
|
6002 | result.topRows(reduced_size).noalias() += |
355 |
3/6✓ Branch 3 taken 3001 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3001 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2001 times.
✗ Branch 10 not taken.
|
6002 | m_lhs.subDiagonal().conjugate().asDiagonal() * m_rhs.bottomRows(reduced_size); |
356 | // Sub diagonal | ||
357 |
4/8✓ Branch 1 taken 3001 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3001 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3001 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1000 times.
✗ Branch 11 not taken.
|
6002 | result.bottomRows(reduced_size).noalias() += |
358 |
2/4✓ Branch 3 taken 3001 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2001 times.
✗ Branch 7 not taken.
|
6002 | m_lhs.subDiagonal().asDiagonal() * m_rhs.topRows(reduced_size); |
359 | 6002 | } | |
360 | |||
361 | 18006 | EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT | |
362 | { | ||
363 | 18006 | return m_lhs.rows(); | |
364 | } | ||
365 | 12004 | EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT | |
366 | { | ||
367 | 24008 | return m_rhs.cols(); | |
368 | } | ||
369 | |||
370 | protected: | ||
371 | const TridiagonalSymmetricMatrix & m_lhs; | ||
372 | const RhsMatrixType & m_rhs; | ||
373 | }; | ||
374 | |||
375 | template<typename LhsMatrixType, typename TridiagonalSymmetricMatrix> | ||
376 | struct TridiagonalSymmetricMatrixApplyOnTheLeftReturnType | ||
377 | : public Eigen::ReturnByValue< | ||
378 | TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<LhsMatrixType, TridiagonalSymmetricMatrix>> | ||
379 | { | ||
380 | typedef TridiagonalSymmetricMatrixApplyOnTheLeftReturnType Self; | ||
381 | typedef typename traits<Self>::PlainMatrixType PlainMatrixType; | ||
382 | |||
383 | 1000 | TridiagonalSymmetricMatrixApplyOnTheLeftReturnType( | |
384 | const LhsMatrixType & lhs, const TridiagonalSymmetricMatrix & rhs) | ||
385 | 1000 | : m_lhs(lhs) | |
386 | 1000 | , m_rhs(rhs) | |
387 | { | ||
388 | 1000 | } | |
389 | |||
390 | template<typename ResultType> | ||
391 | 1000 | inline void evalTo(ResultType & result) const | |
392 | { | ||
393 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1000 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1000 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows()); |
394 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1000 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1000 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols()); |
395 | |||
396 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1000 times.
|
1000 | assert(cols() >= 1); |
397 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1000 times.
|
1000 | assert(rows() >= 1); |
398 | |||
399 | 1000 | const Eigen::DenseIndex reduced_size = cols() - 1; | |
400 | // Main diagonal | ||
401 |
3/6✓ Branch 3 taken 1000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1000 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1000 times.
✗ Branch 10 not taken.
|
1000 | result.noalias() = m_lhs * m_rhs.diagonal().asDiagonal(); |
402 | // Upper diagonal | ||
403 |
3/6✓ Branch 1 taken 1000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1000 times.
✗ Branch 8 not taken.
|
1000 | result.rightCols(reduced_size).noalias() += |
404 |
2/4✓ Branch 4 taken 1000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1000 times.
✗ Branch 8 not taken.
|
1000 | m_lhs.leftCols(reduced_size) * m_rhs.subDiagonal().conjugate().asDiagonal(); |
405 | // Sub diagonal | ||
406 |
3/6✓ Branch 1 taken 1000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1000 times.
✗ Branch 8 not taken.
|
1000 | result.leftCols(reduced_size).noalias() += |
407 |
2/4✓ Branch 3 taken 1000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1000 times.
✗ Branch 7 not taken.
|
1000 | m_lhs.rightCols(reduced_size) * m_rhs.subDiagonal().asDiagonal(); |
408 | 1000 | } | |
409 | |||
410 | 3000 | EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT | |
411 | { | ||
412 | 3000 | return m_lhs.rows(); | |
413 | } | ||
414 | 4000 | EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT | |
415 | { | ||
416 | 4000 | return m_rhs.cols(); | |
417 | } | ||
418 | |||
419 | protected: | ||
420 | const LhsMatrixType & m_lhs; | ||
421 | const TridiagonalSymmetricMatrix & m_rhs; | ||
422 | }; | ||
423 | |||
424 | template<typename _TridiagonalSymmetricMatrix> | ||
425 | struct TridiagonalSymmetricMatrixInverse | ||
426 | : public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverse<_TridiagonalSymmetricMatrix>> | ||
427 | { | ||
428 | typedef _TridiagonalSymmetricMatrix TridiagonalSymmetricMatrix; | ||
429 | typedef TridiagonalSymmetricMatrixInverse Self; | ||
430 | typedef typename TridiagonalSymmetricMatrix::Scalar Scalar; | ||
431 | enum | ||
432 | { | ||
433 | Options = TridiagonalSymmetricMatrix::Options | ||
434 | }; | ||
435 | |||
436 | typedef typename TridiagonalSymmetricMatrix::CoeffVectorType CoeffVectorType; | ||
437 | typedef typename traits<Self>::PlainMatrixType PlainMatrixType; | ||
438 | |||
439 | 1 | explicit TridiagonalSymmetricMatrixInverse( | |
440 | const TridiagonalSymmetricMatrix & tridiagonal_matrix) | ||
441 | 1 | : tridiagonal_matrix(tridiagonal_matrix) | |
442 | 1 | , m_size(tridiagonal_matrix.rows()) | |
443 | 1 | , m_diagonal(m_size) | |
444 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | , m_sub_diagonal(m_size - 1) |
445 | { | ||
446 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | eval(); |
447 | 1 | } | |
448 | |||
449 | 1 | const TridiagonalSymmetricMatrix & inverse() const | |
450 | { | ||
451 | 1 | return tridiagonal_matrix; | |
452 | } | ||
453 | |||
454 | template<typename MatrixDerived> | ||
455 | TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, MatrixDerived> | ||
456 | 1 | applyOnTheRight(const Eigen::MatrixBase<MatrixDerived> & mat) const | |
457 | { | ||
458 | typedef TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, MatrixDerived> | ||
459 | ReturnType; | ||
460 | 1 | return ReturnType(*this, mat.derived()); | |
461 | } | ||
462 | |||
463 | template<typename MatrixDerived> | ||
464 | inline TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, MatrixDerived> | ||
465 | 1 | operator*(const Eigen::MatrixBase<MatrixDerived> & mat) const | |
466 | { | ||
467 | 1 | return this->applyOnTheRight(mat.derived()); | |
468 | } | ||
469 | |||
470 | template<typename ResultType> | ||
471 | 1 | inline void evalTo(ResultType & result) const | |
472 | { | ||
473 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows()); |
474 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols()); |
475 | |||
476 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | assert(cols() >= 1); |
477 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | assert(rows() >= 1); |
478 | |||
479 | 1 | const auto & b = m_diagonal; | |
480 | 1 | const auto & c = tridiagonal_matrix.subDiagonal(); | |
481 | 1 | const auto & w = m_sub_diagonal; | |
482 | |||
483 | // Forward sweep | ||
484 | 1 | result.setIdentity(); | |
485 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | for (Eigen::DenseIndex i = 1; i < m_size; ++i) |
486 | { | ||
487 |
6/12✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 9 times.
✗ Branch 18 not taken.
|
9 | result.row(i).head(i) -= w[i - 1] * result.row(i - 1).head(i); |
488 | } | ||
489 | |||
490 | // Backward sweep | ||
491 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | result.row(m_size - 1) /= b[m_size - 1]; |
492 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | for (Eigen::DenseIndex i = m_size - 2; i >= 0; --i) |
493 | { | ||
494 |
4/8✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
|
9 | result.row(i) -= c[i] * result.row(i + 1); |
495 |
1/2✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
|
9 | result.row(i) /= b[i]; |
496 | } | ||
497 | 1 | } | |
498 | |||
499 | 8 | EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT | |
500 | { | ||
501 | 8 | return m_size; | |
502 | } | ||
503 | 4 | EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT | |
504 | { | ||
505 | 4 | return m_size; | |
506 | } | ||
507 | |||
508 | protected: | ||
509 | template<typename T, typename MatrixDerived> | ||
510 | friend struct TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType; | ||
511 | |||
512 | /// \brief Forward sweep of https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm | ||
513 | 1 | void eval() | |
514 | { | ||
515 | 1 | m_diagonal = tridiagonal_matrix.diagonal(); | |
516 | 1 | m_sub_diagonal = tridiagonal_matrix.subDiagonal(); | |
517 | 1 | auto & w = m_sub_diagonal; | |
518 | 1 | auto & b = m_diagonal; | |
519 | 1 | const auto & c = tridiagonal_matrix.subDiagonal(); | |
520 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | for (Eigen::DenseIndex i = 1; i < m_size; ++i) |
521 | { | ||
522 | 9 | w.coeffRef(i - 1) /= b[i - 1]; | |
523 | 9 | m_diagonal.coeffRef(i) -= w[i - 1] * c[i - 1]; | |
524 | } | ||
525 | 1 | } | |
526 | |||
527 | const TridiagonalSymmetricMatrix & tridiagonal_matrix; | ||
528 | Eigen::DenseIndex m_size; | ||
529 | CoeffVectorType m_diagonal; | ||
530 | CoeffVectorType m_sub_diagonal; | ||
531 | }; | ||
532 | |||
533 | template<typename TridiagonalSymmetricMatrixInverse, typename RhsMatrixType> | ||
534 | struct TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType | ||
535 | : public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType< | ||
536 | TridiagonalSymmetricMatrixInverse, | ||
537 | RhsMatrixType>> | ||
538 | { | ||
539 | typedef TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType Self; | ||
540 | typedef typename traits<Self>::PlainMatrixType PlainMatrixType; | ||
541 | |||
542 | 1 | TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType( | |
543 | const TridiagonalSymmetricMatrixInverse & lhs, const RhsMatrixType & rhs) | ||
544 | 1 | : m_lhs(lhs) | |
545 | 1 | , m_rhs(rhs) | |
546 | { | ||
547 | 1 | } | |
548 | |||
549 | template<typename ResultType> | ||
550 | 1 | inline void evalTo(ResultType & result) const | |
551 | { | ||
552 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows()); |
553 |
1/24✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
|
1 | PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols()); |
554 | |||
555 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | assert(cols() >= 1); |
556 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | assert(rows() >= 1); |
557 | |||
558 | 1 | const Eigen::DenseIndex size = m_lhs.rows(); | |
559 | 1 | const auto & b = m_lhs.m_diagonal; | |
560 | 1 | const auto & c = m_lhs.tridiagonal_matrix.subDiagonal(); | |
561 | 1 | const auto & w = m_lhs.m_sub_diagonal; | |
562 | |||
563 | // Forward sweep | ||
564 | 1 | result = m_rhs; | |
565 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | for (Eigen::DenseIndex i = 1; i < size; ++i) |
566 | { | ||
567 |
4/8✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
|
9 | result.row(i) -= w[i - 1] * result.row(i - 1); |
568 | } | ||
569 | |||
570 | // Backward sweep | ||
571 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | result.row(size - 1) /= b[size - 1]; |
572 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | for (Eigen::DenseIndex i = size - 2; i >= 0; --i) |
573 | { | ||
574 |
4/8✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 9 times.
✗ Branch 12 not taken.
|
9 | result.row(i) -= c[i] * result.row(i + 1); |
575 |
1/2✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
|
9 | result.row(i) /= b[i]; |
576 | } | ||
577 | 1 | } | |
578 | |||
579 | 3 | EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT | |
580 | { | ||
581 | 3 | return m_lhs.rows(); | |
582 | } | ||
583 | 3 | EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT | |
584 | { | ||
585 | 3 | return m_rhs.cols(); | |
586 | } | ||
587 | |||
588 | protected: | ||
589 | const TridiagonalSymmetricMatrixInverse & m_lhs; | ||
590 | const RhsMatrixType & m_rhs; | ||
591 | }; | ||
592 | } // namespace pinocchio | ||
593 | |||
594 | #endif // #ifndef __pinocchio_math_tridiagonal_matrix_hpp__ | ||
595 |