GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ccolamd.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2005-2018 David Bateman
4 
5 This file is part of Octave.
6 
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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
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 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cstdlib>
31 
32 #include "CSparse.h"
33 #include "Sparse.h"
34 #include "dNDArray.h"
35 #include "oct-locbuf.h"
36 #include "oct-sparse.h"
37 
38 #include "defun-dld.h"
39 #include "error.h"
40 #include "errwarn.h"
41 #include "ov.h"
42 #include "pager.h"
43 
44 DEFUN_DLD (ccolamd, args, nargout,
45  doc: /* -*- texinfo -*-
46 @deftypefn {} {@var{p} =} ccolamd (@var{S})
47 @deftypefnx {} {@var{p} =} ccolamd (@var{S}, @var{knobs})
48 @deftypefnx {} {@var{p} =} ccolamd (@var{S}, @var{knobs}, @var{cmember})
49 @deftypefnx {} {[@var{p}, @var{stats}] =} ccolamd (@dots{})
50 
51 Constrained column approximate minimum degree permutation.
52 
53 @code{@var{p} = ccolamd (@var{S})} returns the column approximate minimum
54 degree permutation vector for the sparse matrix @var{S}. For a
55 non-symmetric matrix @var{S}, @code{@var{S}(:, @var{p})} tends to have
56 sparser LU@tie{}factors than @var{S}.
57 @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))} also tends to be
58 sparser than @code{chol (@var{S}' * @var{S})}.
59 @code{@var{p} = ccolamd (@var{S}, 1)} optimizes the ordering for
60 @code{lu (@var{S}(:, @var{p}))}. The ordering is followed by a column
61 elimination tree post-ordering.
62 
63 @var{knobs} is an optional 1-element to 5-element input vector, with a
64 default value of @code{[0 10 10 1 0]} if not present or empty. Entries not
65 present are set to their defaults.
66 
67 @table @code
68 @item @var{knobs}(1)
69 if nonzero, the ordering is optimized for @code{lu (S(:, p))}. It will be a
70 poor ordering for @code{chol (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))}.
71 This is the most important knob for ccolamd.
72 
73 @item @var{knobs}(2)
74 if @var{S} is m-by-n, rows with more than
75 @code{max (16, @var{knobs}(2) * sqrt (n))} entries are ignored.
76 
77 @item @var{knobs}(3)
78 columns with more than
79 @code{max (16, @var{knobs}(3) * sqrt (min (@var{m}, @var{n})))} entries are
80 ignored and ordered last in the output permutation
81 (subject to the cmember constraints).
82 
83 @item @var{knobs}(4)
84 if nonzero, aggressive absorption is performed.
85 
86 @item @var{knobs}(5)
87 if nonzero, statistics and knobs are printed.
88 
89 @end table
90 
91 @var{cmember} is an optional vector of length @math{n}. It defines the
92 constraints on the column ordering. If @code{@var{cmember}(j) = @var{c}},
93 then column @var{j} is in constraint set @var{c} (@var{c} must be in the
94 range 1 to n). In the output permutation @var{p}, all columns in set 1
95 appear first, followed by all columns in set 2, and so on.
96 @code{@var{cmember} = ones (1,n)} if not present or empty.
97 @code{ccolamd (@var{S}, [], 1 : n)} returns @code{1 : n}
98 
99 @code{@var{p} = ccolamd (@var{S})} is about the same as
100 @code{@var{p} = colamd (@var{S})}. @var{knobs} and its default values
101 differ. @code{colamd} always does aggressive absorption, and it finds an
102 ordering suitable for both @code{lu (@var{S}(:, @var{p}))} and @code{chol
103 (@var{S}(:, @var{p})' * @var{S}(:, @var{p}))}; it cannot optimize its
104 ordering for @code{lu (@var{S}(:, @var{p}))} to the extent that
105 @code{ccolamd (@var{S}, 1)} can.
106 
107 @var{stats} is an optional 20-element output vector that provides data
108 about the ordering and the validity of the input matrix @var{S}. Ordering
109 statistics are in @code{@var{stats}(1 : 3)}. @code{@var{stats}(1)} and
110 @code{@var{stats}(2)} are the number of dense or empty rows and columns
111 ignored by @sc{ccolamd} and @code{@var{stats}(3)} is the number of garbage
112 collections performed on the internal data structure used by @sc{ccolamd}
113 (roughly of size @code{2.2 * nnz (@var{S}) + 4 * @var{m} + 7 * @var{n}}
114 integers).
115 
116 @code{@var{stats}(4 : 7)} provide information if CCOLAMD was able to
117 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if
118 invalid. @code{@var{stats}(5)} is the rightmost column index that is
119 unsorted or contains duplicate entries, or zero if no such column exists.
120 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row
121 index in the column index given by @code{@var{stats}(5)}, or zero if no
122 such row index exists. @code{@var{stats}(7)} is the number of duplicate
123 or out-of-order row indices. @code{@var{stats}(8 : 20)} is always zero in
124 the current version of @sc{ccolamd} (reserved for future use).
125 
126 The authors of the code itself are @nospell{S. Larimore, T. Davis} and
127 @nospell{S. Rajamanickam} in collaboration with @nospell{J. Bilbert and E. Ng}.
128 Supported by the National Science Foundation
129 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from
130 @nospell{Sandia} National Lab.
131 See @url{http://faculty.cse.tamu.edu/davis/suitesparse.html} for ccolamd,
132 csymamd, amd, colamd, symamd, and other related orderings.
133 @seealso{colamd, csymamd}
134 @end deftypefn */)
135 {
136 #if defined (HAVE_CCOLAMD)
137 
138  int nargin = args.length ();
139 
141  print_usage ();
142 
143  octave_value_list retval (nargout == 2 ? 2 : 1);
144  int spumoni = 0;
145 
146  // Get knobs
147  static_assert (CCOLAMD_KNOBS <= 40, "ccolamd: # of CCOLAMD_KNOBS exceeded. Please report this to bugs.octave.org");
148  double knob_storage[CCOLAMD_KNOBS];
149  double *knobs = &knob_storage[0];
150  CCOLAMD_NAME (_set_defaults) (knobs);
151 
152  // Check for user-passed knobs
153  if (nargin > 1)
154  {
155  NDArray User_knobs = args(1).array_value ();
156  int nel_User_knobs = User_knobs.numel ();
157 
158  if (nel_User_knobs > 0)
159  knobs[CCOLAMD_LU] = (User_knobs(0) != 0);
160  if (nel_User_knobs > 1)
161  knobs[CCOLAMD_DENSE_ROW] = User_knobs(1);
162  if (nel_User_knobs > 2)
163  knobs[CCOLAMD_DENSE_COL] = User_knobs(2);
164  if (nel_User_knobs > 3)
165  knobs[CCOLAMD_AGGRESSIVE] = (User_knobs(3) != 0);
166  if (nel_User_knobs > 4)
167  spumoni = (User_knobs(4) != 0);
168 
169  // print knob settings if spumoni is set
170  if (spumoni)
171  {
172  octave_stdout << "\nccolamd version " << CCOLAMD_MAIN_VERSION << '.'
173  << CCOLAMD_SUB_VERSION << ", " << CCOLAMD_DATE
174  << ":\nknobs(1): " << User_knobs(0) << ", order for ";
175  if (knobs[CCOLAMD_LU] != 0)
176  octave_stdout << "lu (A)\n";
177  else
178  octave_stdout << "chol (A'*A)\n";
179 
180  if (knobs[CCOLAMD_DENSE_ROW] >= 0)
181  octave_stdout << "knobs(2): " << User_knobs(1)
182  << ", rows with > max (16,"
183  << knobs[CCOLAMD_DENSE_ROW]
184  << "*sqrt (size(A,2)))"
185  << " entries removed\n";
186  else
187  octave_stdout << "knobs(2): " << User_knobs(1)
188  << ", no dense rows removed\n";
189 
190  if (knobs[CCOLAMD_DENSE_COL] >= 0)
191  octave_stdout << "knobs(3): " << User_knobs(2)
192  << ", cols with > max (16,"
193  << knobs[CCOLAMD_DENSE_COL] << "*sqrt (size(A)))"
194  << " entries removed\n";
195  else
196  octave_stdout << "knobs(3): " << User_knobs(2)
197  << ", no dense columns removed\n";
198 
199  if (knobs[CCOLAMD_AGGRESSIVE] != 0)
200  octave_stdout << "knobs(4): " << User_knobs(3)
201  << ", aggressive absorption: yes";
202  else
203  octave_stdout << "knobs(4): " << User_knobs(3)
204  << ", aggressive absorption: no";
205 
206  octave_stdout << "knobs(5): " << User_knobs(4)
207  << ", statistics and knobs printed\n";
208  }
209  }
210 
211  octave_idx_type n_row, n_col, nnz;
212  octave_idx_type *ridx, *cidx;
214  SparseMatrix sm;
215 
216  if (args(0).issparse ())
217  {
218  if (args(0).iscomplex ())
219  {
220  scm = args(0).sparse_complex_matrix_value ();
221  n_row = scm.rows ();
222  n_col = scm.cols ();
223  nnz = scm.nnz ();
224  ridx = scm.xridx ();
225  cidx = scm.xcidx ();
226  }
227  else
228  {
229  sm = args(0).sparse_matrix_value ();
230 
231  n_row = sm.rows ();
232  n_col = sm.cols ();
233  nnz = sm.nnz ();
234  ridx = sm.xridx ();
235  cidx = sm.xcidx ();
236  }
237  }
238  else
239  {
240  if (args(0).iscomplex ())
241  sm = SparseMatrix (real (args(0).complex_matrix_value ()));
242  else
243  sm = SparseMatrix (args(0).matrix_value ());
244 
245  n_row = sm.rows ();
246  n_col = sm.cols ();
247  nnz = sm.nnz ();
248  ridx = sm.xridx ();
249  cidx = sm.xcidx ();
250  }
251 
252  // Allocate workspace for ccolamd
254  for (octave_idx_type i = 0; i < n_col+1; i++)
255  p[i] = cidx[i];
256 
257  octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col);
259  for (octave_idx_type i = 0; i < nnz; i++)
260  A[i] = ridx[i];
261 
262  static_assert (CCOLAMD_STATS <= 40, "ccolamd: # of CCOLAMD_STATS exceeded. Please report this to bugs.octave.org");
263  octave::suitesparse_integer stats_storage[CCOLAMD_STATS];
264  octave::suitesparse_integer *stats = &stats_storage[0];
265 
266  if (nargin > 2)
267  {
268  NDArray in_cmember = args(2).array_value ();
269  octave_idx_type cslen = in_cmember.numel ();
271  for (octave_idx_type i = 0; i < cslen; i++)
272  // convert cmember from 1-based to 0-based
273  cmember[i] = static_cast<octave::suitesparse_integer>(in_cmember(i) - 1);
274 
275  if (cslen != n_col)
276  error ("ccolamd: CMEMBER must be of length equal to #cols of A");
277 
278  // Order the columns (destroys A)
279  if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats,cmember))
280  {
281  CCOLAMD_NAME (_report) (stats);
282 
283  error ("ccolamd: internal error!");
284  }
285  }
286  else
287  {
288  // Order the columns (destroys A)
289  if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, nullptr))
290  {
291  CCOLAMD_NAME (_report) (stats);
292 
293  error ("ccolamd: internal error!");
294  }
295  }
296 
297  // return the permutation vector
298  NDArray out_perm (dim_vector (1, n_col));
299  for (octave_idx_type i = 0; i < n_col; i++)
300  out_perm(i) = p[i] + 1;
301 
302  retval(0) = out_perm;
303 
304  // print stats if spumoni > 0
305  if (spumoni > 0)
306  CCOLAMD_NAME (_report) (stats);
307 
308  // Return the stats vector
309  if (nargout == 2)
310  {
311  NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
312  for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
313  out_stats(i) = stats[i];
314  retval(1) = out_stats;
315 
316  // fix stats (5) and (6), for 1-based information on
317  // jumbled matrix. note that this correction doesn't
318  // occur if symamd returns FALSE
319  out_stats(CCOLAMD_INFO1)++;
320  out_stats(CCOLAMD_INFO2)++;
321  }
322 
323  return retval;
324 
325 #else
326 
327  octave_unused_parameter (args);
328  octave_unused_parameter (nargout);
329 
330  err_disabled_feature ("ccolamd", "CCOLAMD");
331 
332 #endif
333 }
334 
335 DEFUN_DLD (csymamd, args, nargout,
336  doc: /* -*- texinfo -*-
337 @deftypefn {} {@var{p} =} csymamd (@var{S})
338 @deftypefnx {} {@var{p} =} csymamd (@var{S}, @var{knobs})
339 @deftypefnx {} {@var{p} =} csymamd (@var{S}, @var{knobs}, @var{cmember})
340 @deftypefnx {} {[@var{p}, @var{stats}] =} csymamd (@dots{})
341 
342 For a symmetric positive definite matrix @var{S}, return the permutation
343 vector @var{p} such that @code{@var{S}(@var{p},@var{p})} tends to have a
344 sparser Cholesky@tie{}factor than @var{S}.
345 
346 Sometimes @code{csymamd} works well for symmetric indefinite matrices too.
347 The matrix @var{S} is assumed to be symmetric; only the strictly lower
348 triangular part is referenced. @var{S} must be square. The ordering is
349 followed by an elimination tree post-ordering.
350 
351 @var{knobs} is an optional 1-element to 3-element input vector, with a
352 default value of @code{[10 1 0]}. Entries not present are set to their
353 defaults.
354 
355 @table @code
356 @item @var{knobs}(1)
357 If @var{S} is n-by-n, then rows and columns with more than
358 @code{max(16,@var{knobs}(1)*sqrt(n))} entries are ignored, and ordered
359 last in the output permutation (subject to the cmember constraints).
360 
361 @item @var{knobs}(2)
362 If nonzero, aggressive absorption is performed.
363 
364 @item @var{knobs}(3)
365 If nonzero, statistics and knobs are printed.
366 
367 @end table
368 
369 @var{cmember} is an optional vector of length n. It defines the constraints
370 on the ordering. If @code{@var{cmember}(j) = @var{S}}, then row/column j is
371 in constraint set @var{c} (@var{c} must be in the range 1 to n). In the
372 output permutation @var{p}, rows/columns in set 1 appear first, followed
373 by all rows/columns in set 2, and so on. @code{@var{cmember} = ones (1,n)}
374 if not present or empty. @code{csymamd (@var{S},[],1:n)} returns
375 @code{1:n}.
376 
377 @code{@var{p} = csymamd (@var{S})} is about the same as
378 @code{@var{p} = symamd (@var{S})}. @var{knobs} and its default values
379 differ.
380 
381 @code{@var{stats}(4:7)} provide information if CCOLAMD was able to
382 continue. The matrix is OK if @code{@var{stats}(4)} is zero, or 1 if
383 invalid. @code{@var{stats}(5)} is the rightmost column index that is
384 unsorted or contains duplicate entries, or zero if no such column exists.
385 @code{@var{stats}(6)} is the last seen duplicate or out-of-order row
386 index in the column index given by @code{@var{stats}(5)}, or zero if no
387 such row index exists. @code{@var{stats}(7)} is the number of duplicate
388 or out-of-order row indices. @code{@var{stats}(8:20)} is always zero in
389 the current version of @sc{ccolamd} (reserved for future use).
390 
391 The authors of the code itself are @nospell{S. Larimore, T. Davis} and
392 @nospell{S. Rajamanickam} in collaboration with @nospell{J. Bilbert and E. Ng}.
393 Supported by the National Science Foundation
394 @nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from
395 @nospell{Sandia} National Lab.
396 See @url{http://faculty.cse.tamu.edu/davis/suitesparse.html} for ccolamd,
397 colamd, csymamd, amd, colamd, symamd, and other related orderings.
398 @seealso{symamd, ccolamd}
399 @end deftypefn */)
400 {
401 #if defined (HAVE_CCOLAMD)
402 
403  int nargin = args.length ();
404 
406  print_usage ();
407 
408  octave_value_list retval (nargout == 2 ? 2 : 1);
409  int spumoni = 0;
410 
411  // Get knobs
412  static_assert (CCOLAMD_KNOBS <= 40, "csymamd: # of CCOLAMD_KNOBS exceeded. Please report this to bugs.octave.org");
413  double knob_storage[CCOLAMD_KNOBS];
414  double *knobs = &knob_storage[0];
415  CCOLAMD_NAME (_set_defaults) (knobs);
416 
417  // Check for user-passed knobs
418  if (nargin > 1)
419  {
420  NDArray User_knobs = args(1).array_value ();
421  int nel_User_knobs = User_knobs.numel ();
422 
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));
429 
430  // print knob settings if spumoni is set
431  if (spumoni)
432  {
433  octave_stdout << "\ncsymamd version " << CCOLAMD_MAIN_VERSION
434  << '.' << CCOLAMD_SUB_VERSION
435  << ", " << CCOLAMD_DATE << "\n";
436 
437  if (knobs[CCOLAMD_DENSE_ROW] >= 0)
438  octave_stdout << "knobs(1): " << User_knobs(0)
439  << ", rows/cols with > max (16,"
440  << knobs[CCOLAMD_DENSE_ROW]
441  << "*sqrt (size(A,2)))"
442  << " entries removed\n";
443  else
444  octave_stdout << "knobs(1): " << User_knobs(0)
445  << ", no dense rows/cols removed\n";
446 
447  if (knobs[CCOLAMD_AGGRESSIVE] != 0)
448  octave_stdout << "knobs(2): " << User_knobs(1)
449  << ", aggressive absorption: yes";
450  else
451  octave_stdout << "knobs(2): " << User_knobs(1)
452  << ", aggressive absorption: no";
453 
454  octave_stdout << "knobs(3): " << User_knobs(2)
455  << ", statistics and knobs printed\n";
456  }
457  }
458 
459  octave_idx_type n_row, n_col;
460  octave_idx_type *ridx, *cidx;
461  SparseMatrix sm;
463 
464  if (args(0).issparse ())
465  {
466  if (args(0).iscomplex ())
467  {
468  scm = args(0).sparse_complex_matrix_value ();
469  n_row = scm.rows ();
470  n_col = scm.cols ();
471  ridx = scm.xridx ();
472  cidx = scm.xcidx ();
473  }
474  else
475  {
476  sm = args(0).sparse_matrix_value ();
477  n_row = sm.rows ();
478  n_col = sm.cols ();
479  ridx = sm.xridx ();
480  cidx = sm.xcidx ();
481  }
482  }
483  else
484  {
485  if (args(0).iscomplex ())
486  sm = SparseMatrix (real (args(0).complex_matrix_value ()));
487  else
488  sm = SparseMatrix (args(0).matrix_value ());
489 
490  n_row = sm.rows ();
491  n_col = sm.cols ();
492  ridx = sm.xridx ();
493  cidx = sm.xcidx ();
494  }
495 
496  if (n_row != n_col)
497  err_square_matrix_required ("csymamd", "S");
498 
499  // Allocate workspace for symamd
501  static_assert (CCOLAMD_STATS <= 40, "csymamd: # of CCOLAMD_STATS exceeded. Please report this to bugs.octave.org");
502  octave::suitesparse_integer stats_storage[CCOLAMD_STATS];
503  octave::suitesparse_integer *stats = &stats_storage[0];
504 
505  if (nargin > 2)
506  {
507  NDArray in_cmember = args(2).array_value ();
508  octave_idx_type cslen = in_cmember.numel ();
510  for (octave_idx_type i = 0; i < cslen; i++)
511  // convert cmember from 1-based to 0-based
512  cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
513 
514  if (cslen != n_col)
515  error ("csymamd: CMEMBER must be of length equal to #cols of A");
516 
517  if (! CSYMAMD_NAME () (n_col,
520  perm, knobs, stats, &calloc, &free, cmember, -1))
521  {
522  CSYMAMD_NAME (_report)(stats);
523 
524  error ("csymamd: internal error!");
525  }
526  }
527  else
528  {
529  if (! CSYMAMD_NAME () (n_col,
532  perm, knobs, stats, &calloc, &free, nullptr, -1))
533  {
534  CSYMAMD_NAME (_report)(stats);
535 
536  error ("csymamd: internal error!");
537  }
538  }
539 
540  // return the permutation vector
541  NDArray out_perm (dim_vector (1, n_col));
542  for (octave_idx_type i = 0; i < n_col; i++)
543  out_perm(i) = perm[i] + 1;
544 
545  retval(0) = out_perm;
546 
547  // print stats if spumoni > 0
548  if (spumoni > 0)
549  CSYMAMD_NAME (_report)(stats);
550 
551  // Return the stats vector
552  if (nargout == 2)
553  {
554  NDArray out_stats (dim_vector (1, CCOLAMD_STATS));
555  for (octave_idx_type i = 0 ; i < CCOLAMD_STATS ; i++)
556  out_stats(i) = stats[i];
557  retval(1) = out_stats;
558 
559  // fix stats (5) and (6), for 1-based information on
560  // jumbled matrix. note that this correction doesn't
561  // occur if symamd returns FALSE
562  out_stats(CCOLAMD_INFO1)++;
563  out_stats(CCOLAMD_INFO2)++;
564  }
565 
566  return retval;
567 
568 #else
569 
570  octave_unused_parameter (args);
571  octave_unused_parameter (nargout);
572 
573  err_disabled_feature ("csymamd", "CCOLAMD");
574 
575 #endif
576 }
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
void error(const char *fmt,...)
Definition: error.cc:578
void err_square_matrix_required(const char *fcn, const char *name)
Definition: errwarn.cc:118
octave_idx_type nnz(void) const
Actual number of nonzero terms.
Definition: Sparse.h:240
F77_RET_T const F77_INT F77_CMPLX * A
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
#define CCOLAMD_NAME(name)
Definition: oct-sparse.h:116
int suitesparse_integer
Definition: oct-sparse.h:168
#define CSYMAMD_NAME(name)
Definition: oct-sparse.h:117
octave_value retval
Definition: data.cc:6246
octave_idx_type * xridx(void)
Definition: Sparse.h:501
octave_idx_type cols(void) const
Definition: Sparse.h:259
#define octave_stdout
Definition: pager.h:174
p
Definition: lu.cc:138
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:41
args.length() nargin
Definition: file-io.cc:589
for i
Definition: data.cc:5264
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
Definition: defun-dld.h:58
octave_idx_type * xcidx(void)
Definition: Sparse.h:514
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:135
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:50
octave_idx_type rows(void) const
Definition: Sparse.h:258
suitesparse_integer * to_suitesparse_intptr(octave_idx_type *i)
Definition: oct-sparse.cc:48