14 #include <Eigen/Eigenvalues> 21 template <
typename Scalar,
class Derived>
23 const std::vector<std::size_t>& idxs)
26 const auto nR = mbDerived().rows();
27 for (
auto it = idxs.rbegin(); it != idxs.rend(); ++it, ++k)
29 const auto nC = mbDerived().cols() - *it - k;
31 mbDerived().asEigen().block(0, *it, nR, nC) =
32 mbDerived().asEigen().block(0, *it + 1, nR, nC).eval();
34 mbDerived().setSize(nR, mbDerived().cols() - idxs.size());
37 template <
typename Scalar,
class Derived>
39 const std::vector<std::size_t>& idxsToRemove)
41 std::vector<std::size_t> idxs = idxsToRemove;
42 std::sort(idxs.begin(), idxs.end());
43 auto itEnd = std::unique(idxs.begin(), idxs.end());
44 idxs.resize(itEnd - idxs.begin());
45 unsafeRemoveColumns(idxs);
48 template <
typename Scalar,
class Derived>
50 const std::vector<size_t>& idxs)
53 const auto nC = mbDerived().cols();
54 for (
auto it = idxs.rbegin(); it != idxs.rend(); ++it, ++k)
56 const auto nR = mbDerived().rows() - *it - k;
58 mbDerived().asEigen().block(*it, 0, nR, nC) =
59 mbDerived().asEigen().block(*it + 1, 0, nR, nC).eval();
61 mbDerived().setSize(mbDerived().rows() - idxs.size(), nC);
64 template <
typename Scalar,
class Derived>
66 const std::vector<size_t>& idxsToRemove)
68 std::vector<std::size_t> idxs = idxsToRemove;
69 std::sort(idxs.begin(), idxs.end());
70 auto itEnd = std::unique(idxs.begin(), idxs.end());
71 idxs.resize(itEnd - idxs.begin());
72 unsafeRemoveRows(idxs);
75 template <
typename Scalar,
class Derived>
78 return mbDerived().asEigen().eval().determinant();
84 template <
typename Scalar,
typename VEC1,
typename MATRIX1,
typename MATRIX2>
86 const VEC1& eVals,
const MATRIX1& eVecs, std::vector<Scalar>& sorted_eVals,
87 MATRIX2& sorted_eVecs)
89 const int64_t N =
static_cast<int64_t
>(eVals.size());
90 std::vector<std::pair<Scalar, int64_t>> D;
92 for (int64_t i = 0; i < N; i++) D.emplace_back(eVals[i], i);
93 std::sort(D.begin(), D.end());
96 sorted_eVecs.resize(eVecs.rows(), eVecs.cols());
97 sorted_eVals.resize(N);
98 for (int64_t i = 0; i < N; i++)
100 sorted_eVals[i] = D[i].first;
101 sorted_eVecs.col(i) = eVecs.col(D[i].second);
106 template <
typename Scalar,
class Derived>
108 Derived& eVecs, std::vector<Scalar>& eVals,
bool sorted)
const 110 Eigen::EigenSolver<typename Derived::eigen_t> es(mbDerived().asEigen());
111 if (es.info() != Eigen::Success)
return false;
112 const auto eigenVal = es.eigenvalues().real();
114 const auto N = eigenVal.rows();
119 eigenVal, es.eigenvectors().real(), eVals, eVecs);
124 eVecs = es.eigenvectors().real();
125 for (
int i = 0; i < N; i++) eVals[i] = eigenVal[i];
130 template <
typename Scalar,
class Derived>
132 Derived& eVecs, std::vector<Scalar>& eVals,
bool sorted)
const 135 mbDerived().asEigen());
136 if (es.info() != Eigen::Success)
return false;
137 const auto eigenVal = es.eigenvalues().real();
139 const auto N = eigenVal.rows();
144 eigenVal, es.eigenvectors().real(), eVals, eVecs);
149 eVecs = es.eigenvectors().real();
150 for (
int i = 0; i < N; i++) eVals[i] = eigenVal[i];
155 template <
typename Scalar,
class Derived>
158 Eigen::FullPivLU<typename Derived::eigen_t> lu(
159 mbDerived().asEigen().eval());
160 if (threshold > 0) lu.setThreshold(threshold);
164 template <
typename Scalar,
class Derived>
167 Eigen::LLT<typename Derived::eigen_t> Chol =
168 mbDerived().asEigen().template selfadjointView<Eigen::Lower>().llt();
169 if (Chol.info() == Eigen::NoConvergence)
return false;
170 U =
typename Derived::eigen_t(Chol.matrixU());
174 template <
typename Scalar,
class Derived>
176 const Derived&
A,
const Derived& B)
178 mbDerived().resize(
A.rows(), B.cols());
179 mbDerived().asEigen() = (
A.asEigen() * B.asEigen()).eval();
182 template <
typename Scalar,
class Derived>
186 const auto N = mbDerived().cols();
187 const auto I = Derived::eigen_t::Identity(N, N);
190 inv.asEigen() = mbDerived().asEigen().lu().solve(I).eval();
194 template <
typename Scalar,
class Derived>
198 const auto N = mbDerived().cols();
199 const auto I = Derived::eigen_t::Identity(N, N);
202 inv.asEigen() = mbDerived().asEigen().llt().solve(I).eval();
206 template <
typename Scalar,
class Derived>
209 return mbDerived().asEigen().diagonal().maxCoeff();
212 template <
typename Scalar,
class Derived>
215 return mbDerived().asEigen().diagonal().minCoeff();
218 template <
typename Scalar,
class Derived>
221 return mbDerived().asEigen().trace();
bool eig(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Computes the eigenvectors and eigenvalues for a square, general matrix.
void unsafeRemoveColumns(const std::vector< std::size_t > &idxs)
Removes columns of the matrix.
bool chol(Derived &U) const
Cholesky M=UT * U decomposition for symmetric matrix (upper-half of the matrix is actually ignored...
int rank(Scalar threshold=0) const
Finds the rank of the matrix via LU decomposition.
bool eig_symmetric(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Read: eig()
This base provides a set of functions for maths stuff.
Derived inverse() const
Returns the inverse of a general matrix using LU.
Scalar minimumDiagonal() const
Returns the minimum value in the diagonal.
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
Scalar det() const
Determinant of matrix.
Scalar maximumDiagonal() const
Returns the maximum value in the diagonal.
void matProductOf_AB(const Derived &A, const Derived &B)
this = A*B, with A & B of the same type of this.
Derived inverse_LLt() const
Returns the inverse of a symmetric matrix using LLt.
void removeColumns(const std::vector< std::size_t > &idxsToRemove)
Removes columns of the matrix.
void sortEigResults(const VEC1 &eVals, const MATRIX1 &eVecs, std::vector< Scalar > &sorted_eVals, MATRIX2 &sorted_eVecs)
void unsafeRemoveRows(const std::vector< std::size_t > &idxs)
Removes rows of the matrix.
Scalar trace() const
Returns the trace of the matrix (not necessarily square).
void removeRows(const std::vector< std::size_t > &idxsToRemove)
Removes rows of the matrix.