12 #ifndef EIGEN_SPARSE_LU_H
13 #define EIGEN_SPARSE_LU_H
19 template <
typename MatrixType_,
typename OrderingType_ = COLAMDOrdering<
typename MatrixType_::StorageIndex> >
class SparseLU;
20 template <
typename MappedSparseMatrixType>
struct SparseLUMatrixLReturnType;
21 template <
typename MatrixLType,
typename MatrixUType>
struct SparseLUMatrixUReturnType;
23 template <
bool Conjugate,
class SparseLUType>
30 typedef typename SparseLUType::Scalar
Scalar;
47 using APIBase::_solve_impl;
48 template<
typename Rhs,
typename Dest>
54 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
59 X.col(
j) =
m_sparseLU->colsPermutation() *
B.const_cast_derived().col(
j);
62 m_sparseLU->matrixU().template solveTransposedInPlace<Conjugate>(
X);
65 m_sparseLU->matrixL().template solveTransposedInPlace<Conjugate>(
X);
133 template <
typename MatrixType_,
typename OrderingType_>
134 class SparseLU :
public SparseSolverBase<SparseLU<MatrixType_,OrderingType_> >,
public internal::SparseLUImpl<typename MatrixType_::Scalar, typename MatrixType_::StorageIndex>
140 using APIBase::_solve_impl;
148 typedef internal::MappedSuperNodalMatrix<Scalar, StorageIndex>
SCMatrix;
152 typedef internal::SparseLUImpl<Scalar, StorageIndex>
Base;
208 return transposeView;
283 #ifdef EIGEN_PARSED_BY_DOXYGEN
290 template<
typename Rhs>
316 template<
typename Rhs,
typename Dest>
322 THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
326 X.resize(
B.rows(),
B.cols());
333 this->
matrixL().solveInPlace(X);
334 this->
matrixU().solveInPlace(X);
363 for (
typename SCMatrix::InnerIterator it(
m_Lstore,
j); it; ++it)
367 det *=
abs(it.value());
392 for (
typename SCMatrix::InnerIterator it(
m_Lstore,
j); it; ++it)
394 if(it.row() <
j)
continue;
397 det +=
log(
abs(it.value()));
418 for (
typename SCMatrix::InnerIterator it(
m_Lstore,
j); it; ++it)
424 else if(it.value()==0)
446 for (
typename SCMatrix::InnerIterator it(
m_Lstore,
j); it; ++it)
512 template <
typename MatrixType,
typename OrderingType>
533 if(!
mat.isCompressed())
534 IndexVector::Map(outerIndexPtr,
mat.
cols()+1) = IndexVector::Map(m_mat.outerIndexPtr(),
mat.
cols()+1);
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];
549 if (!m_symmetricmode) {
558 for (
Index i = 0;
i <
m; ++
i) iwork(post(
i)) = post(m_etree(
i));
567 if(m_perm_c.size()) {
568 m_perm_c = post_perm * m_perm_c;
573 m_analysisIsOk =
true;
597 template <
typename MatrixType,
typename OrderingType>
601 eigen_assert(m_analysisIsOk &&
"analyzePattern() should be called first");
602 eigen_assert((matrix.rows() == matrix.cols()) &&
"Only for squared matrices");
604 m_isInitialized =
true;
614 if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
618 for(
Index i = 0;
i <= matrix.cols();
i++) outerIndexPtr_t[
i] = m_mat.outerIndexPtr()[
i];
619 outerIndexPtr = outerIndexPtr_t;
621 for (
Index i = 0;
i < matrix.cols();
i++)
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];
626 if(!matrix.isCompressed())
delete[] outerIndexPtr;
630 m_perm_c.resize(matrix.cols());
636 Index nnz = m_mat.nonZeros();
637 Index maxpanel = m_perfv.panel_size *
m;
640 Index info = Base::memInit(
m,
n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
643 m_lastError =
"UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
644 m_factorizationIsOk =
false;
671 if ( m_symmetricmode ==
true )
672 Base::heap_relax_snode(
n, m_etree, m_perfv.relax, marker, relax_end);
674 Base::relax_snode(
n, m_etree, m_perfv.relax, marker, relax_end);
678 m_perm_r.indices().setConstant(-1);
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);
694 for (jcol = 0; jcol <
n; )
697 Index panel_size = m_perfv.panel_size;
698 for (k = jcol + 1; k < (
std::min)(jcol+panel_size,
n); k++)
702 panel_size = k - jcol;
707 panel_size =
n - jcol;
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);
713 Base::panel_bmod(
m, panel_size, jcol, nseg1, dense, tempv, segrep, repfnz, m_glu);
716 for ( jj = jcol; jj< jcol + panel_size; jj++)
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);
727 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_DFS() ";
729 m_factorizationIsOk =
false;
735 info = Base::column_bmod(jj, (nseg - nseg1), dense_k, tempv, segrep_k, repfnz_k, jcol, m_glu);
738 m_lastError =
"UNABLE TO EXPAND MEMORY IN COLUMN_BMOD() ";
740 m_factorizationIsOk =
false;
745 info = Base::copy_to_ucol(jj, nseg, segrep, repfnz_k ,m_perm_r.indices(), dense_k, m_glu);
748 m_lastError =
"UNABLE TO EXPAND MEMORY IN COPY_TO_UCOL() ";
750 m_factorizationIsOk =
false;
755 info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.
indices(), pivrow, m_glu);
758 m_lastError =
"THE MATRIX IS STRUCTURALLY SINGULAR";
760 std::ostringstream returnInfo;
761 returnInfo <<
" ... ZERO COLUMN AT ";
763 m_lastError += returnInfo.str();
766 m_factorizationIsOk =
false;
772 if (pivrow != jj) m_detPermR = -m_detPermR;
775 Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
778 for (
i = 0;
i < nseg;
i++)
787 m_detPermR = m_perm_r.determinant();
788 m_detPermC = m_perm_c.determinant();
791 Base::countnz(
n, m_nnzL, m_nnzU, m_glu);
793 Base::fixupL(
n, m_perm_r.indices(), m_glu);
796 m_Lstore.setInfos(
m,
n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
801 m_factorizationIsOk =
true;
804 template<
typename MappedSupernodalType>
807 typedef typename MappedSupernodalType::Scalar
Scalar;
812 template<
typename Dest>
817 template<
bool Conjugate,
typename Dest>
820 m_mapL.template solveTransposedInPlace<Conjugate>(
X);
826 typename MappedSupernodalType::InnerIterator iter(
m_mapL,
i);
827 for (; iter; ++iter) {
828 if (iter.row() > iter.col()) {
829 colCount(iter.col())++;
837 typename MappedSupernodalType::InnerIterator iter(
m_mapL,
i);
838 for (; iter; ++iter) {
839 if (iter.row() > iter.col()) {
840 sL.
insert(iter.row(), iter.col()) = iter.value();
851 template<
typename MatrixLType,
typename MatrixUType>
854 typedef typename MatrixLType::Scalar
Scalar;
876 X(fsupc,
j) /=
m_mapL.valuePtr()[luptr];
883 typename Dest::RowsBlockXpr U =
X.derived().middleRows(fsupc, nsupc);
884 U =
A.template triangularView<Upper>().solve(U);
889 for (
Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
891 typename MatrixUType::InnerIterator it(
m_mapU, jcol);
894 Index irow = it.index();
895 X(irow,
j) -=
X(jcol,
j) * it.value();
916 for (
Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
918 typename MatrixUType::InnerIterator it(
m_mapU, jcol);
921 Index irow = it.index();
936 typename Dest::RowsBlockXpr U =
X.derived().middleRows(fsupc, nsupc);
938 U =
A.adjoint().template triangularView<Lower>().solve(U);
940 U =
A.transpose().template triangularView<Lower>().solve(U);
948 typename MatrixLType::InnerIterator iter(
m_mapL,
i);
949 for (; iter; ++iter) {
950 if (iter.row() <= iter.col()) {
951 rowCount(iter.row())++;
959 typename MatrixLType::InnerIterator iter(
m_mapL,
i);
960 for (; iter; ++iter) {
961 if (iter.row() <= iter.col()) {
962 sU.
insert(iter.row(), iter.col()) = iter.value();
const AbsReturnType abs() const
const LogReturnType log() const
#define ei_declare_aligned_stack_constructed_variable(TYPE, NAME, SIZE, BUFFER)
#define EIGEN_STATIC_ASSERT(X, MSG)
Matrix< float, 1, Dynamic > MatrixType
General-purpose arrays with easy API for coefficient-wise operations.
NumTraits< Scalar >::Real RealScalar
static const ConstantReturnType Ones()
internal::traits< Derived >::StorageIndex StorageIndex
The type used to store indices.
static const ConstantReturnType Zero()
internal::traits< Derived >::Scalar Scalar
A matrix or vector expression mapping an existing array of data.
Base class for all dense matrices, vectors, and expressions.
Convenience specialization of Stride to specify only an outer stride See class Map for some examples.
InverseReturnType inverse() const
const IndicesType & indices() const
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Derived & setConstant(Index size, const Scalar &val)
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Derived & setZero(Index size)
constexpr void resize(Index rows, Index cols)
Pseudo expression representing a solving operation.
SparseLUType::MatrixType MatrixType
SparseLUType * m_sparseLU
void setSparseLU(SparseLUType *sparseLU)
SparseLUType::Scalar Scalar
bool _solve_impl(const MatrixBase< Rhs > &B, MatrixBase< Dest > &X_base) const
SparseSolverBase< SparseLUTransposeView< Conjugate, SparseLUType > > APIBase
SparseLUTransposeView & operator=(const SparseLUTransposeView &)
void setIsInitialized(const bool isInitialized)
SparseLUType::OrderingType OrderingType
SparseLUTransposeView(const SparseLUTransposeView &view)
SparseLUType::StorageIndex StorageIndex
Sparse supernodal LU factorization for general matrices.
SparseLU(const SparseLU &)
Matrix< StorageIndex, Dynamic, 1 > IndexVector
void setPivotThreshold(const RealScalar &thresh)
Scalar logAbsDeterminant() const
MatrixType::Scalar Scalar
MatrixType::RealScalar RealScalar
SparseMatrix< Scalar, ColMajor, StorageIndex > NCMatrix
SparseLUMatrixUReturnType< SCMatrix, Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > > matrixU() const
void factorize(const MatrixType &matrix)
const PermutationType & rowsPermutation() const
std::string lastErrorMessage() const
const SparseLUTransposeView< true, SparseLU< MatrixType_, OrderingType_ > > adjoint()
SparseLUMatrixLReturnType< SCMatrix > matrixL() const
SparseSolverBase< SparseLU< MatrixType_, OrderingType_ > > APIBase
void compute(const MatrixType &matrix)
ComputationInfo info() const
Reports whether previous computation was successful.
bool _solve_impl(const MatrixBase< Rhs > &B, MatrixBase< Dest > &X_base) const
void simplicialfactorize(const MatrixType &matrix)
internal::perfvalues m_perfv
Matrix< Scalar, Dynamic, 1 > ScalarVector
OrderingType_ OrderingType
internal::MappedSuperNodalMatrix< Scalar, StorageIndex > SCMatrix
void analyzePattern(const MatrixType &matrix)
const Solve< SparseLU, Rhs > solve(const MatrixBase< Rhs > &B) const
PermutationMatrix< Dynamic, Dynamic, StorageIndex > PermutationType
const SparseLUTransposeView< false, SparseLU< MatrixType_, OrderingType_ > > transpose()
void isSymmetric(bool sym)
const PermutationType & colsPermutation() const
RealScalar m_diagpivotthresh
Map< SparseMatrix< Scalar, ColMajor, StorageIndex > > m_Ustore
SparseLU(const MatrixType &matrix)
MatrixType::StorageIndex StorageIndex
internal::SparseLUImpl< Scalar, StorageIndex > Base
void reserve(Index reserveSize)
Scalar & insert(Index row, Index col)
A base class for sparse solvers.
Expression of a fixed-size or dynamic-size sub-vector.
const unsigned int RowMajorBit
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Index LUnumTempV(Index &m, Index &w, Index &t, Index &b)
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.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_log_op< typename Derived::Scalar >, const Derived > log(const Eigen::ArrayBase< Derived > &x)
void solveTransposedInPlace(MatrixBase< Dest > &X) const
const MappedSupernodalType & m_mapL
SparseLUMatrixLReturnType(const MappedSupernodalType &mapL)
void solveInPlace(MatrixBase< Dest > &X) const
SparseMatrix< Scalar, ColMajor, Index > toSparse() const
MappedSupernodalType::Scalar Scalar
const MatrixUType & m_mapU
SparseMatrix< Scalar, RowMajor, Index > toSparse()
SparseLUMatrixUReturnType(const MatrixLType &mapL, const MatrixUType &mapU)
void solveInPlace(MatrixBase< Dest > &X) const
const MatrixLType & m_mapL
void solveTransposedInPlace(MatrixBase< Dest > &X) const
MatrixLType::Scalar Scalar