Shapeworks Studio  2.1
Shape analysis software suite
List of all members | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes
Eigen::SparseLU< _MatrixType, _OrderingType > Class Template Reference

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

#include <SparseLU.h>

+ Inheritance diagram for Eigen::SparseLU< _MatrixType, _OrderingType >:
+ Collaboration diagram for Eigen::SparseLU< _MatrixType, _OrderingType >:

Public Types

typedef _MatrixType MatrixType
 
typedef _OrderingType OrderingType
 
typedef MatrixType::Scalar Scalar
 
typedef MatrixType::RealScalar RealScalar
 
typedef MatrixType::Index Index
 
typedef SparseMatrix< Scalar, ColMajor, Index > NCMatrix
 
typedef internal::MappedSuperNodalMatrix< Scalar, Index > SCMatrix
 
typedef Matrix< Scalar, Dynamic, 1 > ScalarVector
 
typedef Matrix< Index, Dynamic, 1 > IndexVector
 
typedef PermutationMatrix< Dynamic, Dynamic, Index > PermutationType
 
typedef internal::SparseLUImpl< Scalar, Index > Base
 
- Public Types inherited from Eigen::internal::SparseLUImpl< _MatrixType::Scalar, _MatrixType::Index >
typedef Matrix< _MatrixType::Scalar, Dynamic, 1 > ScalarVector
 
typedef Matrix< _MatrixType::Index, Dynamic, 1 > IndexVector
 
typedef ScalarVector::RealScalar RealScalar
 
typedef Ref< Matrix< _MatrixType::Scalar, Dynamic, 1 > > BlockScalarVector
 
typedef Ref< Matrix< _MatrixType::Index, Dynamic, 1 > > BlockIndexVector
 
typedef LU_GlobalLU_t< IndexVector, ScalarVectorGlobalLU_t
 
typedef SparseMatrix< _MatrixType::Scalar, ColMajor, _MatrixType::Index > MatrixType
 

Public Member Functions

 SparseLU (const MatrixType &matrix)
 
void analyzePattern (const MatrixType &matrix)
 
void factorize (const MatrixType &matrix)
 
void simplicialfactorize (const MatrixType &matrix)
 
void compute (const MatrixType &matrix)
 
Index rows () const
 
Index cols () const
 
void isSymmetric (bool sym)
 
SparseLUMatrixLReturnType< SCMatrixmatrixL () const
 
SparseLUMatrixUReturnType< SCMatrix, MappedSparseMatrix< Scalar, ColMajor, Index > > matrixU () const
 
const PermutationTyperowsPermutation () const
 
const PermutationTypecolsPermutation () const
 
void setPivotThreshold (const RealScalar &thresh)
 
template<typename Rhs >
const internal::solve_retval< SparseLU, Rhs > solve (const MatrixBase< Rhs > &B) const
 
template<typename Rhs >
const internal::sparse_solve_retval< SparseLU, Rhs > solve (const SparseMatrixBase< Rhs > &B) const
 
ComputationInfo info () const
 Reports whether previous computation was successful. More...
 
std::string lastErrorMessage () const
 
template<typename Rhs , typename Dest >
bool _solve (const MatrixBase< Rhs > &B, MatrixBase< Dest > &_X) const
 
Scalar absDeterminant ()
 
Scalar logAbsDeterminant () const
 
Scalar signDeterminant ()
 

Protected Member Functions

void initperfvalues ()
 
- Protected Member Functions inherited from Eigen::internal::SparseLUImpl< _MatrixType::Scalar, _MatrixType::Index >
_MatrixType::Index expand (VectorType &vec, _MatrixType::Index &length, _MatrixType::Index nbElts, _MatrixType::Index keep_prev, _MatrixType::Index &num_expansions)
 
_MatrixType::Index memInit (_MatrixType::Index m, _MatrixType::Index n, _MatrixType::Index annz, _MatrixType::Index lwork, _MatrixType::Index fillratio, _MatrixType::Index panel_size, GlobalLU_t &glu)
 Allocate various working space for the numerical factorization phase. More...
 
_MatrixType::Index memXpand (VectorType &vec, _MatrixType::Index &maxlen, _MatrixType::Index nbElts, MemType memtype, _MatrixType::Index &num_expansions)
 Expand the existing storage. More...
 
void heap_relax_snode (const _MatrixType::Index n, IndexVector &et, const _MatrixType::Index relax_columns, IndexVector &descendants, IndexVector &relax_end)
 Identify the initial relaxed supernodes. More...
 
