12#ifndef EIGEN_SPARSE_LU_H
13#define EIGEN_SPARSE_LU_H
17template <
typename _MatrixType,
typename _OrderingType = COLAMDOrdering<
typename _MatrixType::StorageIndex> >
class SparseLU;
18template <
typename MappedSparseMatrixType>
struct SparseLUMatrixLReturnType;
19template <
typename MatrixLType,
typename MatrixUType>
struct SparseLUMatrixUReturnType;
21template <
bool Conjugate,
class SparseLUType>
26 using APIBase::m_isInitialized;
28 typedef typename SparseLUType::Scalar Scalar;
29 typedef typename SparseLUType::StorageIndex StorageIndex;
30 typedef typename SparseLUType::MatrixType MatrixType;
31 typedef typename SparseLUType::OrderingType OrderingType;
34 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
35 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
40 this->m_sparseLU = view.m_sparseLU;
41 this->m_isInitialized = view.m_isInitialized;
45 using APIBase::_solve_impl;
46 template<
typename Rhs,
typename Dest>
50 eigen_assert(m_sparseLU->info() ==
Success &&
"The matrix should be factorized first");
52 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
56 for(
Index j = 0; j < B.cols(); ++j){
57 X.col(j) = m_sparseLU->colsPermutation() * B.const_cast_derived().col(j);
66 for (
Index j = 0; j < B.cols(); ++j)
67 X.col(j) = m_sparseLU->rowsPermutation().
transpose() * X.col(j);
70 inline Index rows()
const {
return m_sparseLU->rows(); }
71 inline Index cols()
const {
return m_sparseLU->cols(); }
131template <
typename _MatrixType,
typename _OrderingType>
136 using APIBase::m_isInitialized;
138 using APIBase::_solve_impl;
140 typedef _MatrixType MatrixType;
142 typedef typename MatrixType::Scalar Scalar;
143 typedef typename MatrixType::RealScalar RealScalar;
144 typedef typename MatrixType::StorageIndex StorageIndex;
153 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
154 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
159 SparseLU():m_lastError(
""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(
false),m_diagpivotthresh(1.0),m_detPermR(1)
163 explicit SparseLU(
const MatrixType& matrix)
164 : m_lastError(
""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(
false),m_diagpivotthresh(1.0),m_detPermR(1)
176 void factorize (
const MatrixType& matrix);
177 void simplicialfactorize(
const MatrixType& matrix);
226 adjointView.setIsInitialized(this->m_isInitialized);
230 inline Index rows()
const {
return m_mat.
rows(); }
231 inline Index cols()
const {
return m_mat.
cols(); }
235 m_symmetricmode =
sym;
278 m_diagpivotthresh =
thresh;
281#ifdef EIGEN_PARSED_BY_DOXYGEN
288 template<
typename Rhs>
302 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
314 template<
typename Rhs,
typename Dest>
318 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first");
320 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
324 X.resize(B.rows(),B.cols());
327 for(
Index j = 0; j < B.cols(); ++j)
331 this->
matrixL().solveInPlace(X);
332 this->
matrixU().solveInPlace(X);
335 for (
Index j = 0; j < B.cols(); ++j)
354 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
356 Scalar
det = Scalar(1.);
359 for (
Index j = 0; j < this->cols(); ++j)
361 for (
typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
365 det *= abs(it.value());
386 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
387 Scalar
det = Scalar(0.);
388 for (
Index j = 0; j < this->cols(); ++j)
390 for (
typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
392 if(it.row() < j)
continue;
395 det += log(abs(it.value()));
409 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
414 for (
Index j = 0; j < this->cols(); ++j)
416 for (
typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
422 else if(it.value()==0)
428 return det * m_detPermR * m_detPermC;
437 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
439 Scalar
det = Scalar(1.);
442 for (
Index j = 0; j < this->cols(); ++j)
444 for (
typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
453 return (m_detPermR * m_detPermC) > 0 ?
det : -
det;
456 Index nnzL()
const {
return m_nnzL; };
457 Index nnzU()
const {
return m_nnzU; };
461 void initperfvalues()
463 m_perfv.panel_size = 16;
465 m_perfv.maxsuper = 128;
468 m_perfv.fillfactor = 20;
473 bool m_factorizationIsOk;
475 std::string m_lastError;
478 MappedSparseMatrix<Scalar,ColMajor,StorageIndex> m_Ustore;
479 PermutationType m_perm_c;
480 PermutationType m_perm_r ;
483 typename Base::GlobalLU_t m_glu;
486 bool m_symmetricmode;
488 internal::perfvalues m_perfv;
489 RealScalar m_diagpivotthresh;
490 Index m_nnzL, m_nnzU;
491 Index m_detPermR, m_detPermC;
494 SparseLU (
const SparseLU& );
510template <
typename MatrixType,
typename OrderingType>
528 ei_declare_aligned_stack_constructed_variable(StorageIndex,outerIndexPtr,
mat.cols()+1,
mat.isCompressed()?
const_cast<StorageIndex*
>(
mat.outerIndexPtr()):0);
531 if(!
mat.isCompressed())
532 IndexVector::Map(outerIndexPtr,
mat.cols()+1) = IndexVector::Map(m_mat.outerIndexPtr(),
mat.cols()+1);
535 for (
Index i = 0; i <
mat.cols(); i++)
537 m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
538 m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
547 if (!m_symmetricmode) {
550 internal::treePostorder(StorageIndex(m_mat.cols()), m_etree,
post);
554 Index m = m_mat.cols();
561 for (
Index i = 0; i < m; i++)
565 if(m_perm_c.size()) {
571 m_analysisIsOk =
true;
595template <
typename MatrixType,
typename OrderingType>
598 using internal::emptyIdxLU;
599 eigen_assert(m_analysisIsOk &&
"analyzePattern() should be called first");
600 eigen_assert((matrix.rows() == matrix.cols()) &&
"Only for squared matrices");
602 m_isInitialized =
true;
611 const StorageIndex * outerIndexPtr;
612 if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
619 for (
Index i = 0; i < matrix.cols(); i++)
621 m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
622 m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
624 if(!matrix.isCompressed())
delete[] outerIndexPtr;
628 m_perm_c.
resize(matrix.cols());
629 for(StorageIndex i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i;
632 Index m = m_mat.rows();
633 Index n = m_mat.cols();
634 Index nnz = m_mat.nonZeros();
638 Index info = Base::memInit(m, n, nnz,
lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
641 m_lastError =
"UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
642 m_factorizationIsOk =
false;
662 tempv.
setZero(internal::LUnumTempV(m, m_perfv.panel_size, m_perfv.maxsuper, m) );
669 if ( m_symmetricmode ==
true )
676 m_perm_r.indices().setConstant(-1);
680 m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0);
681 m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) =
Index(0);
695 Index panel_size = m_perfv.panel_size;
696 for (k =
jcol + 1; k < (std::min)(
jcol+panel_size, n); k++)
700 panel_size = k -
jcol;
705 panel_size = n -
jcol;
708 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);
722 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 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
727 m_factorizationIsOk =
false;
736 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
738 m_factorizationIsOk =
false;
746 m_lastError =
"UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
748 m_factorizationIsOk =
false;
753 info = Base::pivotL(
jj, m_diagpivotthresh, m_perm_r.indices(),
iperm_c.indices(),
pivrow, m_glu);
756 m_lastError =
"THE MATRIX IS STRUCTURALLY SINGULAR";
764 m_factorizationIsOk =
false;
770 if (
pivrow !=
jj) m_detPermR = -m_detPermR;
776 for (i = 0; i <
nseg; i++)
786 m_detPermC = m_perm_c.determinant();
789 Base::countnz(n, m_nnzL, m_nnzU, m_glu);
791 Base::fixupL(n, m_perm_r.indices(), m_glu);
794 m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
799 m_factorizationIsOk =
true;
802template<
typename MappedSupernodalType>
805 typedef typename MappedSupernodalType::Scalar Scalar;
808 Index rows()
const {
return m_mapL.rows(); }
809 Index cols()
const {
return m_mapL.cols(); }
810 template<
typename Dest>
813 m_mapL.solveInPlace(X);
815 template<
bool Conjugate,
typename Dest>
824template<
typename MatrixLType,
typename MatrixUType>
827 typedef typename MatrixLType::Scalar Scalar;
831 Index rows()
const {
return m_mapL.rows(); }
832 Index cols()
const {
return m_mapL.cols(); }
838 for (
Index k = m_mapL.nsuper(); k >= 0; k--)
841 Index lda = m_mapL.colIndexPtr()[
fsupc+1] - m_mapL.colIndexPtr()[
fsupc];
856 typename Dest::RowsBlockXpr
U = X.derived().middleRows(
fsupc,
nsupc);
864 typename MatrixUType::InnerIterator it(m_mapU,
jcol);
868 X(
irow, j) -= X(
jcol, j) * it.value();
875 template<
bool Conjugate,
typename Dest>
void solveTransposedInPlace(
MatrixBase<Dest> &X)
const
880 for (
Index k = 0; k <= m_mapL.nsuper(); k++)
883 Index lda = m_mapL.colIndexPtr()[
fsupc+1] - m_mapL.colIndexPtr()[
fsupc];
891 typename MatrixUType::InnerIterator it(m_mapU,
jcol);
909 typename Dest::RowsBlockXpr
U = X.derived().middleRows(
fsupc,
nsupc);
920 const MatrixUType& m_mapU;
Definition ForwardDeclarations.h:87
EIGEN_DEVICE_FUNC void resize(Index newSize)
Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods...
Definition DenseBase.h:246
EIGEN_DEVICE_FUNC Derived & setConstant(const Scalar &value)
Sets all coefficients in this expression to value val.
Definition CwiseNullaryOp.h:345
EIGEN_DEVICE_FUNC CoeffReturnType value() const
Definition DenseBase.h:526
EIGEN_DEVICE_FUNC Derived & setZero()
Sets all coefficients in this expression to zero.
Definition CwiseNullaryOp.h:546
EIGEN_DEVICE_FUNC TransposeReturnType transpose()
Definition Transpose.h:182
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
EIGEN_DEVICE_FUNC Scalar determinant() const
\lu_module
Definition Determinant.h:108
EIGEN_DEVICE_FUNC const Inverse< Derived > inverse() const
\lu_module
Definition InverseImpl.h:348
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
Resizes to the given size, and sets all coefficients in this expression to zero.
Definition CwiseNullaryOp.h:562
Sparse supernodal LU factorization for general matrices.
Definition SparseLU.h:133
Scalar determinant()
Definition SparseLU.h:435
Scalar absDeterminant()
Definition SparseLU.h:351
const PermutationType & colsPermutation() const
Definition SparseLU.h:271
const SparseLUTransposeView< false, SparseLU< _MatrixType, _OrderingType > > transpose()
Definition SparseLU.h:201
void factorize(const MatrixType &matrix)
Definition SparseLU.h:596
SparseLUMatrixLReturnType< SCMatrix > matrixL() const
Definition SparseLU.h:244
std::string lastErrorMessage() const
Definition SparseLU.h:309
Scalar signDeterminant()
Definition SparseLU.h:407
Scalar logAbsDeterminant() const
Definition SparseLU.h:381
void setPivotThreshold(const RealScalar &thresh)
Set the threshold used for a diagonal entry to be an acceptable pivot.
Definition SparseLU.h:276
void compute(const MatrixType &matrix)
Compute the symbolic and numeric factorization of the input sparse matrix.
Definition SparseLU.h:183
void analyzePattern(const MatrixType &matrix)
Compute the column permutation to minimize the fill-in.
Definition SparseLU.h:511
const SparseLUTransposeView< true, SparseLU< _MatrixType, _OrderingType > > adjoint()
Definition SparseLU.h:222
ComputationInfo info() const
Reports whether previous computation was successful.
Definition SparseLU.h:300
const PermutationType & rowsPermutation() const
Definition SparseLU.h:263
SparseLUMatrixUReturnType< SCMatrix, MappedSparseMatrix< Scalar, ColMajor, StorageIndex > > matrixU() const
Definition SparseLU.h:254
void isSymmetric(bool sym)
Indicate that the pattern of the input matrix is symmetric.
Definition SparseLU.h:233
Index rows() const
Definition SparseMatrix.h:138
Index cols() const
Definition SparseMatrix.h:140
A base class for sparse solvers.
Definition SparseSolverBase.h:68
const Solve< SparseLU< _MatrixType, _OrderingType >, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition SparseSolverBase.h:88
a class to manipulate the L supernodal factor from the SparseLU factorization
Definition SparseLU_SupernodalMatrix.h:34
Base class for sparseLU.
Definition SparseLUImpl.h:21
Definition XprHelper.h:110
ComputationInfo
Enum for reporting the status of a computation.
Definition Constants.h:440
@ NumericalIssue
The provided data did not satisfy the prerequisites.
Definition Constants.h:444
@ Success
Computation was successful.
Definition Constants.h:442
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition Constants.h:66
Namespace containing all symbols from the Eigen library.
Definition LDLT.h:16
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
Definition SparseLU.h:804
Definition SparseLU.h:826