matrix_utilities.h
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Christoph Rösmann
23  *********************************************************************/
24 
25 #ifndef SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_MATRIX_UTILITIES_H_
26 #define SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_MATRIX_UTILITIES_H_
27 
28 #include <Eigen/Cholesky>
29 #include <Eigen/Core>
30 
31 #include <type_traits>
32 
33 namespace corbo {
34 
42 template <typename Derived>
44 {
45  return matrix.rows() == matrix.cols();
46 }
47 
55 inline bool is_square(int numel)
56 {
57  double q = std::sqrt(numel);
58  if (q * q != numel) return false;
59  return true;
60 }
61 
70 template <typename DerivedA, typename DerivedB>
71 inline bool have_equal_size(const Eigen::MatrixBase<DerivedA>& matrix1, const Eigen::MatrixBase<DerivedB>& matrix2)
72 {
73  return matrix1.rows() == matrix2.rows() && matrix1.cols() == matrix2.cols();
74 }
75 
84 template <typename DerivedA, typename DerivedB, typename... Derived>
85 inline bool have_equal_size(const Eigen::MatrixBase<DerivedA>& matrix1, const Eigen::MatrixBase<DerivedB>& matrix2,
86  const Eigen::MatrixBase<Derived>&... matrices_other)
87 {
88  return have_equal_size(matrix1, matrix2) ? have_equal_size(matrix2, matrices_other...) : false;
89 }
90 
102 template <typename Derived>
104 {
105  if (!is_square(matrix)) return false;
106  Eigen::LLT<Eigen::MatrixXd> cholesky(matrix);
107  return cholesky.info() != Eigen::NumericalIssue;
108 }
109 
120 template <typename Derived>
122 {
123  if (!is_square(matrix))
124  {
125  return -1.0;
126  }
127  auto& eigenvalues = matrix.eigenvalues();
128  auto eig_min = eigenvalues.minCoeff();
129  auto eig_max = eigenvalues.maxCoeff();
130  // if (std::abs(eig_min) < 1e-15)
131  // return eig_max > 0 ? CORBO_INF_DBL : -CORBO_INF_DBL;
132 
133  return std::abs(eig_max / eig_min);
134 }
135 
143 template <typename Derived>
145 {
146  if (matrix.rows() == 0 || matrix.cols() == 0) return -1.0;
147 
148  const typename Eigen::JacobiSVD<typename Derived::PlainObject>::SingularValuesType& sing_vals = matrix.jacobiSvd().singularValues();
149  // Singular values are always sorted in decreasing order.
150  double sigma_max = sing_vals[0];
151  double sigma_min = sing_vals[sing_vals.size() - 1];
152  // if (sigma_min < 1e-15)
153  // return sigma_max > 0 ? CORBO_INF_DBL : -CORBO_INF_DBL;
154 
155  return sigma_max / sigma_min;
156 }
157 
163 template <typename Derived>
165 {
167  // TODO(roesmann): do we need FullU and FullV, or is Thin sufficient?
168 
170  SingularValuesType sing_inv = svd.singularValues();
171 
172  for (int i = 0; i < sing_inv.size(); ++i)
173  {
174  if (sing_inv[i] > tolerance)
175  sing_inv[i] = 1.0 / sing_inv[i];
176  else
177  sing_inv[i] = 0.0;
178  }
179  pinvmat.noalias() = svd.matrixV() * sing_inv.asDiagonal() * svd.matrixU().transpose();
180 }
181 
182 } // namespace corbo
183 
184 #endif // SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_MATRIX_UTILITIES_H_
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:102
bool have_equal_size(const Eigen::MatrixBase< DerivedA > &matrix1, const Eigen::MatrixBase< DerivedB > &matrix2)
Determine if two matrices exhibit equal sizes/dimensions.
double compute_condition_number(const Eigen::MatrixBase< Derived > &matrix)
Compute condition number of matrix using SVD.
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
void compute_pseudo_inverse(const Eigen::MatrixBase< Derived > &matrix, Eigen::MatrixBase< Derived > &pinvmat, double tolerance=1e-6)
Compute the pseudo inverse using SVD.
bool is_square(const Eigen::MatrixBase< Derived > &matrix)
Determine if a given matrix is square.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
bool is_positive_definite(const Eigen::MatrixBase< Derived > &matrix)
Determine if a given matrix is positive definiteThe current implementation performs Eigen&#39;s Cholesky ...
JacobiSVD< PlainObject > jacobiSvd(unsigned int computationOptions=0) const
Definition: JacobiSVD.h:797
double compute_condition_number_square_matrix(const Eigen::MatrixBase< Derived > &matrix)
Compute condition number of a square matrix using the EigenvaluesThis method computes the eigenvalues...
Standard Cholesky decomposition (LL^T) of a matrix and associated features.
Definition: LLT.h:56
EIGEN_DEVICE_FUNC const Scalar & q
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: LLT.h:186
Two-sided Jacobi SVD decomposition of a rectangular matrix.
const SingularValuesType & singularValues() const
Definition: SVDBase.h:111
NoAlias< Derived, Eigen::MatrixBase > noalias()
Definition: NoAlias.h:101
EigenvaluesReturnType eigenvalues() const
Computes the eigenvalues of a matrix.
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Mon Feb 28 2022 22:07:02