Eigen::SparseInverse< Scalar > Class Template Reference

calculate sparse subset of inverse of sparse matrix More...

#include <SparseInverse.h>

Public Types

typedef SparseMatrix< Scalar, ColMajorMatrixType
 
typedef SparseMatrix< Scalar, RowMajorRowMatrixType
 

Public Member Functions

 SparseInverse ()
 
 SparseInverse (const SparseLU< MatrixType > &slu)
 This Constructor is for if you already have a factored SparseLU and would like to use it to calculate a sparse inverse. More...
 
SparseInversecompute (const SparseMatrix< Scalar > &A)
 Calculate the sparse inverse from a given sparse input. More...
 
const MatrixTypeinverse () const
 return the already-calculated sparse inverse, or a 0x0 matrix if it could not be computed More...
 

Static Public Member Functions

static MatrixType computeInverse (const SparseLU< MatrixType > &slu)
 Internal function to calculate the sparse inverse in a functional way. More...
 
static MatrixType computeInverse (const RowMatrixType &Upper, const Matrix< Scalar, Dynamic, 1 > &inverseDiagonal, const MatrixType &Lower)
 Internal function to calculate the inverse from strictly upper, diagonal and strictly lower components. More...
 

Private Attributes

MatrixType _result
 

Detailed Description

template<typename Scalar>
class Eigen::SparseInverse< Scalar >

calculate sparse subset of inverse of sparse matrix

This class returns a sparse subset of the inverse of the input matrix. The nonzeros correspond to the nonzeros of the input, plus any additional elements required due to fill-in of the internal LU factorization. This is is minimized via a applying a fill-reducing permutation as part of the LU factorization.

If there are specific entries of the input matrix which you need inverse values for, which are zero for the input, you need to insert entries into the input sparse matrix for them to be calculated.

Due to the sensitive nature of matrix inversion, particularly on large matrices which are made possible via sparsity, high accuracy dot products based on Kahan summation are used to reduce numerical error. If you still encounter numerical errors you may with to equilibrate your matrix before calculating the inverse, as well as making sure it is actually full rank.

Member Typedef Documentation

◆ MatrixType

template<typename Scalar >
typedef SparseMatrix<Scalar, ColMajor> Eigen::SparseInverse< Scalar >::MatrixType

◆ RowMatrixType

template<typename Scalar >
typedef SparseMatrix<Scalar, RowMajor> Eigen::SparseInverse< Scalar >::RowMatrixType

Constructor & Destructor Documentation

◆ SparseInverse() [1/2]

template<typename Scalar >
Eigen::SparseInverse< Scalar >::SparseInverse ( )
inline
133 {}

◆ SparseInverse() [2/2]

template<typename Scalar >
Eigen::SparseInverse< Scalar >::SparseInverse ( const SparseLU< MatrixType > &  slu)
inline

This Constructor is for if you already have a factored SparseLU and would like to use it to calculate a sparse inverse.

Just call this constructor with your already factored SparseLU class and you can directly call the .inverse() method to get the result.

142 { _result = computeInverse(slu); }
static MatrixType computeInverse(const SparseLU< MatrixType > &slu)
Internal function to calculate the sparse inverse in a functional way.
Definition: SparseInverse.h:163
MatrixType _result
Definition: SparseInverse.h:228

References Eigen::SparseInverse< Scalar >::_result, and Eigen::SparseInverse< Scalar >::computeInverse().

Member Function Documentation

◆ compute()

template<typename Scalar >
SparseInverse& Eigen::SparseInverse< Scalar >::compute ( const SparseMatrix< Scalar > &  A)
inline

Calculate the sparse inverse from a given sparse input.

147  {
148  SparseLU<MatrixType> slu;
149  slu.compute(A);
150  _result = computeInverse(slu);
151  return *this;
152  }
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47

References Eigen::SparseInverse< Scalar >::_result, Eigen::SparseLU< MatrixType_, OrderingType_ >::compute(), and Eigen::SparseInverse< Scalar >::computeInverse().

Referenced by check_sparse_inverse().

◆ computeInverse() [1/2]

template<typename Scalar >
static MatrixType Eigen::SparseInverse< Scalar >::computeInverse ( const RowMatrixType Upper,
const Matrix< Scalar, Dynamic, 1 > &  inverseDiagonal,
const MatrixType Lower 
)
inlinestatic

Internal function to calculate the inverse from strictly upper, diagonal and strictly lower components.

