Eigen::SparseLU< MatrixType_, OrderingType_ > Class Template Reference

Sparse supernodal LU factorization for general matrices. More...

+ Inheritance diagram for Eigen::SparseLU< MatrixType_, OrderingType_ >:

Public Types

enum  {
  ColsAtCompileTime ,
  MaxColsAtCompileTime
}
 
typedef internal::SparseLUImpl< Scalar, StorageIndexBase
 
typedef Matrix< StorageIndex, Dynamic, 1 > IndexVector
 
typedef MatrixType_ MatrixType
 
typedef SparseMatrix< Scalar, ColMajor, StorageIndexNCMatrix
 
typedef OrderingType_ OrderingType
 
typedef PermutationMatrix< Dynamic, Dynamic, StorageIndexPermutationType
 
typedef MatrixType::RealScalar RealScalar
 
typedef MatrixType::Scalar Scalar
 
typedef Matrix< Scalar, Dynamic, 1 > ScalarVector
 
typedef internal::MappedSuperNodalMatrix< Scalar, StorageIndexSCMatrix
 
typedef MatrixType::StorageIndex StorageIndex
 

Public Member Functions

template<typename Rhs , typename Dest >
bool _solve_impl (const MatrixBase< Rhs > &B, MatrixBase< Dest > &X_base) const
 
Scalar absDeterminant ()
 
const SparseLUTransposeView< true, SparseLU< MatrixType_, OrderingType_ > > adjoint ()
 
void analyzePattern (const MatrixType &matrix)
 
Index cols () const
 
const PermutationTypecolsPermutation () const
 
void compute (const MatrixType &matrix)
 
Scalar determinant ()
 
void factorize (const MatrixType &matrix)
 
ComputationInfo info () const
 Reports whether previous computation was successful. More...
 
void isSymmetric (bool sym)
 
std::string lastErrorMessage () const
 
Scalar logAbsDeterminant () const
 
SparseLUMatrixLReturnType< SCMatrixmatrixL () const
 
SparseLUMatrixUReturnType< SCMatrix, Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > > matrixU () const
 
Index nnzL () const
 
Index nnzU () const
 
Index rows () const
 
const PermutationTyperowsPermutation () const
 
void setPivotThreshold (const RealScalar &thresh)
 
Scalar signDeterminant ()
 
void simplicialfactorize (const MatrixType &matrix)
 
template<typename Rhs >
const Solve< SparseLU, Rhs > solve (const MatrixBase< Rhs > &B) const
 
 SparseLU ()
 
 SparseLU (const MatrixType &matrix)
 
const SparseLUTransposeView< false, SparseLU< MatrixType_, OrderingType_ > > transpose ()
 
 ~SparseLU ()
 
- Public Member Functions inherited from Eigen::SparseSolverBase< SparseLU< MatrixType_, OrderingType_ > >
SparseLU< MatrixType_, OrderingType_ > & derived ()
 
const SparseLU< MatrixType_, OrderingType_ > & derived () const
 
const Solve< SparseLU< MatrixType_, OrderingType_ >, Rhs > solve (const MatrixBase< Rhs > &b) const
 
const Solve< SparseLU< MatrixType_, OrderingType_ >, Rhs > solve (const SparseMatrixBase< Rhs > &b) const
 
 SparseSolverBase ()
 
 SparseSolverBase (SparseSolverBase &&other)
 
 ~SparseSolverBase ()
 

Protected Types

typedef SparseSolverBase< SparseLU< MatrixType_, OrderingType_ > > APIBase
 

Protected Member Functions

void initperfvalues ()
 

Protected Attributes

bool m_analysisIsOk
 
Index m_detPermC
 
Index m_detPermR
 
RealScalar m_diagpivotthresh
 
IndexVector m_etree
 
bool m_factorizationIsOk
 
Base::GlobalLU_t m_glu
 
ComputationInfo m_info
 
std::string m_lastError
 
SCMatrix m_Lstore
 
NCMatrix m_mat
 
Index m_nnzL
 
Index m_nnzU
 
internal::perfvalues m_perfv
 
PermutationType m_perm_c
 
PermutationType m_perm_r
 
bool m_symmetricmode
 
Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > m_Ustore
 
- Protected Attributes inherited from Eigen::SparseSolverBase< SparseLU< MatrixType_, OrderingType_ > >
bool m_isInitialized
 

Private Member Functions

 SparseLU (const SparseLU &)
 

Detailed Description

template<typename MatrixType_, typename OrderingType_>
class Eigen::SparseLU< MatrixType_, OrderingType_ >

Sparse supernodal LU factorization for general matrices.

