46 #ifdef USE_64_BIT_IDX_T
47 #define CCOLAMD_NAME(name) ccolamd_l ## name
48 #define CSYMAMD_NAME(name) csymamd_l ## name
50 #define CCOLAMD_NAME(name) ccolamd ## name
51 #define CSYMAMD_NAME(name) csymamd ## name
56 @deftypefn {Loadable Function} {@var{p} =} ccolamd (@var{S})\n\
57 @deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs})\n\
58 @deftypefnx {Loadable Function} {@var{p} =} ccolamd (@var{S}, @var{knobs}, @var{cmember})\n\
59 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} ccolamd (@dots{})\n\
61 Constrained column approximate minimum degree permutation.\n\
62 @code{@var{p} = ccolamd (@var{S})} returns the column approximate minimum\n\
63 degree permutation vector for the sparse matrix @var{S}. For a non-symmetric\n\
66 @code{@var{S}(:, @var{p})} tends to have sparser LU@tie{}factors than\n\
67 @var{S}. @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))} also\n\
68 tends to be sparser than @code{chol (@var{S}' * @var{S})}. @code{@var{p} =\n\
69 ccolamd (@var{S}, 1)} optimizes the ordering for @code{lu (@var{S}(:,\n\
70 @var{p}))}. The ordering is followed by a column elimination tree\n\
73 @var{knobs} is an optional 1-element to 5-element input vector, with a\n\
74 default value of @code{[0 10 10 1 0]} if not present or empty. Entries not\n\
75 present are set to their defaults.\n\
78 @item @var{knobs}(1)\n\
79 if nonzero, the ordering is optimized for @code{lu (S(:, p))}. It will be a\n\
80 poor ordering for @code{chol (@var{S}(:, @var{p})' * @var{S}(:,\n\
81 @var{p}))}. This is the most important knob for ccolamd.\n\
83 @item @var{knobs}(2)\n\
84 if @var{S} is m-by-n, rows with more than @code{max (16, @var{knobs}(2) *\n\
85 sqrt (n))} entries are ignored.\n\
87 @item @var{knobs}(3)\n\
88 columns with more than @code{max (16, @var{knobs}(3) * sqrt (min (@var{m},\n\
89 @var{n})))} entries are ignored and ordered last in the output permutation\n\
90 (subject to the cmember constraints).\n\
92 @item @var{knobs}(4)\n\
93 if nonzero, aggressive absorption is performed.\n\
95 @item @var{knobs}(5)\n\
96 if nonzero, statistics and knobs are printed.\n\
100 @var{cmember} is an optional vector of length @math{n}. It defines the\n\
101 constraints on the column ordering. If @code{@var{cmember}(j) = @var{c}},\n\
102 then column @var{j} is in constraint set @var{c} (@var{c} must be in the\n\
104 n). In the output permutation @var{p}, all columns in set 1 appear\n\
105 first, followed by all columns in set 2, and so on. @code{@var{cmember} =\n\
106 ones (1,n)} if not present or empty.\n\
107 @code{ccolamd (@var{S}, [], 1 : n)} returns @code{1 : n}\n\
109 @code{@var{p} = ccolamd (@var{S})} is about the same as\n\
110 @code{@var{p} = colamd (@var{S})}. @var{knobs} and its default values\n\
111 differ. @code{colamd} always does aggressive absorption, and it finds an\n\
112 ordering suitable for both @code{lu (@var{S}(:, @var{p}))} and @code{chol\n\
113 (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))}; it cannot optimize its\n\
114 ordering for @code{lu (@var{S}(:, @var{p}))} to the extent that\n\
115 @code{ccolamd (@var{S}, 1)} can.\n\
117 @var{stats} is an optional 20-element output vector that provides data\n\
118 about the ordering and the validity of the input matrix @var{S}. Ordering\n\
119 statistics are in @code{@var{stats}(1 : 3)}. @code{@var{stats}(1)} and\n\
120 @code{@var{stats}(2)} are the number of dense or empty rows and columns\n\
121 ignored by @sc{ccolamd} and @code{@var{stats}(3)} is the number of garbage\n\
122 collections performed on the internal data structure used by @sc{ccolamd}\n\
123 (roughly of size @code{2.2 * nnz (@var{S}) + 4 * @var{m} + 7 * @var{n}}\n\
126 @code{@var{stats}(4 : 7)} provide information if CCOLAMD was able to\n\
127 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
128 invalid. @code{@var{stats}(5)} is the rightmost column index that is\n\
129 unsorted or contains duplicate entries, or zero if no such column exists.\n\
130 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
131 index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
132 such row index exists. @code{@var{stats}(7)} is the number of duplicate\n\
133 or out-of-order row indices. @code{@var{stats}(8 : 20)} is always zero in\n\
134 the current version of @sc{ccolamd} (reserved for future use).\n\
136 The authors of the code itself are S. Larimore, T. Davis (Univ. of Florida)\n\
137 and S. Rajamanickam in collaboration with J. Bilbert and E. Ng. Supported\n\
138 by the National Science Foundation\n\
139 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from Sandia\n\
140 National Lab. See @url{http://www.cise.ufl.edu/research/sparse} for\n\
141 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
142 @seealso{colamd, csymamd}\n\
149 int nargin = args.
length ();
152 if (nargout > 2 || nargin < 1 || nargin > 3)
153 usage (
"ccolamd: incorrect number of input and/or output arguments");
163 NDArray User_knobs = args(1).array_value ();
164 int nel_User_knobs = User_knobs.
length ();
166 if (nel_User_knobs > 0)
167 knobs[CCOLAMD_LU] = (User_knobs(0) != 0);
168 if (nel_User_knobs > 1)
169 knobs[CCOLAMD_DENSE_ROW] = User_knobs(1);
170 if (nel_User_knobs > 2)
171 knobs[CCOLAMD_DENSE_COL] = User_knobs(2);
172 if (nel_User_knobs > 3)
173 knobs[CCOLAMD_AGGRESSIVE] = (User_knobs(3) != 0);
174 if (nel_User_knobs > 4)
175 spumoni = (User_knobs(4) != 0);
180 octave_stdout <<
"\nccolamd version " << CCOLAMD_MAIN_VERSION <<
"."
181 << CCOLAMD_SUB_VERSION <<
", " << CCOLAMD_DATE
182 <<
":\nknobs(1): " << User_knobs(0) <<
", order for ";
183 if (knobs[CCOLAMD_LU] != 0)
188 if (knobs[CCOLAMD_DENSE_ROW] >= 0)
190 <<
", rows with > max (16,"
191 << knobs[CCOLAMD_DENSE_ROW]
192 <<
"*sqrt (size(A,2)))"
193 <<
" entries removed\n";
196 <<
", no dense rows removed\n";
198 if (knobs[CCOLAMD_DENSE_COL] >= 0)
200 <<
", cols with > max (16,"
201 << knobs[CCOLAMD_DENSE_COL] <<
"*sqrt (size(A)))"
202 <<
" entries removed\n";
205 <<
", no dense columns removed\n";
207 if (knobs[CCOLAMD_AGGRESSIVE] != 0)
209 <<
", aggressive absorption: yes";
212 <<
", aggressive absorption: no";
215 <<
", statistics and knobs printed\n";
224 if (args(0).is_sparse_type ())
226 if (args(0).is_complex_type ())
228 scm = args(0). sparse_complex_matrix_value ();
237 sm = args(0).sparse_matrix_value ();
248 if (args(0).is_complex_type ())
274 NDArray in_cmember = args(2).array_value ();
279 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
282 error (
"ccolamd: CMEMBER must be of length equal to #cols of A");
286 knobs, stats, cmember))
289 error (
"ccolamd: internal error!");
296 if (!
CCOLAMD_NAME () (n_row, n_col, Alen,
A, p, knobs, stats, 0))
299 error (
"ccolamd: internal error!");
307 out_perm(i) = p[i] + 1;
309 retval(0) = out_perm;
320 out_stats(i) = stats[i] ;
321 retval(1) = out_stats;
326 out_stats (CCOLAMD_INFO1) ++ ;
327 out_stats (CCOLAMD_INFO2) ++ ;
333 error (
"ccolamd: not available in this version of Octave");
342 @deftypefn {Loadable Function} {@var{p} =} csymamd (@var{S})\n\
343 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs})\n\
344 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs}, @var{cmember})\n\
345 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\
347 For a symmetric positive definite matrix @var{S}, returns the permutation\n\
348 vector @var{p} such that @code{@var{S}(@var{p},@var{p})} tends to have a\n\
349 sparser Cholesky@tie{}factor than @var{S}. Sometimes @code{csymamd} works\n\
350 well for symmetric indefinite matrices too. The matrix @var{S} is assumed\n\
351 to be symmetric; only the strictly lower triangular part is referenced.\n\
352 @var{S} must be square. The ordering is followed by an elimination tree\n\
355 @var{knobs} is an optional 1-element to 3-element input vector, with a\n\
356 default value of @code{[10 1 0]} if present or empty. Entries not\n\
357 present are set to their defaults.\n\
360 @item @var{knobs}(1)\n\
361 If @var{S} is n-by-n, then rows and columns with more than\n\
362 @code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\
363 last in the output permutation (subject to the cmember constraints).\n\
365 @item @var{knobs}(2)\n\
366 If nonzero, aggressive absorption is performed.\n\
368 @item @var{knobs}(3)\n\
369 If nonzero, statistics and knobs are printed.\n\
373 @var{cmember} is an optional vector of length n. It defines the constraints\n\
374 on the ordering. If @code{@var{cmember}(j) = @var{S}}, then row/column j is\n\
375 in constraint set @var{c} (@var{c} must be in the range 1 to n). In the\n\
376 output permutation @var{p}, rows/columns in set 1 appear first, followed\n\
377 by all rows/columns in set 2, and so on. @code{@var{cmember} = ones (1,n)}\n\
378 if not present or empty. @code{csymamd (@var{S},[],1:n)} returns @code{1:n}.\n\
380 @code{@var{p} = csymamd (@var{S})} is about the same as @code{@var{p} =\n\
381 symamd (@var{S})}. @var{knobs} and its default values differ.\n\
383 @code{@var{stats}(4:7)} provide information if CCOLAMD was able to\n\
384 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
385 invalid. @code{@var{stats}(5)} is the rightmost column index that is\n\
386 unsorted or contains duplicate entries, or zero if no such column exists.\n\
387 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
388 index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
389 such row index exists. @code{@var{stats}(7)} is the number of duplicate\n\
390 or out-of-order row indices. @code{@var{stats}(8:20)} is always zero in\n\
391 the current version of @sc{ccolamd} (reserved for future use).\n\
393 The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
394 and S. Rajamanickam in collaboration with J. Bilbert and E. Ng. Supported\n\
395 by the National Science Foundation\n\
396 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from Sandia\n\
397 National Lab. See @url{http://www.cise.ufl.edu/research/sparse} for\n\
398 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
399 @seealso{symamd, ccolamd}\n\
406 int nargin = args.
length ();
409 if (nargout > 2 || nargin < 1 || nargin > 3)
410 usage (
"ccolamd: incorrect number of input and/or output arguments");
420 NDArray User_knobs = args(1).array_value ();
421 int nel_User_knobs = User_knobs.
length ();
423 if (nel_User_knobs > 0)
424 knobs[CCOLAMD_DENSE_ROW] = User_knobs(0);
425 if (nel_User_knobs > 0)
426 knobs[CCOLAMD_AGGRESSIVE] = User_knobs(1);
427 if (nel_User_knobs > 1)
428 spumoni =
static_cast<int> (User_knobs(2));
433 octave_stdout <<
"\ncsymamd version " << CCOLAMD_MAIN_VERSION
434 <<
"." << CCOLAMD_SUB_VERSION
435 <<
", " << CCOLAMD_DATE <<
"\n";
437 if (knobs[CCOLAMD_DENSE_ROW] >= 0)
439 <<
", rows/cols with > max (16,"
440 << knobs[CCOLAMD_DENSE_ROW]
441 <<
"*sqrt (size(A,2)))"
442 <<
" entries removed\n";
445 <<
", no dense rows/cols removed\n";
447 if (knobs[CCOLAMD_AGGRESSIVE] != 0)
449 <<
", aggressive absorption: yes";
452 <<
", aggressive absorption: no";
456 <<
", statistics and knobs printed\n";
465 if (args(0).is_sparse_type ())
467 if (args(0).is_complex_type ())
469 scm = args(0).sparse_complex_matrix_value ();
477 sm = args(0).sparse_matrix_value ();
486 if (args(0).is_complex_type ())
499 error (
"csymamd: matrix S must be square");
509 NDArray in_cmember = args(2).array_value ();
514 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
517 error (
"csymamd: CMEMBER must be of length equal to #cols of A");
518 else if (!
CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
519 &calloc, &free, cmember, -1))
522 error (
"csymamd: internal error!") ;
528 if (!
CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
529 &calloc, &free, 0, -1))
532 error (
"csymamd: internal error!") ;
540 out_perm(i) = perm[i] + 1;
542 retval(0) = out_perm;
549 out_stats(i) = stats[i] ;
550 retval(1) = out_stats;
555 out_stats (CCOLAMD_INFO1) ++ ;
556 out_stats (CCOLAMD_INFO2) ++ ;
568 out_stats(i) = stats[i] ;
569 retval(1) = out_stats;
574 out_stats (CCOLAMD_INFO1) ++ ;
575 out_stats (CCOLAMD_INFO2) ++ ;
581 error (
"csymamd: not available in this version of Octave");