mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-25 22:34:30 +08:00
Change int to Index type for SparseLU
This commit is contained in:
parent
57e50789f3
commit
8bc00925e5
@ -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--)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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++)
|
||||||
|
@ -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);
|
||||||
|
@ -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 )
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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[]
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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++)
|
||||||
|
@ -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);
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user