Use a template Index for COLAMD ordering

This commit is contained in:
Desire NUENTSA 2013-03-20 16:02:03 +01:00
parent 4107b371e3
commit 22460edb49
2 changed files with 1044 additions and 1041 deletions

View File

@ -50,6 +50,7 @@
#ifndef EIGEN_COLAMD_H #ifndef EIGEN_COLAMD_H
#define EIGEN_COLAMD_H #define EIGEN_COLAMD_H
namespace internal { namespace internal {
/* Ensure that debugging is turned off: */ /* Ensure that debugging is turned off: */
#ifndef COLAMD_NDEBUG #ifndef COLAMD_NDEBUG
@ -133,56 +134,58 @@ namespace internal {
/* === Colamd reporting mechanism =========================================== */ /* === Colamd reporting mechanism =========================================== */
/* ========================================================================== */ /* ========================================================================== */
// == Row and Column structures == // == Row and Column structures ==
typedef struct colamd_col_struct template <typename Index>
struct colamd_col
{ {
int start ; /* index for A of first row in this column, or DEAD */ Index start ; /* index for A of first row in this column, or DEAD */
/* if column is dead */ /* if column is dead */
int length ; /* number of rows in this column */ Index length ; /* number of rows in this column */
union union
{ {
int thickness ; /* number of original columns represented by this */ Index thickness ; /* number of original columns represented by this */
/* col, if the column is alive */ /* col, if the column is alive */
int parent ; /* parent in parent tree super-column structure, if */ Index parent ; /* parent in parent tree super-column structure, if */
/* the column is dead */ /* the column is dead */
} shared1 ; } shared1 ;
union union
{ {
int score ; /* the score used to maintain heap, if col is alive */ Index score ; /* the score used to maintain heap, if col is alive */
int order ; /* pivot ordering of this column, if col is dead */ Index order ; /* pivot ordering of this column, if col is dead */
} shared2 ; } shared2 ;
union union
{ {
int headhash ; /* head of a hash bucket, if col is at the head of */ Index headhash ; /* head of a hash bucket, if col is at the head of */
/* a degree list */ /* a degree list */
int hash ; /* hash value, if col is not in a degree list */ Index hash ; /* hash value, if col is not in a degree list */
int prev ; /* previous column in degree list, if col is in a */ Index prev ; /* previous column in degree list, if col is in a */
/* degree list (but not at the head of a degree list) */ /* degree list (but not at the head of a degree list) */
} shared3 ; } shared3 ;
union union
{ {
int degree_next ; /* next column, if col is in a degree list */ Index degree_next ; /* next column, if col is in a degree list */
int hash_next ; /* next column, if col is in a hash list */ Index hash_next ; /* next column, if col is in a hash list */
} shared4 ; } shared4 ;
} colamd_col ; };
typedef struct Colamd_Row_struct template <typename Index>
struct Colamd_Row
{ {
int start ; /* index for A of first col in this row */ Index start ; /* index for A of first col in this row */
int length ; /* number of principal columns in this row */ Index length ; /* number of principal columns in this row */
union union
{ {
int degree ; /* number of principal & non-principal columns in row */ Index degree ; /* number of principal & non-principal columns in row */
int p ; /* used as a row pointer in init_rows_cols () */ Index p ; /* used as a row pointer in init_rows_cols () */
} shared1 ; } shared1 ;
union union
{ {
int mark ; /* for computing set differences and marking dead rows*/ Index mark ; /* for computing set differences and marking dead rows*/
int first_column ;/* first column in row (used in garbage collection) */ Index first_column ;/* first column in row (used in garbage collection) */
} shared2 ; } shared2 ;
} Colamd_Row ; };
/* ========================================================================== */ /* ========================================================================== */
/* === Colamd recommended memory size ======================================= */ /* === Colamd recommended memory size ======================================= */
@ -199,41 +202,38 @@ typedef struct Colamd_Row_struct
This macro is not needed when using symamd. This macro is not needed when using symamd.
Explicit typecast to int added Sept. 23, 2002, COLAMD version 2.2, to avoid Explicit typecast to Index added Sept. 23, 2002, COLAMD version 2.2, to avoid
gcc -pedantic warning messages. gcc -pedantic warning messages.
*/ */
template <typename Index>
inline Index colamd_c(Index n_col)
{ return Index( ((n_col) + 1) * sizeof (colamd_col<Index>) / sizeof (Index) ) ; }
inline int colamd_c(int n_col) template <typename Index>
{ return int( ((n_col) + 1) * sizeof (colamd_col) / sizeof (int) ) ; } inline Index colamd_r(Index n_row)
{ return Index(((n_row) + 1) * sizeof (Colamd_Row<Index>) / sizeof (Index)); }
inline int colamd_r(int n_row) // Prototypes of non-user callable routines
{ return int(((n_row) + 1) * sizeof (Colamd_Row) / sizeof (int)); } template <typename Index>
static Index init_rows_cols (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> col [], Index A [], Index p [], Index stats[COLAMD_STATS] );
// Various routines template <typename Index>
inline int colamd_recommended (int nnz, int n_row, int n_col) ; static void init_scoring (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index head [], double knobs[COLAMD_KNOBS], Index *p_n_row2, Index *p_n_col2, Index *p_max_deg);
static inline void colamd_set_defaults (double knobs [COLAMD_KNOBS]) ; template <typename Index>
static Index find_ordering (Index n_row, Index n_col, Index Alen, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index head [], Index n_col2, Index max_deg, Index pfree);
static bool colamd (int n_row, int n_col, int Alen, int A [], int p [], double knobs[COLAMD_KNOBS], int stats [COLAMD_STATS]) ; template <typename Index>
static void order_children (Index n_col, colamd_col<Index> Col [], Index p []);
static int init_rows_cols (int n_row, int n_col, Colamd_Row Row [], colamd_col col [], int A [], int p [], int stats[COLAMD_STATS] ); template <typename Index>
static void detect_super_cols (colamd_col<Index> Col [], Index A [], Index head [], Index row_start, Index row_length ) ;
static void init_scoring (int n_row, int n_col, Colamd_Row Row [], colamd_col Col [], int A [], int head [], double knobs[COLAMD_KNOBS], int *p_n_row2, int *p_n_col2, int *p_max_deg); template <typename Index>
static Index garbage_collection (Index n_row, Index n_col, Colamd_Row<Index> Row [], colamd_col<Index> Col [], Index A [], Index *pfree) ;
static int find_ordering (int n_row, int n_col, int Alen, Colamd_Row Row [], colamd_col Col [], int A [], int head [], int n_col2, int max_deg, int pfree); template <typename Index>
static inline Index clear_mark (Index n_row, Colamd_Row<Index> Row [] ) ;
static void order_children (int n_col, colamd_col Col [], int p []);
static void detect_super_cols (
colamd_col Col [],
int A [],
int head [],
int row_start,
int row_length ) ;
static int garbage_collection (int n_row, int n_col, Colamd_Row Row [], colamd_col Col [], int A [], int *pfree) ;
static inline int clear_mark (int n_row, Colamd_Row Row [] ) ;
/* === No debugging ========================================================= */ /* === No debugging ========================================================= */
@ -260,7 +260,8 @@ static inline int clear_mark (int n_row, Colamd_Row Row [] ) ;
* \param n_col number of columns in A * \param n_col number of columns in A
* \return recommended value of Alen for use by colamd * \return recommended value of Alen for use by colamd
*/ */
inline int colamd_recommended ( int nnz, int n_row, int n_col) template <typename Index>
inline Index colamd_recommended ( Index nnz, Index n_row, Index n_col)
{ {
if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0) if ((nnz) < 0 || (n_row) < 0 || (n_col) < 0)
return (-1); return (-1);
@ -288,6 +289,7 @@ inline int colamd_recommended ( int nnz, int n_row, int n_col)
* *
* \param knobs parameter settings for colamd * \param knobs parameter settings for colamd
*/ */
static inline void colamd_set_defaults(double knobs[COLAMD_KNOBS]) static inline void colamd_set_defaults(double knobs[COLAMD_KNOBS])
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
@ -323,21 +325,22 @@ static inline void colamd_set_defaults(double knobs[COLAMD_KNOBS])
* \param knobs parameter settings for colamd * \param knobs parameter settings for colamd
* \param stats colamd output statistics and error codes * \param stats colamd output statistics and error codes
*/ */
static bool colamd(int n_row, int n_col, int Alen, int *A, int *p, double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS]) template <typename Index>
static bool colamd(Index n_row, Index n_col, Index Alen, Index *A, Index *p, double knobs[COLAMD_KNOBS], Index stats[COLAMD_STATS])
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int i ; /* loop index */ Index i ; /* loop index */
int nnz ; /* nonzeros in A */ Index nnz ; /* nonzeros in A */
int Row_size ; /* size of Row [], in integers */ Index Row_size ; /* size of Row [], in integers */
int Col_size ; /* size of Col [], in integers */ Index Col_size ; /* size of Col [], in integers */
int need ; /* minimum required length of A */ Index need ; /* minimum required length of A */
Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ Colamd_Row<Index> *Row ; /* pointer into A of Row [0..n_row] array */
colamd_col *Col ; /* pointer into A of Col [0..n_col] array */ colamd_col<Index> *Col ; /* pointer into A of Col [0..n_col] array */
int n_col2 ; /* number of non-dense, non-empty columns */ Index n_col2 ; /* number of non-dense, non-empty columns */
int n_row2 ; /* number of non-dense, non-empty rows */ Index n_row2 ; /* number of non-dense, non-empty rows */
int ngarbage ; /* number of garbage collections performed */ Index ngarbage ; /* number of garbage collections performed */
int max_deg ; /* maximum row degree */ Index max_deg ; /* maximum row degree */
double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ double default_knobs [COLAMD_KNOBS] ; /* default knobs array */
@ -428,8 +431,8 @@ static bool colamd(int n_row, int n_col, int Alen, int *A, int *p, double knobs[
} }
Alen -= Col_size + Row_size ; Alen -= Col_size + Row_size ;
Col = (colamd_col *) &A [Alen] ; Col = (colamd_col<Index> *) &A [Alen] ;
Row = (Colamd_Row *) &A [Alen + Col_size] ; Row = (Colamd_Row<Index> *) &A [Alen + Col_size] ;
/* === Construct the row and column data structures ===================== */ /* === Construct the row and column data structures ===================== */
@ -482,29 +485,29 @@ static bool colamd(int n_row, int n_col, int Alen, int *A, int *p, double knobs[
column form of the matrix. Returns false if the matrix is invalid, column form of the matrix. Returns false if the matrix is invalid,
true otherwise. Not user-callable. true otherwise. Not user-callable.
*/ */
template <typename Index>
static int init_rows_cols /* returns true if OK, or false otherwise */ static Index init_rows_cols /* returns true if OK, or false otherwise */
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_row, /* number of rows of A */ Index n_row, /* number of rows of A */
int n_col, /* number of columns of A */ Index n_col, /* number of columns of A */
Colamd_Row Row [], /* of size n_row+1 */ Colamd_Row<Index> Row [], /* of size n_row+1 */
colamd_col Col [], /* of size n_col+1 */ colamd_col<Index> Col [], /* of size n_col+1 */
int A [], /* row indices of A, of size Alen */ Index A [], /* row indices of A, of size Alen */
int p [], /* pointers to columns in A, of size n_col+1 */ Index p [], /* pointers to columns in A, of size n_col+1 */
int stats [COLAMD_STATS] /* colamd statistics */ Index stats [COLAMD_STATS] /* colamd statistics */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int col ; /* a column index */ Index col ; /* a column index */
int row ; /* a row index */ Index row ; /* a row index */
int *cp ; /* a column pointer */ Index *cp ; /* a column pointer */
int *cp_end ; /* a pointer to the end of a column */ Index *cp_end ; /* a pointer to the end of a column */
int *rp ; /* a row pointer */ Index *rp ; /* a row pointer */
int *rp_end ; /* a pointer to the end of a row */ Index *rp_end ; /* a pointer to the end of a row */
int last_row ; /* previous row */ Index last_row ; /* previous row */
/* === Initialize columns, and check column pointers ==================== */ /* === Initialize columns, and check column pointers ==================== */
@ -698,40 +701,40 @@ static bool colamd(int n_row, int n_col, int Alen, int *A, int *p, double knobs[
Kills dense or empty columns and rows, calculates an initial score for Kills dense or empty columns and rows, calculates an initial score for
each column, and places all columns in the degree lists. Not user-callable. each column, and places all columns in the degree lists. Not user-callable.
*/ */
template <typename Index>
static void init_scoring static void init_scoring
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_row, /* number of rows of A */ Index n_row, /* number of rows of A */
int n_col, /* number of columns of A */ Index n_col, /* number of columns of A */
Colamd_Row Row [], /* of size n_row+1 */ Colamd_Row<Index> Row [], /* of size n_row+1 */
colamd_col Col [], /* of size n_col+1 */ colamd_col<Index> Col [], /* of size n_col+1 */
int A [], /* column form and row form of A */ Index A [], /* column form and row form of A */
int head [], /* of size n_col+1 */ Index head [], /* of size n_col+1 */
double knobs [COLAMD_KNOBS],/* parameters */ double knobs [COLAMD_KNOBS],/* parameters */
int *p_n_row2, /* number of non-dense, non-empty rows */ Index *p_n_row2, /* number of non-dense, non-empty rows */
int *p_n_col2, /* number of non-dense, non-empty columns */ Index *p_n_col2, /* number of non-dense, non-empty columns */
int *p_max_deg /* maximum row degree */ Index *p_max_deg /* maximum row degree */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int c ; /* a column index */ Index c ; /* a column index */
int r, row ; /* a row index */ Index r, row ; /* a row index */
int *cp ; /* a column pointer */ Index *cp ; /* a column pointer */
int deg ; /* degree of a row or column */ Index deg ; /* degree of a row or column */
int *cp_end ; /* a pointer to the end of a column */ Index *cp_end ; /* a pointer to the end of a column */
int *new_cp ; /* new column pointer */ Index *new_cp ; /* new column pointer */
int col_length ; /* length of pruned column */ Index col_length ; /* length of pruned column */
int score ; /* current column score */ Index score ; /* current column score */
int n_col2 ; /* number of non-dense, non-empty columns */ Index n_col2 ; /* number of non-dense, non-empty columns */
int n_row2 ; /* number of non-dense, non-empty rows */ Index n_row2 ; /* number of non-dense, non-empty rows */
int dense_row_count ; /* remove rows with more entries than this */ Index dense_row_count ; /* remove rows with more entries than this */
int dense_col_count ; /* remove cols with more entries than this */ Index dense_col_count ; /* remove cols with more entries than this */
int min_score ; /* smallest column score */ Index min_score ; /* smallest column score */
int max_deg ; /* maximum row degree */ Index max_deg ; /* maximum row degree */
int next_col ; /* Used to add to degree list.*/ Index next_col ; /* Used to add to degree list.*/
/* === Extract knobs ==================================================== */ /* === Extract knobs ==================================================== */
@ -842,7 +845,7 @@ static void init_scoring
score = COLAMD_MIN (score, n_col) ; score = COLAMD_MIN (score, n_col) ;
} }
/* determine pruned column length */ /* determine pruned column length */
col_length = (int) (new_cp - &A [Col [c].start]) ; col_length = (Index) (new_cp - &A [Col [c].start]) ;
if (col_length == 0) if (col_length == 0)
{ {
/* a newly-made null column (all rows in this col are "dense" */ /* a newly-made null column (all rows in this col are "dense" */
@ -935,56 +938,56 @@ static void init_scoring
(no supercolumns on input). Uses a minimum approximate column minimum (no supercolumns on input). Uses a minimum approximate column minimum
degree ordering method. Not user-callable. degree ordering method. Not user-callable.
*/ */
template <typename Index>
static int find_ordering /* return the number of garbage collections */ static Index find_ordering /* return the number of garbage collections */
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_row, /* number of rows of A */ Index n_row, /* number of rows of A */
int n_col, /* number of columns of A */ Index n_col, /* number of columns of A */
int Alen, /* size of A, 2*nnz + n_col or larger */ Index Alen, /* size of A, 2*nnz + n_col or larger */
Colamd_Row Row [], /* of size n_row+1 */ Colamd_Row<Index> Row [], /* of size n_row+1 */
colamd_col Col [], /* of size n_col+1 */ colamd_col<Index> Col [], /* of size n_col+1 */
int A [], /* column form and row form of A */ Index A [], /* column form and row form of A */
int head [], /* of size n_col+1 */ Index head [], /* of size n_col+1 */
int n_col2, /* Remaining columns to order */ Index n_col2, /* Remaining columns to order */
int max_deg, /* Maximum row degree */ Index max_deg, /* Maximum row degree */
int pfree /* index of first free slot (2*nnz on entry) */ Index pfree /* index of first free slot (2*nnz on entry) */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int k ; /* current pivot ordering step */ Index k ; /* current pivot ordering step */
int pivot_col ; /* current pivot column */ Index pivot_col ; /* current pivot column */
int *cp ; /* a column pointer */ Index *cp ; /* a column pointer */
int *rp ; /* a row pointer */ Index *rp ; /* a row pointer */
int pivot_row ; /* current pivot row */ Index pivot_row ; /* current pivot row */
int *new_cp ; /* modified column pointer */ Index *new_cp ; /* modified column pointer */
int *new_rp ; /* modified row pointer */ Index *new_rp ; /* modified row pointer */
int pivot_row_start ; /* pointer to start of pivot row */ Index pivot_row_start ; /* pointer to start of pivot row */
int pivot_row_degree ; /* number of columns in pivot row */ Index pivot_row_degree ; /* number of columns in pivot row */
int pivot_row_length ; /* number of supercolumns in pivot row */ Index pivot_row_length ; /* number of supercolumns in pivot row */
int pivot_col_score ; /* score of pivot column */ Index pivot_col_score ; /* score of pivot column */
int needed_memory ; /* free space needed for pivot row */ Index needed_memory ; /* free space needed for pivot row */
int *cp_end ; /* pointer to the end of a column */ Index *cp_end ; /* pointer to the end of a column */
int *rp_end ; /* pointer to the end of a row */ Index *rp_end ; /* pointer to the end of a row */
int row ; /* a row index */ Index row ; /* a row index */
int col ; /* a column index */ Index col ; /* a column index */
int max_score ; /* maximum possible score */ Index max_score ; /* maximum possible score */
int cur_score ; /* score of current column */ Index cur_score ; /* score of current column */
unsigned int hash ; /* hash value for supernode detection */ unsigned int hash ; /* hash value for supernode detection */
int head_column ; /* head of hash bucket */ Index head_column ; /* head of hash bucket */
int first_col ; /* first column in hash bucket */ Index first_col ; /* first column in hash bucket */
int tag_mark ; /* marker value for mark array */ Index tag_mark ; /* marker value for mark array */
int row_mark ; /* Row [row].shared2.mark */ Index row_mark ; /* Row [row].shared2.mark */
int set_difference ; /* set difference size of row with pivot row */ Index set_difference ; /* set difference size of row with pivot row */
int min_score ; /* smallest column score */ Index min_score ; /* smallest column score */
int col_thickness ; /* "thickness" (no. of columns in a supercol) */ Index col_thickness ; /* "thickness" (no. of columns in a supercol) */
int max_mark ; /* maximum value of tag_mark */ Index max_mark ; /* maximum value of tag_mark */
int pivot_col_thickness ; /* number of columns represented by pivot col */ Index pivot_col_thickness ; /* number of columns represented by pivot col */
int prev_col ; /* Used by Dlist operations. */ Index prev_col ; /* Used by Dlist operations. */
int next_col ; /* Used by Dlist operations. */ Index next_col ; /* Used by Dlist operations. */
int ngarbage ; /* number of garbage collections performed */ Index ngarbage ; /* number of garbage collections performed */
/* === Initialization and clear mark ==================================== */ /* === Initialization and clear mark ==================================== */
@ -1274,7 +1277,7 @@ static int find_ordering /* return the number of garbage collections */
} }
/* recompute the column's length */ /* recompute the column's length */
Col [col].length = (int) (new_cp - &A [Col [col].start]) ; Col [col].length = (Index) (new_cp - &A [Col [col].start]) ;
/* === Further mass elimination ================================= */ /* === Further mass elimination ================================= */
@ -1322,7 +1325,7 @@ static int find_ordering /* return the number of garbage collections */
Col [col].shared4.hash_next = first_col ; Col [col].shared4.hash_next = first_col ;
/* save hash function in Col [col].shared3.hash */ /* save hash function in Col [col].shared3.hash */
Col [col].shared3.hash = (int) hash ; Col [col].shared3.hash = (Index) hash ;
COLAMD_ASSERT (COL_IS_ALIVE (col)) ; COLAMD_ASSERT (COL_IS_ALIVE (col)) ;
} }
} }
@ -1419,7 +1422,7 @@ static int find_ordering /* return the number of garbage collections */
/* update pivot row length to reflect any cols that were killed */ /* update pivot row length to reflect any cols that were killed */
/* during super-col detection and mass elimination */ /* during super-col detection and mass elimination */
Row [pivot_row].start = pivot_row_start ; Row [pivot_row].start = pivot_row_start ;
Row [pivot_row].length = (int) (new_rp - &A[pivot_row_start]) ; Row [pivot_row].length = (Index) (new_rp - &A[pivot_row_start]) ;
Row [pivot_row].shared1.degree = pivot_row_degree ; Row [pivot_row].shared1.degree = pivot_row_degree ;
Row [pivot_row].shared2.mark = 0 ; Row [pivot_row].shared2.mark = 0 ;
/* pivot row is no longer dead */ /* pivot row is no longer dead */
@ -1448,22 +1451,22 @@ static int find_ordering /* return the number of garbage collections */
taken by this routine is O (n_col), that is, linear in the number of taken by this routine is O (n_col), that is, linear in the number of
columns. Not user-callable. columns. Not user-callable.
*/ */
template <typename Index>
static inline void order_children static inline void order_children
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_col, /* number of columns of A */ Index n_col, /* number of columns of A */
colamd_col Col [], /* of size n_col+1 */ colamd_col<Index> Col [], /* of size n_col+1 */
int p [] /* p [0 ... n_col-1] is the column permutation*/ Index p [] /* p [0 ... n_col-1] is the column permutation*/
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int i ; /* loop counter for all columns */ Index i ; /* loop counter for all columns */
int c ; /* column index */ Index c ; /* column index */
int parent ; /* index of column's parent */ Index parent ; /* index of column's parent */
int order ; /* column's order */ Index order ; /* column's order */
/* === Order each non-principal column ================================== */ /* === Order each non-principal column ================================== */
@ -1549,33 +1552,33 @@ static inline void order_children
just been computed in the approximate degree computation. just been computed in the approximate degree computation.
Not user-callable. Not user-callable.
*/ */
template <typename Index>
static void detect_super_cols static void detect_super_cols
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
colamd_col Col [], /* of size n_col+1 */ colamd_col<Index> Col [], /* of size n_col+1 */
int A [], /* row indices of A */ Index A [], /* row indices of A */
int head [], /* head of degree lists and hash buckets */ Index head [], /* head of degree lists and hash buckets */
int row_start, /* pointer to set of columns to check */ Index row_start, /* pointer to set of columns to check */
int row_length /* number of columns to check */ Index row_length /* number of columns to check */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int hash ; /* hash value for a column */ Index hash ; /* hash value for a column */
int *rp ; /* pointer to a row */ Index *rp ; /* pointer to a row */
int c ; /* a column index */ Index c ; /* a column index */
int super_c ; /* column index of the column to absorb into */ Index super_c ; /* column index of the column to absorb into */
int *cp1 ; /* column pointer for column super_c */ Index *cp1 ; /* column pointer for column super_c */
int *cp2 ; /* column pointer for column c */ Index *cp2 ; /* column pointer for column c */
int length ; /* length of column super_c */ Index length ; /* length of column super_c */
int prev_c ; /* column preceding c in hash bucket */ Index prev_c ; /* column preceding c in hash bucket */
int i ; /* loop counter */ Index i ; /* loop counter */
int *rp_end ; /* pointer to the end of the row */ Index *rp_end ; /* pointer to the end of the row */
int col ; /* a column index in the row to check */ Index col ; /* a column index in the row to check */
int head_column ; /* first column in hash bucket or degree list */ Index head_column ; /* first column in hash bucket or degree list */
int first_col ; /* first column in hash bucket */ Index first_col ; /* first column in hash bucket */
/* === Consider each column in the row ================================== */ /* === Consider each column in the row ================================== */
@ -1700,27 +1703,27 @@ static void detect_super_cols
itself linear in the number of nonzeros in the input matrix. itself linear in the number of nonzeros in the input matrix.
Not user-callable. Not user-callable.
*/ */
template <typename Index>
static int garbage_collection /* returns the new value of pfree */ static Index garbage_collection /* returns the new value of pfree */
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_row, /* number of rows */ Index n_row, /* number of rows */
int n_col, /* number of columns */ Index n_col, /* number of columns */
Colamd_Row Row [], /* row info */ Colamd_Row<Index> Row [], /* row info */
colamd_col Col [], /* column info */ colamd_col<Index> Col [], /* column info */
int A [], /* A [0 ... Alen-1] holds the matrix */ Index A [], /* A [0 ... Alen-1] holds the matrix */
int *pfree /* &A [0] ... pfree is in use */ Index *pfree /* &A [0] ... pfree is in use */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int *psrc ; /* source pointer */ Index *psrc ; /* source pointer */
int *pdest ; /* destination pointer */ Index *pdest ; /* destination pointer */
int j ; /* counter */ Index j ; /* counter */
int r ; /* a row index */ Index r ; /* a row index */
int c ; /* a column index */ Index c ; /* a column index */
int length ; /* length of a row or column */ Index length ; /* length of a row or column */
/* === Defragment the columns =========================================== */ /* === Defragment the columns =========================================== */
@ -1733,7 +1736,7 @@ static int garbage_collection /* returns the new value of pfree */
/* move and compact the column */ /* move and compact the column */
COLAMD_ASSERT (pdest <= psrc) ; COLAMD_ASSERT (pdest <= psrc) ;
Col [c].start = (int) (pdest - &A [0]) ; Col [c].start = (Index) (pdest - &A [0]) ;
length = Col [c].length ; length = Col [c].length ;
for (j = 0 ; j < length ; j++) for (j = 0 ; j < length ; j++)
{ {
@ -1743,7 +1746,7 @@ static int garbage_collection /* returns the new value of pfree */
*pdest++ = r ; *pdest++ = r ;
} }
} }
Col [c].length = (int) (pdest - &A [Col [c].start]) ; Col [c].length = (Index) (pdest - &A [Col [c].start]) ;
} }
} }
@ -1790,7 +1793,7 @@ static int garbage_collection /* returns the new value of pfree */
/* move and compact the row */ /* move and compact the row */
COLAMD_ASSERT (pdest <= psrc) ; COLAMD_ASSERT (pdest <= psrc) ;
Row [r].start = (int) (pdest - &A [0]) ; Row [r].start = (Index) (pdest - &A [0]) ;
length = Row [r].length ; length = Row [r].length ;
for (j = 0 ; j < length ; j++) for (j = 0 ; j < length ; j++)
{ {
@ -1800,7 +1803,7 @@ static int garbage_collection /* returns the new value of pfree */
*pdest++ = c ; *pdest++ = c ;
} }
} }
Row [r].length = (int) (pdest - &A [Row [r].start]) ; Row [r].length = (Index) (pdest - &A [Row [r].start]) ;
} }
} }
@ -1809,7 +1812,7 @@ static int garbage_collection /* returns the new value of pfree */
/* === Return the new value of pfree ==================================== */ /* === Return the new value of pfree ==================================== */
return ((int) (pdest - &A [0])) ; return ((Index) (pdest - &A [0])) ;
} }
@ -1821,18 +1824,18 @@ static int garbage_collection /* returns the new value of pfree */
Clears the Row [].shared2.mark array, and returns the new tag_mark. Clears the Row [].shared2.mark array, and returns the new tag_mark.
Return value is the new tag_mark. Not user-callable. Return value is the new tag_mark. Not user-callable.
*/ */
template <typename Index>
static inline int clear_mark /* return the new value for tag_mark */ static inline Index clear_mark /* return the new value for tag_mark */
( (
/* === Parameters ======================================================= */ /* === Parameters ======================================================= */
int n_row, /* number of rows in A */ Index n_row, /* number of rows in A */
Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ Colamd_Row<Index> Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */
) )
{ {
/* === Local variables ================================================== */ /* === Local variables ================================================== */
int r ; Index r ;
for (r = 0 ; r < n_row ; r++) for (r = 0 ; r < n_row ; r++)
{ {

View File

@ -122,26 +122,26 @@ class COLAMDOrdering
template <typename MatrixType> template <typename MatrixType>
void operator() (const MatrixType& mat, PermutationType& perm) void operator() (const MatrixType& mat, PermutationType& perm)
{ {
int m = mat.rows(); Index m = mat.rows();
int n = mat.cols(); Index n = mat.cols();
int nnz = mat.nonZeros(); Index nnz = mat.nonZeros();
// Get the recommended value of Alen to be used by colamd // Get the recommended value of Alen to be used by colamd
int Alen = internal::colamd_recommended(nnz, m, n); Index Alen = internal::colamd_recommended(nnz, m, n);
// Set the default parameters // Set the default parameters
double knobs [COLAMD_KNOBS]; double knobs [COLAMD_KNOBS];
int stats [COLAMD_STATS]; Index stats [COLAMD_STATS];
internal::colamd_set_defaults(knobs); internal::colamd_set_defaults(knobs);
int info; Index info;
IndexVector p(n+1), A(Alen); IndexVector p(n+1), A(Alen);
for(int i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i]; for(Index i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
for(int i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i]; for(Index i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
// Call Colamd routine to compute the ordering // Call Colamd routine to compute the ordering
info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats);
eigen_assert( info && "COLAMD failed " ); eigen_assert( info && "COLAMD failed " );
perm.resize(n); perm.resize(n);
for (int i = 0; i < n; i++) perm.indices()(p(i)) = i; for (Index i = 0; i < n; i++) perm.indices()(p(i)) = i;
} }
}; };