void relax_snode (const _MatrixType::Index n, IndexVector &et, const _MatrixType::Index relax_columns, IndexVector &descendants, IndexVector &relax_end)
 Identify the initial relaxed supernodes. More...
 
_MatrixType::Index snode_dfs (const _MatrixType::Index jcol, const _MatrixType::Index kcol, const MatrixType &mat, IndexVector &xprune, IndexVector &marker, GlobalLU_t &glu)
 
_MatrixType::Index snode_bmod (const _MatrixType::Index jcol, const _MatrixType::Index fsupc, ScalarVector &dense, GlobalLU_t &glu)
 
_MatrixType::Index pivotL (const _MatrixType::Index jcol, const RealScalar &diagpivotthresh, IndexVector &perm_r, IndexVector &iperm_c, _MatrixType::Index &pivrow, GlobalLU_t &glu)
 Performs the numerical pivotin on the current column of L, and the CDIV operation. More...
 
void dfs_kernel (const _MatrixType::Index jj, IndexVector &perm_r, _MatrixType::Index &nseg, IndexVector &panel_lsub, IndexVector &segrep, Ref< IndexVector > repfnz_col, IndexVector &xprune, Ref< IndexVector > marker, IndexVector &parent, IndexVector &xplore, GlobalLU_t &glu, _MatrixType::Index &nextl_col, _MatrixType::Index krow, Traits &traits)
 
void panel_dfs (const _MatrixType::Index m, const _MatrixType::Index w, const _MatrixType::Index jcol, MatrixType &A, IndexVector &perm_r, _MatrixType::Index &nseg, ScalarVector &dense, IndexVector &panel_lsub, IndexVector &segrep, IndexVector &repfnz, IndexVector &xprune, IndexVector &marker, IndexVector &parent, IndexVector &xplore, GlobalLU_t &glu)
 Performs a symbolic factorization on a panel of columns [jcol, jcol+w) More...
 
void panel_bmod (const _MatrixType::Index m, const _MatrixType::Index w, const _MatrixType::Index jcol, const _MatrixType::Index nseg, ScalarVector &dense, ScalarVector &tempv, IndexVector &segrep, IndexVector &repfnz, GlobalLU_t &glu)
 Performs numeric block updates (sup-panel) in topological order. More...
 
_MatrixType::Index column_dfs (const _MatrixType::Index m, const _MatrixType::Index jcol, IndexVector &perm_r, _MatrixType::Index maxsuper, _MatrixType::Index &nseg, BlockIndexVector lsub_col, IndexVector &segrep, BlockIndexVector repfnz, IndexVector &xprune, IndexVector &marker, IndexVector &parent, IndexVector &xplore, GlobalLU_t &glu)
 Performs a symbolic factorization on column jcol and decide the supernode boundary. More...
 
_MatrixType::Index column_bmod (const _MatrixType::Index jcol, const _MatrixType::Index nseg, BlockScalarVector dense, ScalarVector &tempv, BlockIndexVector segrep, BlockIndexVector repfnz, _MatrixType::Index fpanelc, GlobalLU_t &glu)
 Performs numeric block updates (sup-col) in topological order. More...
 
_MatrixType::Index copy_to_ucol (const _MatrixType::Index jcol, const _MatrixType::Index nseg, IndexVector &segrep, BlockIndexVector repfnz, IndexVector &perm_r, BlockScalarVector dense, GlobalLU_t &glu)
 Performs numeric block updates (sup-col) in topological order. More...
 
void pruneL (const _MatrixType::Index jcol, const IndexVector &perm_r, const _MatrixType::Index pivrow, const _MatrixType::Index nseg, const IndexVector &segrep, BlockIndexVector repfnz, IndexVector &xprune, GlobalLU_t &glu)
 Prunes the L-structure. More...
 
void countnz (const _MatrixType::Index n, _MatrixType::Index &nnzL, _MatrixType::Index &nnzU, GlobalLU_t &glu)
 Count Nonzero elements in the factors.
 
void fixupL (const _MatrixType::Index n, const IndexVector &perm_r, GlobalLU_t &glu)
 Fix up the data storage lsub for L-subscripts. More...
 

Protected Attributes

ComputationInfo m_info
 
bool m_isInitialized
 
bool m_factorizationIsOk
 
bool m_analysisIsOk
 
