diff options
author | Gael Guennebaud <g.gael@free.fr> | 2019-09-03 00:50:51 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2019-09-03 00:50:51 +0200 |
commit | 15f3d9d2720f060100b2559058c9383b6ffa4d3e (patch) | |
tree | 70a927d1d441f98d8eb8a9a9afe7ad26904b6c73 /Eigen/src/OrderingMethods | |
parent | a4d1a6cd7de5112e1b2aca1eaf76b06ed1619c81 (diff) |
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
Diffstat (limited to 'Eigen/src/OrderingMethods')
-rw-r--r-- | Eigen/src/OrderingMethods/Eigen_Colamd.h | 329 | ||||
-rw-r--r-- | Eigen/src/OrderingMethods/Ordering.h | 10 |
2 files changed, 155 insertions, 184 deletions
diff --git a/Eigen/src/OrderingMethods/Eigen_Colamd.h b/Eigen/src/OrderingMethods/Eigen_Colamd.h index 3c9e85aa8..8e339a704 100644 --- a/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ b/Eigen/src/OrderingMethods/Eigen_Colamd.h @@ -47,25 +47,26 @@ #ifndef 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; +namespace internal { -/* number of output statistics. Only stats [0..6] are currently used. */ -const size_t ColamdStats = 20; +namespace Colamd { -namespace internal { /* Ensure that debugging is turned off: */ #ifndef COLAMD_NDEBUG #define COLAMD_NDEBUG #endif /* NDEBUG */ + + /* ========================================================================== */ /* === 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. */ enum KnobsStatsIndex { /* knobs [0] and stats [0]: dense row knob and output statistic. */ @@ -132,7 +133,7 @@ enum ColumnStatus { // == Row and Column structures == template <typename IndexType> -struct colamd_col +struct ColStructure { IndexType start ; /* index for A of first row in this column, or Dead */ /* if column is dead */ @@ -163,10 +164,20 @@ struct colamd_col IndexType hash_next ; /* next column, if col is in a hash list */ } 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> -struct Colamd_Row +struct RowStructure { IndexType start ; /* index for A of first col in this row */ IndexType length ; /* number of principal columns in this row */ @@ -181,53 +192,13 @@ struct Colamd_Row IndexType first_column ;/* first column in row (used in garbage collection) */ } shared2 ; -}; + inline bool is_dead() const { return shared2.mark < Alive; } -/* 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; -} + inline bool is_alive() const { return shared2.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); -} + inline void kill() { shared2.mark = Dead; } -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 ======================================= */ @@ -249,33 +220,33 @@ void kill_non_principal_col(colamd_col<IndexType>* col, const IndexType c) { */ template <typename IndexType> 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> 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 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> -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> -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> -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> -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> -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> -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 ========================================================= */ @@ -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 */ 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) return (-1); @@ -332,7 +303,7 @@ inline IndexType colamd_recommended ( IndexType nnz, IndexType n_row, IndexType * \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 ================================================== */ @@ -342,12 +313,12 @@ static inline void colamd_set_defaults(double knobs[ColamdKnobs]) { return ; /* no knobs to initialize */ } - for (i = 0 ; i < ColamdKnobs ; i++) + for (i = 0 ; i < NKnobs ; i++) { knobs [i] = 0 ; } - knobs [DenseRow] = 0.5 ; /* ignore rows over 50% dense */ - knobs [DenseCol] = 0.5 ; /* ignore columns over 50% dense */ + knobs [Colamd::DenseRow] = 0.5 ; /* ignore rows 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 */ 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 ================================================== */ @@ -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 Col_size ; /* size of Col [], in integers */ IndexType need ; /* minimum required length of A */ - Colamd_Row<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::RowStructure<IndexType> *Row ; /* pointer into A of Row [0..n_row] 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_row2 ; /* number of non-dense, non-empty rows */ IndexType ngarbage ; /* number of garbage collections performed */ IndexType max_deg ; /* maximum row degree */ - double default_knobs [ColamdKnobs] ; /* default knobs array */ + double default_knobs [NKnobs] ; /* default knobs array */ /* === 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")) ; return (false) ; } - for (i = 0 ; i < ColamdStats ; i++) + for (i = 0 ; i < NStats ; i++) { stats [i] = 0 ; } - stats [Status] = Ok ; - stats [Info1] = -1 ; - stats [Info2] = -1 ; + stats [Colamd::Status] = Colamd::Ok ; + stats [Colamd::Info1] = -1 ; + stats [Colamd::Info2] = -1 ; if (!A) /* A is not present */ { - stats [Status] = ErrorANotPresent ; + stats [Colamd::Status] = Colamd::ErrorANotPresent ; COLAMD_DEBUG0 (("colamd: A not present\n")) ; return (false) ; } if (!p) /* p is not present */ { - stats [Status] = ErrorPNotPresent ; + stats [Colamd::Status] = Colamd::ErrorPNotPresent ; COLAMD_DEBUG0 (("colamd: p not present\n")) ; return (false) ; } if (n_row < 0) /* n_row must be >= 0 */ { - stats [Status] = ErrorNrowNegative ; - stats [Info1] = n_row ; + stats [Colamd::Status] = Colamd::ErrorNrowNegative ; + stats [Colamd::Info1] = n_row ; COLAMD_DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; return (false) ; } if (n_col < 0) /* n_col must be >= 0 */ { - stats [Status] = ErrorNcolNegative ; - stats [Info1] = n_col ; + stats [Colamd::Status] = Colamd::ErrorNcolNegative ; + stats [Colamd::Info1] = n_col ; COLAMD_DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; return (false) ; } @@ -434,16 +405,16 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType * nnz = p [n_col] ; if (nnz < 0) /* nnz must be >= 0 */ { - stats [Status] = ErrorNnzNegative ; - stats [Info1] = nnz ; + stats [Colamd::Status] = Colamd::ErrorNnzNegative ; + stats [Colamd::Info1] = nnz ; COLAMD_DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; return (false) ; } if (p [0] != 0) { - stats [Status] = ErrorP0Nonzero ; - stats [Info1] = p [0] ; + stats [Colamd::Status] = Colamd::ErrorP0Nonzero ; + stats [Colamd::Info1] = p [0] ; COLAMD_DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; return (false) ; } @@ -452,7 +423,7 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType * if (!knobs) { - colamd_set_defaults (default_knobs) ; + set_defaults (default_knobs) ; knobs = default_knobs ; } @@ -465,20 +436,20 @@ static bool colamd(IndexType n_row, IndexType n_col, IndexType Alen, IndexType * if (need > Alen) { /* not enough space in array A to perform the ordering */ - stats [Status] = ErrorATooSmall ; - stats [Info1] = need ; - stats [Info2] = Alen ; + stats [Colamd::Status] = Colamd::ErrorATooSmall ; + stats [Colamd::Info1] = need ; + stats [Colamd::Info2] = Alen ; COLAMD_DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); return (false) ; } Alen -= Col_size + Row_size ; - Col = (colamd_col<IndexType> *) &A [Alen] ; - Row = (Colamd_Row<IndexType> *) &A [Alen + Col_size] ; + Col = (ColStructure<IndexType> *) &A [Alen] ; + Row = (RowStructure<IndexType> *) &A [Alen + Col_size] ; /* === 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 */ 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 ======================= */ - 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) ; /* === 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) ; /* === Order the non-principal columns ================================== */ - Eigen::internal::order_children (n_col, Col, p) ; + Colamd::order_children (n_col, Col, p) ; /* === Return statistics in stats ======================================= */ - stats [DenseRow] = n_row - n_row2 ; - stats [DenseCol] = n_col - n_col2 ; - stats [DefragCount] = ngarbage ; + stats [Colamd::DenseRow] = n_row - n_row2 ; + stats [Colamd::DenseCol] = n_col - n_col2 ; + stats [Colamd::DefragCount] = ngarbage ; COLAMD_DEBUG0 (("colamd: done.\n")) ; 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 */ - /* ========================================================================== */ /* === 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_col, /* number of columns of A */ - Colamd_Row<IndexType> Row [], /* of size n_row+1 */ - colamd_col<IndexType> Col [], /* of size n_col+1 */ + RowStructure<IndexType> Row [], /* of size n_row+1 */ + ColStructure<IndexType> Col [], /* of size n_col+1 */ IndexType A [], /* row indices of A, of size Alen */ IndexType p [], /* pointers to columns in A, of size n_col+1 */ - IndexType stats [ColamdStats] /* colamd statistics */ + IndexType stats [NStats] /* colamd statistics */ ) { /* === 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 { /* column pointers must be non-decreasing */ - stats [Status] = ErrorColLengthNegative ; - stats [Info1] = col ; - stats [Info2] = Col [col].length ; + stats [Colamd::Status] = Colamd::ErrorColLengthNegative ; + stats [Colamd::Info1] = col ; + stats [Colamd::Info2] = Col [col].length ; COLAMD_DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; return (false) ; } @@ -600,10 +570,10 @@ static IndexType init_rows_cols /* returns true if OK, or false otherwise */ /* make sure row indices within range */ if (row < 0 || row >= n_row) { - stats [Status] = ErrorRowIndexOutOfBounds ; - stats [Info1] = col ; - stats [Info2] = row ; - stats [Info3] = n_row ; + stats [Colamd::Status] = Colamd::ErrorRowIndexOutOfBounds ; + stats [Colamd::Info1] = col ; + stats [Colamd::Info2] = row ; + stats [Colamd::Info3] = n_row ; COLAMD_DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; 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 */ /* is jumbled. This is a notice, not an error condition. */ - stats [Status] = OkButJumbled ; - stats [Info1] = col ; - stats [Info2] = row ; - (stats [Info3]) ++ ; + stats [Colamd::Status] = Colamd::OkButJumbled ; + stats [Colamd::Info1] = col ; + stats [Colamd::Info2] = row ; + (stats [Colamd::Info3]) ++ ; 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_col, /* number of columns of A */ - Colamd_Row<IndexType> Row [], /* of size n_row+1 */ - colamd_col<IndexType> Col [], /* of size n_col+1 */ + RowStructure<IndexType> Row [], /* of size n_row+1 */ + ColStructure<IndexType> Col [], /* of size n_col+1 */ IndexType A [], /* column form and row form of A */ 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_col2, /* number of non-dense, non-empty columns */ IndexType *p_max_deg /* maximum row degree */ @@ -781,8 +751,8 @@ static void init_scoring /* === Extract knobs ==================================================== */ - dense_row_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [DenseRow] * n_col), n_col)) ; - dense_col_count = numext::maxi(IndexType(0), numext::mini(IndexType(knobs [DenseCol] * n_row), n_row)) ; + 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 [Colamd::DenseCol] * n_row), n_row)) ; COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; max_deg = 0 ; n_col2 = n_col ; @@ -799,7 +769,7 @@ static void init_scoring { /* this is a empty column, kill and order it last */ 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)) ; @@ -810,7 +780,7 @@ static void init_scoring for (c = n_col-1 ; c >= 0 ; c--) { /* skip any dead columns */ - if (col_is_dead(Col, c)) + if (Col[c].is_dead()) { continue ; } @@ -826,7 +796,7 @@ static void init_scoring { 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)) ; @@ -840,7 +810,7 @@ static void init_scoring if (deg > dense_row_count || deg == 0) { /* kill a dense or empty row */ - kill_row(Row, r) ; + Row[r].kill() ; --n_row2 ; } else @@ -862,7 +832,7 @@ static void init_scoring for (c = n_col-1 ; c >= 0 ; c--) { /* skip dead column */ - if (col_is_dead(Col, c)) + if (Col[c].is_dead()) { continue ; } @@ -875,7 +845,7 @@ static void init_scoring /* get a row */ row = *cp++ ; /* skip if dead */ - if (row_is_dead(Row, row)) + if (Row[row].is_dead()) { continue ; } @@ -894,7 +864,7 @@ static void init_scoring /* and have already been killed) */ COLAMD_DEBUG2 (("Newly null killed: %d\n", c)) ; Col [c].shared2.order = --n_col2 ; - kill_principal_col(Col, c) ; + Col[c].kill_principal() ; } else { @@ -927,7 +897,7 @@ static void init_scoring for (c = n_col-1 ; c >= 0 ; c--) { /* 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", 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_col, /* number of columns of A */ IndexType Alen, /* size of A, 2*nnz + n_col or larger */ - Colamd_Row<IndexType> Row [], /* of size n_row+1 */ - colamd_col<IndexType> Col [], /* of size n_col+1 */ + RowStructure<IndexType> Row [], /* of size n_row+1 */ + ColStructure<IndexType> Col [], /* of size n_col+1 */ IndexType A [], /* column form and row form of A */ IndexType head [], /* of size n_col+1 */ 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 ==================================== */ 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 ; ngarbage = 0 ; 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 ; } - COLAMD_ASSERT (col_is_alive(Col, pivot_col)) ; + COLAMD_ASSERT (Col[pivot_col].is_alive()) ; COLAMD_DEBUG3 (("Pivot col: %d\n", pivot_col)) ; /* 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) ; 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++ ; /* after garbage collection we will have enough */ COLAMD_ASSERT (pfree + needed_memory < Alen) ; /* 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 */ 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 */ - if (row_is_dead(Row, row)) + if (Row[row].is_dead()) { continue ; } @@ -1127,7 +1097,7 @@ static IndexType find_ordering /* return the number of garbage collections */ col = *rp++ ; /* add the column, if alive and untagged */ 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 */ 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 */ row = *cp++ ; 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 =============== */ @@ -1206,7 +1176,7 @@ static IndexType find_ordering /* return the number of garbage collections */ while (rp < rp_end) { 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)) ; /* 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 */ row = *cp++ ; - row_mark = Row [row].shared2.mark ; /* skip if dead */ - if (row_is_marked_dead (row_mark)) + if (Row[row].is_dead()) { continue ; } + row_mark = Row [row].shared2.mark ; COLAMD_ASSERT (row != pivot_row) ; set_difference = row_mark - tag_mark ; /* 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) { COLAMD_DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; - kill_row(Row, row) ; + Row[row].kill() ; } else { @@ -1286,7 +1256,7 @@ static IndexType find_ordering /* return the number of garbage collections */ { /* get a column */ col = *rp++ ; - COLAMD_ASSERT (col_is_alive(Col, col) && col != pivot_col) ; + COLAMD_ASSERT (Col[col].is_alive() && col != pivot_col) ; hash = 0 ; cur_score = 0 ; cp = &A [Col [col].start] ; @@ -1301,12 +1271,12 @@ static IndexType find_ordering /* return the number of garbage collections */ /* get a row */ row = *cp++ ; COLAMD_ASSERT(row >= 0 && row < n_row) ; - row_mark = Row [row].shared2.mark ; /* skip if dead */ - if (row_is_marked_dead (row_mark)) + if (Row [row].is_dead()) { continue ; } + row_mark = Row [row].shared2.mark ; COLAMD_ASSERT (row_mark > tag_mark) ; /* compact the column */ *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)) ; /* 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 ; COLAMD_ASSERT (pivot_row_degree >= 0) ; /* order it */ @@ -1368,7 +1338,7 @@ static IndexType find_ordering /* return the number of garbage collections */ /* save hash function in Col [col].shared3.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")) ; - 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_principal_col(Col, pivot_col) ; + Col[pivot_col].kill_principal() ; /* === Clear mark =================================================== */ @@ -1390,7 +1360,7 @@ static IndexType find_ordering /* return the number of garbage collections */ if (tag_mark >= max_mark) { 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 ================ */ @@ -1406,7 +1376,7 @@ static IndexType find_ordering /* return the number of garbage collections */ { col = *rp++ ; /* skip dead columns */ - if (col_is_dead(Col, col)) + if (Col[col].is_dead()) { continue ; } @@ -1497,7 +1467,7 @@ static inline void order_children /* === Parameters ======================================================= */ 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*/ ) { @@ -1514,14 +1484,14 @@ static inline void order_children { /* find an un-ordered non-principal column */ 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 ; /* once found, find its principal parent */ do { 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 */ /* to this parent. collapse tree at the same time */ @@ -1597,7 +1567,7 @@ static void detect_super_cols ( /* === 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 head [], /* head of degree lists and hash buckets */ IndexType row_start, /* pointer to set of columns to check */ @@ -1627,7 +1597,7 @@ static void detect_super_cols while (rp < rp_end) { col = *rp++ ; - if (col_is_dead(Col, col)) + if (Col[col].is_dead()) { continue ; } @@ -1653,7 +1623,7 @@ static void detect_super_cols for (super_c = first_col ; super_c != Empty ; 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) ; length = Col [super_c].length ; @@ -1666,7 +1636,7 @@ static void detect_super_cols c != Empty ; c = Col [c].shared4.hash_next) { 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) ; /* not identical if lengths or scores are different */ @@ -1684,8 +1654,8 @@ static void detect_super_cols for (i = 0 ; i < length ; i++) { /* the columns are "clean" (no dead rows) */ - COLAMD_ASSERT (ROW_IS_ALIVE (*cp1)) ; - COLAMD_ASSERT (ROW_IS_ALIVE (*cp2)) ; + COLAMD_ASSERT ( cp1->is_alive() ); + COLAMD_ASSERT ( cp2->is_alive() ); /* row indices will same order for both supercols, */ /* no gather scatter necessary */ if (*cp1++ != *cp2++) @@ -1707,7 +1677,7 @@ static void detect_super_cols Col [super_c].shared1.thickness += Col [c].shared1.thickness ; Col [c].shared1.parent = super_c ; - kill_non_principal_col(Col, c) ; + Col[c].kill_non_principal() ; /* order c later, in order_children() */ Col [c].shared2.order = Empty ; /* 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_col, /* number of columns */ - Colamd_Row<IndexType> Row [], /* row info */ - colamd_col<IndexType> Col [], /* column info */ + RowStructure<IndexType> Row [], /* row info */ + ColStructure<IndexType> Col [], /* column info */ IndexType A [], /* A [0 ... Alen-1] holds the matrix */ 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] ; for (c = 0 ; c < n_col ; c++) { - if (col_is_alive(Col, c)) + if (Col[c].is_alive()) { 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++) { r = *psrc++ ; - if (row_is_alive(Row, r)) + if (Row[r].is_alive()) { *pdest++ = r ; } @@ -1794,22 +1764,22 @@ static IndexType garbage_collection /* returns the new value of pfree */ for (r = 0 ; r < n_row ; r++) { - if (row_is_alive(Row, r)) + if (Row[r].is_alive()) { if (Row [r].length == 0) { - /* this row is of zero length. cannot compact it, so kill it */ - COLAMD_DEBUG3 (("Defrag row kill\n")) ; - kill_row(Row, r) ; + /* this row is of zero length. cannot compact it, so kill it */ + COLAMD_DEBUG3 (("Defrag row kill\n")) ; + Row[r].kill() ; } else { - /* save first column index in Row [r].shared2.first_column */ - psrc = &A [Row [r].start] ; - Row [r].shared2.first_column = *psrc ; - COLAMD_ASSERT (row_is_alive(Row, r)) ; - /* flag the start of the row with the one's complement of row */ - *psrc = ones_complement(r) ; + /* save first column index in Row [r].shared2.first_column */ + psrc = &A [Row [r].start] ; + Row [r].shared2.first_column = *psrc ; + COLAMD_ASSERT (Row[r].is_alive()) ; + /* flag the start of the row with the one's complement of row */ + *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) ; /* restore first column index */ *psrc = Row [r].shared2.first_column ; - COLAMD_ASSERT (row_is_alive(Row, r)) ; + COLAMD_ASSERT (Row[r].is_alive()) ; /* move and compact the row */ COLAMD_ASSERT (pdest <= psrc) ; @@ -1838,7 +1808,7 @@ static IndexType garbage_collection /* returns the new value of pfree */ for (j = 0 ; j < length ; j++) { c = *psrc++ ; - if (col_is_alive(Col, c)) + if (Col[c].is_alive()) { *pdest++ = c ; } @@ -1870,7 +1840,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */ /* === Parameters ======================================================= */ 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 ================================================== */ @@ -1879,7 +1849,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */ for (r = 0 ; r < n_row ; r++) { - if (row_is_alive(Row, r)) + if (Row[r].is_alive()) { Row [r].shared2.mark = 0 ; } @@ -1887,6 +1857,7 @@ static inline IndexType clear_mark /* return the new value for tag_mark */ return (1) ; } +} // namespace Colamd } // namespace internal #endif diff --git a/Eigen/src/OrderingMethods/Ordering.h b/Eigen/src/OrderingMethods/Ordering.h index 10ba6b464..c57897014 100644 --- a/Eigen/src/OrderingMethods/Ordering.h +++ b/Eigen/src/OrderingMethods/Ordering.h @@ -129,17 +129,17 @@ class COLAMDOrdering StorageIndex n = StorageIndex(mat.cols()); StorageIndex nnz = StorageIndex(mat.nonZeros()); // 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 - double knobs [ColamdKnobs]; - StorageIndex stats [ColamdStats]; - internal::colamd_set_defaults(knobs); + double knobs [internal::Colamd::NKnobs]; + StorageIndex stats [internal::Colamd::NStats]; + internal::Colamd::set_defaults(knobs); IndexVector p(n+1), A(Alen); for(StorageIndex i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i]; for(StorageIndex i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i]; // 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_assert( info && "COLAMD failed " ); |