12 #ifndef EIGEN_SPARSE_LU_H 13 #define EIGEN_SPARSE_LU_H 17 template <
typename _MatrixType,
typename _OrderingType = COLAMDOrdering<
typename _MatrixType::StorageIndex> >
class SparseLU;
21 template <
bool Conjugate,
class SparseLUType>
45 template<
typename Rhs,
typename Dest>
48 Dest&
X(X_base.derived());
51 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
59 m_sparseLU->matrixU().template solveTransposedInPlace<Conjugate>(
X);
62 m_sparseLU->matrixL().template solveTransposedInPlace<Conjugate>(
X);
130 template <
typename _MatrixType,
typename _OrderingType>
158 SparseLU():m_lastError(
""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
163 : m_lastError(
""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
174 void analyzePattern (
const MatrixType&
matrix);
175 void factorize (
const MatrixType& matrix);
176 void simplicialfactorize(
const MatrixType& matrix);
185 analyzePattern(matrix);
205 return transposeView;
234 m_symmetricmode = sym;
277 m_diagpivotthresh = thresh;
280 #ifdef EIGEN_PARSED_BY_DOXYGEN 287 template<
typename Rhs>
289 #endif // EIGEN_PARSED_BY_DOXYGEN 313 template<
typename Rhs,
typename Dest>
316 Dest&
X(X_base.derived());
317 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first");
319 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
323 X.resize(B.rows(),B.cols());
327 X.col(
j) = rowsPermutation() * B.const_cast_derived().
col(
j);
330 this->matrixL().solveInPlace(
X);
331 this->matrixU().solveInPlace(
X);
334 for (
Index j = 0;
j < B.cols(); ++
j)
335 X.col(
j) = colsPermutation().inverse() *
X.col(
j);
353 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
360 for (
typename SCMatrix::InnerIterator it(m_Lstore,
j); it; ++it)
364 det *=
abs(it.value());
385 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
389 for (
typename SCMatrix::InnerIterator it(m_Lstore,
j); it; ++it)
391 if(it.row() <
j)
continue;
394 det +=
log(
abs(it.value()));
408 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
415 for (
typename SCMatrix::InnerIterator it(m_Lstore,
j); it; ++it)
421 else if(it.value()==0)
427 return det * m_detPermR * m_detPermC;
436 eigen_assert(m_factorizationIsOk &&
"The matrix should be factorized first.");
443 for (
typename SCMatrix::InnerIterator it(m_Lstore,
j); it; ++it)
452 return (m_detPermR * m_detPermC) > 0 ? det : -det;
462 m_perfv.panel_size = 16;
464 m_perfv.maxsuper = 128;
467 m_perfv.fillfactor = 20;
509 template <
typename MatrixType,
typename OrderingType>
531 IndexVector::Map(outerIndexPtr, mat.
cols()+1) = IndexVector::Map(m_mat.outerIndexPtr(),mat.
cols()+1);
536 m_mat.outerIndexPtr()[m_perm_c.indices()(
i)] = outerIndexPtr[
i];
537 m_mat.innerNonZeroPtr()[m_perm_c.indices()(
i)] = outerIndexPtr[
i+1] - outerIndexPtr[
i];
546 if (!m_symmetricmode) {
555 for (
Index i = 0;
i <
m; ++
i) iwork(post(
i)) = post(m_etree(
i));
564 if(m_perm_c.size()) {
565 m_perm_c = post_perm * m_perm_c;
570 m_analysisIsOk =
true;
594 template <
typename MatrixType,
typename OrderingType>
598 eigen_assert(m_analysisIsOk &&
"analyzePattern() should be called first");
615 for(
Index i = 0;
i <= matrix.
cols();
i++) outerIndexPtr_t[
i] = m_mat.outerIndexPtr()[
i];
616 outerIndexPtr = outerIndexPtr_t;
620 m_mat.outerIndexPtr()[m_perm_c.indices()(
i)] = outerIndexPtr[
i];
621 m_mat.innerNonZeroPtr()[m_perm_c.indices()(
i)] = outerIndexPtr[
i+1] - outerIndexPtr[
i];
627 m_perm_c.resize(matrix.
cols());
633 Index nnz = m_mat.nonZeros();
634 Index maxpanel = m_perfv.panel_size *
m;
637 Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
640 m_lastError =
"UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
641 m_factorizationIsOk =
false;
668 if ( m_symmetricmode ==
true )
669 Base::heap_relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
671 Base::relax_snode(n, m_etree, m_perfv.relax, marker, relax_end);
675 m_perm_r.indices().setConstant(-1);
679 m_glu.supno(0) =
emptyIdxLU; m_glu.xsup.setConstant(0);
680 m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) =
Index(0);
691 for (jcol = 0; jcol <
n; )
694 Index panel_size = m_perfv.panel_size;
695 for (k = jcol + 1; k < (
std::min)(jcol+panel_size, n); k++)
699 panel_size = k - jcol;
704 panel_size = n - jcol;
707 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);
710 Base::panel_bmod(m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu);
713 for ( jj = jcol; jj< jcol + panel_size; jj++)
721 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);
724 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
726 m_factorizationIsOk =
false;
732 info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu);
735 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
737 m_factorizationIsOk =
false;
742 info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu);
745 m_lastError =
"UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
747 m_factorizationIsOk =
false;
752 info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu);
755 m_lastError =
"THE MATRIX IS STRUCTURALLY SINGULAR ... ZERO COLUMN AT ";
756 std::ostringstream returnInfo;
758 m_lastError += returnInfo.str();
760 m_factorizationIsOk =
false;
766 if (pivrow != jj) m_detPermR = -m_detPermR;
769 Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
772 for (i = 0; i < nseg; i++)
781 m_detPermR = m_perm_r.determinant();
782 m_detPermC = m_perm_c.determinant();
785 Base::countnz(n, m_nnzL, m_nnzU, m_glu);
787 Base::fixupL(n, m_perm_r.indices(), m_glu);
790 m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
795 m_factorizationIsOk =
true;
798 template<
typename MappedSupernodalType>
806 template<
typename Dest>
809 m_mapL.solveInPlace(X);
811 template<
bool Conjugate,
typename Dest>
814 m_mapL.template solveTransposedInPlace<Conjugate>(
X);
820 template<
typename MatrixLType,
typename MatrixUType>
825 : m_mapL(mapL),m_mapU(mapU)
832 Index nrhs = X.cols();
835 for (
Index k = m_mapL.nsuper(); k >= 0; k--)
837 Index fsupc = m_mapL.supToCol()[k];
838 Index lda = m_mapL.colIndexPtr()[fsupc+1] - m_mapL.colIndexPtr()[fsupc];
839 Index nsupc = m_mapL.supToCol()[k+1] - fsupc;
840 Index luptr = m_mapL.colIndexPtr()[fsupc];
846 X(fsupc,
j) /= m_mapL.valuePtr()[luptr];
854 U =
A.template triangularView<Upper>().
solve(U);
859 for (
Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
861 typename MatrixUType::InnerIterator it(m_mapU, jcol);
864 Index irow = it.index();
865 X(irow,
j) -=
X(jcol,
j) * it.value();
875 Index nrhs = X.cols();
878 for (
Index k = 0; k <= m_mapL.nsuper(); k++)
880 Index fsupc = m_mapL.supToCol()[k];
881 Index lda = m_mapL.colIndexPtr()[fsupc+1] - m_mapL.colIndexPtr()[fsupc];
882 Index nsupc = m_mapL.supToCol()[k+1] - fsupc;
883 Index luptr = m_mapL.colIndexPtr()[fsupc];
887 for (
Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
889 typename MatrixUType::InnerIterator it(m_mapU, jcol);
892 Index irow = it.index();
901 X(fsupc,
j) /= (
Conjugate?
conj(m_mapL.valuePtr()[luptr]) : m_mapL.valuePtr()[luptr]);
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ColXpr col(Index i)
bool isCompressed() const
SparseLUTransposeView(const SparseLUTransposeView &view)
SparseLUMatrixUReturnType(const MatrixLType &mapL, const MatrixUType &mapU)
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
const AutoDiffScalar< DerType > & conj(const AutoDiffScalar< DerType > &x)
MatrixLType::Scalar Scalar
MatrixType::StorageIndex StorageIndex
const MatrixLType & m_mapL
int coletree(const MatrixType &mat, IndexVector &parent, IndexVector &firstRowElt, typename MatrixType::StorageIndex *perm=0)
const StorageIndex * outerIndexPtr() const
SparseSolverBase< SparseLUTransposeView< Conjugate, SparseLUType > > APIBase
void solveInPlace(MatrixBase< Dest > &X) const
const PermutationType & rowsPermutation() const
A matrix or vector expression mapping an existing array of data.
Matrix< Scalar, Dynamic, 1 > ScalarVector
bool _solve_impl(const MatrixBase< Rhs > &B, MatrixBase< Dest > &X_base) const
A base class for sparse solvers.
const Solve< SparseLUTransposeView< Conjugate, SparseLUType >, Rhs > solve(const MatrixBase< Rhs > &b) const
internal::perfvalues m_perfv
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set view
PermutationMatrix< Dynamic, Dynamic, StorageIndex > PermutationType
Namespace containing all symbols from the Eigen library.
const MappedSupernodalType & m_mapL
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
void factorize(const MatrixType &matrix)
const unsigned int RowMajorBit
EIGEN_DEVICE_FUNC const LogReturnType log() const
Sparse supernodal LU factorization for general matrices.
AnnoyingScalar conj(const AnnoyingScalar &x)
SparseLUType * m_sparseLU
void solveInPlace(MatrixBase< Dest > &X) const
SparseLU(const MatrixType &matrix)
void setPivotThreshold(const RealScalar &thresh)
internal::traits< SparseMatrix< _Scalar, _Options, _StorageIndex > >::StorageIndex StorageIndex
SparseLUMatrixLReturnType< SCMatrix > matrixL() const
void _solve_impl(const SparseMatrixBase< Rhs > &b, SparseMatrixBase< Dest > &dest) const
Expression of a fixed-size or dynamic-size sub-vector.
Matrix< StorageIndex, Dynamic, 1 > IndexVector
const SparseLUTransposeView< true, SparseLU< _MatrixType, _OrderingType > > adjoint()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
SparseLUType::StorageIndex StorageIndex
const IndicesType & indices() const
RealScalar m_diagpivotthresh
void compute(const MatrixType &matrix)
internal::traits< SparseMatrix< _Scalar, _Options, _StorageIndex > >::Scalar Scalar
void isSymmetric(bool sym)
MatrixType::Scalar Scalar
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
SparseLUType::MatrixType MatrixType
Index LUnumTempV(Index &m, Index &w, Index &t, Index &b)
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
#define ei_declare_aligned_stack_constructed_variable(TYPE, NAME, SIZE, BUFFER)
MappedSparseMatrix< Scalar, ColMajor, StorageIndex > m_Ustore
internal::MappedSuperNodalMatrix< Scalar, StorageIndex > SCMatrix
SparseMatrix< Scalar, ColMajor, StorageIndex > NCMatrix
SparseLUMatrixUReturnType< SCMatrix, MappedSparseMatrix< Scalar, ColMajor, StorageIndex > > matrixU() const
_OrderingType OrderingType
void setIsInitialized(const bool isInitialized)
void setSparseLU(SparseLUType *sparseLU)
SparseLUType::Scalar Scalar
void solveTransposedInPlace(MatrixBase< Dest > &X) const
void solveTransposedInPlace(MatrixBase< Dest > &X) const
A triangularView< Lower >().adjoint().solveInPlace(B)
internal::SparseLUImpl< Scalar, StorageIndex > Base
SparseLUType::OrderingType OrderingType
std::string lastErrorMessage() const
Scalar logAbsDeterminant() const
const SparseLUTransposeView< false, SparseLU< _MatrixType, _OrderingType > > transpose()
bool _solve_impl(const MatrixBase< Rhs > &B, MatrixBase< Dest > &X_base) const
void treePostorder(typename IndexVector::Scalar n, IndexVector &parent, IndexVector &post)
Post order a tree.
const PermutationType & colsPermutation() const
SparseSolverBase< SparseLU< _MatrixType, _OrderingType > > APIBase
SparseLUMatrixLReturnType(const MappedSupernodalType &mapL)
Pseudo expression representing a solving operation.
void analyzePattern(const MatrixType &matrix)
const MatrixUType & m_mapU
EIGEN_DONT_INLINE void compute(Solver &solver, const MatrixType &A)
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
NumTraits< Scalar >::Real RealScalar
MatrixType::RealScalar RealScalar
Convenience specialization of Stride to specify only an outer stride See class Map for some examples...
Base class for all dense matrices, vectors, and expressions.
ComputationInfo info() const
Reports whether previous computation was successful.
SparseLUTransposeView & operator=(const SparseLUTransposeView &)
MappedSupernodalType::Scalar Scalar