std::string m_lastError
 
NCMatrix m_mat
 
SCMatrix m_Lstore
 
MappedSparseMatrix< Scalar, ColMajor, Index > m_Ustore
 
PermutationType m_perm_c
 
PermutationType m_perm_r
 
IndexVector m_etree
 
Base::GlobalLU_t m_glu
 
bool m_symmetricmode
 
internal::perfvalues< Index > m_perfv
 
RealScalar m_diagpivotthresh
 
Index m_nnzL
 
Index m_nnzU
 
Index m_detPermR
 

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 arithmetics 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, ColMajor> A;
SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<Index> > 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);
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
_MatrixTypeThe type of the sparse matrix. It must be a column-major SparseMatrix<>
_OrderingTypeThe ordering method to use, either AMD, COLAMD or METIS. Default is COLMAD
See also
TutorialSparseDirectSolvers
OrderingMethods_Module

Definition at line 17 of file SparseLU.h.

Member Function Documentation

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 256 of file SparseLU.h.

257  {
258  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
259  // Initialize with the determinant of the row matrix
260  Scalar det = Scalar(1.);
261  //Note that the diagonal blocks of U are stored in supernodes,
262  // which are available in the L part :)
263  for (Index j = 0; j < this->cols(); ++j)
264  {
265  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
266  {
267  if(it.row() < j) continue;
268  if(it.row() == j)
269  {
270  det *= (std::abs)(it.value());
271  break;
272  }
273  }
274  }
275  return det;
276  }
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 369 of file SparseLU.h.

370 {
371 
372  //TODO It is possible as in SuperLU to compute row and columns scaling vectors to equilibrate the matrix mat.
373 
374  OrderingType ord;
375  ord(mat,m_perm_c);
376 
377  // Apply the permutation to the column of the input matrix
378  //First copy the whole input matrix.
379  m_mat = mat;
380  if (m_perm_c.size()) {
381  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.
382  //Then, permute only the column pointers
383  const Index * outerIndexPtr;
384  if (mat.isCompressed()) outerIndexPtr = mat.outerIndexPtr();
385  else
386  {
387  Index *outerIndexPtr_t = new Index[mat.cols()+1];
388  for(Index i = 0; i <= mat.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
389  outerIndexPtr = outerIndexPtr_t;
390  }
391  for (Index i = 0; i < mat.cols(); i++)
392  {
393  m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
394  m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
395  }
396  if(!mat.isCompressed()) delete[] outerIndexPtr;
397  }
398  // Compute the column elimination tree of the permuted matrix
399  IndexVector firstRowElt;
400  internal::coletree(m_mat, m_etree,firstRowElt);
401 
402  // In symmetric mode, do not do postorder here
403  if (!m_symmetricmode) {
404  IndexVector post, iwork;
405  // Post order etree
406  internal::treePostorder(m_mat.cols(), m_etree, post);
407 
408 
409  // Renumber etree in postorder
410  Index m = m_mat.cols();
411  iwork.resize(m+1);
412  for (Index i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i));
413  m_etree = iwork;
414 
415  // Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree
416  PermutationType post_perm(m);
417  for (Index i = 0; i < m; i++)
418  post_perm.indices()(i) = post(i);
419 
420  // Combine the two permutations : postorder the permutation for future use
421  if(m_perm_c.size()) {
422  m_perm_c = post_perm * m_perm_c;
423  }
424 
425  } // end postordering
426 
427  m_analysisIsOk = true;
428 }
Index cols() const
Definition: SparseMatrix.h:121
const Index * innerNonZeroPtr() const
Definition: SparseMatrix.h:158
const IndicesType & indices() const
void treePostorder(Index n, IndexVector &parent, IndexVector &post)
Post order a tree.
const Index * outerIndexPtr() const
Definition: SparseMatrix.h:149
int coletree(const MatrixType &mat, IndexVector &parent, IndexVector &firstRowElt, typename MatrixType::Index *perm=0)
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 161 of file SparseLU.h.

162  {
163  return m_perm_c;
164  }
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 112 of file SparseLU.h.

113  {
114  // Analyze
116  //Factorize
117  factorize(matrix);
118  }
Definition: math3d.h:219
void analyzePattern(const MatrixType &matrix)
Definition: SparseLU.h:369
void factorize(const MatrixType &matrix)
Definition: SparseLU.h:452
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 452 of file SparseLU.h.

