GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
dmperm.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2005-2017 David Bateman
4 Copyright (C) 1998-2005 Andy Adler
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include "defun-dld.h"
29 #include "error.h"
30 #include "errwarn.h"
31 #include "ovl.h"
32 #include "utils.h"
33 
34 #include "oct-sparse.h"
35 #include "ov-re-sparse.h"
36 #include "ov-cx-sparse.h"
37 
38 #if defined (OCTAVE_ENABLE_64)
39 # define CXSPARSE_NAME(name) cs_dl ## name
40 #else
41 # define CXSPARSE_NAME(name) cs_di ## name
42 #endif
43 
44 #if defined (HAVE_CXSPARSE)
45 
46 static RowVector
48 {
49  RowVector ret (n);
50  for (octave_idx_type i = 0; i < n; i++)
51  ret.xelem (i) = p[i] + 1;
52  return ret;
53 }
54 
55 static octave_value_list
56 dmperm_internal (bool rank, const octave_value arg, int nargout)
57 {
59  octave_idx_type nr = arg.rows ();
60  octave_idx_type nc = arg.columns ();
63  CXSPARSE_NAME () csm;
64  csm.m = nr;
65  csm.n = nc;
66  csm.x = 0;
67  csm.nz = -1;
68 
69  if (arg.is_real_type ())
70  {
71  m = arg.sparse_matrix_value ();
72  csm.nzmax = m.nnz ();
73  csm.p = m.xcidx ();
74  csm.i = m.xridx ();
75  }
76  else
77  {
78  cm = arg.sparse_complex_matrix_value ();
79  csm.nzmax = cm.nnz ();
80  csm.p = cm.xcidx ();
81  csm.i = cm.xridx ();
82  }
83 
84  if (nargout <= 1 || rank)
85  {
86  octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
87  if (rank)
88  {
89  octave_idx_type r = 0;
90  for (octave_idx_type i = 0; i < nc; i++)
91  if (jmatch[nr+i] >= 0)
92  r++;
93  retval(0) = static_cast<double>(r);
94  }
95  else
96  retval(0) = put_int (jmatch + nr, nc);
97  CXSPARSE_NAME (_free) (jmatch);
98  }
99  else
100  {
101  CXSPARSE_NAME (d) *dm = CXSPARSE_NAME(_dmperm) (&csm, 0);
102 
103  //retval(5) = put_int (dm->rr, 5);
104  //retval(4) = put_int (dm->cc, 5);
105  retval = ovl (put_int (dm->p, nr), put_int (dm->q, nc),
106  put_int (dm->r, dm->nb+1), put_int (dm->s, dm->nb+1));
107 
108  CXSPARSE_NAME (_dfree) (dm);
109  }
110 
111  return retval;
112 }
113 
114 #endif
115 
116 DEFUN_DLD (dmperm, args, nargout,
117  doc: /* -*- texinfo -*-
118 @deftypefn {} {@var{p} =} dmperm (@var{S})
119 @deftypefnx {} {[@var{p}, @var{q}, @var{r}, @var{S}] =} dmperm (@var{S})
120 
121 @cindex Dulmage-Mendelsohn decomposition
122 Perform a @nospell{Dulmage-Mendelsohn} permutation of the sparse matrix
123 @var{S}.
124 
125 With a single output argument @code{dmperm} performs the row permutations
126 @var{p} such that @code{@var{S}(@var{p},:)} has no zero elements on the
127 diagonal.
128 
129 Called with two or more output arguments, returns the row and column
130 permutations, such that @code{@var{S}(@var{p}, @var{q})} is in block
131 triangular form. The values of @var{r} and @var{S} define the boundaries
132 of the blocks. If @var{S} is square then @code{@var{r} == @var{S}}.
133 
134 The method used is described in: @nospell{A. Pothen & C.-J. Fan.}
135 @cite{Computing the Block Triangular Form of a Sparse Matrix}.
136 ACM Trans. Math. Software, 16(4):303-324, 1990.
137 @seealso{colamd, ccolamd}
138 @end deftypefn */)
139 {
140 #if defined (HAVE_CXSPARSE)
141 
142  if (args.length () != 1)
143  print_usage ();
144 
145  return ovl (dmperm_internal (false, args(0), nargout));
146 
147 #else
148 
149  octave_unused_parameter (args);
150  octave_unused_parameter (nargout);
151 
152  err_disabled_feature ("dmperm", "CXSparse");
153 
154 #endif
155 }
156 
157 /*
158 %!testif HAVE_CXSPARSE
159 %! n = 20;
160 %! a = speye (n,n);
161 %! a = a(randperm (n),:);
162 %! assert (a(dmperm (a),:), speye (n));
163 
164 %!testif HAVE_CXSPARSE
165 %! n = 20;
166 %! d = 0.2;
167 %! a = tril (sprandn (n,n,d), -1) + speye (n,n);
168 %! a = a(randperm (n), randperm (n));
169 %! [p,q,r,s] = dmperm (a);
170 %! assert (tril (a(p,q), -1), sparse (n, n));
171 */
172 
173 DEFUN_DLD (sprank, args, nargout,
174  doc: /* -*- texinfo -*-
175 @deftypefn {} {@var{p} =} sprank (@var{S})
176 @cindex structural rank
177 
178 Calculate the structural rank of the sparse matrix @var{S}.
179 
180 Note that only the structure of the matrix is used in this calculation based
181 on a @nospell{Dulmage-Mendelsohn} permutation to block triangular form. As
182 such the numerical rank of the matrix @var{S} is bounded by
183 @code{sprank (@var{S}) >= rank (@var{S})}. Ignoring floating point errors
184 @code{sprank (@var{S}) == rank (@var{S})}.
185 @seealso{dmperm}
186 @end deftypefn */)
187 {
188 #if defined (HAVE_CXSPARSE)
189 
190  if (args.length () != 1)
191  print_usage ();
192 
193  return ovl (dmperm_internal (true, args(0), nargout));
194 
195 #else
196 
197  octave_unused_parameter (args);
198  octave_unused_parameter (nargout);
199 
200  err_disabled_feature ("sprank", "CXSparse");
201 
202 #endif
203 }
204 
205 /*
206 %!testif HAVE_CXSPARSE
207 %! assert (sprank (speye (20)), 20);
208 %!testif HAVE_CXSPARSE
209 %! assert (sprank ([1,0,2,0;2,0,4,0]), 2);
210 
211 %!error sprank (1,2)
212 */
octave_idx_type * xridx(void)
Definition: Sparse.h:536
bool is_real_type(void) const
Definition: ov.h:667
octave_idx_type rows(void) const
Definition: ov.h:489
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_idx_type * xcidx(void)
Definition: Sparse.h:549
octave_value arg
Definition: pr-output.cc:3440
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
#define CXSPARSE_NAME(name)
Definition: dmperm.cc:41
octave_idx_type nnz(void) const
Actual number of nonzero terms.
Definition: Sparse.h:253
octave_idx_type nzmax(void) const
Amount of storage for nonzero elements.
Definition: Sparse.h:245
JNIEnv void * args
Definition: ov-java.cc:67
octave_idx_type columns(void) const
Definition: ov.h:491
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:935
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
octave_value retval
Definition: data.cc:6294
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:838
T & xelem(octave_idx_type n)
Definition: Array.h:455
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Definition: defun-dld.h:45
static RowVector put_int(octave_idx_type *p, octave_idx_type n)
Definition: dmperm.cc:47
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:834
static octave_value_list dmperm_internal(bool rank, const octave_value arg, int nargout)
Definition: dmperm.cc:56
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:50