This class implements the supernodal LU factorization for general matrices. It uses the main techniques from the sequential SuperLU package (http://crd-legacy.lbl.gov/~xiaoye/SuperLU/). It handles transparently real and complex arithmetic with single and double precision, depending on the scalar type of your input matrix. The code has been optimized to provide BLAS-3 operations during supernode-panel updates. It benefits directly from the built-in high-performant Eigen BLAS routines. Moreover, when the size of a supernode is very small, the BLAS calls are avoided to enable a better optimization from the compiler. For best performance, you should compile it with NDEBUG flag to avoid the numerous bounds checking on vectors.

An important parameter of this class is the ordering method. It is used to reorder the columns (and eventually the rows) of the matrix to reduce the number of new elements that are created during numerical factorization. The cheapest method available is COLAMD. See the OrderingMethods module for the list of built-in and external ordering methods.

Simple example with key steps

VectorXd x(n), b(n);
SparseMatrix<double> A;
SparseLU<SparseMatrix<double>, COLAMDOrdering<int> > solver;
// fill A and b;
// Compute the ordering permutation vector from the structural pattern of A
solver.analyzePattern(A);
// Compute the numerical factorization
solver.factorize(A);
//Use the factors to solve the linear system
x = solver.solve(b);
Array< int, 3, 1 > b
BiCGSTAB< SparseMatrix< double > > solver
int n
MatrixXcf A
Matrix< double, Dynamic, 1 > VectorXd
DynamicĂ—1 vector of type double.
Definition: Matrix.h:502
Warning
The input matrix A should be in a compressed and column-major form. Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
Note
Unlike the initial SuperLU implementation, there is no step to equilibrate the matrix. For badly scaled matrices, this step can be useful to reduce the pivoting during factorization. If this is the case for your matrices, you can try the basic scaling method at "unsupported/Eigen/src/IterativeSolvers/Scaling.h"
Template Parameters
MatrixType_The type of the sparse matrix. It must be a column-major SparseMatrix<>
OrderingType_The ordering method to use, either AMD, COLAMD or METIS. Default is COLMAD

This class follows the sparse solver concept .

See also
Sparse solver concept
OrderingMethods module

Definition at line 134 of file SparseLU.h.

Member Typedef Documentation

◆ APIBase

template<typename MatrixType_ , typename OrderingType_ >
typedef SparseSolverBase<SparseLU<MatrixType_,OrderingType_> > Eigen::SparseLU< MatrixType_, OrderingType_ >::APIBase
protected

Definition at line 137 of file SparseLU.h.

◆ Base

template<typename MatrixType_ , typename OrderingType_ >
typedef internal::SparseLUImpl<Scalar, StorageIndex> Eigen::SparseLU< MatrixType_, OrderingType_ >::Base

Definition at line 152 of file SparseLU.h.

◆ IndexVector

template<typename MatrixType_ , typename OrderingType_ >
typedef Matrix<StorageIndex,Dynamic,1> Eigen::SparseLU< MatrixType_, OrderingType_ >::IndexVector

Definition at line 150 of file SparseLU.h.

◆ MatrixType

template<typename MatrixType_ , typename OrderingType_ >
typedef MatrixType_ Eigen::SparseLU< MatrixType_, OrderingType_ >::MatrixType

Definition at line 142 of file SparseLU.h.

◆ NCMatrix

template<typename MatrixType_ , typename OrderingType_ >
typedef SparseMatrix<Scalar,ColMajor,StorageIndex> Eigen::SparseLU< MatrixType_, OrderingType_ >::NCMatrix

Definition at line 147 of file SparseLU.h.

◆ OrderingType

template<typename MatrixType_ , typename OrderingType_ >
typedef OrderingType_ Eigen::SparseLU< MatrixType_, OrderingType_ >::OrderingType

Definition at line 143 of file SparseLU.h.

◆ PermutationType

template<typename MatrixType_ , typename OrderingType_ >
typedef PermutationMatrix<Dynamic, Dynamic, StorageIndex> Eigen::SparseLU< MatrixType_, OrderingType_ >::PermutationType

Definition at line 151 of file SparseLU.h.

◆ RealScalar

template<typename MatrixType_ , typename OrderingType_ >
typedef MatrixType::RealScalar Eigen::SparseLU< MatrixType_, OrderingType_ >::RealScalar

Definition at line 145 of file SparseLU.h.

◆ Scalar

template<typename MatrixType_ , typename OrderingType_ >
typedef MatrixType::Scalar Eigen::SparseLU< MatrixType_, OrderingType_ >::Scalar

Definition at line 144 of file SparseLU.h.

◆ ScalarVector

template<typename MatrixType_ , typename OrderingType_ >
typedef Matrix<Scalar,Dynamic,1> Eigen::SparseLU< MatrixType_, OrderingType_ >::ScalarVector

Definition at line 149 of file SparseLU.h.

◆ SCMatrix

template<typename MatrixType_ , typename OrderingType_ >
typedef internal::MappedSuperNodalMatrix<Scalar, StorageIndex> Eigen::SparseLU< MatrixType_, OrderingType_ >::SCMatrix

Definition at line 148 of file SparseLU.h.

◆ StorageIndex

template<typename MatrixType_ , typename OrderingType_ >
typedef MatrixType::StorageIndex Eigen::SparseLU< MatrixType_, OrderingType_ >::StorageIndex

Definition at line 146 of file SparseLU.h.

Member Enumeration Documentation

◆ anonymous enum

template<typename MatrixType_ , typename OrderingType_ >
anonymous enum
Enumerator
ColsAtCompileTime 
MaxColsAtCompileTime 

Definition at line 154 of file SparseLU.h.

154  {
155  ColsAtCompileTime = MatrixType::ColsAtCompileTime,
156  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
157  };
@ MaxColsAtCompileTime
Definition: SparseLU.h:156

Constructor & Destructor Documentation

◆ SparseLU() [1/3]

template<typename MatrixType_ , typename OrderingType_ >
Eigen::SparseLU< MatrixType_, OrderingType_ >::SparseLU ( )
inline

Definition at line 161 of file SparseLU.h.

161  :m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
162  {
163  initperfvalues();
164  }
std::string m_lastError
Definition: SparseLU.h:477
Index m_detPermR
Definition: SparseLU.h:493
void initperfvalues()
Definition: SparseLU.h:463
bool m_symmetricmode
Definition: SparseLU.h:488
RealScalar m_diagpivotthresh
Definition: SparseLU.h:491
Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > m_Ustore
Definition: SparseLU.h:480

◆ SparseLU() [2/3]

template<typename MatrixType_ , typename OrderingType_ >
Eigen::SparseLU< MatrixType_, OrderingType_ >::SparseLU ( const MatrixType matrix)
inlineexplicit

Definition at line 165 of file SparseLU.h.

166  : m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
167  {
168  initperfvalues();
169  compute(matrix);
170  }
void compute(const MatrixType &matrix)
Definition: SparseLU.h:185

◆ ~SparseLU()

template<typename MatrixType_ , typename OrderingType_ >
Eigen::SparseLU< MatrixType_, OrderingType_ >::~SparseLU ( )
inline

Definition at line 172 of file SparseLU.h.

173  {
174  // Free all explicit dynamic pointers
175  }

◆ SparseLU() [3/3]

template<typename MatrixType_ , typename OrderingType_ >
Eigen::SparseLU< MatrixType_, OrderingType_ >::SparseLU ( const SparseLU< MatrixType_, OrderingType_ > &  )
private

Member Function Documentation

◆ _solve_impl()

template<typename MatrixType_ , typename OrderingType_ >
template<typename Rhs , typename Dest >
bool Eigen::SparseLU< MatrixType_, OrderingType_ >::_solve_impl ( const MatrixBase< Rhs > &  B,
MatrixBase< Dest > &  X_base 
) const
inline

Definition at line 317 of file SparseLU.h.

318  {
319  Dest& X(X_base.derived());
320  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first");
321  EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0,
322  THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
323 
324  // Permute the right hand side to form X = Pr*B
325  // on return, X is overwritten by the computed solution
326  X.resize(B.rows(),B.cols());
327 
328  // this ugly const_cast_derived() helps to detect aliasing when applying the permutations
329  for(Index j = 0; j < B.cols(); ++j)
330  X.col(j) = rowsPermutation() * B.const_cast_derived().col(j);
331 
332  //Forward substitution with L
333  this->matrixL().solveInPlace(X);
334  this->matrixU().solveInPlace(X);
335 
336  // Permute back the solution
337  for (Index j = 0; j < B.cols(); ++j)
338  X.col(j) = colsPermutation().inverse() * X.col(j);
339 
340  return true;
341  }
MatrixXf B
#define eigen_assert(x)
Definition: Macros.h:902
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
InverseReturnType inverse() const
bool m_factorizationIsOk
Definition: SparseLU.h:475
SparseLUMatrixUReturnType< SCMatrix, Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > > matrixU() const
Definition: SparseLU.h:256
const PermutationType & rowsPermutation() const
Definition: SparseLU.h:265
SparseLUMatrixLReturnType< SCMatrix > matrixL() const
Definition: SparseLU.h:246
const PermutationType & colsPermutation() const
Definition: SparseLU.h:273
const unsigned int RowMajorBit
Definition: Constants.h:68
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
std::ptrdiff_t j

◆ absDeterminant()

template<typename MatrixType_ , typename OrderingType_ >
Scalar Eigen::SparseLU< MatrixType_, OrderingType_ >::absDeterminant ( )
inline
Returns
the absolute value of the determinant of the matrix of which *this is the QR decomposition.
Warning
a determinant can be very big or small, so for matrices of large enough dimension, there is a risk of overflow/underflow. One way to work around that is to use logAbsDeterminant() instead.
See also
logAbsDeterminant(), signDeterminant()

Definition at line 353 of file SparseLU.h.

354  {
355  using std::abs;
356  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
357  // Initialize with the determinant of the row matrix
358  Scalar det = Scalar(1.);
359  // Note that the diagonal blocks of U are stored in supernodes,
360  // which are available in the L part :)
361  for (Index j = 0; j < this->cols(); ++j)
362  {
363  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
364  {
365  if(it.index() == j)
366  {
367  det *= abs(it.value());
368  break;
369  }
370  }
371  }
372  return det;
373  }
const AbsReturnType abs() const
Index cols() const
Definition: SparseLU.h:233
MatrixType::Scalar Scalar
Definition: SparseLU.h:144
SCMatrix m_Lstore
Definition: SparseLU.h:479
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)

