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;
326 struct TridiagonalSymmetricMatrixApplyOnTheRightReturnType
327 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixApplyOnTheRightReturnType<
328 TridiagonalSymmetricMatrix,
331 typedef TridiagonalSymmetricMatrixApplyOnTheRightReturnType Self;
334 TridiagonalSymmetricMatrixApplyOnTheRightReturnType(
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;
376 struct TridiagonalSymmetricMatrixApplyOnTheLeftReturnType
377 :
public Eigen::ReturnByValue<
378 TridiagonalSymmetricMatrixApplyOnTheLeftReturnType<LhsMatrixType, TridiagonalSymmetricMatrix>>
380 typedef TridiagonalSymmetricMatrixApplyOnTheLeftReturnType Self;
383 TridiagonalSymmetricMatrixApplyOnTheLeftReturnType(
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;
425 struct TridiagonalSymmetricMatrixInverse
426 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverse<_TridiagonalSymmetricMatrix>>
428 typedef _TridiagonalSymmetricMatrix TridiagonalSymmetricMatrix;
429 typedef TridiagonalSymmetricMatrixInverse Self;
430 typedef typename TridiagonalSymmetricMatrix::Scalar Scalar;
433 Options = TridiagonalSymmetricMatrix::Options
436 typedef typename TridiagonalSymmetricMatrix::CoeffVectorType CoeffVectorType;
439 explicit TridiagonalSymmetricMatrixInverse(
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>
455 TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, MatrixDerived>
456 applyOnTheRight(
const Eigen::MatrixBase<MatrixDerived> & mat)
const 458 typedef TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, MatrixDerived>
463 template<
typename MatrixDerived>
464 inline TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<Self, 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>
510 friend struct TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType;
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;
534 struct TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType
535 :
public Eigen::ReturnByValue<TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType<
536 TridiagonalSymmetricMatrixInverse,
539 typedef TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType Self;
542 TridiagonalSymmetricMatrixInverseApplyOnTheRightReturnType(
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;