453 {
454  using internal::emptyIdxLU;
455  eigen_assert(m_analysisIsOk && "analyzePattern() should be called first");
456  eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices");
457 
458  typedef typename IndexVector::Scalar Index;
459 
460 
461  // Apply the column permutation computed in analyzepattern()
462  // m_mat = matrix * m_perm_c.inverse();
463  m_mat = matrix;
464  if (m_perm_c.size())
465  {
466  m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers.
467  //Then, permute only the column pointers
468  const Index * outerIndexPtr;
469  if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
470  else
471  {
472  Index* outerIndexPtr_t = new Index[matrix.cols()+1];
473  for(Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
474  outerIndexPtr = outerIndexPtr_t;
475  }
476  for (Index i = 0; i < matrix.cols(); i++)
477  {
478  m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
479  m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
480  }
481  if(!matrix.isCompressed()) delete[] outerIndexPtr;
482  }
483  else
484  { //FIXME This should not be needed if the empty permutation is handled transparently
485  m_perm_c.resize(matrix.cols());
486  for(Index i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i;
487  }
488 
489  Index m = m_mat.rows();
490  Index n = m_mat.cols();
491  Index nnz = m_mat.nonZeros();
492  Index maxpanel = m_perfv.panel_size * m;
493  // Allocate working storage common to the factor routines
494  Index lwork = 0;
495  Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
496  if (info)
497  {
498  m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
499  m_factorizationIsOk = false;
500  return ;
501  }
502 
503  // Set up pointers for integer working arrays
504  IndexVector segrep(m); segrep.setZero();
505  IndexVector parent(m); parent.setZero();
506  IndexVector xplore(m); xplore.setZero();
507  IndexVector repfnz(maxpanel);
508  IndexVector panel_lsub(maxpanel);
509  IndexVector xprune(n); xprune.setZero();
510  IndexVector marker(m*internal::LUNoMarker); marker.setZero();
511 
512  repfnz.setConstant(-1);
513  panel_lsub.setConstant(-1);
514 
515  // Set up pointers for scalar working arrays
516  ScalarVector dense;
517  dense.setZero(maxpanel);
518  ScalarVector tempv;
519  tempv.setZero(internal::LUnumTempV(m, m_perfv.panel_size, m_perfv.maxsuper, /*m_perfv.rowblk*/m) );
520 
521  // Compute the inverse of perm_c
522  PermutationType iperm_c(m_perm_c.inverse());
523 
524  // Identify initial relaxed snodes
525  IndexVector relax_end(n);
526  if ( m_symmetricmode == true )
527  Base::heap_relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
528  else
529  Base::relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
530 
531 
532  m_perm_r.resize(m);
533  m_perm_r.indices().setConstant(-1);
534  marker.setConstant(-1);
535  m_detPermR = 1; // Record the determinant of the row permutation
536 
537  m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0);
538  m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) = Index(0);
539 
540  // Work on one 'panel' at a time. A panel is one of the following :
541  // (a) a relaxed supernode at the bottom of the etree, or
542  // (b) panel_size contiguous columns, <panel_size> defined by the user
543  Index jcol;
544  IndexVector panel_histo(n);
545  Index pivrow; // Pivotal row number in the original row matrix
546  Index nseg1; // Number of segments in U-column above panel row jcol
547  Index nseg; // Number of segments in each U-column
548  Index irep;
549  Index i, k, jj;
550  for (jcol = 0; jcol < n; )
551  {
552  // Adjust panel size so that a panel won't overlap with the next relaxed snode.
553  Index panel_size = m_perfv.panel_size; // upper bound on panel width
554  for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++)
555  {
556  if (relax_end(k) != emptyIdxLU)
557  {
558  panel_size = k - jcol;
559  break;
560  }
561  }
562  if (k == n)
563  panel_size = n - jcol;
564 
565  // Symbolic outer factorization on a panel of columns
566  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);
567 
568  // Numeric sup-panel updates in topological order
569  Base::panel_bmod(m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu);
570 
571  // Sparse LU within the panel, and below the panel diagonal
572  for ( jj = jcol; jj< jcol + panel_size; jj++)
573  {
574  k = (jj - jcol) * m; // Column index for w-wide arrays
575 
576  nseg = nseg1; // begin after all the panel segments
577  //Depth-first-search for the current column
578  VectorBlock<IndexVector> panel_lsubk(panel_lsub, k, m);
579  VectorBlock<IndexVector> repfnz_k(repfnz, k, m);
580  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);
581  if ( info )
582  {
583  m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
584  m_info = NumericalIssue;
585  m_factorizationIsOk = false;
586  return;
587  }
588  // Numeric updates to this column
589  VectorBlock<ScalarVector> dense_k(dense, k, m);
590  VectorBlock<IndexVector> segrep_k(segrep, nseg1, m-nseg1);
591  info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu);
592  if ( info )
593  {
594  m_lastError = "UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
595  m_info = NumericalIssue;
596  m_factorizationIsOk = false;
597  return;
598  }
599 
600  // Copy the U-segments to ucol(*)
601  info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu);
602  if ( info )
603  {
604  m_lastError = "UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
605  m_info = NumericalIssue;
606  m_factorizationIsOk = false;
607  return;
608  }
609 
610  // Form the L-segment
611  info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu);
612  if ( info )
613  {
614  m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR ... ZERO COLUMN AT ";
615  std::ostringstream returnInfo;
616  returnInfo << info;
617  m_lastError += returnInfo.str();
618  m_info = NumericalIssue;
619  m_factorizationIsOk = false;
620  return;
621  }
622 
623  // Update the determinant of the row permutation matrix
624  if (pivrow != jj) m_detPermR *= -1;
625 
626  // Prune columns (0:jj-1) using column jj
627  Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
628 
629  // Reset repfnz for this column
630  for (i = 0; i < nseg; i++)
631  {
632  irep = segrep(i);
633  repfnz_k(irep) = emptyIdxLU;
634  }
635  } // end SparseLU within the panel
636  jcol += panel_size; // Move to the next panel
637  } // end for -- end elimination
638 
639  // Count the number of nonzeros in factors
640  Base::countnz(n, m_nnzL, m_nnzU, m_glu);
641  // Apply permutation to the L subscripts
642  Base::fixupL(n, m_perm_r.indices(), m_glu);
643 
644  // Create supernode matrix L
645  m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
646  // Create the column major upper sparse matrix U;
647  new (&m_Ustore) MappedSparseMatrix<Scalar, ColMajor, Index> ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() );
648 
649  m_info = Success;
650  m_factorizationIsOk = true;
651 }
Index copy_to_ucol(const Index jcol, const Index nseg, IndexVector &segrep, BlockIndexVector repfnz, IndexVector &perm_r, BlockScalarVector dense, GlobalLU_t &glu)
Performs numeric block updates (sup-col) in topological order.
void pruneL(const Index jcol, const IndexVector &perm_r, const Index pivrow, const Index nseg, const IndexVector &segrep, BlockIndexVector repfnz, IndexVector &xprune, GlobalLU_t &glu)
Prunes the L-structure.
void setInfos(Index m, Index n, ScalarVector &nzval, IndexVector &nzval_colptr, IndexVector &rowind, IndexVector &rowind_colptr, IndexVector &col_to_sup, IndexVector &sup_to_col)
void relax_snode(const Index n, IndexVector &et, const Index relax_columns, IndexVector &descendants, IndexVector &relax_end)
Identify the initial relaxed supernodes.
Index cols() const
Definition: SparseMatrix.h:121
void fixupL(const Index n, const IndexVector &perm_r, GlobalLU_t &glu)
Fix up the data storage lsub for L-subscripts.
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: SparseLU.h:207
Definition: math3d.h:219
void resize(Index newSize)
Index pivotL(const Index jcol, const RealScalar &diagpivotthresh, IndexVector &perm_r, IndexVector &iperm_c, Index &pivrow, GlobalLU_t &glu)
Performs the numerical pivotin on the current column of L, and the CDIV operation.
Index rows() const
Definition: SparseMatrix.h:119
Index nonZeros() const
Definition: SparseMatrix.h:246
void countnz(const Index n, Index &nnzL, Index &nnzU, GlobalLU_t &glu)
Count Nonzero elements in the factors.
void heap_relax_snode(const Index n, IndexVector &et, const Index relax_columns, IndexVector &descendants, IndexVector &relax_end)
Identify the initial relaxed supernodes.
void panel_dfs(const Index m, const Index w, const Index jcol, MatrixType &A, IndexVector &perm_r, Index &nseg, ScalarVector &dense, IndexVector &panel_lsub, IndexVector &segrep, IndexVector &repfnz, IndexVector &xprune, IndexVector &marker, IndexVector &parent, IndexVector &xplore, GlobalLU_t &glu)
Performs a symbolic factorization on a panel of columns [jcol, jcol+w)
Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t &glu)
Allocate various working space for the numerical factorization phase.
Derived & setConstant(Index size, const Scalar &value)
EIGEN_STRONG_INLINE const Scalar * data() const
void panel_bmod(const Index m, const Index w, const Index jcol, const Index nseg, ScalarVector &dense, ScalarVector &tempv, IndexVector &segrep, IndexVector &repfnz, GlobalLU_t &glu)
Performs numeric block updates (sup-panel) in topological order.
const Index * innerNonZeroPtr() const
Definition: SparseMatrix.h:158
const IndicesType & indices() const
Transpose< PermutationBase > inverse() const
Derived & setZero(Index size)
Index column_dfs(const Index m, const Index jcol, IndexVector &perm_r, Index maxsuper, Index &nseg, BlockIndexVector lsub_col, IndexVector &segrep, BlockIndexVector repfnz, IndexVector &xprune, IndexVector &marker, IndexVector &parent, IndexVector &xplore, GlobalLU_t &glu)
Performs a symbolic factorization on column jcol and decide the supernode boundary.
const Index * outerIndexPtr() const
Definition: SparseMatrix.h:149
Index column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector &tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t &glu)
Performs numeric block updates (sup-col) in topological order.
template<typename _MatrixType , typename _OrderingType >
ComputationInfo Eigen::SparseLU< _MatrixType, _OrderingType >::info ( ) const
inline

