673 #ifdef MATLAB_MEX_FILE
678 #if !defined (NPRINT) || !defined (NDEBUG)
683 #define NULL ((void *) 0)
696 #define ID UF_long_id
697 #define Int_MAX UF_long_max
699 #define COLAMD_recommended amesos_colamd_l_recommended
700 #define COLAMD_set_defaults amesos_colamd_l_set_defaults
701 #define COLAMD_MAIN amesos_colamd_l
702 #define SYMAMD_MAIN amesos_symamd_l
703 #define COLAMD_report amesos_colamd_l_report
704 #define SYMAMD_report amesos_symamd_l_report
710 #define Int_MAX INT_MAX
712 #define COLAMD_recommended amesos_colamd_recommended
713 #define COLAMD_set_defaults amesos_colamd_set_defaults
714 #define COLAMD_MAIN amesos_colamd
715 #define SYMAMD_MAIN amesos_symamd
716 #define COLAMD_report amesos_colamd_report
717 #define SYMAMD_report amesos_symamd_report
784 #define PRIVATE static
786 #define DENSE_DEGREE(alpha,n) \
787 ((Int) MAX (16.0, (alpha) * sqrt ((double) (n))))
789 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
790 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
792 #define ONES_COMPLEMENT(r) (-(r)-1)
815 #define DEAD_PRINCIPAL (-1)
816 #define DEAD_NON_PRINCIPAL (-2)
819 #define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark)
820 #define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE)
821 #define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE)
822 #define COL_IS_DEAD(c) (Col [c].start < ALIVE)
823 #define COL_IS_ALIVE(c) (Col [c].start >= ALIVE)
824 #define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL)
825 #define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; }
826 #define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; }
827 #define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; }
833 #if defined (MATLAB_MEX_FILE) || defined (MATHWORKS)
835 #define INDEX(i) ((i)+1)
842 #define PRINTF(params) { if (amesos_colamd_printf != NULL) (void) amesos_colamd_printf params ; }
947 #define DEBUG0(params) { PRINTF (params) ; }
948 #define DEBUG1(params) { if (colamd_debug >= 1) PRINTF (params) ; }
949 #define DEBUG2(params) { if (colamd_debug >= 2) PRINTF (params) ; }
950 #define DEBUG3(params) { if (colamd_debug >= 3) PRINTF (params) ; }
951 #define DEBUG4(params) { if (colamd_debug >= 4) PRINTF (params) ; }
953 #ifdef MATLAB_MEX_FILE
954 #define ASSERT(expression) (mxAssert ((expression), ""))
956 #define ASSERT(expression) (assert (expression))
1007 #define DEBUG0(params) ;
1008 #define DEBUG1(params) ;
1009 #define DEBUG2(params) ;
1010 #define DEBUG3(params) ;
1011 #define DEBUG4(params) ;
1013 #define ASSERT(expression)
1043 static size_t t_add (
size_t a,
size_t b,
int *ok)
1045 (*ok) = (*ok) && ((a + b) >=
MAX (a,b)) ;
1046 return ((*ok) ? (a + b) : 0) ;
1050 static size_t t_mult (
size_t a,
size_t k,
int *ok)
1053 for (i = 0 ; i < k ; i++)
1055 s =
t_add (s, a, ok) ;
1061 #define COLAMD_C(n_col,ok) \
1062 ((t_mult (t_add (n_col, 1, ok), sizeof (Colamd_Col), ok) / sizeof (Int)))
1064 #define COLAMD_R(n_row,ok) \
1065 ((t_mult (t_add (n_row, 1, ok), sizeof (Colamd_Row), ok) / sizeof (Int)))
1079 if (
nnz < 0 || n_row < 0 || n_col < 0)
1086 s =
t_add (s, c, &ok) ;
1087 s =
t_add (s, r, &ok) ;
1088 s =
t_add (s, n_col, &ok) ;
1091 return (ok ? s : 0) ;
1161 void * (*allocate) (size_t, size_t),
1164 void (*release) (
void *)
1189 colamd_get_debug (
"symamd") ;
1196 DEBUG0 ((
"symamd: stats not present\n")) ;
1210 DEBUG0 ((
"symamd: A not present\n")) ;
1217 DEBUG0 ((
"symamd: p not present\n")) ;
1225 DEBUG0 ((
"symamd: n negative %d\n", n)) ;
1234 DEBUG0 ((
"symamd: number of entries negative %d\n", nnz)) ;
1242 DEBUG0 ((
"symamd: p[0] not zero %d\n", p [0])) ;
1251 knobs = default_knobs ;
1256 count = (
Int *) ((*allocate) (n+1,
sizeof (
Int))) ;
1260 DEBUG0 ((
"symamd: allocate count (size %d) failed\n", n+1)) ;
1264 mark = (
Int *) ((*allocate) (n+1,
sizeof (
Int))) ;
1268 (*release) ((
void *) count) ;
1269 DEBUG0 ((
"symamd: allocate mark (size %d) failed\n", n+1)) ;
1277 for (i = 0 ; i < n ; i++)
1282 for (j = 0 ; j < n ; j++)
1286 length = p [j+1] - p [j] ;
1293 (*release) ((
void *) count) ;
1294 (*release) ((
void *) mark) ;
1295 DEBUG0 ((
"symamd: col %d negative length %d\n", j, length)) ;
1299 for (pp = p [j] ; pp < p [j+1] ; pp++)
1302 if (i < 0 || i >= n)
1309 (*release) ((
void *) count) ;
1310 (*release) ((
void *) mark) ;
1311 DEBUG0 ((
"symamd: row %d col %d out of bounds\n", i, j)) ;
1315 if (i <= last_row || mark [i] == j)
1323 DEBUG1 ((
"symamd: row %d col %d unsorted/duplicate\n", i, j)) ;
1326 if (i > j && mark [i] != j)
1346 for (j = 1 ; j <= n ; j++)
1348 perm [j] = perm [j-1] + count [j-1] ;
1350 for (j = 0 ; j < n ; j++)
1352 count [j] = perm [j] ;
1360 M = (
Int *) ((*allocate) (Mlen,
sizeof (
Int))) ;
1361 DEBUG0 ((
"symamd: M is %d-by-%d with %d entries, Mlen = %g\n",
1362 n_row, n, mnz, (
double) Mlen)) ;
1367 (*release) ((
void *) count) ;
1368 (*release) ((
void *) mark) ;
1369 DEBUG0 ((
"symamd: allocate M (size %g) failed\n", (
double) Mlen)) ;
1378 for (j = 0 ; j < n ; j++)
1380 ASSERT (p [j+1] - p [j] >= 0) ;
1381 for (pp = p [j] ; pp < p [j+1] ; pp++)
1384 ASSERT (i >= 0 && i < n) ;
1388 M [count [i]++] = k ;
1389 M [count [j]++] = k ;
1398 DEBUG0 ((
"symamd: Duplicates in A.\n")) ;
1399 for (i = 0 ; i < n ; i++)
1403 for (j = 0 ; j < n ; j++)
1405 ASSERT (p [j+1] - p [j] >= 0) ;
1406 for (pp = p [j] ; pp < p [j+1] ; pp++)
1409 ASSERT (i >= 0 && i < n) ;
1410 if (i > j && mark [i] != j)
1413 M [count [i]++] = k ;
1414 M [count [j]++] = k ;
1424 (*release) ((
void *) count) ;
1425 (*release) ((
void *) mark) ;
1432 cknobs [i] = knobs [i] ;
1442 (void)
COLAMD_MAIN (n_row, n, (
Int) Mlen, M, perm, cknobs, stats) ;
1453 (*release) ((
void *) M) ;
1454 DEBUG0 ((
"symamd: done.\n")) ;
1502 colamd_get_debug (
"colamd") ;
1509 DEBUG0 ((
"colamd: stats not present\n")) ;
1523 DEBUG0 ((
"colamd: A not present\n")) ;
1530 DEBUG0 ((
"colamd: p not present\n")) ;
1538 DEBUG0 ((
"colamd: nrow negative %d\n", n_row)) ;
1546 DEBUG0 ((
"colamd: ncol negative %d\n", n_col)) ;
1555 DEBUG0 ((
"colamd: number of entries negative %d\n", nnz)) ;
1563 DEBUG0 ((
"colamd: p[0] not zero %d\n", p [0])) ;
1572 knobs = default_knobs ;
1584 need =
t_mult (nnz, 2, &ok) ;
1585 need =
t_add (need, n_col, &ok) ;
1586 need =
t_add (need, Col_size, &ok) ;
1587 need =
t_add (need, Row_size, &ok) ;
1589 if (!ok || need > (
size_t) Alen || need >
Int_MAX)
1595 DEBUG0 ((
"colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen));
1599 Alen -= Col_size + Row_size ;
1608 DEBUG0 ((
"colamd: Matrix invalid\n")) ;
1615 &n_row2, &n_col2, &max_deg) ;
1619 ngarbage =
find_ordering (n_row, n_col, Alen, Row, Col, A, p,
1620 n_col2, max_deg, 2*nnz, aggressive) ;
1631 DEBUG0 ((
"colamd: done.\n")) ;
1655 Int stats [COLAMD_STATS]
1708 for (col = 0 ; col < n_col ; col++)
1710 Col [col].start = p [col] ;
1711 Col [col].length = p [col+1] - p [col] ;
1713 if (Col [col].length < 0)
1719 DEBUG0 ((
"colamd: col %d length %d < 0\n", col, Col [col].length)) ;
1723 Col [col].shared1.thickness = 1 ;
1724 Col [col].shared2.score = 0 ;
1725 Col [col].shared3.prev =
EMPTY ;
1726 Col [col].shared4.degree_next =
EMPTY ;
1735 for (row = 0 ; row < n_row ; row++)
1737 Row [row].length = 0 ;
1738 Row [row].shared2.mark = -1 ;
1741 for (col = 0 ; col < n_col ; col++)
1746 cp_end = &A [p [col+1]] ;
1753 if (row < 0 || row >= n_row)
1759 DEBUG0 ((
"colamd: row %d col %d out of bounds\n", row, col)) ;
1763 if (row <= last_row || Row [row].shared2.mark == col)
1771 DEBUG1 ((
"colamd: row %d col %d unsorted/duplicate\n",row,col));
1774 if (Row [row].shared2.mark != col)
1776 Row [row].length++ ;
1782 Col [col].length-- ;
1786 Row [row].shared2.mark = col ;
1796 Row [0].start = p [n_col] ;
1797 Row [0].shared1.p = Row [0].start ;
1798 Row [0].shared2.mark = -1 ;
1799 for (row = 1 ; row < n_row ; row++)
1801 Row [row].start = Row [row-1].start + Row [row-1].length ;
1802 Row [row].shared1.p = Row [row].start ;
1803 Row [row].shared2.mark = -1 ;
1811 for (col = 0 ; col < n_col ; col++)
1814 cp_end = &A [p [col+1]] ;
1818 if (Row [row].shared2.mark != col)
1820 A [(Row [row].shared1.p)++] = col ;
1821 Row [row].shared2.mark = col ;
1829 for (col = 0 ; col < n_col ; col++)
1832 cp_end = &A [p [col+1]] ;
1835 A [(Row [*cp++].shared1.p)++] = col ;
1842 for (row = 0 ; row < n_row ; row++)
1844 Row [row].shared2.mark = 0 ;
1845 Row [row].shared1.degree = Row [row].length ;
1852 DEBUG0 ((
"colamd: reconstructing column form, matrix jumbled\n")) ;
1856 for (col = 0 ; col < n_col ; col++)
1858 p [col] = Col [col].length ;
1860 for (row = 0 ; row < n_row ; row++)
1862 rp = &A [Row [row].start] ;
1863 rp_end = rp + Row [row].length ;
1869 for (col = 0 ; col < n_col ; col++)
1883 p [0] = Col [0].start ;
1884 for (col = 1 ; col < n_col ; col++)
1888 Col [col].start = Col [col-1].start + Col [col-1].length ;
1889 p [col] = Col [col].start ;
1894 for (row = 0 ; row < n_row ; row++)
1896 rp = &A [Row [row].start] ;
1897 rp_end = rp + Row [row].length ;
1900 A [(p [*rp++])++] = row ;
1930 double knobs [COLAMD_KNOBS],
1948 Int dense_row_count ;
1949 Int dense_col_count ;
1964 dense_row_count = n_col-1 ;
1973 dense_col_count = n_row-1 ;
1981 DEBUG1 ((
"colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ;
1990 for (c = n_col-1 ; c >= 0 ; c--)
2000 DEBUG1 ((
"colamd: null columns killed: %d\n", n_col - n_col2)) ;
2005 for (c = n_col-1 ; c >= 0 ; c--)
2013 if (deg > dense_col_count)
2018 cp = &A [Col [c].
start] ;
2019 cp_end = cp + Col [c].length ;
2027 DEBUG1 ((
"colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ;
2031 for (r = 0 ; r < n_row ; r++)
2034 ASSERT (deg >= 0 && deg <= n_col) ;
2035 if (deg > dense_row_count || deg == 0)
2044 max_deg =
MAX (max_deg, deg) ;
2047 DEBUG1 ((
"colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ;
2057 for (c = n_col-1 ; c >= 0 ; c--)
2065 cp = &A [Col [c].
start] ;
2067 cp_end = cp + Col [c].length ;
2082 score =
MIN (score, n_col) ;
2085 col_length = (
Int) (new_cp - &A [Col [c].
start]) ;
2086 if (col_length == 0)
2090 DEBUG2 ((
"Newly null killed: %d\n", c)) ;
2091 Col [c].shared2.order = --n_col2 ;
2098 ASSERT (score <= n_col) ;
2099 Col [c].length = col_length ;
2100 Col [c].shared2.score = score ;
2103 DEBUG1 ((
"colamd: Dense, null, and newly-null columns killed: %d\n",
2112 debug_structures (n_row, n_col, Row, Col, A, n_col2) ;
2122 for (c = 0 ; c <= n_col ; c++)
2129 for (c = n_col-1 ; c >= 0 ; c--)
2134 DEBUG4 ((
"place %d score %d minscore %d ncol %d\n",
2135 c, Col [c].shared2.
score, min_score, n_col)) ;
2141 ASSERT (min_score >= 0) ;
2142 ASSERT (min_score <= n_col) ;
2144 ASSERT (score <= n_col) ;
2148 next_col = head [score] ;
2154 if (next_col !=
EMPTY)
2161 min_score =
MIN (min_score, score) ;
2171 DEBUG1 ((
"colamd: Live cols %d out of %d, non-princ: %d\n",
2172 debug_count, n_col, n_col-debug_count)) ;
2173 ASSERT (debug_count == n_col2) ;
2174 debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ;
2179 *p_n_col2 = n_col2 ;
2180 *p_n_row2 = n_row2 ;
2181 *p_max_deg = max_deg ;
2221 Int pivot_row_start ;
2222 Int pivot_row_degree ;
2223 Int pivot_row_length ;
2224 Int pivot_col_score ;
2237 Int set_difference ;
2241 Int pivot_col_thickness ;
2248 Int debug_step = 0 ;
2253 max_mark = INT_MAX - n_col ;
2254 tag_mark =
clear_mark (0, max_mark, n_row, Row) ;
2257 DEBUG1 ((
"colamd: Ordering, n_col2=%d\n", n_col2)) ;
2261 for (k = 0 ; k < n_col2 ; )
2265 if (debug_step % 100 == 0)
2267 DEBUG2 ((
"\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ;
2271 DEBUG3 ((
"\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ;
2274 debug_deg_lists (n_row, n_col, Row, Col, head,
2275 min_score, n_col2-k, max_deg) ;
2276 debug_matrix (n_row, n_col, Row, Col, A) ;
2282 ASSERT (min_score >= 0) ;
2283 ASSERT (min_score <= n_col) ;
2287 for (debug_d = 0 ; debug_d < min_score ; debug_d++)
2294 while (head [min_score] ==
EMPTY && min_score < n_col)
2298 pivot_col = head [min_score] ;
2299 ASSERT (pivot_col >= 0 && pivot_col <= n_col) ;
2300 next_col = Col [pivot_col].shared4.degree_next ;
2301 head [min_score] = next_col ;
2302 if (next_col !=
EMPTY)
2304 Col [next_col].shared3.prev =
EMPTY ;
2310 pivot_col_score = Col [pivot_col].shared2.score ;
2313 Col [pivot_col].shared2.order = k ;
2316 pivot_col_thickness = Col [pivot_col].shared1.thickness ;
2317 k += pivot_col_thickness ;
2318 ASSERT (pivot_col_thickness > 0) ;
2319 DEBUG3 ((
"Pivot col: %d thick %d\n", pivot_col, pivot_col_thickness)) ;
2323 needed_memory =
MIN (pivot_col_score, n_col - k) ;
2324 if (pfree + needed_memory >= Alen)
2329 ASSERT (pfree + needed_memory < Alen) ;
2331 tag_mark =
clear_mark (0, max_mark, n_row, Row) ;
2334 debug_matrix (n_row, n_col, Row, Col, A) ;
2341 pivot_row_start = pfree ;
2344 pivot_row_degree = 0 ;
2348 Col [pivot_col].shared1.thickness = -pivot_col_thickness ;
2351 cp = &A [Col [pivot_col].start] ;
2352 cp_end = cp + Col [pivot_col].length ;
2361 rp = &A [Row [row].start] ;
2362 rp_end = rp + Row [row].length ;
2368 col_thickness = Col [col].shared1.thickness ;
2372 Col [col].shared1.thickness = -col_thickness ;
2376 pivot_row_degree += col_thickness ;
2383 Col [pivot_col].shared1.thickness = pivot_col_thickness ;
2384 max_deg =
MAX (max_deg, pivot_row_degree) ;
2388 debug_mark (n_row, Row, tag_mark, max_mark) ;
2394 cp = &A [Col [pivot_col].start] ;
2395 cp_end = cp + Col [pivot_col].length ;
2400 DEBUG3 ((
"Kill row in pivot col: %d\n", row)) ;
2406 pivot_row_length = pfree - pivot_row_start ;
2407 if (pivot_row_length > 0)
2410 pivot_row = A [Col [pivot_col].start] ;
2411 DEBUG3 ((
"Pivotal row is %d\n", pivot_row)) ;
2417 ASSERT (pivot_row_length == 0) ;
2419 ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ;
2442 DEBUG3 ((
"** Computing set differences phase. **\n")) ;
2446 DEBUG3 ((
"Pivot row: ")) ;
2448 rp = &A [pivot_row_start] ;
2449 rp_end = rp + pivot_row_length ;
2454 DEBUG3 ((
"Col: %d\n", col)) ;
2457 col_thickness = -Col [col].shared1.thickness ;
2458 ASSERT (col_thickness > 0) ;
2459 Col [col].shared1.thickness = col_thickness ;
2463 cur_score = Col [col].shared2.score ;
2464 prev_col = Col [col].shared3.prev ;
2465 next_col = Col [col].shared4.degree_next ;
2466 ASSERT (cur_score >= 0) ;
2467 ASSERT (cur_score <= n_col) ;
2469 if (prev_col ==
EMPTY)
2471 head [cur_score] = next_col ;
2475 Col [prev_col].shared4.degree_next = next_col ;
2477 if (next_col !=
EMPTY)
2479 Col [next_col].shared3.prev = prev_col ;
2484 cp = &A [Col [col].start] ;
2485 cp_end = cp + Col [col].length ;
2490 row_mark = Row [row].shared2.mark ;
2496 ASSERT (row != pivot_row) ;
2497 set_difference = row_mark - tag_mark ;
2499 if (set_difference < 0)
2501 ASSERT (Row [row].shared1.degree <= max_deg) ;
2502 set_difference = Row [row].shared1.degree ;
2505 set_difference -= col_thickness ;
2506 ASSERT (set_difference >= 0) ;
2508 if (set_difference == 0 && aggressive)
2510 DEBUG3 ((
"aggressive absorption. Row: %d\n", row)) ;
2516 Row [row].shared2.mark = set_difference + tag_mark ;
2522 debug_deg_lists (n_row, n_col, Row, Col, head,
2523 min_score, n_col2-k-pivot_row_degree, max_deg) ;
2528 DEBUG3 ((
"** Adding set differences phase. **\n")) ;
2531 rp = &A [pivot_row_start] ;
2532 rp_end = rp + pivot_row_length ;
2540 cp = &A [Col [col].start] ;
2543 cp_end = cp + Col [col].length ;
2545 DEBUG4 ((
"Adding set diffs for Col: %d.\n", col)) ;
2551 ASSERT(row >= 0 && row < n_row) ;
2552 row_mark = Row [row].shared2.mark ;
2556 DEBUG4 ((
" Row %d, dead\n", row)) ;
2559 DEBUG4 ((
" Row %d, set diff %d\n", row, row_mark-tag_mark));
2560 ASSERT (row_mark >= tag_mark) ;
2566 cur_score += row_mark - tag_mark ;
2568 cur_score =
MIN (cur_score, n_col) ;
2572 Col [col].length = (
Int) (new_cp - &A [Col [col].
start]) ;
2576 if (Col [col].length == 0)
2578 DEBUG4 ((
"further mass elimination. Col: %d\n", col)) ;
2581 pivot_row_degree -= Col [col].shared1.thickness ;
2582 ASSERT (pivot_row_degree >= 0) ;
2584 Col [col].shared2.order = k ;
2586 k += Col [col].shared1.thickness ;
2592 DEBUG4 ((
"Preparing supercol detection for Col: %d.\n", col)) ;
2595 Col [col].shared2.score = cur_score ;
2600 DEBUG4 ((
" Hash = %d, n_col = %d.\n", hash, n_col)) ;
2603 head_column = head [hash] ;
2604 if (head_column >
EMPTY)
2608 first_col = Col [head_column].shared3.headhash ;
2609 Col [head_column].shared3.headhash = col ;
2614 first_col = - (head_column + 2) ;
2615 head [hash] = - (col + 2) ;
2617 Col [col].shared4.hash_next = first_col ;
2620 Col [col].shared3.hash = (
Int) hash ;
2629 DEBUG3 ((
"** Supercolumn detection phase. **\n")) ;
2637 Col, A, head, pivot_row_start, pivot_row_length) ;
2645 tag_mark =
clear_mark (tag_mark+max_deg+1, max_mark, n_row, Row) ;
2649 debug_mark (n_row, Row, tag_mark, max_mark) ;
2654 DEBUG3 ((
"** Finalize scores phase. **\n")) ;
2657 rp = &A [pivot_row_start] ;
2660 rp_end = rp + pivot_row_length ;
2671 A [Col [col].start + (Col [col].length++)] = pivot_row ;
2676 cur_score = Col [col].shared2.score + pivot_row_degree ;
2681 max_score = n_col - k - Col [col].shared1.thickness ;
2684 cur_score -= Col [col].shared1.thickness ;
2687 cur_score =
MIN (cur_score, max_score) ;
2688 ASSERT (cur_score >= 0) ;
2691 Col [col].shared2.score = cur_score ;
2695 ASSERT (min_score >= 0) ;
2696 ASSERT (min_score <= n_col) ;
2697 ASSERT (cur_score >= 0) ;
2698 ASSERT (cur_score <= n_col) ;
2700 next_col = head [cur_score] ;
2701 Col [col].shared4.degree_next = next_col ;
2702 Col [col].shared3.prev =
EMPTY ;
2703 if (next_col !=
EMPTY)
2705 Col [next_col].shared3.prev = col ;
2707 head [cur_score] = col ;
2710 min_score =
MIN (min_score, cur_score) ;
2715 debug_deg_lists (n_row, n_col, Row, Col, head,
2716 min_score, n_col2-k, max_deg) ;
2721 if (pivot_row_degree > 0)
2725 Row [pivot_row].start = pivot_row_start ;
2726 Row [pivot_row].length = (
Int) (new_rp - &A[pivot_row_start]) ;
2727 ASSERT (Row [pivot_row].length > 0) ;
2728 Row [pivot_row].shared1.degree = pivot_row_degree ;
2729 Row [pivot_row].shared2.mark = 0 ;
2732 DEBUG1 ((
"Resurrect Pivot_row %d deg: %d\n",
2733 pivot_row, pivot_row_degree)) ;
2778 for (i = 0 ; i < n_col ; i++)
2821 for (c = 0 ; c < n_col ; c++)
2896 rp = &A [row_start] ;
2897 rp_end = rp + row_length ;
2907 hash = Col [col].shared3.hash ;
2912 head_column = head [hash] ;
2913 if (head_column >
EMPTY)
2915 first_col = Col [head_column].shared3.headhash ;
2919 first_col = - (head_column + 2) ;
2924 for (super_c = first_col ; super_c !=
EMPTY ;
2925 super_c = Col [super_c].shared4.hash_next)
2928 ASSERT (Col [super_c].shared3.hash == hash) ;
2929 length = Col [super_c].length ;
2936 for (c = Col [super_c].shared4.hash_next ;
2937 c !=
EMPTY ; c = Col [c].shared4.hash_next)
2941 ASSERT (Col [c].shared3.hash == hash) ;
2944 if (Col [c].length != length ||
2945 Col [c].shared2.score != Col [super_c].shared2.score)
2952 cp1 = &A [Col [super_c].start] ;
2953 cp2 = &A [Col [c].start] ;
2955 for (i = 0 ; i < length ; i++)
2962 if (*cp1++ != *cp2++)
2977 ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ;
2979 Col [super_c].shared1.thickness += Col [c].shared1.thickness ;
2980 Col [c].shared1.parent = super_c ;
2983 Col [c].shared2.order =
EMPTY ;
2985 Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ;
2991 if (head_column >
EMPTY)
2994 Col [head_column].shared3.headhash =
EMPTY ;
2999 head [hash] =
EMPTY ;
3041 DEBUG2 ((
"Defrag..\n")) ;
3042 for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ;
3049 for (c = 0 ; c < n_col ; c++)
3053 psrc = &A [Col [c].start] ;
3057 Col [c].start = (
Int) (pdest - &A [0]) ;
3058 length = Col [c].length ;
3059 for (j = 0 ; j < length ; j++)
3067 Col [c].length = (
Int) (pdest - &A [Col [c].
start]) ;
3073 for (r = 0 ; r < n_row ; r++)
3086 psrc = &A [Row [r].start] ;
3087 Row [r].shared2.first_column = *psrc ;
3100 while (psrc < pfree)
3108 ASSERT (r >= 0 && r < n_row) ;
3110 *psrc = Row [r].shared2.first_column ;
3112 ASSERT (Row [r].length > 0) ;
3115 Row [r].start = (
Int) (pdest - &A [0]) ;
3116 length = Row [r].length ;
3117 for (j = 0 ; j < length ; j++)
3125 Row [r].length = (
Int) (pdest - &A [Row [r].
start]) ;
3126 ASSERT (Row [r].length > 0) ;
3133 ASSERT (debug_rows == 0) ;
3137 return ((
Int) (pdest - &A [0])) ;
3165 if (tag_mark <= 0 || tag_mark >= max_mark)
3167 for (r = 0 ; r < n_row ; r++)
3171 Row [r].shared2.mark = 0 ;
3188 Int stats [COLAMD_STATS]
3194 PRINTF ((
"\n%s version %d.%d, %s: ", method,
3199 PRINTF ((
"No statistics available.\n")) ;
3221 PRINTF((
"Matrix has unsorted or duplicate row indices.\n")) ;
3223 PRINTF((
"%s: number of duplicate or out-of-order row indices: %d\n",
3226 PRINTF((
"%s: last seen duplicate or out-of-order row index: %d\n",
3227 method,
INDEX (i2))) ;
3229 PRINTF((
"%s: last seen in column: %d",
3230 method,
INDEX (i1))) ;
3238 PRINTF((
"%s: number of dense or empty rows ignored: %d\n",
3241 PRINTF((
"%s: number of dense or empty columns ignored: %d\n",
3244 PRINTF((
"%s: number of garbage collections performed: %d\n",
3250 PRINTF((
"Array A (row indices of matrix) not present.\n")) ;
3255 PRINTF((
"Array p (column pointers for matrix) not present.\n")) ;
3260 PRINTF((
"Invalid number of rows (%d).\n", i1)) ;
3265 PRINTF((
"Invalid number of columns (%d).\n", i1)) ;
3270 PRINTF((
"Invalid number of nonzero entries (%d).\n", i1)) ;
3275 PRINTF((
"Invalid column pointer, p [0] = %d, must be zero.\n", i1));
3280 PRINTF((
"Array A too small.\n")) ;
3281 PRINTF((
" Need Alen >= %d, but given only Alen = %d.\n",
3288 ((
"Column %d has a negative number of nonzero entries (%d).\n",
3295 ((
"Row index (row %d) out of bounds (%d to %d) in column %d.\n",
3301 PRINTF((
"Out of memory.\n")) ;
3358 for (c = 0 ; c < n_col ; c++)
3364 DEBUG4 ((
"initial live col %5d %5d %5d\n", c, len, score)) ;
3368 cp = &A [Col [c].
start] ;
3378 i = Col [c].shared2.order ;
3379 ASSERT (i >= n_col2 && i < n_col) ;
3383 for (r = 0 ; r < n_row ; r++)
3392 rp = &A [Row [r].
start] ;
3441 if (n_col > 10000 && colamd_debug <= 0)
3446 DEBUG4 ((
"Degree lists: %d\n", min_score)) ;
3447 for (deg = 0 ; deg <= n_col ; deg++)
3455 while (col !=
EMPTY)
3464 DEBUG4 ((
"should %d have %d\n", should, have)) ;
3465 ASSERT (should == have) ;
3469 if (n_row > 10000 && colamd_debug <= 0)
3473 for (row = 0 ; row < n_row ; row++)
3508 ASSERT (tag_mark > 0 && tag_mark <= max_mark) ;
3509 if (n_row > 10000 && colamd_debug <= 0)
3513 for (r = 0 ; r < n_row ; r++)
3550 if (colamd_debug < 3)
3554 DEBUG3 ((
"DUMP MATRIX:\n")) ;
3555 for (r = 0 ; r < n_row ; r++)
3562 DEBUG3 ((
"start %d length %d degree %d\n",
3563 Row [r].
start, Row [r].length, Row [r].shared1.
degree)) ;
3564 rp = &A [Row [r].
start] ;
3565 rp_end = rp + Row [r].length ;
3573 for (c = 0 ; c < n_col ; c++)
3580 DEBUG3 ((
"start %d length %d shared1 %d shared2 %d\n",
3581 Col [c].
start, Col [c].length,
3583 cp = &A [Col [c].
start] ;
3584 cp_end = cp + Col [c].length ;
3600 f = fopen (
"debug",
"r") ;
3601 if (f == (FILE *)
NULL)
3607 fscanf (f,
"%d", &colamd_debug) ;
3610 DEBUG0 ((
"%s: debug version, D = %d (THIS WILL BE SLOW!)\n",
3611 method, colamd_debug)) ;
union Colamd_Row_struct::@17 shared2
PRIVATE void print_report(char *method, Int stats[COLAMD_STATS])
#define COLAMD_ERROR_ncol_negative
#define COLAMD_MAIN_VERSION
UF_long CHOLMOD() nnz(cholmod_sparse *A, cholmod_common *Common)
static size_t t_add(size_t a, size_t b, int *ok)
#define COLAMD_ERROR_p0_nonzero
#define COL_IS_DEAD_PRINCIPAL(c)
#define COLAMD_ERROR_row_index_out_of_bounds
union Colamd_Row_struct::@16 shared1
PRIVATE Int init_rows_cols(Int n_row, Int n_col, Colamd_Row Row[], Colamd_Col Col[], Int A[], Int p[], Int stats[COLAMD_STATS])
PRIVATE Int garbage_collection(Int n_row, Int n_col, Colamd_Row Row[], Colamd_Col Col[], Int A[], Int *pfree)
struct Colamd_Col_struct Colamd_Col
#define COLAMD_ERROR_nrow_negative
#define COLAMD_ERROR_out_of_memory
#define COLAMD_OK_BUT_JUMBLED
#define ROW_IS_MARKED_DEAD(row_mark)
#define ASSERT(expression)
#define COLAMD_C(n_col, ok)
PRIVATE void order_children(Int n_col, Colamd_Col Col[], Int p[])
#define COLAMD_set_defaults
#define COLAMD_AGGRESSIVE
#define COLAMD_R(n_row, ok)
#define COLAMD_DEFRAG_COUNT
union Colamd_Col_struct::@13 shared2
#define KILL_PRINCIPAL_COL(c)
#define COLAMD_ERROR_nnz_negative
PRIVATE void detect_super_cols(Colamd_Col Col[], Int A[], Int head[], Int row_start, Int row_length)
int CHOLMOD() start(cholmod_common *Common)
#define COLAMD_ERROR_A_not_present
#define COLAMD_ERROR_A_too_small
#define COLAMD_recommended
union Colamd_Col_struct::@12 shared1
PRIVATE 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, Int aggressive)
#define COLAMD_SUB_VERSION
struct Colamd_Row_struct Colamd_Row
PRIVATE Int clear_mark(Int tag_mark, Int max_mark, Int n_row, Colamd_Row Row[])
#define COLAMD_ERROR_col_length_negative
#define KILL_NON_PRINCIPAL_COL(c)
static size_t t_mult(size_t a, size_t k, int *ok)
#define DENSE_DEGREE(alpha, n)
PRIVATE 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)
union Colamd_Col_struct::@15 shared4
union Colamd_Col_struct::@14 shared3
#define COLAMD_ERROR_p_not_present
#define ONES_COMPLEMENT(r)