◆ adjoint()

template<typename MatrixType_ , typename OrderingType_ >
const SparseLUTransposeView<true, SparseLU<MatrixType_,OrderingType_> > Eigen::SparseLU< MatrixType_, OrderingType_ >::adjoint ( )
inline
Returns
an expression of the adjoint of the factored matrix

A typical usage is to solve for the adjoint problem A' x = b:

solver.compute(A);
x = solver.adjoint().solve(b);

For real scalar types, this function is equivalent to transpose().

See also
transpose(), solve()

Definition at line 224 of file SparseLU.h.

225  {
226  SparseLUTransposeView<true, SparseLU<MatrixType_,OrderingType_> > adjointView;
227  adjointView.setSparseLU(this);
228  adjointView.setIsInitialized(this->m_isInitialized);
229  return adjointView;
230  }

◆ analyzePattern()

template<typename MatrixType , typename OrderingType >
void Eigen::SparseLU< MatrixType, OrderingType >::analyzePattern ( const MatrixType mat)

Compute the column permutation to minimize the fill-in

  • Apply this permutation to the input matrix -
  • Compute the column elimination tree on the permuted matrix
  • Postorder the elimination tree and the column permutation

Definition at line 513 of file SparseLU.h.

514 {
515 
516  //TODO It is possible as in SuperLU to compute row and columns scaling vectors to equilibrate the matrix mat.
517 
518  // Firstly, copy the whole input matrix.
519  m_mat = mat;
520 
521  // Compute fill-in ordering
522  OrderingType ord;
523  ord(m_mat,m_perm_c);
524 
525  // Apply the permutation to the column of the input matrix
526  if (m_perm_c.size())
527  {
528  m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. FIXME : This vector is filled but not subsequently used.
529  // Then, permute only the column pointers
530  ei_declare_aligned_stack_constructed_variable(StorageIndex,outerIndexPtr,mat.cols()+1,mat.isCompressed()?const_cast<StorageIndex*>(mat.outerIndexPtr()):0);
531 
532  // If the input matrix 'mat' is uncompressed, then the outer-indices do not match the ones of m_mat, and a copy is thus needed.
533  if(!mat.isCompressed())
534  IndexVector::Map(outerIndexPtr, mat.cols()+1) = IndexVector::Map(m_mat.outerIndexPtr(),mat.cols()+1);
535 
536  // Apply the permutation and compute the nnz per column.
537  for (Index i = 0; i < mat.cols(); i++)
538  {
539  m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
540  m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
541  }
542  }
543 
544  // Compute the column elimination tree of the permuted matrix
545  IndexVector firstRowElt;
546  internal::coletree(m_mat, m_etree,firstRowElt);
547 
548  // In symmetric mode, do not do postorder here
549  if (!m_symmetricmode) {
550  IndexVector post, iwork;
551  // Post order etree
553 
554 
555  // Renumber etree in postorder
556  Index m = m_mat.cols();
557  iwork.resize(m+1);
558  for (Index i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i));
559  m_etree = iwork;
560 
561  // Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree
562  PermutationType post_perm(m);
563  for (Index i = 0; i < m; i++)
564  post_perm.indices()(i) = post(i);
565 
566  // Combine the two permutations : postorder the permutation for future use
567  if(m_perm_c.size()) {
568  m_perm_c = post_perm * m_perm_c;
569  }
570 
571  } // end postordering
572 
573  m_analysisIsOk = true;
574 }
Matrix3f m
#define ei_declare_aligned_stack_constructed_variable(TYPE, NAME, SIZE, BUFFER)
Definition: Memory.h:847
const IndicesType & indices() const
static ConstMapType Map(const Scalar *data)
Matrix< StorageIndex, Dynamic, 1 > IndexVector
Definition: SparseLU.h:150
PermutationType m_perm_c
Definition: SparseLU.h:481
NCMatrix m_mat
Definition: SparseLU.h:478
bool m_analysisIsOk
Definition: SparseLU.h:476
OrderingType_ OrderingType
Definition: SparseLU.h:143
PermutationMatrix< Dynamic, Dynamic, StorageIndex > PermutationType
Definition: SparseLU.h:151
IndexVector m_etree
Definition: SparseLU.h:483
MatrixType::StorageIndex StorageIndex
Definition: SparseLU.h:146
Index cols() const
Definition: SparseMatrix.h:167
const StorageIndex * innerNonZeroPtr() const
Definition: SparseMatrix.h:204
const StorageIndex * outerIndexPtr() const
Definition: SparseMatrix.h:195
int coletree(const MatrixType &mat, IndexVector &parent, IndexVector &firstRowElt, typename MatrixType::StorageIndex *perm=0)
void treePostorder(typename IndexVector::Scalar n, IndexVector &parent, IndexVector &post)
Post order a tree.

