More colamd cleanup:

- Move colamd implementation in its own namespace to avoid polluting the internal namespace with Ok, Status, etc.
- Fix signed/unsigned warning
- move some ugly free functions as member functions
This commit is contained in:
Gael Guennebaud 2019-09-03 00:50:51 +02:00
parent a4d1a6cd7d
commit 15f3d9d272
2 changed files with 158 additions and 187 deletions

View File

@ -47,25 +47,26 @@
#ifndef EIGEN_COLAMD_H #ifndef EIGEN_COLAMD_H
#define EIGEN_COLAMD_H #define EIGEN_COLAMD_H
/* ========================================================================== */
/* === Knob and statistics definitions used elsewhere ======================= */
/* ========================================================================== */
/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */
const size_t ColamdKnobs = 20;
/* number of output statistics. Only stats [0..6] are currently used. */
const size_t ColamdStats = 20;
namespace internal { namespace internal {
namespace Colamd {
/* Ensure that debugging is turned off: */ /* Ensure that debugging is turned off: */
#ifndef COLAMD_NDEBUG #ifndef COLAMD_NDEBUG
#define COLAMD_NDEBUG #define COLAMD_NDEBUG
#endif /* NDEBUG */ #endif /* NDEBUG */
/* ========================================================================== */ /* ========================================================================== */
/* === Knob and statistics definitions ====================================== */ /* === Knob and statistics definitions ====================================== */
/* ========================================================================== */ /* ========================================================================== */
/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */
const int NKnobs = 20;
/* number of output statistics. Only stats [0..6] are currently used. */
const int NStats = 20;
/* Indices into knobs and stats array. */ /* Indices into knobs and stats array. */
enum KnobsStatsIndex { enum KnobsStatsIndex {
/* knobs [0] and stats [0]: dense row knob and output statistic. */ /* knobs [0] and stats [0]: dense row knob and output statistic. */
@ -132,7 +133,7 @@ enum ColumnStatus {
// == Row and Column structures == // == Row and Column structures ==
template <typename IndexType> template <typename IndexType>
struct colamd_col struct ColStructure
{ {
IndexType start ; /* index for A of first row in this column, or Dead */ IndexType start ; /* index for A of first row in this column, or Dead */
/* if column is dead */ /* if column is dead */
@ -163,10 +164,20 @@ struct colamd_col
IndexType hash_next ; /* next column, if col is in a hash list */ IndexType hash_next ; /* next column, if col is in a hash list */
} shared4 ; } shared4 ;
inline bool is_dead() const { return start < Alive; }
inline bool is_alive() const { return start >= Alive; }
inline bool is_dead_principal() const { return start == DeadPrincipal; }
inline void kill_principal() { start = DeadPrincipal; }
inline void kill_non_principal() { start = DeadNonPrincipal; }
}; };
template <typename IndexType> template <typename IndexType>
struct Colamd_Row struct RowStructure
{ {
IndexType start ; /* index for A of first col in this row */ IndexType start ; /* index for A of first col in this row */
IndexType length ; /* number of principal columns in this row */ IndexType length ; /* number of principal columns in this row */
@ -181,54 +192,14 @@ struct Colamd_Row
IndexType first_column ;/* first column in row (used in garbage collection) */ IndexType first_column ;/* first column in row (used in garbage collection) */
} shared2 ; } shared2 ;
inline bool is_dead() const { return shared2.mark < Alive; }
inline bool is_alive() const { return shared2.mark >= Alive; }
inline void kill() { shared2.mark = Dead; }
}; };
/* Methods for row and column status update and checking. */
template <typename IndexType>
bool row_is_marked_dead(const IndexType row_mark) {
return row_mark < Alive;
}
template <typename IndexType>
bool row_is_dead(const Colamd_Row<IndexType>* row, const IndexType r) {
return row_is_marked_dead(row[r].shared2.mark);
}
template <typename IndexType>
bool row_is_alive(const Colamd_Row<IndexType>* row, const IndexType r) {
return row[r].shared2.mark >= Alive;
}
template <typename IndexType>
void kill_row(Colamd_Row<IndexType>* row, const IndexType r) {
row[r].shared2.mark = Dead;
}
template <typename IndexType>
bool col_is_dead(const colamd_col<IndexType>* col, const IndexType c) {
return col[c].start < Alive;
}
template <typename IndexType>
bool col_is_alive(const colamd_col<IndexType>* col, const IndexType c) {
return col[c].start >= Alive;
}
template <typename IndexType>
bool col_is_dead_principal(const colamd_col<IndexType>* col, const IndexType c) {
return col[c].start == DeadPrincipal;
}
template <typename IndexType>
void kill_principal_col(colamd_col<IndexType>* col, const IndexType c) {
col[c].start = DeadPrincipal;
}
template <typename IndexType>
void kill_non_principal_col(colamd_col<IndexType>* col, const IndexType c) {
col[c].start = DeadNonPrincipal;
}
/* ========================================================================== */ /* ========================================================================== */
/* === Colamd recommended memory size ======================================= */ /* === Colamd recommended memory size ======================================= */
/* ========================================================================== */ /* ========================================================================== */
@ -249,33 +220,33 @@ void kill_non_principal_col(colamd_col<IndexType>* col, const IndexType c) {
*/ */
template <typename IndexType> template <typename IndexType>
inline IndexType colamd_c(IndexType n_col) inline IndexType colamd_c(IndexType n_col)
{ return IndexType( ((n_col) + 1) * sizeof (colamd_col<IndexType>) / sizeof (IndexType) ) ; } { return IndexType( ((n_col) + 1) * sizeof (ColStructure<IndexType>) / sizeof (IndexType) ) ; }
template <typename IndexType> template <typename IndexType>
inline IndexType colamd_r(IndexType n_row) inline IndexType colamd_r(IndexType n_row)
{ return IndexType(((n_row) + 1) * sizeof (Colamd_Row<IndexType>) / sizeof (IndexType)); } { return IndexType(((n_row) + 1) * sizeof (RowStructure<IndexType>) / sizeof (IndexType)); }
// Prototypes of non-user callable routines // Prototypes of non-user callable routines
template <typename IndexType> template <typename IndexType>
static IndexType init_rows_cols (IndexType n_row, IndexType n_col, Colamd_Row<IndexType> Row [], colamd_col<IndexType> col [], IndexType A [], IndexType p [], IndexType stats[ColamdStats] ); static IndexType init_rows_cols (IndexType n_row, IndexType n_col, RowStructure<IndexType> Row [], ColStructure<IndexType> col [], IndexType A [], IndexType p [], IndexType stats[NStats] );
template <typename IndexType> template <typename IndexType>
static void init_scoring (IndexType n_row, IndexType n_col, Colamd_Row<IndexType> Row [], colamd_col<IndexType> Col [], IndexType A [], IndexType head [], double knobs[ColamdKnobs], IndexType *p_n_row2, IndexType *p_n_col2, IndexType *p_max_deg); static void init_scoring (IndexType n_row, IndexType n_col, RowStructure<IndexType> Row [], ColStructure<IndexType> Col [], IndexType A [], IndexType head [], double knobs[NKnobs], IndexType *p_n_row2, IndexType *p_n_col2, IndexType *p_max_deg);
template <typename IndexType> template <typename IndexType>
static IndexType find_ordering (IndexType n_row, IndexType n_col, IndexType Alen, Colamd_Row<IndexType> Row [], colamd_col<IndexType> Col [], IndexType A [], IndexType head [], IndexType n_col2, IndexType max_deg, IndexType pfree); static IndexType find_ordering (IndexType n_row, IndexType n_col, IndexType Alen, RowStructure<IndexType> Row [], ColStructure<IndexType> Col [], IndexType A [], IndexType head [], IndexType n_col2, IndexType max_deg, IndexType pfree);
template <typename IndexType> template <typename IndexType>
static void order_children (IndexType n_col, colamd_col<IndexType> Col [], IndexType p []); static void order_children (IndexType n_col, ColStructure<IndexType> Col [], IndexType p []);
template <typename IndexType> template <typename IndexType>
static void detect_super_cols (colamd_col<IndexType> Col [], IndexType A [], IndexType head [], IndexType row_start, IndexType row_length ) ; static void detect_super_cols (ColStructure<IndexType> Col [], IndexType A [], IndexType head [], IndexType row_start, IndexType row_length ) ;
template <typename IndexType> template <typename IndexType>
static IndexType garbage_collection (IndexType n_row, IndexType n_col, Colamd_Row<IndexType> Row [], colamd_col<IndexType> Col [], IndexType A [], IndexType *pfree) ; static IndexType garbage_collection (IndexType n_row, IndexType n_col, RowStructure<IndexType> Row [], ColStructure<IndexType> Col [], IndexType A [], IndexType *pfree) ;
template <typename IndexType> template <typename IndexType>
static inline IndexType clear_mark (IndexType n_row, Colamd_Row<IndexType> Row [] ) ; static inline IndexType clear_mark (IndexType n_row, RowStructure<IndexType> Row [] ) ;
/* === No debugging ========================================================= */ /* === No debugging ========================================================= */
@ -303,7 +274,7 @@ static inline IndexType clear_mark (IndexType n_row, Colamd_Row<IndexType> Row
* \return recommended value of Alen for use by colamd * \return recommended value of Alen for use by colamd
*/ */
template <typename IndexType> template <typename IndexType>
inline IndexType colamd_recommended ( IndexType nnz, IndexType n_row, IndexType n_col) inline IndexType recommended ( IndexType nnz, IndexType n_row, IndexType n_col)
{ {
if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0) if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0)
return (-1); return (-1);
@ -332,7 +303,7 @@ inline IndexType colamd_recommended ( IndexType nnz, IndexType n_row, IndexType
* \param knobs parameter settings for colamd * \param knobs parameter settings for colamd
*/ */
static inline void colamd_set_defaults(double knobs[ColamdKnobs]) static inline void set_defaults(double knobs[NKnobs])
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
@ -342,12 +313,12 @@ static inline void colamd_set_defaults(double knobs[ColamdKnobs])
{ {
return ; /* no knobs to initialize */ return ; /* no knobs to initialize */
} }
for (i = 0 ; i < ColamdKnobs ; i++) for (i = 0 ; i < NKnobs ; i++)
{ {
knobs [i] = 0 ; knobs [i] = 0 ;
} }
knobs [DenseRow] = 0.5 ; /* ignore rows over 50% dense */ knobs [Colamd::DenseRow] = 0.5 ; /* ignore rows over 50% dense */
knobs [DenseCol] = 0.5 ; /* ignore columns over 50% dense */ knobs [Colamd::DenseCol] = 0.5 ; /* ignore columns over 50% dense */
} }
/** /**
@ -368,7 +339,7 @@ static inline void colamd_set_defaults(double knobs[ColamdKnobs])
* \param stats colamd output statistics and error codes * \param stats colamd output statistics and error codes
*/ */
template <typename IndexType> template <typename IndexType>
static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *A, IndexType *p, double knobs[ColamdKnobs], IndexType stats[ColamdStats]) static bool compute_ordering(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *A, IndexType *p, double knobs[NKnobs], IndexType stats[NStats])
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
@ -377,13 +348,13 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
IndexType Row_size ; /* size of Row [], in integers */ IndexType Row_size ; /* size of Row [], in integers */
IndexType Col_size ; /* size of Col [], in integers */ IndexType Col_size ; /* size of Col [], in integers */
IndexType need ; /* minimum required length of A */ IndexType need ; /* minimum required length of A */
Colamd_Row<IndexType> *Row ; /* pointer into A of Row [0..n_row] array */ Colamd::RowStructure<IndexType> *Row ; /* pointer into A of Row [0..n_row] array */
colamd_col<IndexType> *Col ; /* pointer into A of Col [0..n_col] array */ Colamd::ColStructure<IndexType> *Col ; /* pointer into A of Col [0..n_col] array */
IndexType n_col2 ; /* number of non-dense, non-empty columns */ IndexType n_col2 ; /* number of non-dense, non-empty columns */
IndexType n_row2 ; /* number of non-dense, non-empty rows */ IndexType n_row2 ; /* number of non-dense, non-empty rows */
IndexType ngarbage ; /* number of garbage collections performed */ IndexType ngarbage ; /* number of garbage collections performed */
IndexType max_deg ; /* maximum row degree */ IndexType max_deg ; /* maximum row degree */
double default_knobs [ColamdKnobs] ; /* default knobs array */ double default_knobs [NKnobs] ; /* default knobs array */
/* === Check the input arguments ======================================== */ /* === Check the input arguments ======================================== */
@ -393,40 +364,40 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
COLAMD_DEBUG0 (("colamd: stats not present\n")) ; COLAMD_DEBUG0 (("colamd: stats not present\n")) ;
return (false) ; return (false) ;
} }
for (i = 0 ; i < ColamdStats ; i++) for (i = 0 ; i < NStats ; i++)
{ {
stats [i] = 0 ; stats [i] = 0 ;
} }
stats [Status] = Ok ; stats [Colamd::Status] = Colamd::Ok ;
stats [Info1] = -1 ; stats [Colamd::Info1] = -1 ;
stats [Info2] = -1 ; stats [Colamd::Info2] = -1 ;
if (!A) /* A is not present */ if (!A) /* A is not present */
{ {
stats [Status] = ErrorANotPresent ; stats [Colamd::Status] = Colamd::ErrorANotPresent ;
COLAMD_DEBUG0 (("colamd: A not present\n")) ; COLAMD_DEBUG0 (("colamd: A not present\n")) ;
return (false) ; return (false) ;
} }
if (!p) /* p is not present */ if (!p) /* p is not present */
{ {
stats [Status] = ErrorPNotPresent ; stats [Colamd::Status] = Colamd::ErrorPNotPresent ;
COLAMD_DEBUG0 (("colamd: p not present\n")) ; COLAMD_DEBUG0 (("colamd: p not present\n")) ;
return (false) ; return (false) ;
} }
if (n_row < 0) /* n_row must be >= 0 */ if (n_row < 0) /* n_row must be >= 0 */
{ {
stats [Status] = ErrorNrowNegative ; stats [Colamd::Status] = Colamd::ErrorNrowNegative ;
stats [Info1] = n_row ; stats [Colamd::Info1] = n_row ;
COLAMD_DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; COLAMD_DEBUG0 (("colamd: nrow negative %d\n", n_row)) ;
return (false) ; return (false) ;
} }
if (n_col < 0) /* n_col must be >= 0 */ if (n_col < 0) /* n_col must be >= 0 */
{ {
stats [Status] = ErrorNcolNegative ; stats [Colamd::Status] = Colamd::ErrorNcolNegative ;
stats [Info1] = n_col ; stats [Colamd::Info1] = n_col ;
COLAMD_DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; COLAMD_DEBUG0 (("colamd: ncol negative %d\n", n_col)) ;
return (false) ; return (false) ;
} }
@ -434,16 +405,16 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
nnz = p [n_col] ; nnz = p [n_col] ;
if (nnz < 0) /* nnz must be >= 0 */ if (nnz < 0) /* nnz must be >= 0 */
{ {
stats [Status] = ErrorNnzNegative ; stats [Colamd::Status] = Colamd::ErrorNnzNegative ;
stats [Info1] = nnz ; stats [Colamd::Info1] = nnz ;
COLAMD_DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; COLAMD_DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ;
return (false) ; return (false) ;
} }
if (p [0] != 0) if (p [0] != 0)
{ {
stats [Status] = ErrorP0Nonzero ; stats [Colamd::Status] = Colamd::ErrorP0Nonzero ;
stats [Info1] = p [0] ; stats [Colamd::Info1] = p [0] ;
COLAMD_DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; COLAMD_DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ;
return (false) ; return (false) ;
} }
@ -452,7 +423,7 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
if (!knobs) if (!knobs)
{ {
colamd_set_defaults (default_knobs) ; set_defaults (default_knobs) ;
knobs = default_knobs ; knobs = default_knobs ;
} }
@ -465,20 +436,20 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
if (need > Alen) if (need > Alen)
{ {
/* not enough space in array A to perform the ordering */ /* not enough space in array A to perform the ordering */
stats [Status] = ErrorATooSmall ; stats [Colamd::Status] = Colamd::ErrorATooSmall ;
stats [Info1] = need ; stats [Colamd::Info1] = need ;
stats [Info2] = Alen ; stats [Colamd::Info2] = Alen ;
COLAMD_DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); COLAMD_DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen));
return (false) ; return (false) ;
} }
Alen -= Col_size + Row_size ; Alen -= Col_size + Row_size ;
Col = (colamd_col<IndexType> *) &A [Alen] ; Col = (ColStructure<IndexType> *) &A [Alen] ;
Row = (Colamd_Row<IndexType> *) &A [Alen + Col_size] ; Row = (RowStructure<IndexType> *) &A [Alen + Col_size] ;
/* === Construct the row and column data structures ===================== */ /* === Construct the row and column data structures ===================== */
if (!Eigen::internal::init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) if (!Colamd::init_rows_cols (n_row, n_col, Row, Col, A, p, stats))
{ {
/* input matrix is invalid */ /* input matrix is invalid */
COLAMD_DEBUG0 (("colamd: Matrix invalid\n")) ; COLAMD_DEBUG0 (("colamd: Matrix invalid\n")) ;
@ -487,23 +458,23 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
/* === Initialize scores, kill dense rows/columns ======================= */ /* === Initialize scores, kill dense rows/columns ======================= */
Eigen::internal::init_scoring (n_row, n_col, Row, Col, A, p, knobs, Colamd::init_scoring (n_row, n_col, Row, Col, A, p, knobs,
&n_row2, &n_col2, &max_deg) ; &n_row2, &n_col2, &max_deg) ;
/* === Order the supercolumns =========================================== */ /* === Order the supercolumns =========================================== */
ngarbage = Eigen::internal::find_ordering (n_row, n_col, Alen, Row, Col, A, p, ngarbage = Colamd::find_ordering (n_row, n_col, Alen, Row, Col, A, p,
n_col2, max_deg, 2*nnz) ; n_col2, max_deg, 2*nnz) ;
/* === Order the non-principal columns ================================== */ /* === Order the non-principal columns ================================== */
Eigen::internal::order_children (n_col, Col, p) ; Colamd::order_children (n_col, Col, p) ;
/* === Return statistics in stats ======================================= */ /* === Return statistics in stats ======================================= */
stats [DenseRow] = n_row - n_row2 ; stats [Colamd::DenseRow] = n_row - n_row2 ;
stats [DenseCol] = n_col - n_col2 ; stats [Colamd::DenseCol] = n_col - n_col2 ;
stats [DefragCount] = ngarbage ; stats [Colamd::DefragCount] = ngarbage ;
COLAMD_DEBUG0 (("colamd: done.\n")) ; COLAMD_DEBUG0 (("colamd: done.\n")) ;
return (true) ; return (true) ;
} }
@ -514,7 +485,6 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType *
/* There are no user-callable routines beyond this point in the file */ /* There are no user-callable routines beyond this point in the file */
/* ========================================================================== */ /* ========================================================================== */
/* === init_rows_cols ======================================================= */ /* === init_rows_cols ======================================================= */
/* ========================================================================== */ /* ========================================================================== */
@ -534,11 +504,11 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
IndexType n_row, /* number of rows of A */ IndexType n_row, /* number of rows of A */
IndexType n_col, /* number of columns of A */ IndexType n_col, /* number of columns of A */
Colamd_Row<IndexType> Row [], /* of size n_row+1 */ RowStructure<IndexType> Row [], /* of size n_row+1 */
colamd_col<IndexType> Col [], /* of size n_col+1 */ ColStructure<IndexType> Col [], /* of size n_col+1 */
IndexType A [], /* row indices of A, of size Alen */ IndexType A [], /* row indices of A, of size Alen */
IndexType p [], /* pointers to columns in A, of size n_col+1 */ IndexType p [], /* pointers to columns in A, of size n_col+1 */
IndexType stats [ColamdStats] /* colamd statistics */ IndexType stats [NStats] /* colamd statistics */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
@ -561,9 +531,9 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
if ((Col [col].length) < 0) // extra parentheses to work-around gcc bug 10200 if ((Col [col].length) < 0) // extra parentheses to work-around gcc bug 10200
{ {
/* column pointers must be non-decreasing */ /* column pointers must be non-decreasing */
stats [Status] = ErrorColLengthNegative ; stats [Colamd::Status] = Colamd::ErrorColLengthNegative ;
stats [Info1] = col ; stats [Colamd::Info1] = col ;
stats [Info2] = Col [col].length ; stats [Colamd::Info2] = Col [col].length ;
COLAMD_DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; COLAMD_DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ;
return (false) ; return (false) ;
} }
@ -600,10 +570,10 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
/* make sure row indices within range */ /* make sure row indices within range */
if (row < 0 || row >= n_row) if (row < 0 || row >= n_row)
{ {
stats [Status] = ErrorRowIndexOutOfBounds ; stats [Colamd::Status] = Colamd::ErrorRowIndexOutOfBounds ;
stats [Info1] = col ; stats [Colamd::Info1] = col ;
stats [Info2] = row ; stats [Colamd::Info2] = row ;
stats [Info3] = n_row ; stats [Colamd::Info3] = n_row ;
COLAMD_DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; COLAMD_DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ;
return (false) ; return (false) ;
} }
@ -612,10 +582,10 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */
{ {
/* row index are unsorted or repeated (or both), thus col */ /* row index are unsorted or repeated (or both), thus col */
/* is jumbled. This is a notice, not an error condition. */ /* is jumbled. This is a notice, not an error condition. */
stats [Status] = OkButJumbled ; stats [Colamd::Status] = Colamd::OkButJumbled ;
stats [Info1] = col ; stats [Colamd::Info1] = col ;
stats [Info2] = row ; stats [Colamd::Info2] = row ;
(stats [Info3]) ++ ; (stats [Colamd::Info3]) ++ ;
COLAMD_DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); COLAMD_DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col));
} }
@ -750,11 +720,11 @@ static void init_scoring
IndexType n_row, /* number of rows of A */ IndexType n_row, /* number of rows of A */
IndexType n_col, /* number of columns of A */ IndexType n_col, /* number of columns of A */
Colamd_Row<IndexType> Row [], /* of size n_row+1 */ RowStructure<IndexType> Row [], /* of size n_row+1 */
colamd_col<IndexType> Col [], /* of size n_col+1 */ ColStructure<IndexType> Col [], /* of size n_col+1 */
IndexType A [], /* column form and row form of A */ IndexType A [], /* column form and row form of A */
IndexType head [], /* of size n_col+1 */ IndexType head [], /* of size n_col+1 */
double knobs [ColamdKnobs],/* parameters */ double knobs [NKnobs],/* parameters */
IndexType *p_n_row2, /* number of non-dense, non-empty rows */ IndexType *p_n_row2, /* number of non-dense, non-empty rows */
IndexType *p_n_col2, /* number of non-dense, non-empty columns */ IndexType *p_n_col2, /* number of non-dense, non-empty columns */
IndexType *p_max_deg /* maximum row degree */ IndexType *p_max_deg /* maximum row degree */
@ -781,8 +751,8 @@ static void init_scoring
/* === Extract knobs ==================================================== */ /* === Extract knobs ==================================================== */
dense_row_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [DenseRow] * n_col), n_col)) ; dense_row_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [Colamd::DenseRow] * n_col), n_col)) ;
dense_col_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [DenseCol] * n_row), n_row)) ; dense_col_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [Colamd::DenseCol] * n_row), n_row)) ;
COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ;
max_deg = 0 ; max_deg = 0 ;
n_col2 = n_col ; n_col2 = n_col ;
@ -799,7 +769,7 @@ static void init_scoring
{ {
/* this is a empty column, kill and order it last */ /* this is a empty column, kill and order it last */
Col [c].shared2.order = --n_col2 ; Col [c].shared2.order = --n_col2 ;
kill_principal_col(Col, c) ; Col[c].kill_principal() ;
} }
} }
COLAMD_DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; COLAMD_DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ;
@ -810,7 +780,7 @@ static void init_scoring
for (c = n_col-1 ; c >= 0 ; c--) for (c = n_col-1 ; c >= 0 ; c--)
{ {
/* skip any dead columns */ /* skip any dead columns */
if (col_is_dead(Col, c)) if (Col[c].is_dead())
{ {
continue ; continue ;
} }
@ -826,7 +796,7 @@ static void init_scoring
{ {
Row [*cp++].shared1.degree-- ; Row [*cp++].shared1.degree-- ;
} }
kill_principal_col(Col, c) ; Col[c].kill_principal() ;
} }
} }
COLAMD_DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; COLAMD_DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ;
@ -840,7 +810,7 @@ static void init_scoring
if (deg > dense_row_count || deg == 0) if (deg > dense_row_count || deg == 0)
{ {
/* kill a dense or empty row */ /* kill a dense or empty row */
kill_row(Row, r) ; Row[r].kill() ;
--n_row2 ; --n_row2 ;
} }
else else
@ -862,7 +832,7 @@ static void init_scoring
for (c = n_col-1 ; c >= 0 ; c--) for (c = n_col-1 ; c >= 0 ; c--)
{ {
/* skip dead column */ /* skip dead column */
if (col_is_dead(Col, c)) if (Col[c].is_dead())
{ {
continue ; continue ;
} }
@ -875,7 +845,7 @@ static void init_scoring
/* get a row */ /* get a row */
row = *cp++ ; row = *cp++ ;
/* skip if dead */ /* skip if dead */
if (row_is_dead(Row, row)) if (Row[row].is_dead())
{ {
continue ; continue ;
} }
@ -894,7 +864,7 @@ static void init_scoring
/* and have already been killed) */ /* and have already been killed) */
COLAMD_DEBUG2 (("Newly null killed: %d\n", c)) ; COLAMD_DEBUG2 (("Newly null killed: %d\n", c)) ;
Col [c].shared2.order = --n_col2 ; Col [c].shared2.order = --n_col2 ;
kill_principal_col(Col, c) ; Col[c].kill_principal() ;
} }
else else
{ {
@ -927,7 +897,7 @@ static void init_scoring
for (c = n_col-1 ; c >= 0 ; c--) for (c = n_col-1 ; c >= 0 ; c--)
{ {
/* only add principal columns to degree lists */ /* only add principal columns to degree lists */
if (col_is_alive(Col, c)) if (Col[c].is_alive())
{ {
COLAMD_DEBUG4 (("place %d score %d minscore %d ncol %d\n", COLAMD_DEBUG4 (("place %d score %d minscore %d ncol %d\n",
c, Col [c].shared2.score, min_score, n_col)) ; c, Col [c].shared2.score, min_score, n_col)) ;
@ -988,8 +958,8 @@ static IndexType find_ordering /* return the number of garbage collections */
IndexType n_row, /* number of rows of A */ IndexType n_row, /* number of rows of A */
IndexType n_col, /* number of columns of A */ IndexType n_col, /* number of columns of A */
IndexType Alen, /* size of A, 2*nnz + n_col or larger */ IndexType Alen, /* size of A, 2*nnz + n_col or larger */
Colamd_Row<IndexType> Row [], /* of size n_row+1 */ RowStructure<IndexType> Row [], /* of size n_row+1 */
colamd_col<IndexType> Col [], /* of size n_col+1 */ ColStructure<IndexType> Col [], /* of size n_col+1 */
IndexType A [], /* column form and row form of A */ IndexType A [], /* column form and row form of A */
IndexType head [], /* of size n_col+1 */ IndexType head [], /* of size n_col+1 */
IndexType n_col2, /* Remaining columns to order */ IndexType n_col2, /* Remaining columns to order */
@ -1035,7 +1005,7 @@ static IndexType find_ordering /* return the number of garbage collections */
/* === Initialization and clear mark ==================================== */ /* === Initialization and clear mark ==================================== */
max_mark = INT_MAX - n_col ; /* INT_MAX defined in <limits.h> */ max_mark = INT_MAX - n_col ; /* INT_MAX defined in <limits.h> */
tag_mark = Eigen::internal::clear_mark (n_row, Row) ; tag_mark = Colamd::clear_mark (n_row, Row) ;
min_score = 0 ; min_score = 0 ;
ngarbage = 0 ; ngarbage = 0 ;
COLAMD_DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; COLAMD_DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ;
@ -1066,7 +1036,7 @@ static IndexType find_ordering /* return the number of garbage collections */
Col [next_col].shared3.prev = Empty ; Col [next_col].shared3.prev = Empty ;
} }
COLAMD_ASSERT (col_is_alive(Col, pivot_col)) ; COLAMD_ASSERT (Col[pivot_col].is_alive()) ;
COLAMD_DEBUG3 (("Pivot col: %d\n", pivot_col)) ; COLAMD_DEBUG3 (("Pivot col: %d\n", pivot_col)) ;
/* remember score for defrag check */ /* remember score for defrag check */
@ -1085,12 +1055,12 @@ static IndexType find_ordering /* return the number of garbage collections */
needed_memory = numext::mini(pivot_col_score, n_col - k) ; needed_memory = numext::mini(pivot_col_score, n_col - k) ;
if (pfree + needed_memory >= Alen) if (pfree + needed_memory >= Alen)
{ {
pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; pfree = Colamd::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ;
ngarbage++ ; ngarbage++ ;
/* after garbage collection we will have enough */ /* after garbage collection we will have enough */
COLAMD_ASSERT (pfree + needed_memory < Alen) ; COLAMD_ASSERT (pfree + needed_memory < Alen) ;
/* garbage collection has wiped out the Row[].shared2.mark array */ /* garbage collection has wiped out the Row[].shared2.mark array */
tag_mark = Eigen::internal::clear_mark (n_row, Row) ; tag_mark = Colamd::clear_mark (n_row, Row) ;
} }
@ -1113,9 +1083,9 @@ static IndexType find_ordering /* return the number of garbage collections */
{ {
/* get a row */ /* get a row */
row = *cp++ ; row = *cp++ ;
COLAMD_DEBUG4 (("Pivot col pattern %d %d\n", row_is_alive(Row, row), row)) ; COLAMD_DEBUG4 (("Pivot col pattern %d %d\n", Row[row].is_alive(), row)) ;
/* skip if row is dead */ /* skip if row is dead */
if (row_is_dead(Row, row)) if (Row[row].is_dead())
{ {
continue ; continue ;
} }
@ -1127,7 +1097,7 @@ static IndexType find_ordering /* return the number of garbage collections */
col = *rp++ ; col = *rp++ ;
/* add the column, if alive and untagged */ /* add the column, if alive and untagged */
col_thickness = Col [col].shared1.thickness ; col_thickness = Col [col].shared1.thickness ;
if (col_thickness > 0 && col_is_alive(Col, col)) if (col_thickness > 0 && Col[col].is_alive())
{ {
/* tag column in pivot row */ /* tag column in pivot row */
Col [col].shared1.thickness = -col_thickness ; Col [col].shared1.thickness = -col_thickness ;
@ -1154,7 +1124,7 @@ static IndexType find_ordering /* return the number of garbage collections */
/* may be killing an already dead row */ /* may be killing an already dead row */
row = *cp++ ; row = *cp++ ;
COLAMD_DEBUG3 (("Kill row in pivot col: %d\n", row)) ; COLAMD_DEBUG3 (("Kill row in pivot col: %d\n", row)) ;
kill_row(Row, row) ; Row[row].kill() ;
} }
/* === Select a row index to use as the new pivot row =============== */ /* === Select a row index to use as the new pivot row =============== */
@ -1206,7 +1176,7 @@ static IndexType find_ordering /* return the number of garbage collections */
while (rp < rp_end) while (rp < rp_end)
{ {
col = *rp++ ; col = *rp++ ;
COLAMD_ASSERT (col_is_alive(Col, col) && col != pivot_col) ; COLAMD_ASSERT (Col[col].is_alive() && col != pivot_col) ;
COLAMD_DEBUG3 (("Col: %d\n", col)) ; COLAMD_DEBUG3 (("Col: %d\n", col)) ;
/* clear tags used to construct pivot row pattern */ /* clear tags used to construct pivot row pattern */
@ -1243,12 +1213,12 @@ static IndexType find_ordering /* return the number of garbage collections */
{ {
/* get a row */ /* get a row */
row = *cp++ ; row = *cp++ ;
row_mark = Row [row].shared2.mark ;
/* skip if dead */ /* skip if dead */
if (row_is_marked_dead (row_mark)) if (Row[row].is_dead())
{ {
continue ; continue ;
} }
row_mark = Row [row].shared2.mark ;
COLAMD_ASSERT (row != pivot_row) ; COLAMD_ASSERT (row != pivot_row) ;
set_difference = row_mark - tag_mark ; set_difference = row_mark - tag_mark ;
/* check if the row has been seen yet */ /* check if the row has been seen yet */
@ -1264,7 +1234,7 @@ static IndexType find_ordering /* return the number of garbage collections */
if (set_difference == 0) if (set_difference == 0)
{ {
COLAMD_DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; COLAMD_DEBUG3 (("aggressive absorption. Row: %d\n", row)) ;
kill_row(Row, row) ; Row[row].kill() ;
} }
else else
{ {
@ -1286,7 +1256,7 @@ static IndexType find_ordering /* return the number of garbage collections */
{ {
/* get a column */ /* get a column */
col = *rp++ ; col = *rp++ ;
COLAMD_ASSERT (col_is_alive(Col, col) && col != pivot_col) ; COLAMD_ASSERT (Col[col].is_alive() && col != pivot_col) ;
hash = 0 ; hash = 0 ;
cur_score = 0 ; cur_score = 0 ;
cp = &A [Col [col].start] ; cp = &A [Col [col].start] ;
@ -1301,12 +1271,12 @@ static IndexType find_ordering /* return the number of garbage collections */
/* get a row */ /* get a row */
row = *cp++ ; row = *cp++ ;
COLAMD_ASSERT(row >= 0 && row < n_row) ; COLAMD_ASSERT(row >= 0 && row < n_row) ;
row_mark = Row [row].shared2.mark ;
/* skip if dead */ /* skip if dead */
if (row_is_marked_dead (row_mark)) if (Row [row].is_dead())
{ {
continue ; continue ;
} }
row_mark = Row [row].shared2.mark ;
COLAMD_ASSERT (row_mark > tag_mark) ; COLAMD_ASSERT (row_mark > tag_mark) ;
/* compact the column */ /* compact the column */
*new_cp++ = row ; *new_cp++ = row ;
@ -1327,7 +1297,7 @@ static IndexType find_ordering /* return the number of garbage collections */
{ {
COLAMD_DEBUG4 (("further mass elimination. Col: %d\n", col)) ; COLAMD_DEBUG4 (("further mass elimination. Col: %d\n", col)) ;
/* nothing left but the pivot row in this column */ /* nothing left but the pivot row in this column */
kill_principal_col(Col, col) ; Col[col].kill_principal() ;
pivot_row_degree -= Col [col].shared1.thickness ; pivot_row_degree -= Col [col].shared1.thickness ;
COLAMD_ASSERT (pivot_row_degree >= 0) ; COLAMD_ASSERT (pivot_row_degree >= 0) ;
/* order it */ /* order it */
@ -1368,7 +1338,7 @@ static IndexType find_ordering /* return the number of garbage collections */
/* save hash function in Col [col].shared3.hash */ /* save hash function in Col [col].shared3.hash */
Col [col].shared3.hash = (IndexType) hash ; Col [col].shared3.hash = (IndexType) hash ;
COLAMD_ASSERT (col_is_alive(Col, col)) ; COLAMD_ASSERT (Col[col].is_alive()) ;
} }
} }
@ -1378,11 +1348,11 @@ static IndexType find_ordering /* return the number of garbage collections */
COLAMD_DEBUG3 (("** Supercolumn detection phase. **\n")) ; COLAMD_DEBUG3 (("** Supercolumn detection phase. **\n")) ;
Eigen::internal::detect_super_cols (Col, A, head, pivot_row_start, pivot_row_length) ; Colamd::detect_super_cols (Col, A, head, pivot_row_start, pivot_row_length) ;
/* === Kill the pivotal column ====================================== */ /* === Kill the pivotal column ====================================== */
kill_principal_col(Col, pivot_col) ; Col[pivot_col].kill_principal() ;
/* === Clear mark =================================================== */ /* === Clear mark =================================================== */
@ -1390,7 +1360,7 @@ static IndexType find_ordering /* return the number of garbage collections */
if (tag_mark >= max_mark) if (tag_mark >= max_mark)
{ {
COLAMD_DEBUG2 (("clearing tag_mark\n")) ; COLAMD_DEBUG2 (("clearing tag_mark\n")) ;
tag_mark = Eigen::internal::clear_mark (n_row, Row) ; tag_mark = Colamd::clear_mark (n_row, Row) ;
} }
/* === Finalize the new pivot row, and column scores ================ */ /* === Finalize the new pivot row, and column scores ================ */
@ -1406,7 +1376,7 @@ static IndexType find_ordering /* return the number of garbage collections */
{ {
col = *rp++ ; col = *rp++ ;
/* skip dead columns */ /* skip dead columns */
if (col_is_dead(Col, col)) if (Col[col].is_dead())
{ {
continue ; continue ;
} }
@ -1497,7 +1467,7 @@ static inline void order_children
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
IndexType n_col, /* number of columns of A */ IndexType n_col, /* number of columns of A */
colamd_col<IndexType> Col [], /* of size n_col+1 */ ColStructure<IndexType> Col [], /* of size n_col+1 */
IndexType p [] /* p [0 ... n_col-1] is the column permutation*/ IndexType p [] /* p [0 ... n_col-1] is the column permutation*/
) )
{ {
@ -1514,14 +1484,14 @@ static inline void order_children
{ {
/* find an un-ordered non-principal column */ /* find an un-ordered non-principal column */
COLAMD_ASSERT (col_is_dead(Col, i)) ; COLAMD_ASSERT (col_is_dead(Col, i)) ;
if (!col_is_dead_principal(Col, i) && Col [i].shared2.order == Empty) if (!Col[i].is_dead_principal() && Col [i].shared2.order == Empty)
{ {
parent = i ; parent = i ;
/* once found, find its principal parent */ /* once found, find its principal parent */
do do
{ {
parent = Col [parent].shared1.parent ; parent = Col [parent].shared1.parent ;
} while (!col_is_dead_principal(Col, parent)) ; } while (!Col[parent].is_dead_principal()) ;
/* now, order all un-ordered non-principal columns along path */ /* now, order all un-ordered non-principal columns along path */
/* to this parent. collapse tree at the same time */ /* to this parent. collapse tree at the same time */
@ -1597,7 +1567,7 @@ static void detect_super_cols
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
colamd_col<IndexType> Col [], /* of size n_col+1 */ ColStructure<IndexType> Col [], /* of size n_col+1 */
IndexType A [], /* row indices of A */ IndexType A [], /* row indices of A */
IndexType head [], /* head of degree lists and hash buckets */ IndexType head [], /* head of degree lists and hash buckets */
IndexType row_start, /* pointer to set of columns to check */ IndexType row_start, /* pointer to set of columns to check */
@ -1627,7 +1597,7 @@ static void detect_super_cols
while (rp < rp_end) while (rp < rp_end)
{ {
col = *rp++ ; col = *rp++ ;
if (col_is_dead(Col, col)) if (Col[col].is_dead())
{ {
continue ; continue ;
} }
@ -1653,7 +1623,7 @@ static void detect_super_cols
for (super_c = first_col ; super_c != Empty ; for (super_c = first_col ; super_c != Empty ;
super_c = Col [super_c].shared4.hash_next) super_c = Col [super_c].shared4.hash_next)
{ {
COLAMD_ASSERT (col_is_alive(Col, super_c)) ; COLAMD_ASSERT (Col [super_c].is_alive()) ;
COLAMD_ASSERT (Col [super_c].shared3.hash == hash) ; COLAMD_ASSERT (Col [super_c].shared3.hash == hash) ;
length = Col [super_c].length ; length = Col [super_c].length ;
@ -1666,7 +1636,7 @@ static void detect_super_cols
c != Empty ; c = Col [c].shared4.hash_next) c != Empty ; c = Col [c].shared4.hash_next)
{ {
COLAMD_ASSERT (c != super_c) ; COLAMD_ASSERT (c != super_c) ;
COLAMD_ASSERT (col_is_alive(Col, c)) ; COLAMD_ASSERT (Col[c].is_alive()) ;
COLAMD_ASSERT (Col [c].shared3.hash == hash) ; COLAMD_ASSERT (Col [c].shared3.hash == hash) ;
/* not identical if lengths or scores are different */ /* not identical if lengths or scores are different */
@ -1684,8 +1654,8 @@ static void detect_super_cols
for (i = 0 ; i < length ; i++) for (i = 0 ; i < length ; i++)
{ {
/* the columns are "clean" (no dead rows) */ /* the columns are "clean" (no dead rows) */
COLAMD_ASSERT (ROW_IS_ALIVE (*cp1)) ; COLAMD_ASSERT ( cp1->is_alive() );
COLAMD_ASSERT (ROW_IS_ALIVE (*cp2)) ; COLAMD_ASSERT ( cp2->is_alive() );
/* row indices will same order for both supercols, */ /* row indices will same order for both supercols, */
/* no gather scatter necessary */ /* no gather scatter necessary */
if (*cp1++ != *cp2++) if (*cp1++ != *cp2++)
@ -1707,7 +1677,7 @@ static void detect_super_cols
Col [super_c].shared1.thickness += Col [c].shared1.thickness ; Col [super_c].shared1.thickness += Col [c].shared1.thickness ;
Col [c].shared1.parent = super_c ; Col [c].shared1.parent = super_c ;
kill_non_principal_col(Col, c) ; Col[c].kill_non_principal() ;
/* order c later, in order_children() */ /* order c later, in order_children() */
Col [c].shared2.order = Empty ; Col [c].shared2.order = Empty ;
/* remove c from hash bucket */ /* remove c from hash bucket */
@ -1750,8 +1720,8 @@ static IndexType garbage_collection /* returns the new value of pfree */
IndexType n_row, /* number of rows */ IndexType n_row, /* number of rows */
IndexType n_col, /* number of columns */ IndexType n_col, /* number of columns */
Colamd_Row<IndexType> Row [], /* row info */ RowStructure<IndexType> Row [], /* row info */
colamd_col<IndexType> Col [], /* column info */ ColStructure<IndexType> Col [], /* column info */
IndexType A [], /* A [0 ... Alen-1] holds the matrix */ IndexType A [], /* A [0 ... Alen-1] holds the matrix */
IndexType *pfree /* &A [0] ... pfree is in use */ IndexType *pfree /* &A [0] ... pfree is in use */
) )
@ -1770,7 +1740,7 @@ static IndexType garbage_collection /* returns the new value of pfree */
pdest = &A[0] ; pdest = &A[0] ;
for (c = 0 ; c < n_col ; c++) for (c = 0 ; c < n_col ; c++)
{ {
if (col_is_alive(Col, c)) if (Col[c].is_alive())
{ {
psrc = &A [Col [c].start] ; psrc = &A [Col [c].start] ;
@ -1781,7 +1751,7 @@ static IndexType garbage_collection /* returns the new value of pfree */
for (j = 0 ; j < length ; j++) for (j = 0 ; j < length ; j++)
{ {
r = *psrc++ ; r = *psrc++ ;
if (row_is_alive(Row, r)) if (Row[r].is_alive())
{ {
*pdest++ = r ; *pdest++ = r ;
} }
@ -1794,22 +1764,22 @@ static IndexType garbage_collection /* returns the new value of pfree */
for (r = 0 ; r < n_row ; r++) for (r = 0 ; r < n_row ; r++)
{ {
if (row_is_alive(Row, r)) if (Row[r].is_alive())
{ {
if (Row [r].length == 0) if (Row [r].length == 0)
{ {
/* this row is of zero length. cannot compact it, so kill it */ /* this row is of zero length. cannot compact it, so kill it */
COLAMD_DEBUG3 (("Defrag row kill\n")) ; COLAMD_DEBUG3 (("Defrag row kill\n")) ;
kill_row(Row, r) ; Row[r].kill() ;
} }
else else
{ {
/* save first column index in Row [r].shared2.first_column */ /* save first column index in Row [r].shared2.first_column */
psrc = &A [Row [r].start] ; psrc = &A [Row [r].start] ;
Row [r].shared2.first_column = *psrc ; Row [r].shared2.first_column = *psrc ;
COLAMD_ASSERT (row_is_alive(Row, r)) ; COLAMD_ASSERT (Row[r].is_alive()) ;
/* flag the start of the row with the one's complement of row */ /* flag the start of the row with the one's complement of row */
*psrc = ones_complement(r) ; *psrc = ones_complement(r) ;
} }
} }
@ -1829,7 +1799,7 @@ static IndexType garbage_collection /* returns the new value of pfree */
COLAMD_ASSERT (r >= 0 && r < n_row) ; COLAMD_ASSERT (r >= 0 && r < n_row) ;
/* restore first column index */ /* restore first column index */
*psrc = Row [r].shared2.first_column ; *psrc = Row [r].shared2.first_column ;
COLAMD_ASSERT (row_is_alive(Row, r)) ; COLAMD_ASSERT (Row[r].is_alive()) ;
/* move and compact the row */ /* move and compact the row */
COLAMD_ASSERT (pdest <= psrc) ; COLAMD_ASSERT (pdest <= psrc) ;
@ -1838,7 +1808,7 @@ static IndexType garbage_collection /* returns the new value of pfree */
for (j = 0 ; j < length ; j++) for (j = 0 ; j < length ; j++)
{ {
c = *psrc++ ; c = *psrc++ ;
if (col_is_alive(Col, c)) if (Col[c].is_alive())
{ {
*pdest++ = c ; *pdest++ = c ;
} }
@ -1870,7 +1840,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
IndexType n_row, /* number of rows in A */ IndexType n_row, /* number of rows in A */
Colamd_Row<IndexType> Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ RowStructure<IndexType> Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
@ -1879,7 +1849,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */
for (r = 0 ; r < n_row ; r++) for (r = 0 ; r < n_row ; r++)
{ {
if (row_is_alive(Row, r)) if (Row[r].is_alive())
{ {
Row [r].shared2.mark = 0 ; Row [r].shared2.mark = 0 ;
} }
@ -1887,6 +1857,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */
return (1) ; return (1) ;
} }
} // namespace Colamd
} // namespace internal } // namespace internal
#endif #endif

View File

@ -129,17 +129,17 @@ class COLAMDOrdering
StorageIndex n = StorageIndex(mat.cols()); StorageIndex n = StorageIndex(mat.cols());
StorageIndex nnz = StorageIndex(mat.nonZeros()); StorageIndex nnz = StorageIndex(mat.nonZeros());
// Get the recommended value of Alen to be used by colamd // Get the recommended value of Alen to be used by colamd
StorageIndex Alen = internal::colamd_recommended(nnz, m, n); StorageIndex Alen = internal::Colamd::recommended(nnz, m, n);
// Set the default parameters // Set the default parameters
double knobs [ColamdKnobs]; double knobs [internal::Colamd::NKnobs];
StorageIndex stats [ColamdStats]; StorageIndex stats [internal::Colamd::NStats];
internal::colamd_set_defaults(knobs); internal::Colamd::set_defaults(knobs);
IndexVector p(n+1), A(Alen); IndexVector p(n+1), A(Alen);
for(StorageIndex i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i]; for(StorageIndex i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
for(StorageIndex i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i]; for(StorageIndex i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
// Call Colamd routine to compute the ordering // Call Colamd routine to compute the ordering
StorageIndex info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); StorageIndex info = internal::Colamd::compute_ordering(m, n, Alen, A.data(), p.data(), knobs, stats);
EIGEN_UNUSED_VARIABLE(info); EIGEN_UNUSED_VARIABLE(info);
eigen_assert( info && "COLAMD failed " ); eigen_assert( info && "COLAMD failed " );