5 #ifndef __pinocchio_math_tridiagonal_matrix_hpp__
6 #define __pinocchio_math_tridiagonal_matrix_hpp__
8 #include "pinocchio/fwd.hpp"
13 template<
typename Scalar,
int Options = 0>
14 struct TridiagonalSymmetricMatrixTpl;
16 template<
typename _Scalar,
int _Options>
19 typedef _Scalar Scalar;
24 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Options> PlainMatrixType;
27 template<
typename Tr
idiagonalSymmetricMatrix,
typename MatrixDerived>
30 template<
typename Tr
idiagonalSymmetricMatrix,
typename MatrixDerived>
33 :
public traits<TridiagonalSymmetricMatrix>
37 template<
typename MatrixDerived,
typename Tr
idiagonalSymmetricMatrix>
40 template<
typename MatrixDerived,
typename Tr
idiagonalSymmetricMatrix>
43 :
public traits<TridiagonalSymmetricMatrix>
47 template<
typename Tr
idiagonalSymmetricMatrix>
50 template<
typename Tr
idiagonalSymmetricMatrix>
52 :
public traits<TridiagonalSymmetricMatrix>
56 template<
typename Tr
idiagonalSymmetricMatrixInverse,
typename MatrixDerived>
59 template<
typename Tr
idiagonalSymmetricMatrixInverse,
typename MatrixDerived>
62 MatrixDerived>> :
public traits<TridiagonalSymmetricMatrixInverse>
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>
78 typedef typename Base::PlainMatrixType ReturnType;
85 template<
typename Tr
idiagonalSymmetricMatrix,
typename MatrixDerived>
86 struct traits<
pinocchio::TridiagonalSymmetricMatrixApplyOnTheRightReturnType<
87 TridiagonalSymmetricMatrix,
90 typename pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheRightReturnType<
91 TridiagonalSymmetricMatrix,
92 MatrixDerived>>::PlainMatrixType>
95 TridiagonalSymmetricMatrix,
98 typedef typename Base::PlainMatrixType ReturnType;
105 template<
typename MatrixDerived,
typename Tr
idiagonalSymmetricMatrix>
106 struct traits<
pinocchio::TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<
108 TridiagonalSymmetricMatrix>>
110 typename pinocchio::traits<pinocchio::TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<
112 TridiagonalSymmetricMatrix>>::PlainMatrixType>
116 TridiagonalSymmetricMatrix>>
118 typedef typename Base::PlainMatrixType ReturnType;
125 template<
typename Tr
idiagonalSymmetricMatrix>
126 struct traits<
pinocchio::TridiagonalSymmetricMatrixInverse<TridiagonalSymmetricMatrix>>
127 :
public traits<TridiagonalSymmetricMatrix>
131 template<
typename Tr
idiagonalSymmetricMatrixInverse,
typename MatrixDerived>
132 struct traits<
pinocchio::TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<
133 TridiagonalSymmetricMatrixInverse,
135 :
public traits<typename pinocchio::traits<
136 pinocchio::TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<
137 TridiagonalSymmetricMatrixInverse,
138 MatrixDerived>>::PlainMatrixType>
142 TridiagonalSymmetricMatrixInverse,
145 typedef typename Base::PlainMatrixType ReturnType;
160 template<
typename _Scalar,
int _Options>
162 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixTpl<_Scalar, _Options>>
164 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
166 typedef _Scalar Scalar;
172 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> CoeffVectorType;
179 , m_sub_diagonal(size - 1)
181 assert(size > 0 &&
"size should be greater than 0.");
188 return diagonal() == other.diagonal() && subDiagonal() == other.subDiagonal();
193 return !(*
this == other);
196 TridiagonalSymmetricMatrixInverse<Self> inverse()
const
198 return TridiagonalSymmetricMatrixInverse<Self>(*
this);
201 CoeffVectorType & diagonal()
205 const CoeffVectorType & diagonal()
const
209 CoeffVectorType & subDiagonal()
211 return m_sub_diagonal;
213 const CoeffVectorType & subDiagonal()
const
215 return m_sub_diagonal;
220 diagonal().setOnes();
221 subDiagonal().setZero();
224 bool isIdentity(
const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
226 return subDiagonal().isZero(prec) && diagonal().isOnes(prec);
231 diagonal().setZero();
232 subDiagonal().setZero();
235 bool isZero(
const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
237 return subDiagonal().isZero(prec) && diagonal().isZero(prec);
242 diagonal().setRandom();
243 subDiagonal().setRandom();
246 bool isDiagonal(
const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision())
const
248 return subDiagonal().isZero(prec);
251 template<
typename VectorCoeffType>
252 void setDiagonal(
const Eigen::MatrixBase<VectorCoeffType> & diagonal_coefficients)
254 PINOCCHIO_CHECK_ARGUMENT_SIZE(diagonal_coefficients.size(), cols());
256 VectorCoeffType::IsVectorAtCompileTime,
257 "VectorCoeffType should be a vector type at compile time");
259 diagonal() = diagonal_coefficients;
260 subDiagonal().setZero();
263 EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT
267 EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT
272 PlainMatrixType matrix()
const
274 return PlainMatrixType(*
this);
277 template<
typename ResultType>
278 inline void evalTo(ResultType & result)
const
281 result.template diagonal<1>() = subDiagonal().conjugate();
282 result.diagonal() = diagonal();
283 result.template diagonal<-1>() = subDiagonal();
286 template<
typename MatrixDerived>
287 TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived>
288 applyOnTheRight(
const Eigen::MatrixBase<MatrixDerived> & mat)
const
290 typedef TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived> ReturnType;
291 return ReturnType(*
this, mat.derived());
294 template<
typename MatrixDerived>
295 TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<MatrixDerived, Self>
296 applyOnTheLeft(
const Eigen::MatrixBase<MatrixDerived> & mat)
const
298 typedef TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<MatrixDerived, Self> ReturnType;
299 return ReturnType(mat.derived(), *
this);
302 template<
typename MatrixDerived>
303 inline TridiagonalSymmetricMatrixApplyOnTheRightReturnType<Self, MatrixDerived>
304 operator*(
const Eigen::MatrixBase<MatrixDerived> & mat)
const
306 return this->applyOnTheRight(mat.derived());
310 Eigen::DenseIndex m_size;
311 CoeffVectorType m_diagonal;
312 CoeffVectorType m_sub_diagonal;
315 template<
typename LhsMatrixType,
typename S,
int O>
316 TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<
318 TridiagonalSymmetricMatrixTpl<S, O>>
320 const Eigen::MatrixBase<LhsMatrixType> & lhs,
const TridiagonalSymmetricMatrixTpl<S, O> & rhs)
322 return rhs.applyOnTheLeft(lhs);
325 template<
typename Tr
idiagonalSymmetricMatrix,
typename RhsMatrixType>
327 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixApplyOnTheRightReturnType<
328 TridiagonalSymmetricMatrix,
335 const TridiagonalSymmetricMatrix & lhs,
const RhsMatrixType & rhs)
341 template<
typename ResultType>
342 inline void evalTo(ResultType & result)
const
344 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows());
345 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols());
350 const Eigen::DenseIndex reduced_size = cols() - 1;
352 result.noalias() = m_lhs.diagonal().asDiagonal() * m_rhs;
354 result.topRows(reduced_size).noalias() +=
355 m_lhs.subDiagonal().conjugate().asDiagonal() * m_rhs.bottomRows(reduced_size);
357 result.bottomRows(reduced_size).noalias() +=
358 m_lhs.subDiagonal().asDiagonal() * m_rhs.topRows(reduced_size);
361 EIGEN_CONSTEXPR Eigen::Index rows()
const EIGEN_NOEXCEPT
365 EIGEN_CONSTEXPR Eigen::Index cols()
const EIGEN_NOEXCEPT
371 const TridiagonalSymmetricMatrix & m_lhs;
372 const RhsMatrixType & m_rhs;
375 template<
typename LhsMatrixType,
typename Tr
idiagonalSymmetricMatrix>
377 :
public Eigen::ReturnByValue<
378 TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<LhsMatrixType, TridiagonalSymmetricMatrix>>
384 const LhsMatrixType & lhs,
const TridiagonalSymmetricMatrix & rhs)
390 template<
typename ResultType>
391 inline void evalTo(ResultType & result)
const
393 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows());
394 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols());
399 const Eigen::DenseIndex reduced_size = cols() - 1;
401 result.noalias() = m_lhs * m_rhs.diagonal().asDiagonal();
403 result.rightCols(reduced_size).noalias() +=
404 m_lhs.leftCols(reduced_size) * m_rhs.subDiagonal().conjugate().asDiagonal();
406 result.leftCols(reduced_size).noalias() +=
407 m_lhs.rightCols(reduced_size) * m_rhs.subDiagonal().asDiagonal();
410 EIGEN_CONSTEXPR Eigen::Index rows()
const EIGEN_NOEXCEPT
414 EIGEN_CONSTEXPR Eigen::Index cols()
const EIGEN_NOEXCEPT
420 const LhsMatrixType & m_lhs;
421 const TridiagonalSymmetricMatrix & m_rhs;
424 template<
typename _Tr
idiagonalSymmetricMatrix>
426 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverse<_TridiagonalSymmetricMatrix>>
428 typedef _TridiagonalSymmetricMatrix TridiagonalSymmetricMatrix;
430 typedef typename TridiagonalSymmetricMatrix::Scalar Scalar;
433 Options = TridiagonalSymmetricMatrix::Options
436 typedef typename TridiagonalSymmetricMatrix::CoeffVectorType CoeffVectorType;
440 const TridiagonalSymmetricMatrix & tridiagonal_matrix)
441 : tridiagonal_matrix(tridiagonal_matrix)
442 , m_size(tridiagonal_matrix.rows())
444 , m_sub_diagonal(m_size - 1)
449 const TridiagonalSymmetricMatrix & inverse()
const
451 return tridiagonal_matrix;
454 template<
typename MatrixDerived>
456 applyOnTheRight(
const Eigen::MatrixBase<MatrixDerived> & mat)
const
460 return ReturnType(*
this, mat.derived());
463 template<
typename MatrixDerived>
465 operator*(
const Eigen::MatrixBase<MatrixDerived> & mat)
const
467 return this->applyOnTheRight(mat.derived());
470 template<
typename ResultType>
471 inline void evalTo(ResultType & result)
const
473 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows());
474 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols());
479 const auto & b = m_diagonal;
480 const auto & c = tridiagonal_matrix.subDiagonal();
481 const auto & w = m_sub_diagonal;
484 result.setIdentity();
485 for (Eigen::DenseIndex i = 1; i < m_size; ++i)
487 result.row(i).head(i) -= w[i - 1] * result.row(i - 1).head(i);
491 result.row(m_size - 1) /= b[m_size - 1];
492 for (Eigen::DenseIndex i = m_size - 2; i >= 0; --i)
494 result.row(i) -= c[i] * result.row(i + 1);
495 result.row(i) /= b[i];
499 EIGEN_CONSTEXPR Eigen::Index rows()
const EIGEN_NOEXCEPT
503 EIGEN_CONSTEXPR Eigen::Index cols()
const EIGEN_NOEXCEPT
509 template<
typename T,
typename MatrixDerived>
515 m_diagonal = tridiagonal_matrix.diagonal();
516 m_sub_diagonal = tridiagonal_matrix.subDiagonal();
517 auto & w = m_sub_diagonal;
518 auto & b = m_diagonal;
519 const auto & c = tridiagonal_matrix.subDiagonal();
520 for (Eigen::DenseIndex i = 1; i < m_size; ++i)
522 w.coeffRef(i - 1) /= b[i - 1];
523 m_diagonal.coeffRef(i) -= w[i - 1] * c[i - 1];
527 const TridiagonalSymmetricMatrix & tridiagonal_matrix;
528 Eigen::DenseIndex m_size;
529 CoeffVectorType m_diagonal;
530 CoeffVectorType m_sub_diagonal;
533 template<
typename Tr
idiagonalSymmetricMatrixInverse,
typename RhsMatrixType>
535 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<
536 TridiagonalSymmetricMatrixInverse,
549 template<
typename ResultType>
550 inline void evalTo(ResultType & result)
const
552 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.rows(), rows());
553 PINOCCHIO_CHECK_ARGUMENT_SIZE(result.cols(), cols());
558 const Eigen::DenseIndex size = m_lhs.rows();
559 const auto & b = m_lhs.m_diagonal;
560 const auto & c = m_lhs.tridiagonal_matrix.subDiagonal();
561 const auto & w = m_lhs.m_sub_diagonal;
565 for (Eigen::DenseIndex i = 1; i < size; ++i)
567 result.row(i) -= w[i - 1] * result.row(i - 1);
571 result.row(size - 1) /= b[size - 1];
572 for (Eigen::DenseIndex i = size - 2; i >= 0; --i)
574 result.row(i) -= c[i] * result.row(i + 1);
575 result.row(i) /= b[i];
579 EIGEN_CONSTEXPR Eigen::Index rows()
const EIGEN_NOEXCEPT
583 EIGEN_CONSTEXPR Eigen::Index cols()
const EIGEN_NOEXCEPT
590 const RhsMatrixType & m_rhs;
Main pinocchio namespace.
void eval()
Forward sweep of https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm.
Dynamic size Tridiagonal symmetric matrix type This class is in practice used in Lanczos decompositio...
TridiagonalSymmetricMatrixTpl(const Eigen::DenseIndex size)
Default constructor from a given size.
Common traits structure to fully define base classes for CRTP.