◆ cols()

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::cols ( void  ) const
inline

Definition at line 233 of file SparseLU.h.

233 { return m_mat.cols(); }

◆ colsPermutation()

template<typename MatrixType_ , typename OrderingType_ >
const PermutationType& Eigen::SparseLU< MatrixType_, OrderingType_ >::colsPermutation ( ) const
inline
Returns
a reference to the column matrix permutation \( P_c^T \) such that \(P_r A P_c^T = L U\)
See also
rowsPermutation()

Definition at line 273 of file SparseLU.h.

274  {
275  return m_perm_c;
276  }

◆ compute()

template<typename MatrixType_ , typename OrderingType_ >
void Eigen::SparseLU< MatrixType_, OrderingType_ >::compute ( const MatrixType matrix)
inline

Compute the symbolic and numeric factorization of the input sparse matrix. The input matrix should be in column-major storage.

Definition at line 185 of file SparseLU.h.

186  {
187  // Analyze
188  analyzePattern(matrix);
189  //Factorize
190  factorize(matrix);
191  }
void factorize(const MatrixType &matrix)
Definition: SparseLU.h:598
void analyzePattern(const MatrixType &matrix)
Definition: SparseLU.h:513

◆ determinant()

template<typename MatrixType_ , typename OrderingType_ >
Scalar Eigen::SparseLU< MatrixType_, OrderingType_ >::determinant ( )
inline
Returns
The determinant of the matrix.
See also
absDeterminant(), logAbsDeterminant()

