Mercurial > octave-nkf
annotate src/DLD-FUNCTIONS/ccolamd.cc @ 9064:7c02ec148a3c
Check grammar on all .cc files
Same check as previously done on .m files
Attempt to enforce some conformity in documentation text for rules
such as two spaces after a period, commas around latin abbreviations, etc.
author | Rik <rdrider0-list@yahoo.com> |
---|---|
date | Sat, 28 Mar 2009 13:57:22 -0700 |
parents | eb63fbe60fab |
children | 40dfc0c99116 |
rev | line source |
---|---|
5451 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2005, 2006, 2007, 2008 David Bateman |
5451 | 4 |
7016 | 5 This file is part of Octave. |
6 | |
5451 | 7 Octave is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
5451 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
5451 | 20 |
21 */ | |
22 | |
23 // This is the octave interface to ccolamd, which bore the copyright given | |
24 // in the help of the functions. | |
25 | |
26 #ifdef HAVE_CONFIG_H | |
27 #include <config.h> | |
28 #endif | |
29 | |
30 #include <cstdlib> | |
31 | |
32 #include <string> | |
33 #include <vector> | |
34 | |
35 #include "ov.h" | |
36 #include "defun-dld.h" | |
37 #include "pager.h" | |
38 #include "ov-re-mat.h" | |
39 | |
40 #include "ov-re-sparse.h" | |
41 #include "ov-cx-sparse.h" | |
42 | |
43 #include "oct-sparse.h" | |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
7520
diff
changeset
|
44 #include "oct-locbuf.h" |
5451 | 45 |
46 #ifdef IDX_TYPE_LONG | |
47 #define CCOLAMD_NAME(name) ccolamd_l ## name | |
48 #define CSYMAMD_NAME(name) csymamd_l ## name | |
49 #else | |
50 #define CCOLAMD_NAME(name) ccolamd ## name | |
51 #define CSYMAMD_NAME(name) csymamd ## name | |
52 #endif | |
53 | |
54 DEFUN_DLD (ccolamd, args, nargout, | |
55 "-*- texinfo -*-\n\ | |
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\ | |
60 \n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
61 Constrained column approximate minimum degree permutation. @code{@var{p} =\n\ |
5451 | 62 ccolamd (@var{s})} returns the column approximate minimum degree permutation\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
63 vector for the sparse matrix @var{s}. For a non-symmetric matrix @var{s},\n\ |
7107 | 64 @code{@var{s} (:, @var{p})} tends to have sparser LU factors than @var{s}.\n\ |
65 @code{chol (@var{s} (:, @var{p})' * @var{s} (:, @var{p}))} also tends to be\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
66 sparser than @code{chol (@var{s}' * @var{s})}. @code{@var{p} = ccolamd\n\ |
7107 | 67 (@var{s}, 1)} optimizes the ordering for @code{lu (@var{s} (:, @var{p}))}.\n\ |
5451 | 68 The ordering is followed by a column elimination tree post-ordering.\n\ |
69 \n\ | |
70 @var{knobs} is an optional one- to five-element input vector, with a default\n\ | |
71 value of @code{[0 10 10 1 0]} if not present or empty. Entries not present\n\ | |
72 are set to their defaults.\n\ | |
73 \n\ | |
74 @table @code\n\ | |
75 @item @var{knobs}(1)\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
76 if nonzero, the ordering is optimized for @code{lu (S (:, p))}. It will be a\n\ |
7107 | 77 poor ordering for @code{chol (@var{s} (:, @var{p})' * @var{s} (:,\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
78 @var{p}))}. This is the most important knob for ccolamd.\n\ |
5451 | 79 \n\ |
80 @item @var{knob}(2)\n\ | |
7107 | 81 if @var{s} is m-by-n, rows with more than @code{max (16, @var{knobs} (2) *\n\ |
82 sqrt (n))} entries are ignored.\n\ | |
5451 | 83 \n\ |
84 @item @var{knob}(3)\n\ | |
7107 | 85 columns with more than @code{max (16, @var{knobs} (3) * sqrt (min (@var{m},\n\ |
86 @var{n})))} entries are ignored and ordered last in the output permutation\n\ | |
87 (subject to the cmember constraints).\n\ | |
5451 | 88 \n\ |
89 @item @var{knob}(4)\n\ | |
90 if nonzero, aggressive absorption is performed.\n\ | |
91 \n\ | |
92 @item @var{knob}(5)\n\ | |
93 if nonzero, statistics and knobs are printed.\n\ | |
94 \n\ | |
95 @end table\n\ | |
96 \n\ | |
97 @var{cmember} is an optional vector of length n. It defines the constraints\n\ | |
7107 | 98 on the column ordering. If @code{@var{cmember} (j) = @var{c}}, then column\n\ |
99 @var{j} is in constraint set @var{c} (@var{c} must be in the range 1 to\n\ | |
100 @var{n}). In the output permutation @var{p}, all columns in set 1 appear\n\ | |
101 first, followed by all columns in set 2, and so on. @code{@var{cmember} =\n\ | |
102 ones(1,n)} if not present or empty. @code{ccolamd (@var{s}, [], 1 :\n\ | |
103 @var{n})} returns @code{1 : @var{n}}\n\ | |
5451 | 104 \n\ |
7107 | 105 @code{@var{p} = ccolamd (@var{s})} is about the same as @code{@var{p} =\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
106 colamd (@var{s})}. @var{knobs} and its default values differ. @code{colamd}\n\ |
5451 | 107 always does aggressive absorption, and it finds an ordering suitable for\n\ |
7107 | 108 both @code{lu (@var{s} (:, @var{p}))} and @code{chol (@var{S} (:, @var{p})'\n\ |
109 * @var{s} (:, @var{p}))}; it cannot optimize its ordering for\n\ | |
110 @code{lu (@var{s} (:, @var{p}))} to the extent that\n\ | |
111 @code{ccolamd (@var{s}, 1)} can.\n\ | |
5451 | 112 \n\ |
113 @var{stats} is an optional 20-element output vector that provides data\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
114 about the ordering and the validity of the input matrix @var{s}. Ordering\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
115 statistics are in @code{@var{stats} (1 : 3)}. @code{@var{stats} (1)} and\n\ |
5451 | 116 @code{@var{stats} (2)} are the number of dense or empty rows and columns\n\ |
117 ignored by CCOLAMD and @code{@var{stats} (3)} is the number of garbage\n\ | |
118 collections performed on the internal data structure used by CCOLAMD\n\ | |
7107 | 119 (roughly of size @code{2.2 * nnz (@var{s}) + 4 * @var{m} + 7 * @var{n}}\n\ |
5451 | 120 integers).\n\ |
121 \n\ | |
7107 | 122 @code{@var{stats} (4 : 7)} provide information if CCOLAMD was able to\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
123 continue. The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
124 invalid. @code{@var{stats} (5)} is the rightmost column index that is\n\ |
5451 | 125 unsorted or contains duplicate entries, or zero if no such column exists.\n\ |
126 @code{@var{stats} (6)} is the last seen duplicate or out-of-order row\n\ | |
127 index in the column index given by @code{@var{stats} (5)}, or zero if no\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
128 such row index exists. @code{@var{stats} (7)} is the number of duplicate\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
129 or out-of-order row indices. @code{@var{stats} (8 : 20)} is always zero in\n\ |
5451 | 130 the current version of CCOLAMD (reserved for future use).\n\ |
131 \n\ | |
132 The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
133 and S. Rajamanickam in collaboration with J. Bilbert and E. Ng. Supported\n\ |
5451 | 134 by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\ |
135 and a grant from Sandia National Lab. See\n\ | |
136 @url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\ | |
137 colamd, symamd, and other related orderings.\n\ | |
5642 | 138 @seealso{colamd, csymamd}\n\ |
139 @end deftypefn") | |
5451 | 140 { |
5771 | 141 octave_value_list retval; |
142 | |
5451 | 143 #ifdef HAVE_CCOLAMD |
5771 | 144 |
5451 | 145 int nargin = args.length (); |
146 int spumoni = 0; | |
147 | |
148 if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 3) | |
149 usage ("ccolamd: incorrect number of input and/or output arguments"); | |
150 else | |
151 { | |
152 // Get knobs | |
153 OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS); | |
154 CCOLAMD_NAME (_set_defaults) (knobs); | |
155 | |
156 // Check for user-passed knobs | |
157 if (nargin > 1) | |
158 { | |
159 NDArray User_knobs = args(1).array_value (); | |
160 int nel_User_knobs = User_knobs.length (); | |
161 | |
162 if (nel_User_knobs > 0) | |
163 knobs [CCOLAMD_LU] = (User_knobs (0) != 0); | |
164 if (nel_User_knobs > 1) | |
165 knobs [CCOLAMD_DENSE_ROW] = User_knobs (1); | |
166 if (nel_User_knobs > 2) | |
167 knobs [CCOLAMD_DENSE_COL] = User_knobs (2); | |
168 if (nel_User_knobs > 3) | |
169 knobs [CCOLAMD_AGGRESSIVE] = (User_knobs (3) != 0); | |
170 if (nel_User_knobs > 4) | |
171 spumoni = (User_knobs (4) != 0); | |
172 | |
173 // print knob settings if spumoni is set | |
174 if (spumoni) | |
175 { | |
176 octave_stdout << "\nccolamd version " << CCOLAMD_MAIN_VERSION << "." | |
177 << CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE | |
178 << ":\nknobs(1): " << User_knobs (0) << ", order for "; | |
179 if ( knobs [CCOLAMD_LU] != 0) | |
180 octave_stdout << "lu(A)\n"; | |
181 else | |
182 octave_stdout << "chol(A'*A)\n"; | |
183 | |
184 if (knobs [CCOLAMD_DENSE_ROW] >= 0) | |
185 octave_stdout << "knobs(2): " << User_knobs (1) | |
186 << ", rows with > max(16," | |
187 << knobs [CCOLAMD_DENSE_ROW] << "*sqrt(size(A,2)))" | |
188 << " entries removed\n"; | |
189 else | |
190 octave_stdout << "knobs(2): " << User_knobs (1) | |
191 << ", no dense rows removed\n"; | |
192 | |
193 if (knobs [CCOLAMD_DENSE_COL] >= 0) | |
194 octave_stdout << "knobs(3): " << User_knobs (2) | |
195 << ", cols with > max(16," | |
196 << knobs [CCOLAMD_DENSE_COL] << "*sqrt(size(A)))" | |
197 << " entries removed\n"; | |
198 else | |
199 octave_stdout << "knobs(3): " << User_knobs (2) | |
200 << ", no dense columns removed\n"; | |
201 | |
202 if (knobs [CCOLAMD_AGGRESSIVE] != 0) | |
203 octave_stdout << "knobs(4): " << User_knobs(3) | |
204 << ", aggressive absorption: yes"; | |
205 else | |
206 octave_stdout << "knobs(4): " << User_knobs(3) | |
207 << ", aggressive absorption: no"; | |
208 | |
209 octave_stdout << "knobs(5): " << User_knobs (4) | |
210 << ", statistics and knobs printed\n"; | |
211 } | |
212 } | |
213 | |
214 octave_idx_type n_row, n_col, nnz; | |
215 octave_idx_type *ridx, *cidx; | |
216 SparseComplexMatrix scm; | |
217 SparseMatrix sm; | |
218 | |
5631 | 219 if (args(0).is_sparse_type ()) |
5451 | 220 { |
221 if (args(0).is_complex_type ()) | |
222 { | |
223 scm = args(0). sparse_complex_matrix_value (); | |
224 n_row = scm.rows (); | |
225 n_col = scm.cols (); | |
5604 | 226 nnz = scm.nzmax (); |
5451 | 227 ridx = scm.xridx (); |
228 cidx = scm.xcidx (); | |
229 } | |
230 else | |
231 { | |
232 sm = args(0).sparse_matrix_value (); | |
233 | |
234 n_row = sm.rows (); | |
235 n_col = sm.cols (); | |
5604 | 236 nnz = sm.nzmax (); |
5451 | 237 ridx = sm.xridx (); |
238 cidx = sm.xcidx (); | |
239 } | |
240 } | |
241 else | |
242 { | |
243 if (args(0).is_complex_type ()) | |
244 sm = SparseMatrix (real (args(0).complex_matrix_value ())); | |
245 else | |
246 sm = SparseMatrix (args(0).matrix_value ()); | |
247 | |
248 n_row = sm.rows (); | |
249 n_col = sm.cols (); | |
5604 | 250 nnz = sm.nzmax (); |
5451 | 251 ridx = sm.xridx (); |
252 cidx = sm.xcidx (); | |
253 } | |
254 | |
255 // Allocate workspace for ccolamd | |
256 OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1); | |
257 for (octave_idx_type i = 0; i < n_col+1; i++) | |
258 p[i] = cidx [i]; | |
259 | |
260 octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col); | |
261 OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen); | |
262 for (octave_idx_type i = 0; i < nnz; i++) | |
263 A[i] = ridx [i]; | |
264 | |
265 OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS); | |
266 | |
267 if (nargin > 2) | |
268 { | |
269 NDArray in_cmember = args(2).array_value(); | |
270 octave_idx_type cslen = in_cmember.length(); | |
271 OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen); | |
272 for (octave_idx_type i = 0; i < cslen; i++) | |
273 // convert cmember from 1-based to 0-based | |
274 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1); | |
275 | |
276 if (cslen != n_col) | |
277 error ("ccolamd: cmember must be of length equal to #cols of A"); | |
278 else | |
279 // Order the columns (destroys A) | |
280 if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, cmember)) | |
281 { | |
282 CCOLAMD_NAME (_report) (stats) ; | |
283 error ("ccolamd: internal error!"); | |
284 return retval; | |
285 } | |
286 } | |
287 else | |
288 { | |
289 // Order the columns (destroys A) | |
7520 | 290 if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, 0)) |
5451 | 291 { |
292 CCOLAMD_NAME (_report) (stats) ; | |
293 error ("ccolamd: internal error!"); | |
294 return retval; | |
295 } | |
296 } | |
297 | |
298 // return the permutation vector | |
299 NDArray out_perm (dim_vector (1, n_col)); | |
300 for (octave_idx_type i = 0; i < n_col; i++) | |
301 out_perm(i) = p [i] + 1; | |
302 | |
303 retval (0) = out_perm; | |
304 | |
305 // print stats if spumoni > 0 | |
306 if (spumoni > 0) | |
307 CCOLAMD_NAME (_report) (stats) ; | |
308 | |
309 // Return the stats vector | |
310 if (nargout == 2) | |
311 { | |
312 NDArray out_stats (dim_vector (1, CCOLAMD_STATS)); | |
313 for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++) | |
314 out_stats (i) = stats [i] ; | |
315 retval(1) = out_stats; | |
316 | |
317 // fix stats (5) and (6), for 1-based information on | |
318 // jumbled matrix. note that this correction doesn't | |
319 // occur if symamd returns FALSE | |
320 out_stats (CCOLAMD_INFO1) ++ ; | |
321 out_stats (CCOLAMD_INFO2) ++ ; | |
322 } | |
323 } | |
324 | |
325 #else | |
326 | |
327 error ("ccolamd: not available in this version of Octave"); | |
328 | |
329 #endif | |
5771 | 330 |
331 return retval; | |
5451 | 332 } |
333 | |
334 DEFUN_DLD (csymamd, args, nargout, | |
335 "-*- texinfo -*-\n\ | |
336 @deftypefn {Loadable Function} {@var{p} =} csymamd (@var{s})\n\ | |
337 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs})\n\ | |
338 @deftypefnx {Loadable Function} {@var{p} =} csymamd (@var{s}, @var{knobs}, @var{cmember})\n\ | |
339 @deftypefnx {Loadable Function} {[@var{p}, @var{stats}] =} csymamd (@dots{})\n\ | |
340 \n\ | |
341 For a symmetric positive definite matrix @var{s}, returns the permutation\n\ | |
342 vector @var{p} such that @code{@var{s}(@var{p},@var{p})} tends to have a\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
343 sparser Cholesky factor than @var{s}. Sometimes @code{csymamd} works well\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
344 for symmetric indefinite matrices too. The matrix @var{s} is assumed to\n\ |
5451 | 345 be symmetric; only the strictly lower triangular part is referenced.\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
346 @var{s} must be square. The ordering is followed by an elimination tree\n\ |
5451 | 347 post-ordering.\n\ |
348 \n\ | |
349 @var{knobs} is an optional one- to three-element input vector, with a\n\ | |
350 default value of @code{[10 1 0]} if present or empty. Entries not\n\ | |
351 present are set to their defaults.\n\ | |
352 \n\ | |
353 @table @code\n\ | |
354 @item @var{knobs}(1)\n\ | |
355 If @var{s} is n-by-n, then rows and columns with more than\n\ | |
356 @code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered\n\ | |
357 last in the output permutation (subject to the cmember constraints).\n\ | |
358 \n\ | |
359 @item @var{knobs}(2)\n\ | |
360 If nonzero, aggressive absorption is performed.\n\ | |
361 \n\ | |
362 @item @var{knobs}(3)\n\ | |
363 If nonzero, statistics and knobs are printed.\n\ | |
364 \n\ | |
365 @end table\n\ | |
366 \n\ | |
367 @var{cmember} is an optional vector of length n. It defines the constraints\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
368 on the ordering. If @code{@var{cmember}(j) = @var{s}}, then row/column j is\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
369 in constraint set @var{c} (@var{c} must be in the range 1 to n). In the\n\ |
5451 | 370 output permutation @var{p}, rows/columns in set 1 appear first, followed\n\ |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
371 by all rows/columns in set 2, and so on. @code{@var{cmember} = ones(1,n)}\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
372 if not present or empty. @code{csymamd(@var{s},[],1:n)} returns @code{1:n}.\n\ |
5451 | 373 \n\ |
374 @code{@var{p} = csymamd(@var{s})} is about the same as @code{@var{p} =\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
375 symamd(@var{s})}. @var{knobs} and its default values differ.\n\ |
5451 | 376 \n\ |
377 @code{@var{stats} (4:7)} provide information if CCOLAMD was able to\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
378 continue. The matrix is OK if @code{@var{stats} (4)} is zero, or 1 if\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
379 invalid. @code{@var{stats} (5)} is the rightmost column index that is\n\ |
5451 | 380 unsorted or contains duplicate entries, or zero if no such column exists.\n\ |
381 @code{@var{stats} (6)} is the last seen duplicate or out-of-order row\n\ | |
382 index in the column index given by @code{@var{stats} (5)}, or zero if no\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
383 such row index exists. @code{@var{stats} (7)} is the number of duplicate\n\ |
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
384 or out-of-order row indices. @code{@var{stats} (8:20)} is always zero in\n\ |
5451 | 385 the current version of CCOLAMD (reserved for future use).\n\ |
386 \n\ | |
387 The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\ | |
9064
7c02ec148a3c
Check grammar on all .cc files
Rik <rdrider0-list@yahoo.com>
parents:
8920
diff
changeset
|
388 and S. Rajamanickam in collaboration with J. Bilbert and E. Ng. Supported\n\ |
5451 | 389 by the National Science Foundation (DMS-9504974, DMS-9803599, CCR-0203270),\n\ |
390 and a grant from Sandia National Lab. See\n\ | |
391 @url{http://www.cise.ufl.edu/research/sparse} for ccolamd, csymamd, amd,\n\ | |
392 colamd, symamd, and other related orderings.\n\ | |
5642 | 393 @seealso{symamd, ccolamd}\n\ |
394 @end deftypefn") | |
5451 | 395 { |
5771 | 396 octave_value_list retval; |
397 | |
5451 | 398 #if HAVE_CCOLAMD |
5771 | 399 |
5451 | 400 int nargin = args.length (); |
401 int spumoni = 0; | |
402 | |
403 if (nargout < 0 || nargout > 2 || nargin < 0 || nargin > 3) | |
404 usage ("ccolamd: incorrect number of input and/or output arguments"); | |
405 else | |
406 { | |
407 // Get knobs | |
408 OCTAVE_LOCAL_BUFFER (double, knobs, CCOLAMD_KNOBS); | |
409 CCOLAMD_NAME (_set_defaults) (knobs); | |
410 | |
411 // Check for user-passed knobs | |
412 if (nargin > 1) | |
413 { | |
414 NDArray User_knobs = args(1).array_value (); | |
415 int nel_User_knobs = User_knobs.length (); | |
416 | |
417 if (nel_User_knobs > 0) | |
418 knobs [CCOLAMD_DENSE_ROW] = User_knobs (0); | |
419 if (nel_User_knobs > 0) | |
420 knobs [CCOLAMD_AGGRESSIVE] = User_knobs (1); | |
421 if (nel_User_knobs > 1) | |
5760 | 422 spumoni = static_cast<int> (User_knobs (2)); |
5451 | 423 |
424 // print knob settings if spumoni is set | |
425 if (spumoni) | |
426 { | |
427 octave_stdout << "\ncsymamd version " << CCOLAMD_MAIN_VERSION << "." | |
428 << CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE << "\n"; | |
429 | |
430 if (knobs [CCOLAMD_DENSE_ROW] >= 0) | |
431 octave_stdout << "knobs(1): " << User_knobs (0) | |
432 << ", rows/cols with > max(16," | |
433 << knobs [CCOLAMD_DENSE_ROW] << "*sqrt(size(A,2)))" | |
434 << " entries removed\n"; | |
435 else | |
436 octave_stdout << "knobs(1): " << User_knobs (0) | |
437 << ", no dense rows/cols removed\n"; | |
438 | |
439 if (knobs [CCOLAMD_AGGRESSIVE] != 0) | |
440 octave_stdout << "knobs(2): " << User_knobs(1) | |
441 << ", aggressive absorption: yes"; | |
442 else | |
443 octave_stdout << "knobs(2): " << User_knobs(1) | |
444 << ", aggressive absorption: no"; | |
445 | |
446 | |
447 octave_stdout << "knobs(3): " << User_knobs (2) | |
448 << ", statistics and knobs printed\n"; | |
449 } | |
450 } | |
451 | |
452 octave_idx_type n_row, n_col, nnz; | |
453 octave_idx_type *ridx, *cidx; | |
454 SparseMatrix sm; | |
455 SparseComplexMatrix scm; | |
456 | |
5631 | 457 if (args(0).is_sparse_type ()) |
5451 | 458 { |
459 if (args(0).is_complex_type ()) | |
460 { | |
461 scm = args(0).sparse_complex_matrix_value (); | |
462 n_row = scm.rows (); | |
463 n_col = scm.cols (); | |
5604 | 464 nnz = scm.nzmax (); |
5451 | 465 ridx = scm.xridx (); |
466 cidx = scm.xcidx (); | |
467 } | |
468 else | |
469 { | |
470 sm = args(0).sparse_matrix_value (); | |
471 n_row = sm.rows (); | |
472 n_col = sm.cols (); | |
5604 | 473 nnz = sm.nzmax (); |
5451 | 474 ridx = sm.xridx (); |
475 cidx = sm.xcidx (); | |
476 } | |
477 } | |
478 else | |
479 { | |
480 if (args(0).is_complex_type ()) | |
481 sm = SparseMatrix (real (args(0).complex_matrix_value ())); | |
482 else | |
483 sm = SparseMatrix (args(0).matrix_value ()); | |
484 | |
485 n_row = sm.rows (); | |
486 n_col = sm.cols (); | |
5604 | 487 nnz = sm.nzmax (); |
5451 | 488 ridx = sm.xridx (); |
489 cidx = sm.xcidx (); | |
490 } | |
491 | |
492 if (n_row != n_col) | |
493 { | |
494 error ("symamd: matrix must be square"); | |
495 return retval; | |
496 } | |
497 | |
498 // Allocate workspace for symamd | |
499 OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1); | |
500 OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS); | |
501 | |
502 if (nargin > 2) | |
503 { | |
504 NDArray in_cmember = args(2).array_value(); | |
505 octave_idx_type cslen = in_cmember.length(); | |
506 OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen); | |
507 for (octave_idx_type i = 0; i < cslen; i++) | |
508 // convert cmember from 1-based to 0-based | |
509 cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1); | |
510 | |
511 if (cslen != n_col) | |
512 error ("ccolamd: cmember must be of length equal to #cols of A"); | |
513 else | |
514 if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, | |
515 &calloc, &free, cmember, -1)) | |
516 { | |
517 CSYMAMD_NAME (_report) (stats) ; | |
518 error ("symamd: internal error!") ; | |
519 return retval; | |
520 } | |
521 } | |
522 else | |
523 { | |
524 if (!CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats, | |
7520 | 525 &calloc, &free, 0, -1)) |
5451 | 526 { |
527 CSYMAMD_NAME (_report) (stats) ; | |
528 error ("symamd: internal error!") ; | |
529 return retval; | |
530 } | |
531 } | |
532 | |
533 // return the permutation vector | |
534 NDArray out_perm (dim_vector (1, n_col)); | |
535 for (octave_idx_type i = 0; i < n_col; i++) | |
536 out_perm(i) = perm [i] + 1; | |
537 | |
538 retval (0) = out_perm; | |
539 | |
540 // Return the stats vector | |
541 if (nargout == 2) | |
542 { | |
543 NDArray out_stats (dim_vector (1, CCOLAMD_STATS)); | |
544 for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++) | |
545 out_stats (i) = stats [i] ; | |
546 retval(1) = out_stats; | |
547 | |
548 // fix stats (5) and (6), for 1-based information on | |
549 // jumbled matrix. note that this correction doesn't | |
550 // occur if symamd returns FALSE | |
551 out_stats (CCOLAMD_INFO1) ++ ; | |
552 out_stats (CCOLAMD_INFO2) ++ ; | |
553 } | |
554 | |
555 // print stats if spumoni > 0 | |
556 if (spumoni > 0) | |
557 CSYMAMD_NAME (_report) (stats) ; | |
558 | |
559 // Return the stats vector | |
560 if (nargout == 2) | |
561 { | |
562 NDArray out_stats (dim_vector (1, CCOLAMD_STATS)); | |
563 for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++) | |
564 out_stats (i) = stats [i] ; | |
565 retval(1) = out_stats; | |
566 | |
567 // fix stats (5) and (6), for 1-based information on | |
568 // jumbled matrix. note that this correction doesn't | |
569 // occur if symamd returns FALSE | |
570 out_stats (CCOLAMD_INFO1) ++ ; | |
571 out_stats (CCOLAMD_INFO2) ++ ; | |
572 } | |
573 } | |
574 | |
575 #else | |
576 | |
577 error ("csymamd: not available in this version of Octave"); | |
578 | |
579 #endif | |
5771 | 580 |
581 return retval; | |
5451 | 582 } |
583 | |
584 /* | |
585 ;;; Local Variables: *** | |
586 ;;; mode: C++ *** | |
587 ;;; End: *** | |
588 */ |