Reports whether previous computation was successful.

Returns
Success if computation was succesful, 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 207 of file SparseLU.h.

208  {
209  eigen_assert(m_isInitialized && "Decomposition is not initialized.");
210  return m_info;
211  }
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 123 of file SparseLU.h.

124  {
125  m_symmetricmode = sym;
126  }
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 216 of file SparseLU.h.

217  {
218  return m_lastError;
219  }
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 286 of file SparseLU.h.

287  {
288  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
289  Scalar det = Scalar(0.);
290  for (Index j = 0; j < this->cols(); ++j)
291  {
292  for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
293  {
294  if(it.row() < j) continue;
295  if(it.row() == j)
296  {
297  det += (std::log)((std::abs)(it.value()));
298  break;
299  }
300  }
301  }
302  return det;
303  }
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);

Definition at line 134 of file SparseLU.h.

135  {
136  return SparseLUMatrixLReturnType<SCMatrix>(m_Lstore);
137  }
template<typename _MatrixType , typename _OrderingType >
SparseLUMatrixUReturnType<SCMatrix,MappedSparseMatrix<Scalar,ColMajor,Index> > 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 144 of file SparseLU.h.

145  {
146  return SparseLUMatrixUReturnType<SCMatrix, MappedSparseMatrix<Scalar,ColMajor,Index> >(m_Lstore, m_Ustore);
147  }
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 153 of file SparseLU.h.