Definition at line 437 of file SparseLU.h.

438  {
439  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
440  // Initialize with the determinant of the row matrix
441  Scalar det = Scalar(1.);
442  // Note that the diagonal blocks of U are stored in supernodes,
443  // which are available in the L part :)
444  for (Index j = 0; j < this->cols(); ++j)
445  {
446  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
447  {
448  if(it.index() == j)
449  {
450  det *= it.value();
451  break;
452  }
453  }
454  }
455  return (m_detPermR * m_detPermC) > 0 ? det : -det;
456  }
Index m_detPermC
Definition: SparseLU.h:493

◆ factorize()

template<typename MatrixType , typename OrderingType >
void Eigen::SparseLU< MatrixType, OrderingType >::factorize ( const MatrixType matrix)
  • Numerical factorization
  • Interleaved with the symbolic factorization On exit, info is

    = 0: successful factorization

0: if info = i, and i is

<= A->ncol: U(i,i) is exactly zero. The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations.

> A->ncol: number of bytes allocated when memory allocation failure occurred, plus A->ncol. If lwork = -1, it is the estimated amount of space needed, plus A->ncol.

Definition at line 598 of file SparseLU.h.

599 {
600  using internal::emptyIdxLU;
601  eigen_assert(m_analysisIsOk && "analyzePattern() should be called first");
602  eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices");
603 
604  m_isInitialized = true;
605 
606  // Apply the column permutation computed in analyzepattern()
607  // m_mat = matrix * m_perm_c.inverse();
608  m_mat = matrix;
609  if (m_perm_c.size())
610  {
611  m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers.
612  //Then, permute only the column pointers
613  const StorageIndex * outerIndexPtr;
614  if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
615  else
616  {
617  StorageIndex* outerIndexPtr_t = new StorageIndex[matrix.cols()+1];
618  for(Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
619  outerIndexPtr = outerIndexPtr_t;
620  }
621  for (Index i = 0; i < matrix.cols(); i++)
622  {
623  m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
624  m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
625  }
626  if(!matrix.isCompressed()) delete[] outerIndexPtr;
627  }
628  else
629  { //FIXME This should not be needed if the empty permutation is handled transparently
630  m_perm_c.resize(matrix.cols());
631  for(StorageIndex i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i;
632  }
633 
634  Index m = m_mat.rows();
635  Index n = m_mat.cols();
636  Index nnz = m_mat.nonZeros();
637  Index maxpanel = m_perfv.panel_size * m;
638  // Allocate working storage common to the factor routines
639  Index lwork = 0;
640  Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
641  if (info)
642  {
643  m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
644  m_factorizationIsOk = false;
645  return ;
646  }
647 
648  // Set up pointers for integer working arrays
649  IndexVector segrep(m); segrep.setZero();
650  IndexVector parent(m); parent.setZero();
651  IndexVector xplore(m); xplore.setZero();
652  IndexVector repfnz(maxpanel);
653  IndexVector panel_lsub(maxpanel);
654  IndexVector xprune(n); xprune.setZero();
655  IndexVector marker(m*internal::LUNoMarker); marker.setZero();
656 
657  repfnz.setConstant(-1);
658  panel_lsub.setConstant(-1);
659 
660  // Set up pointers for scalar working arrays
661  ScalarVector dense;
662  dense.setZero(maxpanel);
663  ScalarVector tempv;
664  tempv.setZero(internal::LUnumTempV(m, m_perfv.panel_size, m_perfv.maxsuper, /*m_perfv.rowblk*/m) );
665 
666  // Compute the inverse of perm_c
667  PermutationType iperm_c(m_perm_c.inverse());
668 
669  // Identify initial relaxed snodes
670  IndexVector relax_end(n);
671  if ( m_symmetricmode == true )
672  Base::heap_relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
673  else
674  Base::relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
675 
676 
677  m_perm_r.resize(m);
678  m_perm_r.indices().setConstant(-1);
679  marker.setConstant(-1);
680  m_detPermR = 1; // Record the determinant of the row permutation
681 
682  m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0);
683  m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) = Index(0);
684 
685  // Work on one 'panel' at a time. A panel is one of the following :
686  // (a) a relaxed supernode at the bottom of the etree, or
687  // (b) panel_size contiguous columns, <panel_size> defined by the user
688  Index jcol;
689  Index pivrow; // Pivotal row number in the original row matrix
690  Index nseg1; // Number of segments in U-column above panel row jcol
691  Index nseg; // Number of segments in each U-column
692  Index irep;
693  Index i, k, jj;
694  for (jcol = 0; jcol < n; )
695  {
696  // Adjust panel size so that a panel won't overlap with the next relaxed snode.
697  Index panel_size = m_perfv.panel_size; // upper bound on panel width
698  for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++)
699  {
700  if (relax_end(k) != emptyIdxLU)
701  {
702  panel_size = k - jcol;
703  break;
704  }
705  }
706  if (k == n)
707  panel_size = n - jcol;
708 
709  // Symbolic outer factorization on a panel of columns
710  Base::panel_dfs(m, panel_size, jcol, m_mat, m_perm_r.indices(), nseg1, dense, panel_lsub, segrep, repfnz, xprune, marker, parent, xplore, m_glu);
711 
712  // Numeric sup-panel updates in topological order
713  Base::panel_bmod(m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu);
714 
715  // Sparse LU within the panel, and below the panel diagonal
716  for ( jj = jcol; jj< jcol + panel_size; jj++)
717  {
718  k = (jj - jcol) * m; // Column index for w-wide arrays
719 
720  nseg = nseg1; // begin after all the panel segments
721  //Depth-first-search for the current column
722  VectorBlock<IndexVector> panel_lsubk(panel_lsub, k, m);
723  VectorBlock<IndexVector> repfnz_k(repfnz, k, m);
724  info = Base::column_dfs(m, jj, m_perm_r.indices(), m_perfv.maxsuper, nseg, panel_lsubk, segrep, repfnz_k, xprune, marker, parent, xplore, m_glu);
725  if ( info )
726  {
727  m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
729  m_factorizationIsOk = false;
730  return;
731  }
732  // Numeric updates to this column
733  VectorBlock<ScalarVector> dense_k(dense, k, m);
734  VectorBlock<IndexVector> segrep_k(segrep, nseg1, m-nseg1);
735  info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu);
736  if ( info )
737  {
738  m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
740  m_factorizationIsOk = false;
741  return;
742  }
743 
744  // Copy the U-segments to ucol(*)
745  info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu);
746  if ( info )
747  {
748  m_lastError = "UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
750  m_factorizationIsOk = false;
751  return;
752  }
753 
754  // Form the L-segment
755  info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu);
756  if ( info )
757  {
758  m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR";
759 #ifndef EIGEN_NO_IO
760  std::ostringstream returnInfo;
761  returnInfo << " ... ZERO COLUMN AT ";
762  returnInfo << info;
763  m_lastError += returnInfo.str();
764 #endif
766  m_factorizationIsOk = false;
767  return;
768  }
769 
770  // Update the determinant of the row permutation matrix
771  // FIXME: the following test is not correct, we should probably take iperm_c into account and pivrow is not directly the row pivot.
772  if (pivrow != jj) m_detPermR = -m_detPermR;
773 
774  // Prune columns (0:jj-1) using column jj
775  Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
776 
777  // Reset repfnz for this column
778  for (i = 0; i < nseg; i++)
779  {
780  irep = segrep(i);
781  repfnz_k(irep) = emptyIdxLU;
782  }
783  } // end SparseLU within the panel
784  jcol += panel_size; // Move to the next panel
785  } // end for -- end elimination
786 
789 
790  // Count the number of nonzeros in factors
791  Base::countnz(n, m_nnzL, m_nnzU, m_glu);
792  // Apply permutation to the L subscripts
793  Base::fixupL(n, m_perm_r.indices(), m_glu);
794 
795  // Create supernode matrix L
796  m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
797  // Create the column major upper sparse matrix U;
798  new (&m_Ustore) Map<SparseMatrix<Scalar, ColMajor, StorageIndex>> ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() );
799 
800  m_info = Success;
801  m_factorizationIsOk = true;
802 }
void resize(Index newSize)
Derived & setZero(Index size)
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: SparseLU.h:302
internal::perfvalues m_perfv
Definition: SparseLU.h:490
Matrix< Scalar, Dynamic, 1 > ScalarVector
Definition: SparseLU.h:149
PermutationType m_perm_r
Definition: SparseLU.h:482
Base::GlobalLU_t m_glu
Definition: SparseLU.h:485
ComputationInfo m_info
Definition: SparseLU.h:474
Index rows() const
Definition: SparseMatrix.h:165
@ NumericalIssue
Definition: Constants.h:448
@ Success
Definition: Constants.h:446
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:684
Index LUnumTempV(Index &m, Index &w, Index &t, Index &b)

