47 #ifdef USE_64_BIT_IDX_T
48 #define COLAMD_NAME(name) colamd_l ## name
49 #define SYMAMD_NAME(name) symamd_l ## name
51 #define COLAMD_NAME(name) colamd ## name
52 #define SYMAMD_NAME(name) symamd ## name
83 for ( ; Flag[i] != k ; i = Parent[i])
135 postnum =
etdfs (
w, first_kid, next_kid, post, postnum);
157 next_kid[v] = first_kid[dad];
162 etdfs (n, first_kid, next_kid, post, 0);
182 if (firstcol[row] > col)
205 cset =
link (cset, rset, pp);
214 @deftypefn {Loadable Function} {@var{p} =} colamd (@var{S})\n\
215 @deftypefnx {Loadable Function} {@var{p} =} colamd (@var{S}, @var{knobs})\n\
216 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S})\n\
217 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} colamd (@var{S}, @var{knobs})\n\
219 Column approximate minimum degree permutation.\n\
220 @code{@var{p} = colamd (@var{S})} returns the column approximate minimum\n\
221 degree permutation vector for the sparse matrix @var{S}. For a\n\
222 non-symmetric matrix @var{S}, @code{@var{S}(:,@var{p})} tends to have\n\
223 sparser LU@tie{}factors than @var{S}. The Cholesky@tie{}factorization of\n\
224 @code{@var{S}(:,@var{p})' * @var{S}(:,@var{p})} also tends to be sparser\n\
225 than that of @code{@var{S}' * @var{S}}.\n\
227 @var{knobs} is an optional one- to three-element input vector. If @var{S} is\n\
228 m-by-n, then rows with more than @code{max(16,@var{knobs}(1)*sqrt(n))}\n\
229 entries are ignored. Columns with more than\n\
230 @code{max (16,@var{knobs}(2)*sqrt(min(m,n)))} entries are removed prior to\n\
231 ordering, and ordered last in the output permutation @var{p}. Only\n\
232 completely dense rows or columns are removed if @code{@var{knobs}(1)} and\n\
233 @code{@var{knobs}(2)} are < 0, respectively. If @code{@var{knobs}(3)} is\n\
234 nonzero, @var{stats} and @var{knobs} are printed. The default is\n\
235 @code{@var{knobs} = [10 10 0]}. Note that @var{knobs} differs from earlier\n\
236 versions of colamd.\n\
238 @var{stats} is an optional 20-element output vector that provides data\n\
239 about the ordering and the validity of the input matrix @var{S}. Ordering\n\
240 statistics are in @code{@var{stats}(1:3)}. @code{@var{stats}(1)} and\n\
241 @code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
242 ignored by @sc{colamd} and @code{@var{stats}(3)} is the number of garbage\n\
243 collections performed on the internal data structure used by @sc{colamd}\n\
244 (roughly of size @code{2.2 * nnz(@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
247 Octave built-in functions are intended to generate valid sparse matrices,\n\
248 with no duplicate entries, with ascending row indices of the nonzeros\n\
249 in each column, with a non-negative number of entries in each column (!)\n\
250 and so on. If a matrix is invalid, then @sc{colamd} may or may not be able\n\
251 to continue. If there are duplicate entries (a row index appears two or\n\
252 more times in the same column) or if the row indices in a column are out\n\
253 of order, then @sc{colamd} can correct these errors by ignoring the duplicate\n\
254 entries and sorting each column of its internal copy of the matrix\n\
255 @var{S} (the input matrix @var{S} is not repaired, however). If a matrix\n\
256 is invalid in other ways then @sc{colamd} cannot continue, an error message\n\
257 is printed, and no output arguments (@var{p} or @var{stats}) are returned.\n\
258 @sc{colamd} is thus a simple way to check a sparse matrix to see if it's\n\
261 @code{@var{stats}(4:7)} provide information if COLAMD was able to\n\
262 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
263 invalid. @code{@var{stats}(5)} is the rightmost column index that is\n\
264 unsorted or contains duplicate entries, or zero if no such column exists.\n\
265 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
266 index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
267 such row index exists. @code{@var{stats}(7)} is the number of duplicate\n\
268 or out-of-order row indices. @code{@var{stats}(8:20)} is always zero in\n\
269 the current version of @sc{colamd} (reserved for future use).\n\
271 The ordering is followed by a column elimination tree post-ordering.\n\
273 The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
274 Davis @email{davis@@cise.ufl.edu}, University of Florida. The algorithm was\n\
275 developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
276 Ng, Oak Ridge National Laboratory. (see\n\
277 @url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
278 @seealso{colperm, symamd, ccolamd}\n\
285 int nargin = args.
length ();
288 if (nargout > 2 || nargin < 1 || nargin > 2)
299 NDArray User_knobs = args(1).array_value ();
300 int nel_User_knobs = User_knobs.
length ();
302 if (nel_User_knobs > 0)
303 knobs[COLAMD_DENSE_ROW] = User_knobs(0);
304 if (nel_User_knobs > 1)
305 knobs[COLAMD_DENSE_COL] = User_knobs(1) ;
306 if (nel_User_knobs > 2)
307 spumoni =
static_cast<int> (User_knobs(2));
314 <<
"." << COLAMD_SUB_VERSION
315 <<
", " << COLAMD_DATE <<
":\n";
317 if (knobs[COLAMD_DENSE_ROW] >= 0)
319 <<
", rows with > max (16,"
320 << knobs[COLAMD_DENSE_ROW] <<
"*sqrt (size(A,2)))"
321 <<
" entries removed\n";
324 <<
", only completely dense rows removed\n";
326 if (knobs[COLAMD_DENSE_COL] >= 0)
328 <<
", cols with > max (16,"
329 << knobs[COLAMD_DENSE_COL] <<
"*sqrt (size(A)))"
330 <<
" entries removed\n";
333 <<
", only completely dense columns removed\n";
336 <<
", statistics and knobs printed\n";
346 if (args(0).is_sparse_type ())
348 if (args(0).is_complex_type ())
350 scm = args(0). sparse_complex_matrix_value ();
359 sm = args(0).sparse_matrix_value ();
370 if (args(0).is_complex_type ())
394 if (!
COLAMD_NAME () (n_row, n_col, Alen,
A, p, knobs, stats))
397 error (
"colamd: internal error!");
408 colbeg[i] = cidx[p[i]];
409 colend[i] = cidx[p[i]+1];
412 coletree (ridx, colbeg, colend, etree, n_row, n_col);
420 out_perm(i) = p[colbeg[i]] + 1;
422 retval(0) = out_perm;
433 out_stats(i) = stats[i] ;
434 retval(1) = out_stats;
439 out_stats (COLAMD_INFO1) ++ ;
440 out_stats (COLAMD_INFO2) ++ ;
446 error (
"colamd: not available in this version of Octave");
455 @deftypefn {Loadable Function} {@var{p} =} symamd (@var{S})\n\
456 @deftypefnx {Loadable Function} {@var{p} =} symamd (@var{S}, @var{knobs})\n\
457 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S})\n\
458 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} symamd (@var{S}, @var{knobs})\n\
460 For a symmetric positive definite matrix @var{S}, returns the permutation\n\
461 vector p such that @code{@var{S}(@var{p}, @var{p})} tends to have a\n\
462 sparser Cholesky@tie{}factor than @var{S}. Sometimes @code{symamd} works\n\
463 well for symmetric indefinite matrices too. The matrix @var{S} is assumed\n\
464 to be symmetric; only the strictly lower triangular part is referenced.\n\
465 @var{S} must be square.\n\
467 @var{knobs} is an optional one- to two-element input vector. If @var{S} is\n\
468 n-by-n, then rows and columns with more than\n\
469 @code{max (16,@var{knobs}(1)*sqrt(n))} entries are removed prior to ordering,\n\
470 and ordered last in the output permutation @var{p}. No rows/columns are\n\
471 removed if @code{@var{knobs}(1) < 0}. If @code{@var{knobs} (2)} is nonzero,\n\
472 @code{stats} and @var{knobs} are printed. The default is @code{@var{knobs}\n\
473 = [10 0]}. Note that @var{knobs} differs from earlier versions of symamd.\n\
475 @var{stats} is an optional 20-element output vector that provides data\n\
476 about the ordering and the validity of the input matrix @var{S}. Ordering\n\
477 statistics are in @code{@var{stats}(1:3)}. @code{@var{stats}(1) =\n\
478 @var{stats}(2)} is the number of dense or empty rows and columns\n\
479 ignored by SYMAMD and @code{@var{stats}(3)} is the number of garbage\n\
480 collections performed on the internal data structure used by SYMAMD\n\
481 (roughly of size @code{8.4 * nnz (tril (@var{S}, -1)) + 9 * @var{n}}\n\
484 Octave built-in functions are intended to generate valid sparse matrices,\n\
485 with no duplicate entries, with ascending row indices of the nonzeros\n\
486 in each column, with a non-negative number of entries in each column (!)\n\
487 and so on. If a matrix is invalid, then SYMAMD may or may not be able\n\
488 to continue. If there are duplicate entries (a row index appears two or\n\
489 more times in the same column) or if the row indices in a column are out\n\
490 of order, then SYMAMD can correct these errors by ignoring the duplicate\n\
491 entries and sorting each column of its internal copy of the matrix S (the\n\
492 input matrix S is not repaired, however). If a matrix is invalid in\n\
493 other ways then SYMAMD cannot continue, an error message is printed, and\n\
494 no output arguments (@var{p} or @var{stats}) are returned. SYMAMD is\n\
495 thus a simple way to check a sparse matrix to see if it's valid.\n\
497 @code{@var{stats}(4:7)} provide information if SYMAMD was able to\n\
498 continue. The matrix is OK if @code{@var{stats} (4)} is zero, or 1\n\
499 if invalid. @code{@var{stats}(5)} is the rightmost column index that\n\
500 is unsorted or contains duplicate entries, or zero if no such column\n\
501 exists. @code{@var{stats}(6)} is the last seen duplicate or out-of-order\n\
502 row index in the column index given by @code{@var{stats}(5)}, or zero\n\
503 if no such row index exists. @code{@var{stats}(7)} is the number of\n\
504 duplicate or out-of-order row indices. @code{@var{stats}(8:20)} is\n\
505 always zero in the current version of SYMAMD (reserved for future use).\n\
507 The ordering is followed by a column elimination tree post-ordering.\n\
509 The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
510 Davis @email{davis@@cise.ufl.edu}, University of Florida. The algorithm was\n\
511 developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
512 Ng, Oak Ridge National Laboratory. (see\n\
513 @url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
514 @seealso{colperm, colamd}\n\
521 int nargin = args.
length ();
524 if (nargout > 2 || nargin < 1 || nargin > 2)
535 NDArray User_knobs = args(1).array_value ();
536 int nel_User_knobs = User_knobs.
length ();
538 if (nel_User_knobs > 0)
539 knobs[COLAMD_DENSE_ROW] = User_knobs(COLAMD_DENSE_ROW);
540 if (nel_User_knobs > 1)
541 spumoni =
static_cast<int> (User_knobs (1));
547 << knobs[COLAMD_DENSE_ROW] << std::endl;
554 if (args(0).is_sparse_type ())
556 if (args(0).is_complex_type ())
558 scm = args(0).sparse_complex_matrix_value ();
566 sm = args(0).sparse_matrix_value ();
575 if (args(0).is_complex_type ())
588 error (
"symamd: matrix S must be square");
596 knobs, stats, &calloc, &free))
599 error (
"symamd: internal error!") ;
605 symetree (ridx, cidx, etree, perm, n_col);
614 out_perm(i) = perm[post[i]] + 1;
616 retval(0) = out_perm;
627 out_stats(i) = stats[i] ;
628 retval(1) = out_stats;
633 out_stats (COLAMD_INFO1) ++ ;
634 out_stats (COLAMD_INFO2) ++ ;
640 error (
"symamd: not available in this version of Octave");
649 @deftypefn {Loadable Function} {@var{p} =} etree (@var{S})\n\
650 @deftypefnx {Loadable Function} {@var{p} =} etree (@var{S}, @var{typ})\n\
651 @deftypefnx {Loadable Function} {[@var{p}, @var{q}] =} etree (@var{S}, @var{typ})\n\
653 Return the elimination tree for the matrix @var{S}. By default @var{S}\n\
654 is assumed to be symmetric and the symmetric elimination tree is\n\
655 returned. The argument @var{typ} controls whether a symmetric or\n\
656 column elimination tree is returned. Valid values of @var{typ} are\n\
657 @qcode{\"sym\"} or @qcode{\"col\"}, for symmetric or column elimination tree\n\
660 Called with a second argument, @code{etree} also returns the postorder\n\
661 permutations on the tree.\n\
666 int nargin = args.
length ();
668 if (nargout > 2 || nargin < 1 || nargin > 2)
678 if (args(0).is_sparse_type ())
680 if (args(0).is_complex_type ())
682 scm = args(0).sparse_complex_matrix_value ();
690 sm = args(0).sparse_matrix_value ();
700 error (
"etree: S must be a sparse matrix");
706 if (args(1).is_string ())
708 std::string str = args(1).string_value ();
709 if (str.find (
"C") == 0 || str.find (
"c") == 0)
714 error (
"etree: TYP must be a string");
726 error (
"etree: S is marked as symmetric, but is not square");
730 symetree (ridx, cidx, etree, 0, n_col);
740 colend[i] = cidx[i+1];
743 coletree (ridx, colbeg, colend, etree, n_row, n_col);
750 if (etree[i] == n_col)
753 tree(i) = etree[i] + 1;
765 postorder(i) = post[i] + 1;
767 retval(1) = postorder;