154  {
155  return m_perm_r;
156  }
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 166 of file SparseLU.h.

167  {
168  m_diagpivotthresh = thresh;
169  }
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 309 of file SparseLU.h.

310  {
311  eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
312  return Scalar(m_detPermR);
313  }
template<typename _MatrixType , typename _OrderingType >
template<typename Rhs >
const internal::solve_retval<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()

Definition at line 178 of file SparseLU.h.

179  {
180  eigen_assert(m_factorizationIsOk && "SparseLU is not initialized.");
181  eigen_assert(rows()==B.rows()
182  && "SparseLU::solve(): invalid number of rows of the right hand side matrix B");
183  return internal::solve_retval<SparseLU, Rhs>(*this, B.derived());
184  }
template<typename _MatrixType , typename _OrderingType >
template<typename Rhs >
const internal::sparse_solve_retval<SparseLU, Rhs> Eigen::SparseLU< _MatrixType, _OrderingType >::solve ( const SparseMatrixBase< Rhs > &  B) const
inline
Returns
the solution X of $ A X = B $ using the current decomposition of A.
See also
compute()

Definition at line 191 of file SparseLU.h.

192  {
193  eigen_assert(m_factorizationIsOk && "SparseLU is not initialized.");
194  eigen_assert(rows()==B.rows()
195  && "SparseLU::solve(): invalid number of rows of the right hand side matrix B");
196  return internal::sparse_solve_retval<SparseLU, Rhs>(*this, B.derived());
197  }

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