◆ info()

template<typename MatrixType_ , typename OrderingType_ >
ComputationInfo Eigen::SparseLU< MatrixType_, OrderingType_ >::info ( ) const
inline

Reports whether previous computation was successful.

Returns
Success if computation was successful, NumericalIssue if the LU factorization reports a problem, zero diagonal for instance InvalidInput if the input matrix is invalid
See also
iparm()

Definition at line 302 of file SparseLU.h.

303  {
304  eigen_assert(m_isInitialized && "Decomposition is not initialized.");
305  return m_info;
306  }

◆ initperfvalues()

template<typename MatrixType_ , typename OrderingType_ >
void Eigen::SparseLU< MatrixType_, OrderingType_ >::initperfvalues ( )
inlineprotected

Definition at line 463 of file SparseLU.h.

464  {
465  m_perfv.panel_size = 16;
466  m_perfv.relax = 1;
467  m_perfv.maxsuper = 128;
468  m_perfv.rowblk = 16;
469  m_perfv.colblk = 8;
470  m_perfv.fillfactor = 20;
471  }

◆ isSymmetric()

template<typename MatrixType_ , typename OrderingType_ >
void Eigen::SparseLU< MatrixType_, OrderingType_ >::isSymmetric ( bool  sym)
inline

Indicate that the pattern of the input matrix is symmetric

