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\
63 @code{@var{p} = ccolamd (@var{S})} returns the column approximate minimum\n\
64 degree permutation vector for the sparse matrix @var{S}. For a non-symmetric\n\
65 matrix @var{S}, @code{@var{S}(:, @var{p})} tends to have sparser\n\
66 LU@tie{}factors than @var{S}.\n\
67 @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))} also tends to be\n\
68 sparser than @code{chol (@var{S}' * @var{S})}.\n\
69 @code{@var{p} = ccolamd (@var{S}, 1)} optimizes the ordering for\n\
70 @code{lu (@var{S}(:, @var{p}))}. The ordering is followed by a column\n\
71 elimination tree post-ordering.\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}(:, @var{p}))}.\n\
81 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\n\
85 @code{max (16, @var{knobs}(2) * sqrt (n))} entries are ignored.\n\
87 @item @var{knobs}(3)\n\
88 columns with more than\n\
89 @code{max (16, @var{knobs}(3) * sqrt (min (@var{m}, @var{n})))} entries are\n\
90 ignored and ordered last in the output permutation\n\
91 (subject to the cmember constraints).\n\
93 @item @var{knobs}(4)\n\
94 if nonzero, aggressive absorption is performed.\n\
96 @item @var{knobs}(5)\n\
97 if nonzero, statistics and knobs are printed.\n\
101 @var{cmember} is an optional vector of length @math{n}. It defines the\n\
102 constraints on the column ordering. If @code{@var{cmember}(j) = @var{c}},\n\
103 then column @var{j} is in constraint set @var{c} (@var{c} must be in the\n\
104 range 1 to n). In the output permutation @var{p}, all columns in set 1\n\
105 appear first, followed by all columns in set 2, and so on.\n\
106 @code{@var{cmember} = 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 @nospell{S. Larimore, T. Davis}\n\
137 (Univ. of Florida) and @nospell{S. Rajamanickam} in collaboration with\n\
138 @nospell{J. Bilbert and E. Ng}. Supported by the National Science Foundation\n\
139 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from\n\
140 @nospell{Sandia} National Lab.\n\
141 See @url{http://www.cise.ufl.edu/research/sparse} for\n\
142 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
143 @seealso{colamd, csymamd}\n\
150 int nargin = args.
length ();
153 if (nargout > 2 || nargin < 1 || nargin > 3)
154 usage (
"ccolamd: incorrect number of input and/or output arguments");
164 NDArray User_knobs = args(1).array_value ();
165 int nel_User_knobs = User_knobs.
length ();
167 if (nel_User_knobs > 0)
168 knobs[CCOLAMD_LU] = (User_knobs(0) != 0);
169 if (nel_User_knobs > 1)
170 knobs[CCOLAMD_DENSE_ROW] = User_knobs(1);
171 if (nel_User_knobs > 2)
172 knobs[CCOLAMD_DENSE_COL] = User_knobs(2);
173 if (nel_User_knobs > 3)
174 knobs[CCOLAMD_AGGRESSIVE] = (User_knobs(3) != 0);
175 if (nel_User_knobs > 4)
176 spumoni = (User_knobs(4) != 0);
181 octave_stdout <<
"\nccolamd version " << CCOLAMD_MAIN_VERSION <<
"."
182 << CCOLAMD_SUB_VERSION <<
", " << CCOLAMD_DATE
183 <<
":\nknobs(1): " << User_knobs(0) <<
", order for ";
184 if (knobs[CCOLAMD_LU] != 0)
189 if (knobs[CCOLAMD_DENSE_ROW] >= 0)
191 <<
", rows with > max (16,"
192 << knobs[CCOLAMD_DENSE_ROW]
193 <<
"*sqrt (size(A,2)))"
194 <<
" entries removed\n";
197 <<
", no dense rows removed\n";
199 if (knobs[CCOLAMD_DENSE_COL] >= 0)
201 <<
", cols with > max (16,"
202 << knobs[CCOLAMD_DENSE_COL] <<
"*sqrt (size(A)))"
203 <<
" entries removed\n";
206 <<
", no dense columns removed\n";
208 if (knobs[CCOLAMD_AGGRESSIVE] != 0)
210 <<
", aggressive absorption: yes";
213 <<
", aggressive absorption: no";
216 <<
", statistics and knobs printed\n";
225 if (args(0).is_sparse_type ())
227 if (args(0).is_complex_type ())
229 scm = args(0). sparse_complex_matrix_value ();
238 sm = args(0).sparse_matrix_value ();
249 if (args(0).is_complex_type ())
275 NDArray in_cmember = args(2).array_value ();
280 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
283 error (
"ccolamd: CMEMBER must be of length equal to #cols of A");
287 knobs, stats, cmember))
290 error (
"ccolamd: internal error!");
297 if (!
CCOLAMD_NAME () (n_row, n_col, Alen,
A, p, knobs, stats, 0))
300 error (
"ccolamd: internal error!");
308 out_perm(i) = p[i] + 1;
310 retval(0) = out_perm;
321 out_stats(i) = stats[i] ;
322 retval(1) = out_stats;
327 out_stats (CCOLAMD_INFO1) ++ ;
328 out_stats (CCOLAMD_INFO2) ++ ;
334 error (
"ccolamd: not available in this version of Octave");
343 @deftypefn {Loadable Function} {@var{p} =} csymamd (@var{S})\n\
344 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs})\n\
345 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{S}, @var{knobs}, @var{cmember})\n\
346 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\
348 For a symmetric positive definite matrix @var{S}, return the permutation\n\
349 vector @var{p} such that @code{@var{S}(@var{p},@var{p})} tends to have a\n\
350 sparser Cholesky@tie{}factor than @var{S}.\n\
352 Sometimes @code{csymamd} works well for symmetric indefinite matrices too. \n\
353 The matrix @var{S} is assumed to be symmetric; only the strictly lower\n\
354 triangular part is referenced. @var{S} must be square. The ordering is\n\
355 followed by an elimination tree post-ordering.\n\
357 @var{knobs} is an optional 1-element to 3-element input vector, with a\n\
358 default value of @code{[10 1 0]}. Entries not present are set to their\n\
362 @item @var{knobs}(1)\n\
363 If @var{S} is n-by-n, then rows and columns with more than\n\
364 @code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\
365 last in the output permutation (subject to the cmember constraints).\n\
367 @item @var{knobs}(2)\n\
368 If nonzero, aggressive absorption is performed.\n\
370 @item @var{knobs}(3)\n\
371 If nonzero, statistics and knobs are printed.\n\
375 @var{cmember} is an optional vector of length n. It defines the constraints\n\
376 on the ordering. If @code{@var{cmember}(j) = @var{S}}, then row/column j is\n\
377 in constraint set @var{c} (@var{c} must be in the range 1 to n). In the\n\
378 output permutation @var{p}, rows/columns in set 1 appear first, followed\n\
379 by all rows/columns in set 2, and so on. @code{@var{cmember} = ones (1,n)}\n\
380 if not present or empty. @code{csymamd (@var{S},[],1:n)} returns @code{1:n}.\n\
382 @code{@var{p} = csymamd (@var{S})} is about the same as\n\
383 @code{@var{p} = symamd (@var{S})}. @var{knobs} and its default values\n\
386 @code{@var{stats}(4:7)} provide information if CCOLAMD was able to\n\
387 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if\n\
388 invalid. @code{@var{stats}(5)} is the rightmost column index that is\n\
389 unsorted or contains duplicate entries, or zero if no such column exists.\n\
390 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row\n\
391 index in the column index given by @code{@var{stats}(5)}, or zero if no\n\
392 such row index exists. @code{@var{stats}(7)} is the number of duplicate\n\
393 or out-of-order row indices. @code{@var{stats}(8:20)} is always zero in\n\
394 the current version of @sc{ccolamd} (reserved for future use).\n\
396 The authors of the code itself are @nospell{S. Larimore, T. Davis}\n\
397 (Univ. of Florida) and @nospell{S. Rajamanickam} in collaboration with\n\
398 @nospell{J. Bilbert and E. Ng}. Supported by the National Science Foundation\n\
399 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from\n\
400 @nospell{Sandia} National Lab.\n\
401 See @url{http://www.cise.ufl.edu/research/sparse} for\n\
402 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
403 @seealso{symamd, ccolamd}\n\
410 int nargin = args.
length ();
413 if (nargout > 2 || nargin < 1 || nargin > 3)
414 usage (
"ccolamd: incorrect number of input and/or output arguments");
424 NDArray User_knobs = args(1).array_value ();
425 int nel_User_knobs = User_knobs.
length ();
427 if (nel_User_knobs > 0)
428 knobs[CCOLAMD_DENSE_ROW] = User_knobs(0);
429 if (nel_User_knobs > 0)
430 knobs[CCOLAMD_AGGRESSIVE] = User_knobs(1);
431 if (nel_User_knobs > 1)
432 spumoni =
static_cast<int> (User_knobs(2));
437 octave_stdout <<
"\ncsymamd version " << CCOLAMD_MAIN_VERSION
438 <<
"." << CCOLAMD_SUB_VERSION
439 <<
", " << CCOLAMD_DATE <<
"\n";
441 if (knobs[CCOLAMD_DENSE_ROW] >= 0)
443 <<
", rows/cols with > max (16,"
444 << knobs[CCOLAMD_DENSE_ROW]
445 <<
"*sqrt (size(A,2)))"
446 <<
" entries removed\n";
449 <<
", no dense rows/cols removed\n";
451 if (knobs[CCOLAMD_AGGRESSIVE] != 0)
453 <<
", aggressive absorption: yes";
456 <<
", aggressive absorption: no";
460 <<
", statistics and knobs printed\n";
469 if (args(0).is_sparse_type ())
471 if (args(0).is_complex_type ())
473 scm = args(0).sparse_complex_matrix_value ();
481 sm = args(0).sparse_matrix_value ();
490 if (args(0).is_complex_type ())
503 error (
"csymamd: matrix S must be square");
513 NDArray in_cmember = args(2).array_value ();
518 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
521 error (
"csymamd: CMEMBER must be of length equal to #cols of A");
522 else if (!
CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
523 &calloc, &
free, cmember, -1))
526 error (
"csymamd: internal error!") ;
532 if (!
CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
533 &calloc, &
free, 0, -1))
536 error (
"csymamd: internal error!") ;
544 out_perm(i) = perm[i] + 1;
546 retval(0) = out_perm;
553 out_stats(i) = stats[i] ;
554 retval(1) = out_stats;
559 out_stats (CCOLAMD_INFO1) ++ ;
560 out_stats (CCOLAMD_INFO2) ++ ;
572 out_stats(i) = stats[i] ;
573 retval(1) = out_stats;
578 out_stats (CCOLAMD_INFO1) ++ ;
579 out_stats (CCOLAMD_INFO2) ++ ;
585 error (
"csymamd: not available in this version of Octave");
octave_idx_type * xridx(void)
octave_idx_type cols(void) const
octave_idx_type rows(void) const
octave_idx_type length(void) const
F77_RET_T const octave_idx_type Complex * A
octave_idx_type * xcidx(void)
void error(const char *fmt,...)
void usage(const char *fmt,...)
octave_idx_type nnz(void) const
#define CSYMAMD_NAME(name)
octave_idx_type length(void) const
Number of elements in the array.
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
ColumnVector real(const ComplexColumnVector &a)
#define CCOLAMD_NAME(name)