Change int to Index type for SparseLU

This commit is contained in:
Desire NUENTSA 2013-01-29 16:21:24 +01:00
parent 57e50789f3
commit 8bc00925e5
18 changed files with 207 additions and 203 deletions

View File

@ -36,11 +36,11 @@ namespace Eigen {
namespace internal { namespace internal {
/** Find the root of the tree/set containing the vertex i : Use Path halving */ /** Find the root of the tree/set containing the vertex i : Use Path halving */
template<typename IndexVector> template<typename Index, typename IndexVector>
int etree_find (int i, IndexVector& pp) Index etree_find (Index i, IndexVector& pp)
{ {
int p = pp(i); // Parent Index p = pp(i); // Parent
int gp = pp(p); // Grand parent Index gp = pp(p); // Grand parent
while (gp != p) while (gp != p)
{ {
pp(i) = gp; // Parent pointer on find path is changed to former grand parent pp(i) = gp; // Parent pointer on find path is changed to former grand parent
@ -68,7 +68,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl
pp.setZero(); // Initialize disjoint sets pp.setZero(); // Initialize disjoint sets
parent.resize(mat.cols()); parent.resize(mat.cols());
//Compute first nonzero column in each row //Compute first nonzero column in each row
int row,col; Index row,col;
firstRowElt.resize(m); firstRowElt.resize(m);
firstRowElt.setConstant(nc); firstRowElt.setConstant(nc);
firstRowElt.segment(0, nc).setLinSpaced(nc, 0, nc-1); firstRowElt.segment(0, nc).setLinSpaced(nc, 0, nc-1);
@ -85,7 +85,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl
except use (firstRowElt[r],c) in place of an edge (r,c) of A. except use (firstRowElt[r],c) in place of an edge (r,c) of A.
Thus each row clique in A'*A is replaced by a star Thus each row clique in A'*A is replaced by a star
centered at its first vertex, which has the same fill. */ centered at its first vertex, which has the same fill. */
int rset, cset, rroot; Index rset, cset, rroot;
for (col = 0; col < nc; col++) for (col = 0; col < nc; col++)
{ {
found_diag = false; found_diag = false;
@ -97,7 +97,7 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl
* hence the loop is executed once more */ * hence the loop is executed once more */
for (typename MatrixType::InnerIterator it(mat, col); it||!found_diag; ++it) for (typename MatrixType::InnerIterator it(mat, col); it||!found_diag; ++it)
{ // A sequence of interleaved find and union is performed { // A sequence of interleaved find and union is performed
int i = col; Index i = col;
if(it) i = it.index(); if(it) i = it.index();
if (i == col) found_diag = true; if (i == col) found_diag = true;
row = firstRowElt(i); row = firstRowElt(i);
@ -120,10 +120,10 @@ int coletree(const MatrixType& mat, IndexVector& parent, IndexVector& firstRowEl
* Depth-first search from vertex n. No recursion. * Depth-first search from vertex n. No recursion.
* This routine was contributed by Cédric Doucet, CEDRAT Group, Meylan, France. * This routine was contributed by Cédric Doucet, CEDRAT Group, Meylan, France.
*/ */
template <typename IndexVector> template <typename Index, typename IndexVector>
void nr_etdfs (int n, IndexVector& parent, IndexVector& first_kid, IndexVector& next_kid, IndexVector& post, int postnum) void nr_etdfs (Index n, IndexVector& parent, IndexVector& first_kid, IndexVector& next_kid, IndexVector& post, Index postnum)
{ {
int current = n, first, next; Index current = n, first, next;
while (postnum != n) while (postnum != n)
{ {
// No kid for the current node // No kid for the current node
@ -167,18 +167,18 @@ void nr_etdfs (int n, IndexVector& parent, IndexVector& first_kid, IndexVector&
* \param parent Input tree * \param parent Input tree
* \param post postordered tree * \param post postordered tree
*/ */
template <typename IndexVector> template <typename Index, typename IndexVector>
void treePostorder(int n, IndexVector& parent, IndexVector& post) void treePostorder(Index n, IndexVector& parent, IndexVector& post)
{ {
IndexVector first_kid, next_kid; // Linked list of children IndexVector first_kid, next_kid; // Linked list of children
int postnum; Index postnum;
// Allocate storage for working arrays and results // Allocate storage for working arrays and results
first_kid.resize(n+1); first_kid.resize(n+1);
next_kid.setZero(n+1); next_kid.setZero(n+1);
post.setZero(n+1); post.setZero(n+1);
// Set up structure describing children // Set up structure describing children
int v, dad; Index v, dad;
first_kid.setConstant(-1); first_kid.setConstant(-1);
for (v = n-1; v >= 0; v--) for (v = n-1; v >= 0; v--)
{ {

View File

@ -42,7 +42,7 @@ template <typename MappedSparseMatrixType> struct SparseLUMatrixLReturnType;
* \code * \code
* VectorXd x(n), b(n); * VectorXd x(n), b(n);
* SparseMatrix<double, ColMajor> A; * SparseMatrix<double, ColMajor> A;
* SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<int> > solver; * SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<Index> > solver;
* // fill A and b; * // fill A and b;
* // Compute the ordering permutation vector from the structural pattern of A * // Compute the ordering permutation vector from the structural pattern of A
* solver.analyzePattern(A); * solver.analyzePattern(A);
@ -194,13 +194,13 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
int nrhs = B.cols(); Index nrhs = B.cols();
Index n = B.rows(); Index n = B.rows();
// Permute the right hand side to form X = Pr*B // Permute the right hand side to form X = Pr*B
// on return, X is overwritten by the computed solution // on return, X is overwritten by the computed solution
X.resize(n,nrhs); X.resize(n,nrhs);
for(int j = 0; j < nrhs; ++j) for(Index j = 0; j < nrhs; ++j)
X.col(j) = m_perm_r * B.col(j); X.col(j) = m_perm_r * B.col(j);
//Forward substitution with L //Forward substitution with L
@ -208,7 +208,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
this->matrixL().solveInPlace(X); this->matrixL().solveInPlace(X);
// Backward solve with U // Backward solve with U
for (int k = m_Lstore.nsuper(); k >= 0; k--) for (Index k = m_Lstore.nsuper(); k >= 0; k--)
{ {
Index fsupc = m_Lstore.supToCol()[k]; Index fsupc = m_Lstore.supToCol()[k];
Index lda = m_Lstore.colIndexPtr()[fsupc+1] - m_Lstore.colIndexPtr()[fsupc]; // leading dimension Index lda = m_Lstore.colIndexPtr()[fsupc+1] - m_Lstore.colIndexPtr()[fsupc]; // leading dimension
@ -217,7 +217,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
if (nsupc == 1) if (nsupc == 1)
{ {
for (int j = 0; j < nrhs; j++) for (Index j = 0; j < nrhs; j++)
{ {
X(fsupc, j) /= m_Lstore.valuePtr()[luptr]; X(fsupc, j) /= m_Lstore.valuePtr()[luptr];
} }
@ -229,11 +229,11 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
U = A.template triangularView<Upper>().solve(U); U = A.template triangularView<Upper>().solve(U);
} }
for (int j = 0; j < nrhs; ++j) for (Index j = 0; j < nrhs; ++j)
{ {
for (int jcol = fsupc; jcol < fsupc + nsupc; jcol++) for (Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
{ {
typename MappedSparseMatrix<Scalar>::InnerIterator it(m_Ustore, jcol); typename MappedSparseMatrix<Scalar,ColMajor, Index>::InnerIterator it(m_Ustore, jcol);
for ( ; it; ++it) for ( ; it; ++it)
{ {
Index irow = it.index(); Index irow = it.index();
@ -244,7 +244,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
} // End For U-solve } // End For U-solve
// Permute back the solution // Permute back the solution
for (int j = 0; j < nrhs; ++j) for (Index j = 0; j < nrhs; ++j)
X.col(j) = m_perm_c.inverse() * X.col(j); X.col(j) = m_perm_c.inverse() * X.col(j);
return true; return true;
@ -270,7 +270,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
std::string m_lastError; std::string m_lastError;
NCMatrix m_mat; // The input (permuted ) matrix NCMatrix m_mat; // The input (permuted ) matrix
SCMatrix m_Lstore; // The lower triangular matrix (supernodal) SCMatrix m_Lstore; // The lower triangular matrix (supernodal)
MappedSparseMatrix<Scalar> m_Ustore; // The upper triangular matrix MappedSparseMatrix<Scalar,ColMajor,Index> m_Ustore; // The upper triangular matrix
PermutationType m_perm_c; // Column permutation PermutationType m_perm_c; // Column permutation
PermutationType m_perm_r ; // Row permutation PermutationType m_perm_r ; // Row permutation
IndexVector m_etree; // Column elimination tree IndexVector m_etree; // Column elimination tree
@ -280,9 +280,9 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
// SparseLU options // SparseLU options
bool m_symmetricmode; bool m_symmetricmode;
// values for performance // values for performance
internal::perfvalues m_perfv; internal::perfvalues<Index> m_perfv;
RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot
int m_nnzL, m_nnzU; // Nonzeros in L and U factors Index m_nnzL, m_nnzU; // Nonzeros in L and U factors
private: private:
// Copy constructor // Copy constructor
@ -317,7 +317,7 @@ void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
if (m_perm_c.size()) { if (m_perm_c.size()) {
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. 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.
//Then, permute only the column pointers //Then, permute only the column pointers
for (int i = 0; i < mat.cols(); i++) for (Index i = 0; i < mat.cols(); i++)
{ {
m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i]; m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i];
m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i]; m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i];
@ -335,14 +335,14 @@ void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
// Renumber etree in postorder // Renumber etree in postorder
int m = m_mat.cols(); Index m = m_mat.cols();
iwork.resize(m+1); iwork.resize(m+1);
for (int i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i)); for (Index i = 0; i < m; ++i) iwork(post(i)) = post(m_etree(i));
m_etree = iwork; m_etree = iwork;
// Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree // Postmultiply A*Pc by post, i.e reorder the matrix according to the postorder of the etree
PermutationType post_perm(m); PermutationType post_perm(m);
for (int i = 0; i < m; i++) for (Index i = 0; i < m; i++)
post_perm.indices()(i) = post(i); post_perm.indices()(i) = post(i);
// Combine the two permutations : postorder the permutation for future use // Combine the two permutations : postorder the permutation for future use
@ -393,7 +393,7 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
{ {
m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers.
//Then, permute only the column pointers //Then, permute only the column pointers
for (int i = 0; i < matrix.cols(); i++) for (Index i = 0; i < matrix.cols(); i++)
{ {
m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i]; m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i];
m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i+1] - matrix.outerIndexPtr()[i]; m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i+1] - matrix.outerIndexPtr()[i];
@ -402,16 +402,16 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
else else
{ //FIXME This should not be needed if the empty permutation is handled transparently { //FIXME This should not be needed if the empty permutation is handled transparently
m_perm_c.resize(matrix.cols()); m_perm_c.resize(matrix.cols());
for(int i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i; for(Index i = 0; i < matrix.cols(); ++i) m_perm_c.indices()(i) = i;
} }
int m = m_mat.rows(); Index m = m_mat.rows();
int n = m_mat.cols(); Index n = m_mat.cols();
int nnz = m_mat.nonZeros(); Index nnz = m_mat.nonZeros();
int maxpanel = m_perfv.panel_size * m; Index maxpanel = m_perfv.panel_size * m;
// Allocate working storage common to the factor routines // Allocate working storage common to the factor routines
int lwork = 0; Index lwork = 0;
int info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu); Index info = Base::memInit(m, n, nnz, lwork, m_perfv.fillfactor, m_perfv.panel_size, m_glu);
if (info) if (info)
{ {
m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ; m_lastError = "UNABLE TO ALLOCATE WORKING MEMORY\n\n" ;
@ -458,17 +458,17 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
// Work on one 'panel' at a time. A panel is one of the following : // Work on one 'panel' at a time. A panel is one of the following :
// (a) a relaxed supernode at the bottom of the etree, or // (a) a relaxed supernode at the bottom of the etree, or
// (b) panel_size contiguous columns, <panel_size> defined by the user // (b) panel_size contiguous columns, <panel_size> defined by the user
int jcol; Index jcol;
IndexVector panel_histo(n); IndexVector panel_histo(n);
Index pivrow; // Pivotal row number in the original row matrix Index pivrow; // Pivotal row number in the original row matrix
int nseg1; // Number of segments in U-column above panel row jcol Index nseg1; // Number of segments in U-column above panel row jcol
int nseg; // Number of segments in each U-column Index nseg; // Number of segments in each U-column
int irep; Index irep;
int i, k, jj; Index i, k, jj;
for (jcol = 0; jcol < n; ) for (jcol = 0; jcol < n; )
{ {
// Adjust panel size so that a panel won't overlap with the next relaxed snode. // Adjust panel size so that a panel won't overlap with the next relaxed snode.
int panel_size = m_perfv.panel_size; // upper bound on panel width Index panel_size = m_perfv.panel_size; // upper bound on panel width
for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++) for (k = jcol + 1; k < (std::min)(jcol+panel_size, n); k++)
{ {
if (relax_end(k) != emptyIdxLU) if (relax_end(k) != emptyIdxLU)
@ -559,7 +559,7 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
// Create supernode matrix L // Create supernode matrix L
m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup); m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
// Create the column major upper sparse matrix U; // Create the column major upper sparse matrix U;
new (&m_Ustore) MappedSparseMatrix<Scalar> ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() ); new (&m_Ustore) MappedSparseMatrix<Scalar, ColMajor, Index> ( m, n, m_nnzU, m_glu.xusub.data(), m_glu.usub.data(), m_glu.ucol.data() );
m_info = Success; m_info = Success;
m_factorizationIsOk = true; m_factorizationIsOk = true;

View File

@ -30,29 +30,29 @@ class SparseLUImpl
protected: protected:
template <typename VectorType> template <typename VectorType>
int expand(VectorType& vec, int& length, int nbElts, int keep_prev, int& num_expansions); Index expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions);
int memInit(int m, int n, int annz, int lwork, int fillratio, int panel_size, GlobalLU_t& glu); Index memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu);
template <typename VectorType> template <typename VectorType>
int memXpand(VectorType& vec, int& maxlen, int nbElts, MemType memtype, int& num_expansions); Index memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions);
void heap_relax_snode (const int n, IndexVector& et, const int relax_columns, IndexVector& descendants, IndexVector& relax_end); void heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end);
void relax_snode (const int n, IndexVector& et, const int relax_columns, IndexVector& descendants, IndexVector& relax_end); void relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end);
int snode_dfs(const int jcol, const int kcol,const MatrixType& mat, IndexVector& xprune, IndexVector& marker, GlobalLU_t& glu); Index snode_dfs(const Index jcol, const Index kcol,const MatrixType& mat, IndexVector& xprune, IndexVector& marker, GlobalLU_t& glu);
int snode_bmod (const int jcol, const int fsupc, ScalarVector& dense, GlobalLU_t& glu); Index snode_bmod (const Index jcol, const Index fsupc, ScalarVector& dense, GlobalLU_t& glu);
int pivotL(const int jcol, const RealScalar diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, int& pivrow, GlobalLU_t& glu); Index pivotL(const Index jcol, const RealScalar diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu);
template <typename Traits> template <typename Traits>
void dfs_kernel(const int jj, IndexVector& perm_r, void dfs_kernel(const Index jj, IndexVector& perm_r,
int& nseg, IndexVector& panel_lsub, IndexVector& segrep, Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent, Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
IndexVector& xplore, GlobalLU_t& glu, int& nextl_col, int krow, Traits& traits); IndexVector& xplore, GlobalLU_t& glu, Index& nextl_col, Index krow, Traits& traits);
void panel_dfs(const int m, const int w, const int jcol, MatrixType& A, IndexVector& perm_r, int& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu); 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);
void panel_bmod(const int m, const int w, const int jcol, const int nseg, ScalarVector& dense, ScalarVector& tempv, IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu); 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);
int column_dfs(const int m, const int jcol, IndexVector& perm_r, int maxsuper, int& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu); 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);
int column_bmod(const int jcol, const int nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, int fpanelc, GlobalLU_t& glu); Index column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu);
int copy_to_ucol(const int jcol, const int nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu); Index copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu);
void pruneL(const int jcol, const IndexVector& perm_r, const int pivrow, const int nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu); 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);
void countnz(const int n, int& nnzL, int& nnzU, GlobalLU_t& glu); void countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu);
void fixupL(const int n, const IndexVector& perm_r, GlobalLU_t& glu); void fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu);
template<typename , typename > template<typename , typename >
friend struct column_dfs_traits; friend struct column_dfs_traits;

View File

@ -61,11 +61,11 @@ inline Index LUTempSpace(Index&m, Index& w)
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
template <typename VectorType> template <typename VectorType>
int SparseLUImpl<Scalar,Index>::expand(VectorType& vec, int& length, int nbElts, int keep_prev, int& num_expansions) Index SparseLUImpl<Scalar,Index>::expand(VectorType& vec, Index& length, Index nbElts, Index keep_prev, Index& num_expansions)
{ {
float alpha = 1.5; // Ratio of the memory increase float alpha = 1.5; // Ratio of the memory increase
int new_len; // New size of the allocated memory Index new_len; // New size of the allocated memory
if(num_expansions == 0 || keep_prev) if(num_expansions == 0 || keep_prev)
new_len = length ; // First time allocate requested new_len = length ; // First time allocate requested
@ -96,7 +96,7 @@ int SparseLUImpl<Scalar,Index>::expand(VectorType& vec, int& length, int nbElts
else else
{ {
// Reduce the size and increase again // Reduce the size and increase again
int tries = 0; // Number of attempts Index tries = 0; // Number of attempts
do do
{ {
alpha = (alpha + 1)/2; alpha = (alpha + 1)/2;
@ -136,9 +136,9 @@ int SparseLUImpl<Scalar,Index>::expand(VectorType& vec, int& length, int nbElts
* \note Unlike SuperLU, this routine does not support successive factorization with the same pattern and the same row permutation * \note Unlike SuperLU, this routine does not support successive factorization with the same pattern and the same row permutation
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
int SparseLUImpl<Scalar,Index>::memInit(int m, int n, int annz, int lwork, int fillratio, int panel_size, GlobalLU_t& glu) Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lwork, Index fillratio, Index panel_size, GlobalLU_t& glu)
{ {
int& num_expansions = glu.num_expansions; //No memory expansions so far Index& num_expansions = glu.num_expansions; //No memory expansions so far
num_expansions = 0; num_expansions = 0;
glu.nzumax = glu.nzlumax = (std::max)(fillratio * annz, m*n); // estimated number of nonzeros in U glu.nzumax = glu.nzlumax = (std::max)(fillratio * annz, m*n); // estimated number of nonzeros in U
glu.nzlmax = (std::max)(1., fillratio/4.) * annz; // estimated nnz in L factor glu.nzlmax = (std::max)(1., fillratio/4.) * annz; // estimated nnz in L factor
@ -148,7 +148,7 @@ int SparseLUImpl<Scalar,Index>::memInit(int m, int n, int annz, int lwork, int f
tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar); tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
if (lwork == emptyIdxLU) if (lwork == emptyIdxLU)
{ {
int estimated_size; Index estimated_size;
estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace estimated_size = (5 * n + 5) * sizeof(Index) + tempSpace
+ (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n; + (glu.nzlmax + glu.nzumax) * sizeof(Index) + (glu.nzlumax+glu.nzumax) * sizeof(Scalar) + n;
return estimated_size; return estimated_size;
@ -202,9 +202,9 @@ int SparseLUImpl<Scalar,Index>::memInit(int m, int n, int annz, int lwork, int f
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
template <typename VectorType> template <typename VectorType>
int SparseLUImpl<Scalar,Index>::memXpand(VectorType& vec, int& maxlen, int nbElts, MemType memtype, int& num_expansions) Index SparseLUImpl<Scalar,Index>::memXpand(VectorType& vec, Index& maxlen, Index nbElts, MemType memtype, Index& num_expansions)
{ {
int failed_size; Index failed_size;
if (memtype == USUB) if (memtype == USUB)
failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions); failed_size = this->expand<VectorType>(vec, maxlen, nbElts, 1, num_expansions);
else else

View File

@ -89,19 +89,20 @@ struct LU_GlobalLU_t {
IndexVector xusub; // Pointers to the beginning of each column of U in ucol IndexVector xusub; // Pointers to the beginning of each column of U in ucol
Index nzumax; // Current max size of ucol Index nzumax; // Current max size of ucol
Index n; // Number of columns in the matrix Index n; // Number of columns in the matrix
int num_expansions; Index num_expansions;
}; };
// Values to set for performance // Values to set for performance
template <typename Index>
struct perfvalues { struct perfvalues {
int panel_size; // a panel consists of at most <panel_size> consecutive columns Index panel_size; // a panel consists of at most <panel_size> consecutive columns
int relax; // To control degree of relaxing supernodes. If the number of nodes (columns) Index relax; // To control degree of relaxing supernodes. If the number of nodes (columns)
// in a subtree of the elimination tree is less than relax, this subtree is considered // in a subtree of the elimination tree is less than relax, this subtree is considered
// as one supernode regardless of the row structures of those columns // as one supernode regardless of the row structures of those columns
int maxsuper; // The maximum size for a supernode in complete LU Index maxsuper; // The maximum size for a supernode in complete LU
int rowblk; // The minimum row dimension for 2-D blocking to be used; Index rowblk; // The minimum row dimension for 2-D blocking to be used;
int colblk; // The minimum column dimension for 2-D blocking to be used; Index colblk; // The minimum column dimension for 2-D blocking to be used;
int fillfactor; // The estimated fills factors for L and U, compared with A Index fillfactor; // The estimated fills factors for L and U, compared with A
}; };
} // end namespace internal } // end namespace internal

View File

@ -42,7 +42,7 @@ class MappedSuperNodalMatrix
{ {
} }
MappedSuperNodalMatrix(int m, int n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind, MappedSuperNodalMatrix(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind,
IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col ) IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col )
{ {
setInfos(m, n, nzval, nzval_colptr, rowind, rowind_colptr, col_to_sup, sup_to_col); setInfos(m, n, nzval, nzval_colptr, rowind, rowind_colptr, col_to_sup, sup_to_col);
@ -58,7 +58,7 @@ class MappedSuperNodalMatrix
* FIXME This class will be modified such that it can be use in the course * FIXME This class will be modified such that it can be use in the course
* of the factorization. * of the factorization.
*/ */
void setInfos(int m, int n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind, void setInfos(Index m, Index n, ScalarVector& nzval, IndexVector& nzval_colptr, IndexVector& rowind,
IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col ) IndexVector& rowind_colptr, IndexVector& col_to_sup, IndexVector& sup_to_col )
{ {
m_row = m; m_row = m;
@ -75,12 +75,12 @@ class MappedSuperNodalMatrix
/** /**
* Number of rows * Number of rows
*/ */
int rows() { return m_row; } Index rows() { return m_row; }
/** /**
* Number of columns * Number of columns
*/ */
int cols() { return m_col; } Index cols() { return m_col; }
/** /**
* Return the array of nonzero values packed by column * Return the array of nonzero values packed by column
@ -148,7 +148,7 @@ class MappedSuperNodalMatrix
/** /**
* Return the number of supernodes * Return the number of supernodes
*/ */
int nsuper() const Index nsuper() const
{ {
return m_nsuper; return m_nsuper;
} }
@ -233,11 +233,11 @@ template<typename Dest>
void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) const void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) const
{ {
Index n = X.rows(); Index n = X.rows();
int nrhs = X.cols(); Index nrhs = X.cols();
const Scalar * Lval = valuePtr(); // Nonzero values const Scalar * Lval = valuePtr(); // Nonzero values
Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector
work.setZero(); work.setZero();
for (int k = 0; k <= nsuper(); k ++) for (Index k = 0; k <= nsuper(); k ++)
{ {
Index fsupc = supToCol()[k]; // First column of the current supernode Index fsupc = supToCol()[k]; // First column of the current supernode
Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column
@ -248,7 +248,7 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
if (nsupc == 1 ) if (nsupc == 1 )
{ {
for (int j = 0; j < nrhs; j++) for (Index j = 0; j < nrhs; j++)
{ {
InnerIterator it(*this, fsupc); InnerIterator it(*this, fsupc);
++it; // Skip the diagonal element ++it; // Skip the diagonal element
@ -275,10 +275,10 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
work.block(0, 0, nrow, nrhs) = A * U; work.block(0, 0, nrow, nrhs) = A * U;
//Begin Scatter //Begin Scatter
for (int j = 0; j < nrhs; j++) for (Index j = 0; j < nrhs; j++)
{ {
Index iptr = istart + nsupc; Index iptr = istart + nsupc;
for (int i = 0; i < nrow; i++) for (Index i = 0; i < nrow; i++)
{ {
irow = rowIndex()[iptr]; irow = rowIndex()[iptr];
X(irow, j) -= work(i, j); // Scatter operation X(irow, j) -= work(i, j); // Scatter operation

View File

@ -18,13 +18,13 @@ namespace internal {
* \brief Count Nonzero elements in the factors * \brief Count Nonzero elements in the factors
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::countnz(const int n, int& nnzL, int& nnzU, GlobalLU_t& glu) void SparseLUImpl<Scalar,Index>::countnz(const Index n, Index& nnzL, Index& nnzU, GlobalLU_t& glu)
{ {
nnzL = 0; nnzL = 0;
nnzU = (glu.xusub)(n); nnzU = (glu.xusub)(n);
int nsuper = (glu.supno)(n); Index nsuper = (glu.supno)(n);
int jlen; Index jlen;
int i, j, fsupc; Index i, j, fsupc;
if (n <= 0 ) return; if (n <= 0 ) return;
// For each supernode // For each supernode
for (i = 0; i <= nsuper; i++) for (i = 0; i <= nsuper; i++)
@ -49,12 +49,12 @@ void SparseLUImpl<Scalar,Index>::countnz(const int n, int& nnzL, int& nnzU, Glob
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::fixupL(const int n, const IndexVector& perm_r, GlobalLU_t& glu) void SparseLUImpl<Scalar,Index>::fixupL(const Index n, const IndexVector& perm_r, GlobalLU_t& glu)
{ {
int fsupc, i, j, k, jstart; Index fsupc, i, j, k, jstart;
int nextl = 0; Index nextl = 0;
int nsuper = (glu.supno)(n); Index nsuper = (glu.supno)(n);
// For each supernode // For each supernode
for (i = 0; i <= nsuper; i++) for (i = 0; i <= nsuper; i++)

View File

@ -50,11 +50,11 @@ namespace internal {
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
int SparseLUImpl<Scalar,Index>::column_bmod(const int jcol, const int nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, int fpanelc, GlobalLU_t& glu) Index SparseLUImpl<Scalar,Index>::column_bmod(const Index jcol, const Index nseg, BlockScalarVector dense, ScalarVector& tempv, BlockIndexVector segrep, BlockIndexVector repfnz, Index fpanelc, GlobalLU_t& glu)
{ {
int jsupno, k, ksub, krep, ksupno; Index jsupno, k, ksub, krep, ksupno;
int lptr, nrow, isub, irow, nextlu, new_next, ufirst; Index lptr, nrow, isub, irow, nextlu, new_next, ufirst;
int fsupc, nsupc, nsupr, luptr, kfnz, no_zeros; Index fsupc, nsupc, nsupr, luptr, kfnz, no_zeros;
/* krep = representative of current k-th supernode /* krep = representative of current k-th supernode
* fsupc = first supernodal column * fsupc = first supernodal column
* nsupc = number of columns in a supernode * nsupc = number of columns in a supernode
@ -67,10 +67,10 @@ int SparseLUImpl<Scalar,Index>::column_bmod(const int jcol, const int nseg, Bloc
jsupno = glu.supno(jcol); jsupno = glu.supno(jcol);
// For each nonzero supernode segment of U[*,j] in topological order // For each nonzero supernode segment of U[*,j] in topological order
k = nseg - 1; k = nseg - 1;
int d_fsupc; // distance between the first column of the current panel and the Index d_fsupc; // distance between the first column of the current panel and the
// first column of the current snode // first column of the current snode
int fst_col; // First column within small LU update Index fst_col; // First column within small LU update
int segsize; Index segsize;
for (ksub = 0; ksub < nseg; ksub++) for (ksub = 0; ksub < nseg; ksub++)
{ {
krep = segrep(k); k--; krep = segrep(k); k--;
@ -95,7 +95,7 @@ int SparseLUImpl<Scalar,Index>::column_bmod(const int jcol, const int nseg, Bloc
nsupc = krep - fst_col + 1; nsupc = krep - fst_col + 1;
nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc); nsupr = glu.xlsub(fsupc+1) - glu.xlsub(fsupc);
nrow = nsupr - d_fsupc - nsupc; nrow = nsupr - d_fsupc - nsupc;
int lda = glu.xlusup(fst_col+1) - glu.xlusup(fst_col); Index lda = glu.xlusup(fst_col+1) - glu.xlusup(fst_col);
// Perform a triangular solver and block update, // Perform a triangular solver and block update,
@ -113,9 +113,9 @@ int SparseLUImpl<Scalar,Index>::column_bmod(const int jcol, const int nseg, Bloc
fsupc = glu.xsup(jsupno); fsupc = glu.xsup(jsupno);
// copy the SPA dense into L\U[*,j] // copy the SPA dense into L\U[*,j]
int mem; Index mem;
new_next = nextlu + glu.xlsub(fsupc + 1) - glu.xlsub(fsupc); new_next = nextlu + glu.xlsub(fsupc + 1) - glu.xlsub(fsupc);
int offset = internal::first_multiple<Index>(new_next, internal::packet_traits<Scalar>::size) - new_next; Index offset = internal::first_multiple<Index>(new_next, internal::packet_traits<Scalar>::size) - new_next;
if(offset) if(offset)
new_next += offset; new_next += offset;
while (new_next > glu.nzlumax ) while (new_next > glu.nzlumax )
@ -161,7 +161,7 @@ int SparseLUImpl<Scalar,Index>::column_bmod(const int jcol, const int nseg, Bloc
// points to the beginning of jcol in snode L\U(jsupno) // points to the beginning of jcol in snode L\U(jsupno)
ufirst = glu.xlusup(jcol) + d_fsupc; ufirst = glu.xlusup(jcol) + d_fsupc;
int lda = glu.xlusup(jcol+1) - glu.xlusup(jcol); Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol);
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
VectorBlock<ScalarVector> u(glu.lusup, ufirst, nsupc); VectorBlock<ScalarVector> u(glu.lusup, ufirst, nsupc);
u = A.template triangularView<UnitLower>().solve(u); u = A.template triangularView<UnitLower>().solve(u);

View File

@ -47,7 +47,7 @@ struct column_dfs_traits
{ {
return true; return true;
} }
void mem_expand(IndexVector& lsub, int& nextl, int chmark) void mem_expand(IndexVector& lsub, Index& nextl, Index chmark)
{ {
if (nextl >= m_glu.nzlmax) if (nextl >= m_glu.nzlmax)
m_luImpl.memXpand(lsub, m_glu.nzlmax, nextl, LSUB, m_glu.num_expansions); m_luImpl.memXpand(lsub, m_glu.nzlmax, nextl, LSUB, m_glu.num_expansions);
@ -55,8 +55,8 @@ struct column_dfs_traits
} }
enum { ExpandMem = true }; enum { ExpandMem = true };
int m_jcol; Index m_jcol;
int& m_jsuper_ref; Index& m_jsuper_ref;
typename SparseLUImpl<Scalar, Index>::GlobalLU_t& m_glu; typename SparseLUImpl<Scalar, Index>::GlobalLU_t& m_glu;
SparseLUImpl<Scalar, Index>& m_luImpl; SparseLUImpl<Scalar, Index>& m_luImpl;
}; };
@ -90,22 +90,22 @@ struct column_dfs_traits
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
int SparseLUImpl<Scalar,Index>::column_dfs(const int m, const int jcol, IndexVector& perm_r, int maxsuper, int& nseg, BlockIndexVector lsub_col, IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu) Index SparseLUImpl<Scalar,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)
{ {
int jsuper = glu.supno(jcol); Index jsuper = glu.supno(jcol);
int nextl = glu.xlsub(jcol); Index nextl = glu.xlsub(jcol);
VectorBlock<IndexVector> marker2(marker, 2*m, m); VectorBlock<IndexVector> marker2(marker, 2*m, m);
column_dfs_traits<IndexVector, ScalarVector> traits(jcol, jsuper, glu, *this); column_dfs_traits<IndexVector, ScalarVector> traits(jcol, jsuper, glu, *this);
// For each nonzero in A(*,jcol) do dfs // For each nonzero in A(*,jcol) do dfs
for (int k = 0; lsub_col[k] != emptyIdxLU; k++) for (Index k = 0; lsub_col[k] != emptyIdxLU; k++)
{ {
int krow = lsub_col(k); Index krow = lsub_col(k);
lsub_col(k) = emptyIdxLU; lsub_col(k) = emptyIdxLU;
int kmark = marker2(krow); Index kmark = marker2(krow);
// krow was visited before, go to the next nonz; // krow was visited before, go to the next nonz;
if (kmark == jcol) continue; if (kmark == jcol) continue;
@ -114,10 +114,10 @@ int SparseLUImpl<Scalar,Index>::column_dfs(const int m, const int jcol, IndexVec
xplore, glu, nextl, krow, traits); xplore, glu, nextl, krow, traits);
} // for each nonzero ... } // for each nonzero ...
int fsupc, jptr, jm1ptr, ito, ifrom, istop; Index fsupc, jptr, jm1ptr, ito, ifrom, istop;
int nsuper = glu.supno(jcol); Index nsuper = glu.supno(jcol);
int jcolp1 = jcol + 1; Index jcolp1 = jcol + 1;
int jcolm1 = jcol - 1; Index jcolm1 = jcol - 1;
// check to see if j belongs in the same supernode as j-1 // check to see if j belongs in the same supernode as j-1
if ( jcol == 0 ) if ( jcol == 0 )

View File

@ -47,14 +47,14 @@ namespace internal {
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
int SparseLUImpl<Scalar,Index>::copy_to_ucol(const int jcol, const int nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu) Index SparseLUImpl<Scalar,Index>::copy_to_ucol(const Index jcol, const Index nseg, IndexVector& segrep, BlockIndexVector repfnz ,IndexVector& perm_r, BlockScalarVector dense, GlobalLU_t& glu)
{ {
Index ksub, krep, ksupno; Index ksub, krep, ksupno;
Index jsupno = glu.supno(jcol); Index jsupno = glu.supno(jcol);
// For each nonzero supernode segment of U[*,j] in topological order // For each nonzero supernode segment of U[*,j] in topological order
int k = nseg - 1, i; Index k = nseg - 1, i;
Index nextu = glu.xusub(jcol); Index nextu = glu.xusub(jcol);
Index kfnz, isub, segsize; Index kfnz, isub, segsize;
Index new_next,irow; Index new_next,irow;

View File

@ -43,14 +43,14 @@ namespace internal {
* \param relax_end last column in a supernode * \param relax_end last column in a supernode
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::heap_relax_snode (const int n, IndexVector& et, const int relax_columns, IndexVector& descendants, IndexVector& relax_end) void SparseLUImpl<Scalar,Index>::heap_relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
{ {
// The etree may not be postordered, but its heap ordered // The etree may not be postordered, but its heap ordered
IndexVector post; IndexVector post;
internal::treePostorder(n, et, post); // Post order etree internal::treePostorder(n, et, post); // Post order etree
IndexVector inv_post(n+1); IndexVector inv_post(n+1);
int i; Index i;
for (i = 0; i < n+1; ++i) inv_post(post(i)) = i; // inv_post = post.inverse()??? for (i = 0; i < n+1; ++i) inv_post(post(i)) = i; // inv_post = post.inverse()???
// Renumber etree in postorder // Renumber etree in postorder
@ -65,7 +65,7 @@ void SparseLUImpl<Scalar,Index>::heap_relax_snode (const int n, IndexVector& et,
// compute the number of descendants of each node in the etree // compute the number of descendants of each node in the etree
relax_end.setConstant(emptyIdxLU); relax_end.setConstant(emptyIdxLU);
int j, parent; Index j, parent;
descendants.setZero(); descendants.setZero();
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
{ {
@ -74,11 +74,11 @@ void SparseLUImpl<Scalar,Index>::heap_relax_snode (const int n, IndexVector& et,
descendants(parent) += descendants(j) + 1; descendants(parent) += descendants(j) + 1;
} }
// Identify the relaxed supernodes by postorder traversal of the etree // Identify the relaxed supernodes by postorder traversal of the etree
int snode_start; // beginning of a snode Index snode_start; // beginning of a snode
int k; Index k;
int nsuper_et_post = 0; // Number of relaxed snodes in postordered etree Index nsuper_et_post = 0; // Number of relaxed snodes in postordered etree
int nsuper_et = 0; // Number of relaxed snodes in the original etree Index nsuper_et = 0; // Number of relaxed snodes in the original etree
int l; Index l;
for (j = 0; j < n; ) for (j = 0; j < n; )
{ {
parent = et(j); parent = et(j);

View File

@ -30,15 +30,16 @@ namespace internal {
*/ */
template <int SegSizeAtCompileTime> struct LU_kernel_bmod template <int SegSizeAtCompileTime> struct LU_kernel_bmod
{ {
template <typename BlockScalarVector, typename ScalarVector, typename IndexVector> template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
EIGEN_DONT_INLINE static void run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, int& luptr, const int lda, const int nrow, IndexVector& lsub, const int lptr, const int no_zeros) EIGEN_DONT_INLINE static void run(const int segsize, BlockScalarVector& dense, ScalarVector& tempv, ScalarVector& lusup, Index& luptr, const Index lda, const Index nrow, IndexVector& lsub, const Index lptr, const Index no_zeros)
{ {
typedef typename ScalarVector::Scalar Scalar; typedef typename ScalarVector::Scalar Scalar;
// First, copy U[*,j] segment from dense(*) to tempv(*) // First, copy U[*,j] segment from dense(*) to tempv(*)
// The result of triangular solve is in tempv[*]; // The result of triangular solve is in tempv[*];
// The result of matric-vector update is in dense[*] // The result of matric-vector update is in dense[*]
int isub = lptr + no_zeros; Index isub = lptr + no_zeros;
int i, irow; int i;
Index irow;
for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++) for (i = 0; i < ((SegSizeAtCompileTime==Dynamic)?segsize:SegSizeAtCompileTime); i++)
{ {
irow = lsub(isub); irow = lsub(isub);
@ -55,11 +56,11 @@ template <int SegSizeAtCompileTime> struct LU_kernel_bmod
// Dense matrix-vector product y <-- B*x // Dense matrix-vector product y <-- B*x
luptr += segsize; luptr += segsize;
const int PacketSize = internal::packet_traits<Scalar>::size; const Index PacketSize = internal::packet_traits<Scalar>::size;
int ldl = internal::first_multiple(nrow, PacketSize); Index ldl = internal::first_multiple(nrow, PacketSize);
Map<Matrix<Scalar,Dynamic,SegSizeAtCompileTime>, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); Map<Matrix<Scalar,Dynamic,SegSizeAtCompileTime>, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) );
int aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize); Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize);
int aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize; Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize;
Map<Matrix<Scalar,Dynamic,1>, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) ); Map<Matrix<Scalar,Dynamic,1>, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) );
l.setZero(); l.setZero();
@ -84,20 +85,20 @@ template <int SegSizeAtCompileTime> struct LU_kernel_bmod
template <> struct LU_kernel_bmod<1> template <> struct LU_kernel_bmod<1>
{ {
template <typename BlockScalarVector, typename ScalarVector, typename IndexVector> template <typename BlockScalarVector, typename ScalarVector, typename IndexVector, typename Index>
EIGEN_DONT_INLINE static void run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, int& luptr, const int lda, const int nrow, EIGEN_DONT_INLINE static void run(const int /*segsize*/, BlockScalarVector& dense, ScalarVector& /*tempv*/, ScalarVector& lusup, Index& luptr, const Index lda, const Index nrow,
IndexVector& lsub, const int lptr, const int no_zeros) IndexVector& lsub, const Index lptr, const Index no_zeros)
{ {
typedef typename ScalarVector::Scalar Scalar; typedef typename ScalarVector::Scalar Scalar;
Scalar f = dense(lsub(lptr + no_zeros)); Scalar f = dense(lsub(lptr + no_zeros));
luptr += lda * no_zeros + no_zeros + 1; luptr += lda * no_zeros + no_zeros + 1;
const Scalar* a(lusup.data() + luptr); const Scalar* a(lusup.data() + luptr);
const typename IndexVector::Scalar* irow(lsub.data()+lptr + no_zeros + 1); const /*typename IndexVector::Scalar*/Index* irow(lsub.data()+lptr + no_zeros + 1);
int i = 0; Index i = 0;
for (; i+1 < nrow; i+=2) for (; i+1 < nrow; i+=2)
{ {
int i0 = *(irow++); Index i0 = *(irow++);
int i1 = *(irow++); Index i1 = *(irow++);
Scalar a0 = *(a++); Scalar a0 = *(a++);
Scalar a1 = *(a++); Scalar a1 = *(a++);
Scalar d0 = dense.coeff(i0); Scalar d0 = dense.coeff(i0);

View File

@ -53,19 +53,19 @@ namespace internal {
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int jcol, void SparseLUImpl<Scalar,Index>::panel_bmod(const Index m, const Index w, const Index jcol,
const int nseg, ScalarVector& dense, ScalarVector& tempv, const Index nseg, ScalarVector& dense, ScalarVector& tempv,
IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu) IndexVector& segrep, IndexVector& repfnz, GlobalLU_t& glu)
{ {
int ksub,jj,nextl_col; Index ksub,jj,nextl_col;
int fsupc, nsupc, nsupr, nrow; Index fsupc, nsupc, nsupr, nrow;
int krep, kfnz; Index krep, kfnz;
int lptr; // points to the row subscripts of a supernode Index lptr; // points to the row subscripts of a supernode
int luptr; // ... Index luptr; // ...
int segsize,no_zeros ; Index segsize,no_zeros ;
// For each nonz supernode segment of U[*,j] in topological order // For each nonz supernode segment of U[*,j] in topological order
int k = nseg - 1; Index k = nseg - 1;
const Index PacketSize = internal::packet_traits<Scalar>::size; const Index PacketSize = internal::packet_traits<Scalar>::size;
for (ksub = 0; ksub < nseg; ksub++) for (ksub = 0; ksub < nseg; ksub++)
@ -83,8 +83,8 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
lptr = glu.xlsub(fsupc); lptr = glu.xlsub(fsupc);
// loop over the panel columns to detect the actual number of columns and rows // loop over the panel columns to detect the actual number of columns and rows
int u_rows = 0; Index u_rows = 0;
int u_cols = 0; Index u_cols = 0;
for (jj = jcol; jj < jcol + w; jj++) for (jj = jcol; jj < jcol + w; jj++)
{ {
nextl_col = (jj-jcol) * m; nextl_col = (jj-jcol) * m;
@ -101,11 +101,11 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
if(nsupc >= 2) if(nsupc >= 2)
{ {
int ldu = internal::first_multiple<Index>(u_rows, PacketSize); Index ldu = internal::first_multiple<Index>(u_rows, PacketSize);
Map<Matrix<Scalar,Dynamic,Dynamic>, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); Map<Matrix<Scalar,Dynamic,Dynamic>, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu));
// gather U // gather U
int u_col = 0; Index u_col = 0;
for (jj = jcol; jj < jcol + w; jj++) for (jj = jcol; jj < jcol + w; jj++)
{ {
nextl_col = (jj-jcol) * m; nextl_col = (jj-jcol) * m;
@ -120,12 +120,12 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
luptr = glu.xlusup(fsupc); luptr = glu.xlusup(fsupc);
no_zeros = kfnz - fsupc; no_zeros = kfnz - fsupc;
int isub = lptr + no_zeros; Index isub = lptr + no_zeros;
int off = u_rows-segsize; Index off = u_rows-segsize;
for (int i = 0; i < off; i++) U(i,u_col) = 0; for (Index i = 0; i < off; i++) U(i,u_col) = 0;
for (int i = 0; i < segsize; i++) for (Index i = 0; i < segsize; i++)
{ {
int irow = glu.lsub(isub); Index irow = glu.lsub(isub);
U(i+off,u_col) = dense_col(irow); U(i+off,u_col) = dense_col(irow);
++isub; ++isub;
} }
@ -133,7 +133,7 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
} }
// solve U = A^-1 U // solve U = A^-1 U
luptr = glu.xlusup(fsupc); luptr = glu.xlusup(fsupc);
int lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc);
no_zeros = (krep - u_rows + 1) - fsupc; no_zeros = (krep - u_rows + 1) - fsupc;
luptr += lda * no_zeros + no_zeros; luptr += lda * no_zeros + no_zeros;
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) );
@ -144,8 +144,8 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) );
eigen_assert(tempv.size()>w*ldu + nrow*w + 1); eigen_assert(tempv.size()>w*ldu + nrow*w + 1);
int ldl = internal::first_multiple<Index>(nrow, PacketSize); Index ldl = internal::first_multiple<Index>(nrow, PacketSize);
int offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize; Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize;
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl));
L.setZero(); L.setZero();
@ -165,20 +165,20 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
segsize = krep - kfnz + 1; segsize = krep - kfnz + 1;
no_zeros = kfnz - fsupc; no_zeros = kfnz - fsupc;
int isub = lptr + no_zeros; Index isub = lptr + no_zeros;
int off = u_rows-segsize; Index off = u_rows-segsize;
for (int i = 0; i < segsize; i++) for (Index i = 0; i < segsize; i++)
{ {
int irow = glu.lsub(isub++); Index irow = glu.lsub(isub++);
dense_col(irow) = U.coeff(i+off,u_col); dense_col(irow) = U.coeff(i+off,u_col);
U.coeffRef(i+off,u_col) = 0; U.coeffRef(i+off,u_col) = 0;
} }
// Scatter l into SPA dense[] // Scatter l into SPA dense[]
for (int i = 0; i < nrow; i++) for (Index i = 0; i < nrow; i++)
{ {
int irow = glu.lsub(isub++); Index irow = glu.lsub(isub++);
dense_col(irow) -= L.coeff(i,u_col); dense_col(irow) -= L.coeff(i,u_col);
L.coeffRef(i,u_col) = 0; L.coeffRef(i,u_col) = 0;
} }
@ -201,7 +201,7 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const int m, const int w, const int
segsize = krep - kfnz + 1; segsize = krep - kfnz + 1;
luptr = glu.xlusup(fsupc); luptr = glu.xlusup(fsupc);
int lda = glu.xlusup(fsupc+1)-glu.xlusup(fsupc);// nsupr Index lda = glu.xlusup(fsupc+1)-glu.xlusup(fsupc);// nsupr
// Perform a trianglar solve and block update, // Perform a trianglar solve and block update,
// then scatter the result of sup-col update to dense[] // then scatter the result of sup-col update to dense[]

View File

@ -50,7 +50,7 @@ struct panel_dfs_traits
} }
return false; return false;
} }
void mem_expand(IndexVector& /*glu.lsub*/, int /*nextl*/, int /*chmark*/) {} void mem_expand(IndexVector& /*glu.lsub*/, Index /*nextl*/, Index /*chmark*/) {}
enum { ExpandMem = false }; enum { ExpandMem = false };
Index m_jcol; Index m_jcol;
Index* m_marker; Index* m_marker;
@ -59,19 +59,19 @@ struct panel_dfs_traits
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
template <typename Traits> template <typename Traits>
void SparseLUImpl<Scalar,Index>::dfs_kernel(const int jj, IndexVector& perm_r, void SparseLUImpl<Scalar,Index>::dfs_kernel(const Index jj, IndexVector& perm_r,
int& nseg, IndexVector& panel_lsub, IndexVector& segrep, Index& nseg, IndexVector& panel_lsub, IndexVector& segrep,
Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent, Ref<IndexVector> repfnz_col, IndexVector& xprune, Ref<IndexVector> marker, IndexVector& parent,
IndexVector& xplore, GlobalLU_t& glu, IndexVector& xplore, GlobalLU_t& glu,
int& nextl_col, int krow, Traits& traits Index& nextl_col, Index krow, Traits& traits
) )
{ {
int kmark = marker(krow); Index kmark = marker(krow);
// For each unmarked krow of jj // For each unmarked krow of jj
marker(krow) = jj; marker(krow) = jj;
int kperm = perm_r(krow); Index kperm = perm_r(krow);
if (kperm == emptyIdxLU ) { if (kperm == emptyIdxLU ) {
// krow is in L : place it in structure of L(*, jj) // krow is in L : place it in structure of L(*, jj)
panel_lsub(nextl_col++) = krow; // krow is indexed into A panel_lsub(nextl_col++) = krow; // krow is indexed into A
@ -83,9 +83,9 @@ void SparseLUImpl<Scalar,Index>::dfs_kernel(const int jj, IndexVector& perm_r,
// krow is in U : if its supernode-representative krep // krow is in U : if its supernode-representative krep
// has been explored, update repfnz(*) // has been explored, update repfnz(*)
// krep = supernode representative of the current row // krep = supernode representative of the current row
int krep = glu.xsup(glu.supno(kperm)+1) - 1; Index krep = glu.xsup(glu.supno(kperm)+1) - 1;
// First nonzero element in the current column: // First nonzero element in the current column:
int myfnz = repfnz_col(krep); Index myfnz = repfnz_col(krep);
if (myfnz != emptyIdxLU ) if (myfnz != emptyIdxLU )
{ {
@ -96,26 +96,26 @@ void SparseLUImpl<Scalar,Index>::dfs_kernel(const int jj, IndexVector& perm_r,
else else
{ {
// Otherwise, perform dfs starting at krep // Otherwise, perform dfs starting at krep
int oldrep = emptyIdxLU; Index oldrep = emptyIdxLU;
parent(krep) = oldrep; parent(krep) = oldrep;
repfnz_col(krep) = kperm; repfnz_col(krep) = kperm;
int xdfs = glu.xlsub(krep); Index xdfs = glu.xlsub(krep);
int maxdfs = xprune(krep); Index maxdfs = xprune(krep);
int kpar; Index kpar;
do do
{ {
// For each unmarked kchild of krep // For each unmarked kchild of krep
while (xdfs < maxdfs) while (xdfs < maxdfs)
{ {
int kchild = glu.lsub(xdfs); Index kchild = glu.lsub(xdfs);
xdfs++; xdfs++;
int chmark = marker(kchild); Index chmark = marker(kchild);
if (chmark != jj ) if (chmark != jj )
{ {
marker(kchild) = jj; marker(kchild) = jj;
int chperm = perm_r(kchild); Index chperm = perm_r(kchild);
if (chperm == emptyIdxLU) if (chperm == emptyIdxLU)
{ {
@ -128,7 +128,7 @@ void SparseLUImpl<Scalar,Index>::dfs_kernel(const int jj, IndexVector& perm_r,
// case kchild is in U : // case kchild is in U :
// chrep = its supernode-rep. If its rep has been explored, // chrep = its supernode-rep. If its rep has been explored,
// update its repfnz(*) // update its repfnz(*)
int chrep = glu.xsup(glu.supno(chperm)+1) - 1; Index chrep = glu.xsup(glu.supno(chperm)+1) - 1;
myfnz = repfnz_col(chrep); myfnz = repfnz_col(chrep);
if (myfnz != emptyIdxLU) if (myfnz != emptyIdxLU)
@ -216,9 +216,9 @@ void SparseLUImpl<Scalar,Index>::dfs_kernel(const int jj, IndexVector& perm_r,
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::panel_dfs(const int m, const int w, const int jcol, MatrixType& A, IndexVector& perm_r, int& nseg, ScalarVector& dense, IndexVector& panel_lsub, IndexVector& segrep, IndexVector& repfnz, IndexVector& xprune, IndexVector& marker, IndexVector& parent, IndexVector& xplore, GlobalLU_t& glu) void SparseLUImpl<Scalar,Index>::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)
{ {
int nextl_col; // Next available position in panel_lsub[*,jj] Index nextl_col; // Next available position in panel_lsub[*,jj]
// Initialize pointers // Initialize pointers
VectorBlock<IndexVector> marker1(marker, m, m); VectorBlock<IndexVector> marker1(marker, m, m);
@ -227,7 +227,7 @@ void SparseLUImpl<Scalar,Index>::panel_dfs(const int m, const int w, const int j
panel_dfs_traits<IndexVector> traits(jcol, marker1.data()); panel_dfs_traits<IndexVector> traits(jcol, marker1.data());
// For each column in the panel // For each column in the panel
for (int jj = jcol; jj < jcol + w; jj++) for (Index jj = jcol; jj < jcol + w; jj++)
{ {
nextl_col = (jj - jcol) * m; nextl_col = (jj - jcol) * m;
@ -238,10 +238,10 @@ void SparseLUImpl<Scalar,Index>::panel_dfs(const int m, const int w, const int j
// For each nnz in A[*, jj] do depth first search // For each nnz in A[*, jj] do depth first search
for (typename MatrixType::InnerIterator it(A, jj); it; ++it) for (typename MatrixType::InnerIterator it(A, jj); it; ++it)
{ {
int krow = it.row(); Index krow = it.row();
dense_col(krow) = it.value(); dense_col(krow) = it.value();
int kmark = marker(krow); Index kmark = marker(krow);
if (kmark == jj) if (kmark == jj)
continue; // krow visited before, go to the next nonzero continue; // krow visited before, go to the next nonzero

View File

@ -57,7 +57,7 @@ namespace internal {
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
int SparseLUImpl<Scalar,Index>::pivotL(const int jcol, const RealScalar diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, int& pivrow, GlobalLU_t& glu) Index SparseLUImpl<Scalar,Index>::pivotL(const Index jcol, const RealScalar diagpivotthresh, IndexVector& perm_r, IndexVector& iperm_c, Index& pivrow, GlobalLU_t& glu)
{ {
Index fsupc = (glu.xsup)((glu.supno)(jcol)); // First column in the supernode containing the column jcol Index fsupc = (glu.xsup)((glu.supno)(jcol)); // First column in the supernode containing the column jcol

View File

@ -50,11 +50,11 @@ namespace internal {
* *
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::pruneL(const int jcol, const IndexVector& perm_r, const int pivrow, const int nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu) void SparseLUImpl<Scalar,Index>::pruneL(const Index jcol, const IndexVector& perm_r, const Index pivrow, const Index nseg, const IndexVector& segrep, BlockIndexVector repfnz, IndexVector& xprune, GlobalLU_t& glu)
{ {
// For each supernode-rep irep in U(*,j] // For each supernode-rep irep in U(*,j]
int jsupno = glu.supno(jcol); Index jsupno = glu.supno(jcol);
int i,irep,irep1; Index i,irep,irep1;
bool movnum, do_prune = false; bool movnum, do_prune = false;
Index kmin, kmax, minloc, maxloc,krow; Index kmin, kmax, minloc, maxloc,krow;
for (i = 0; i < nseg; i++) for (i = 0; i < nseg; i++)

View File

@ -44,11 +44,11 @@ namespace internal {
* \param relax_end last column in a supernode * \param relax_end last column in a supernode
*/ */
template <typename Scalar, typename Index> template <typename Scalar, typename Index>
void SparseLUImpl<Scalar,Index>::relax_snode (const int n, IndexVector& et, const int relax_columns, IndexVector& descendants, IndexVector& relax_end) void SparseLUImpl<Scalar,Index>::relax_snode (const Index n, IndexVector& et, const Index relax_columns, IndexVector& descendants, IndexVector& relax_end)
{ {
// compute the number of descendants of each node in the etree // compute the number of descendants of each node in the etree
int j, parent; Index j, parent;
relax_end.setConstant(emptyIdxLU); relax_end.setConstant(emptyIdxLU);
descendants.setZero(); descendants.setZero();
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
@ -58,7 +58,7 @@ void SparseLUImpl<Scalar,Index>::relax_snode (const int n, IndexVector& et, cons
descendants(parent) += descendants(j) + 1; descendants(parent) += descendants(j) + 1;
} }
// Identify the relaxed supernodes by postorder traversal of the etree // Identify the relaxed supernodes by postorder traversal of the etree
int snode_start; // beginning of a snode Index snode_start; // beginning of a snode
for (j = 0; j < n; ) for (j = 0; j < n; )
{ {
parent = et(j); parent = et(j);

View File

@ -29,9 +29,11 @@ template<typename T> void test_sparselu_T()
{ {
SparseLU<SparseMatrix<T, ColMajor>, COLAMDOrdering<int> > sparselu_colamd; SparseLU<SparseMatrix<T, ColMajor>, COLAMDOrdering<int> > sparselu_colamd;
SparseLU<SparseMatrix<T, ColMajor>, AMDOrdering<int> > sparselu_amd; SparseLU<SparseMatrix<T, ColMajor>, AMDOrdering<int> > sparselu_amd;
SparseLU<SparseMatrix<T, ColMajor, long int>, NaturalOrdering<long int> > sparselu_natural;
check_sparse_square_solving(sparselu_colamd); check_sparse_square_solving(sparselu_colamd);
check_sparse_square_solving(sparselu_amd); check_sparse_square_solving(sparselu_amd);
check_sparse_square_solving(sparselu_natural);
} }
void test_sparselu() void test_sparselu()