Definition at line 235 of file SparseLU.h.

236  {
237  m_symmetricmode = sym;
238  }

◆ lastErrorMessage()

template<typename MatrixType_ , typename OrderingType_ >
std::string Eigen::SparseLU< MatrixType_, OrderingType_ >::lastErrorMessage ( ) const
inline
Returns
A string describing the type of error

Definition at line 311 of file SparseLU.h.

312  {
313  return m_lastError;
314  }

◆ logAbsDeterminant()

template<typename MatrixType_ , typename OrderingType_ >
Scalar Eigen::SparseLU< MatrixType_, OrderingType_ >::logAbsDeterminant ( ) const
inline
Returns
the natural log of the absolute value of the determinant of the matrix of which **this is the QR decomposition
Note
This method is useful to work around the risk of overflow/underflow that's inherent to the determinant computation.
See also
absDeterminant(), signDeterminant()

Definition at line 383 of file SparseLU.h.

384  {
385  using std::log;
386  using std::abs;
387 
388  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
389  Scalar det = Scalar(0.);
390  for (Index j = 0; j < this->cols(); ++j)
391  {
392  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
393  {
394  if(it.row() < j) continue;
395  if(it.row() == j)
396  {
397  det += log(abs(it.value()));
398  break;
399  }
400  }
401  }
402  return det;
403  }
const LogReturnType log() const
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)

◆ matrixL()

template<typename MatrixType_ , typename OrderingType_ >
SparseLUMatrixLReturnType<SCMatrix> Eigen::SparseLU< MatrixType_, OrderingType_ >::matrixL ( ) const
inline
Returns
an expression of the matrix L, internally stored as supernodes The only operation available with this expression is the triangular solve
y = b; matrixL().solveInPlace(y);
const Scalar & y

Definition at line 246 of file SparseLU.h.

247  {
248  return SparseLUMatrixLReturnType<SCMatrix>(m_Lstore);
249  }

◆ matrixU()

template<typename MatrixType_ , typename OrderingType_ >
SparseLUMatrixUReturnType<SCMatrix,Map<SparseMatrix<Scalar,ColMajor,StorageIndex> > > Eigen::SparseLU< MatrixType_, OrderingType_ >::matrixU ( ) const
inline
Returns
an expression of the matrix U, The only operation available with this expression is the triangular solve
y = b; matrixU().solveInPlace(y);

Definition at line 256 of file SparseLU.h.

257  {
258  return SparseLUMatrixUReturnType<SCMatrix, Map<SparseMatrix<Scalar,ColMajor,StorageIndex> > >(m_Lstore, m_Ustore);
259  }

◆ nnzL()

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::nnzL ( ) const
inline

Definition at line 458 of file SparseLU.h.

458 { return m_nnzL; }

◆ nnzU()

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::nnzU ( ) const
inline

Definition at line 459 of file SparseLU.h.

459 { return m_nnzU; }

◆ rows()

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::rows ( void  ) const
inline

Definition at line 232 of file SparseLU.h.

232 { return m_mat.rows(); }

◆ rowsPermutation()

template<typename MatrixType_ , typename OrderingType_ >
const PermutationType& Eigen::SparseLU< MatrixType_, OrderingType_ >::rowsPermutation ( ) const
inline
Returns
a reference to the row matrix permutation \( P_r \) such that \(P_r A P_c^T = L U\)
See also
colsPermutation()

Definition at line 265 of file SparseLU.h.

266  {
267  return m_perm_r;
268  }

◆ setPivotThreshold()

template<typename MatrixType_ , typename OrderingType_ >
void Eigen::SparseLU< MatrixType_, OrderingType_ >::setPivotThreshold ( const RealScalar thresh)
inline

Set the threshold used for a diagonal entry to be an acceptable pivot.

Definition at line 278 of file SparseLU.h.

279  {
280  m_diagpivotthresh = thresh;
281  }

◆ signDeterminant()

template<typename MatrixType_ , typename OrderingType_ >
Scalar Eigen::SparseLU< MatrixType_, OrderingType_ >::signDeterminant ( )
inline
Returns
A number representing the sign of the determinant
See also
absDeterminant(), logAbsDeterminant()

Definition at line 409 of file SparseLU.h.

410  {
411  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
412  // Initialize with the determinant of the row matrix
413  Index det = 1;
414  // Note that the diagonal blocks of U are stored in supernodes,
415  // which are available in the L part :)
416  for (Index j = 0; j < this->cols(); ++j)
417  {
418  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
419  {
420  if(it.index() == j)
421  {
422  if(it.value()<0)
423  det = -det;
424  else if(it.value()==0)
425  return 0;
426  break;
427  }
428  }
429  }
430  return det * m_detPermR * m_detPermC;
431  }

◆ simplicialfactorize()

template<typename MatrixType_ , typename OrderingType_ >
void Eigen::SparseLU< MatrixType_, OrderingType_ >::simplicialfactorize ( const MatrixType matrix)

◆ solve()

template<typename MatrixType_ , typename OrderingType_ >
template<typename Rhs >
const Solve<SparseLU, Rhs> Eigen::SparseLU< MatrixType_, OrderingType_ >::solve ( const MatrixBase< Rhs > &  B) const
inline
Returns
the solution X of \( A X = B \) using the current decomposition of A.
Warning
the destination matrix X in X = this->solve(B) must be colmun-major.
See also
compute()

◆ transpose()

template<typename MatrixType_ , typename OrderingType_ >
const SparseLUTransposeView<false,SparseLU<MatrixType_,OrderingType_> > Eigen::SparseLU< MatrixType_, OrderingType_ >::transpose ( )
inline
Returns
an expression of the transposed of the factored matrix.

A typical usage is to solve for the transposed problem A^T x = b:

solver.compute(A);
x = solver.transpose().solve(b);
See also
adjoint(), solve()

Definition at line 203 of file SparseLU.h.

204  {
205  SparseLUTransposeView<false, SparseLU<MatrixType_,OrderingType_> > transposeView;
206  transposeView.setSparseLU(this);
207  transposeView.setIsInitialized(this->m_isInitialized);
208  return transposeView;
209  }

Member Data Documentation

◆ m_analysisIsOk

template<typename MatrixType_ , typename OrderingType_ >
bool Eigen::SparseLU< MatrixType_, OrderingType_ >::m_analysisIsOk
protected

Definition at line 476 of file SparseLU.h.

◆ m_detPermC

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::m_detPermC
protected

Definition at line 493 of file SparseLU.h.

◆ m_detPermR

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::m_detPermR
protected

Definition at line 493 of file SparseLU.h.

◆ m_diagpivotthresh

template<typename MatrixType_ , typename OrderingType_ >
RealScalar Eigen::SparseLU< MatrixType_, OrderingType_ >::m_diagpivotthresh
protected

Definition at line 491 of file SparseLU.h.

◆ m_etree

template<typename MatrixType_ , typename OrderingType_ >
IndexVector Eigen::SparseLU< MatrixType_, OrderingType_ >::m_etree
protected

Definition at line 483 of file SparseLU.h.

◆ m_factorizationIsOk

template<typename MatrixType_ , typename OrderingType_ >
bool Eigen::SparseLU< MatrixType_, OrderingType_ >::m_factorizationIsOk
protected

Definition at line 475 of file SparseLU.h.

◆ m_glu

template<typename MatrixType_ , typename OrderingType_ >
Base::GlobalLU_t Eigen::SparseLU< MatrixType_, OrderingType_ >::m_glu
protected

Definition at line 485 of file SparseLU.h.

◆ m_info

template<typename MatrixType_ , typename OrderingType_ >
ComputationInfo Eigen::SparseLU< MatrixType_, OrderingType_ >::m_info
mutableprotected

Definition at line 474 of file SparseLU.h.

◆ m_lastError

template<typename MatrixType_ , typename OrderingType_ >
std::string Eigen::SparseLU< MatrixType_, OrderingType_ >::m_lastError
protected

Definition at line 477 of file SparseLU.h.

◆ m_Lstore

template<typename MatrixType_ , typename OrderingType_ >
SCMatrix Eigen::SparseLU< MatrixType_, OrderingType_ >::m_Lstore
protected

Definition at line 479 of file SparseLU.h.

◆ m_mat

template<typename MatrixType_ , typename OrderingType_ >
NCMatrix Eigen::SparseLU< MatrixType_, OrderingType_ >::m_mat
protected

Definition at line 478 of file SparseLU.h.

◆ m_nnzL

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::m_nnzL
protected

Definition at line 492 of file SparseLU.h.

◆ m_nnzU

template<typename MatrixType_ , typename OrderingType_ >
Index Eigen::SparseLU< MatrixType_, OrderingType_ >::m_nnzU
protected

Definition at line 492 of file SparseLU.h.

◆ m_perfv

template<typename MatrixType_ , typename OrderingType_ >
internal::perfvalues Eigen::SparseLU< MatrixType_, OrderingType_ >::m_perfv
protected

Definition at line 490 of file SparseLU.h.

◆ m_perm_c

template<typename MatrixType_ , typename OrderingType_ >
PermutationType Eigen::SparseLU< MatrixType_, OrderingType_ >::m_perm_c
protected

Definition at line 481 of file SparseLU.h.

◆ m_perm_r

template<typename MatrixType_ , typename OrderingType_ >
PermutationType Eigen::SparseLU< MatrixType_, OrderingType_ >::m_perm_r
protected

Definition at line 482 of file SparseLU.h.

◆ m_symmetricmode

template<typename MatrixType_ , typename OrderingType_ >
bool Eigen::SparseLU< MatrixType_, OrderingType_ >::m_symmetricmode
protected

Definition at line 488 of file SparseLU.h.

◆ m_Ustore

template<typename MatrixType_ , typename OrderingType_ >
Map<SparseMatrix<Scalar,ColMajor,StorageIndex> > Eigen::SparseLU< MatrixType_, OrderingType_ >::m_Ustore
protected

Definition at line 480 of file SparseLU.h.


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