tridiagonal-matrix.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2024 INRIA
3 //
4 
5 #include <iostream>
6 
8 
9 #include <boost/variant.hpp> // to avoid C99 warnings
10 
11 #include <boost/test/unit_test.hpp>
12 #include <boost/utility/binary.hpp>
13 
14 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
15 
16 using namespace pinocchio;
17 
19 {
20  const Eigen::DenseIndex mat_size = 20;
21  TridiagonalSymmetricMatrixTpl<double> tridiagonal_matrix(mat_size);
22 
23  tridiagonal_matrix.setZero();
24  BOOST_CHECK(tridiagonal_matrix.isZero(0));
25  BOOST_CHECK(tridiagonal_matrix.isDiagonal(0));
26  BOOST_CHECK(tridiagonal_matrix.matrix().isZero(0));
27 }
28 
29 BOOST_AUTO_TEST_CASE(test_identity)
30 {
31  const Eigen::DenseIndex mat_size = 20;
32  TridiagonalSymmetricMatrixTpl<double> tridiagonal_matrix(mat_size);
34 
35  tridiagonal_matrix.setIdentity();
36  BOOST_CHECK(tridiagonal_matrix.isIdentity(0));
37  BOOST_CHECK(tridiagonal_matrix.isDiagonal(0));
38 
39  BOOST_CHECK(tridiagonal_matrix.rows() == mat_size);
40  BOOST_CHECK(tridiagonal_matrix.cols() == mat_size);
41  BOOST_CHECK(tridiagonal_matrix.diagonal().size() == mat_size);
42  BOOST_CHECK(tridiagonal_matrix.subDiagonal().size() == mat_size - 1);
43 
44  BOOST_CHECK(tridiagonal_matrix.diagonal().isOnes(0));
45  BOOST_CHECK(tridiagonal_matrix.subDiagonal().isZero(0));
46  BOOST_CHECK(tridiagonal_matrix.matrix().isIdentity(0));
47 
48  // Fill matrix
49  {
50  PlainMatrixType mat(mat_size, mat_size);
51  mat = tridiagonal_matrix;
52 
53  BOOST_CHECK(mat.isIdentity(0));
54  }
55 
56  // Matrix multiplication left and right
57  for (int k = 0; k < 1000; ++k)
58  {
59  PlainMatrixType mat = PlainMatrixType::Random(mat_size, mat_size);
60 
61  PlainMatrixType plain(mat_size, mat_size);
62  plain = tridiagonal_matrix;
63 
64  PlainMatrixType res_apply_on_the_right = tridiagonal_matrix * mat;
65  PlainMatrixType res_apply_on_the_right_ref = plain * mat;
66  BOOST_CHECK(res_apply_on_the_right.isApprox(res_apply_on_the_right_ref));
67 
68  PlainMatrixType res_apply_on_the_left = mat * tridiagonal_matrix;
69  PlainMatrixType res_apply_on_the_left_ref = mat * plain;
70  BOOST_CHECK(res_apply_on_the_left.isApprox(res_apply_on_the_left_ref));
71  }
72 }
73 
75 {
76  const Eigen::DenseIndex mat_size = 20;
77  TridiagonalSymmetricMatrixTpl<double> tridiagonal_matrix(mat_size);
79 
80  tridiagonal_matrix.setRandom();
81 
82  BOOST_CHECK(tridiagonal_matrix.rows() == mat_size);
83  BOOST_CHECK(tridiagonal_matrix.cols() == mat_size);
84  BOOST_CHECK(tridiagonal_matrix.diagonal().size() == mat_size);
85  BOOST_CHECK(tridiagonal_matrix.subDiagonal().size() == mat_size - 1);
86 
87  // Fill matrix
88  {
89  PlainMatrixType mat(mat_size, mat_size);
90  mat = tridiagonal_matrix;
91 
92  BOOST_CHECK(mat.diagonal() == tridiagonal_matrix.diagonal());
93  BOOST_CHECK(mat.diagonal<-1>() == tridiagonal_matrix.subDiagonal());
94  BOOST_CHECK(mat.diagonal<+1>().conjugate() == tridiagonal_matrix.subDiagonal().conjugate());
95  }
96 
97  // Matrix multiplication
98  for (int k = 0; k < 1000; ++k)
99  {
100  PlainMatrixType rhs_mat = PlainMatrixType::Random(mat_size, mat_size);
101 
102  PlainMatrixType plain(mat_size, mat_size);
103  plain = tridiagonal_matrix;
104 
105  PlainMatrixType res = tridiagonal_matrix * rhs_mat;
106 
107  PlainMatrixType res_ref = plain * rhs_mat;
108  BOOST_CHECK(res.isApprox(res_ref));
109  BOOST_CHECK((tridiagonal_matrix * PlainMatrixType::Identity(mat_size, mat_size))
110  .isApprox(tridiagonal_matrix.matrix()));
111  }
112 }
113 
114 BOOST_AUTO_TEST_CASE(test_inverse)
115 {
116  typedef TridiagonalSymmetricMatrixTpl<double> TridiagonalSymmetricMatrixd;
117  const Eigen::DenseIndex mat_size = 10;
118  TridiagonalSymmetricMatrixTpl<double> tridiagonal_matrix(mat_size);
120 
121  tridiagonal_matrix.setRandom();
122 
123  PlainMatrixType plain_mat(mat_size, mat_size);
124  plain_mat = tridiagonal_matrix;
125  const PlainMatrixType plain_mat_inverse = plain_mat.inverse();
126 
128  tridiagonal_matrix_inverse = tridiagonal_matrix.inverse();
129 
130  BOOST_CHECK(tridiagonal_matrix_inverse.rows() == tridiagonal_matrix.rows());
131  BOOST_CHECK(tridiagonal_matrix_inverse.cols() == tridiagonal_matrix.cols());
132 
133  const auto & tridiagonal_matrix_ref = tridiagonal_matrix_inverse.inverse();
134  BOOST_CHECK(&tridiagonal_matrix_ref == &tridiagonal_matrix);
135 
136  const PlainMatrixType tridiagonal_matrix_inverse_plain = tridiagonal_matrix_inverse;
137  BOOST_CHECK(tridiagonal_matrix_inverse_plain.isApprox(plain_mat_inverse));
138 
139  // Matrix multiplication
140  for (int k = 0; k < 1; ++k)
141  {
142  PlainMatrixType rhs_mat = PlainMatrixType::Random(mat_size, mat_size);
143 
144  PlainMatrixType res(mat_size, mat_size);
145  res = tridiagonal_matrix_ref * rhs_mat;
146 
147  BOOST_CHECK(res.isApprox((plain_mat * rhs_mat).eval()));
148 
149  res = tridiagonal_matrix_inverse * rhs_mat;
150  const PlainMatrixType res_ref = plain_mat_inverse * rhs_mat;
151 
152  BOOST_CHECK(res.isApprox(res_ref));
153  }
154 
155  // Test diagonal
156  {
157  Eigen::MatrixXd sub_diagonal_matrix = Eigen::MatrixXd::Zero(mat_size, mat_size);
158  sub_diagonal_matrix.diagonal<1>().setRandom();
159  sub_diagonal_matrix.diagonal().setRandom();
160  sub_diagonal_matrix.diagonal<-1>().setRandom();
161 
162  const Eigen::MatrixXd test_mat = Eigen::MatrixXd::Random(mat_size, mat_size);
163  const Eigen::MatrixXd res_ref = sub_diagonal_matrix * test_mat;
164 
165  Eigen::MatrixXd res(mat_size, mat_size); // res.setZero();
166  res.noalias() = sub_diagonal_matrix.diagonal().asDiagonal() * test_mat;
167  res.topRows(mat_size - 1) +=
168  sub_diagonal_matrix.diagonal<1>().asDiagonal() * test_mat.bottomRows(mat_size - 1);
169  res.bottomRows(mat_size - 1) +=
170  sub_diagonal_matrix.diagonal<-1>().asDiagonal() * test_mat.topRows(mat_size - 1);
171  BOOST_CHECK(res.isApprox(res_ref));
172  }
173 }
174 
175 BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_zero)
Definition: tridiagonal-matrix.cpp:18
pinocchio::TridiagonalSymmetricMatrixTpl::subDiagonal
CoeffVectorType & subDiagonal()
Definition: math/tridiagonal-matrix.hpp:209
pinocchio::TridiagonalSymmetricMatrixTpl::inverse
TridiagonalSymmetricMatrixInverse< Self > inverse() const
Definition: math/tridiagonal-matrix.hpp:196
pinocchio::TridiagonalSymmetricMatrixTpl::matrix
PlainMatrixType matrix() const
Definition: math/tridiagonal-matrix.hpp:272
pinocchio::TridiagonalSymmetricMatrixTpl::rows
EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT
Definition: math/tridiagonal-matrix.hpp:263
pinocchio::res
ReturnType res
Definition: spatial/classic-acceleration.hpp:57
pinocchio::TridiagonalSymmetricMatrixTpl::PlainMatrixType
traits< Self >::PlainMatrixType PlainMatrixType
Definition: math/tridiagonal-matrix.hpp:173
pinocchio::TridiagonalSymmetricMatrixTpl
Dynamic size Tridiagonal symmetric matrix type This class is in practice used in Lanczos decompositio...
Definition: math/tridiagonal-matrix.hpp:14
plain
MatrixDerived plain(const Eigen::PlainObjectBase< MatrixDerived > &m)
pinocchio::TridiagonalSymmetricMatrixTpl::setRandom
void setRandom()
Definition: math/tridiagonal-matrix.hpp:240
pinocchio::TridiagonalSymmetricMatrixTpl::setZero
void setZero()
Definition: math/tridiagonal-matrix.hpp:229
pinocchio::TridiagonalSymmetricMatrixInverse
Definition: math/tridiagonal-matrix.hpp:48
mat
mat
pinocchio::TridiagonalSymmetricMatrixTpl::diagonal
CoeffVectorType & diagonal()
Definition: math/tridiagonal-matrix.hpp:201
pinocchio::TridiagonalSymmetricMatrixTpl::isDiagonal
bool isDiagonal(const Scalar prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
Definition: math/tridiagonal-matrix.hpp:246
pinocchio::TridiagonalSymmetricMatrixInverse::cols
EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT
Definition: math/tridiagonal-matrix.hpp:503
pinocchio::TridiagonalSymmetricMatrixTpl::setIdentity
void setIdentity()
Definition: math/tridiagonal-matrix.hpp:218
tridiagonal-matrix.hpp
pinocchio::TridiagonalSymmetricMatrixTpl::isIdentity
bool isIdentity(const Scalar prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
Definition: math/tridiagonal-matrix.hpp:224
pinocchio::TridiagonalSymmetricMatrixInverse::rows
EIGEN_CONSTEXPR Eigen::Index rows() const EIGEN_NOEXCEPT
Definition: math/tridiagonal-matrix.hpp:499
pinocchio::TridiagonalSymmetricMatrixTpl::isZero
bool isZero(const Scalar prec=Eigen::NumTraits< Scalar >::dummy_precision()) const
Definition: math/tridiagonal-matrix.hpp:235
pinocchio::TridiagonalSymmetricMatrixInverse::inverse
const TridiagonalSymmetricMatrix & inverse() const
Definition: math/tridiagonal-matrix.hpp:449
pinocchio::TridiagonalSymmetricMatrixTpl::cols
EIGEN_CONSTEXPR Eigen::Index cols() const EIGEN_NOEXCEPT
Definition: math/tridiagonal-matrix.hpp:267
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27
isApprox
bool isApprox(const Box &s1, const Box &s2, const FCL_REAL tol)


pinocchio
Author(s):
autogenerated on Sun Dec 22 2024 03:41:12