186  {
187  // Calculate the 'minimal set', which is the nonzeros of (L+U).transpose()
188  // It could be zeroed, but we will overwrite all non-zeros anyways.
189  MatrixType colInv = Lower.transpose().template triangularView<UnitUpper>();
190  colInv += Upper.transpose();
191 
192  // We also need rowmajor representation in order to do efficient row-wise dot products
193  RowMatrixType rowInv = Upper.transpose().template triangularView<UnitLower>();
194  rowInv += Lower.transpose();
195 
196  // Use the Takahashi algorithm to build the supporting elements of the inverse
197  // upwards and to the left, from the bottom right element, 1 col/row at a time
198  for (Index recurseLevel = Upper.cols() - 1; recurseLevel >= 0; recurseLevel--) {
199  const auto& col = Lower.col(recurseLevel);
200  const auto& row = Upper.row(recurseLevel);
201 
202  // Calculate the inverse values for the nonzeros in this column
203  typename MatrixType::ReverseInnerIterator colIter(colInv, recurseLevel);
204  for (; recurseLevel < colIter.index(); --colIter) {
205  const Scalar element = -accurateDot(col, rowInv.row(colIter.index()));
206  colIter.valueRef() = element;
207  rowInv.coeffRef(colIter.index(), recurseLevel) = element;
208  }
209 
210  // Calculate the inverse values for the nonzeros in this row
211  typename RowMatrixType::ReverseInnerIterator rowIter(rowInv, recurseLevel);
212  for (; recurseLevel < rowIter.index(); --rowIter) {
213  const Scalar element = -accurateDot(row, colInv.col(rowIter.index()));
214  rowIter.valueRef() = element;
215  colInv.coeffRef(recurseLevel, rowIter.index()) = element;
216  }
217 
218  // And finally the diagonal, which corresponds to both row and col iterator now
219  const Scalar diag = inverseDiagonal(recurseLevel) - accurateDot(row, colInv.col(recurseLevel));
220  rowIter.valueRef() = diag;
221  colIter.valueRef() = diag;
222  }
223 
224  return colInv;
225  }
m col(1)
m row(1)
SCALAR Scalar
Definition: bench_gemm.cpp:45
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
SparseMatrix< Scalar, RowMajor > RowMatrixType
Definition: SparseInverse.h:131
Base::ReverseInnerIterator ReverseInnerIterator
Definition: SparseMatrix.h:139
@ Lower
Definition: Constants.h:211
@ Upper
Definition: Constants.h:213
const char const char const char * diag
Definition: level2_impl.h:86
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
Derived::Scalar accurateDot(const SparseMatrixBase< Derived > &A, const SparseMatrixBase< OtherDerived > &other)
computes an accurate dot product on two sparse vectors
Definition: SparseInverse.h:81

References Eigen::accurateDot(), Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), col(), diag, Eigen::Lower, row(), and Eigen::Upper.

◆ computeInverse() [2/2]

template<typename Scalar >
static MatrixType Eigen::SparseInverse< Scalar >::computeInverse ( const SparseLU< MatrixType > &  slu)
inlinestatic

Internal function to calculate the sparse inverse in a functional way.

Returns
A sparse inverse representation, or, if the decomposition didn't complete, a 0x0 matrix.
163  {
164  if (slu.info() != Success) {
165  return MatrixType(0, 0);
166  }
167 
168  // Extract from SparseLU and decompose into L, inverse D and U terms
169  Matrix<Scalar, Dynamic, 1> invD;
171  {
172  RowMatrixType DU = slu.matrixU().toSparse();
173  invD = DU.diagonal().cwiseInverse();
174  Upper = (invD.asDiagonal() * DU).template triangularView<StrictlyUpper>();
175  }
176  MatrixType Lower = slu.matrixL().toSparse().template triangularView<StrictlyLower>();
177 
178  // Compute the inverse and reapply the permutation matrix from the LU decomposition
179  return slu.colsPermutation().transpose() * computeInverse(Upper, invD, Lower) * slu.rowsPermutation();
180  }
SparseMatrix< Scalar, ColMajor > MatrixType
Definition: SparseInverse.h:130
const ConstDiagonalReturnType diagonal() const
Definition: SparseMatrix.h:757
@ Success
Definition: Constants.h:440

References Eigen::SparseLU< MatrixType_, OrderingType_ >::colsPermutation(), Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::diagonal(), Eigen::SparseLU< MatrixType_, OrderingType_ >::info(), Eigen::Lower, Eigen::SparseLU< MatrixType_, OrderingType_ >::matrixL(), Eigen::SparseLU< MatrixType_, OrderingType_ >::matrixU(), Eigen::SparseLU< MatrixType_, OrderingType_ >::rowsPermutation(), Eigen::Success, Eigen::PermutationBase< Derived >::transpose(), and Eigen::Upper.

Referenced by Eigen::SparseInverse< Scalar >::compute(), and Eigen::SparseInverse< Scalar >::SparseInverse().

◆ inverse()

template<typename Scalar >
const MatrixType& Eigen::SparseInverse< Scalar >::inverse ( ) const
inline

return the already-calculated sparse inverse, or a 0x0 matrix if it could not be computed

157 { return _result; }

References Eigen::SparseInverse< Scalar >::_result.

Referenced by check_sparse_inverse().

Member Data Documentation

◆ _result


The documentation for this class was generated from the following file: