GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
sparse.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2018 David Bateman
4 Copyright (C) 1998-2004 Andy Adler
5 Copyright (C) 2010 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software: you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <https://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <cstdlib>
30 #include <string>
31 
32 #include "variables.h"
33 #include "utils.h"
34 #include "pager.h"
35 #include "defun.h"
36 #include "errwarn.h"
37 #include "quit.h"
38 #include "unwind-prot.h"
39 
40 #include "ov-re-sparse.h"
41 #include "ov-cx-sparse.h"
42 #include "ov-bool-sparse.h"
43 
44 DEFUN (issparse, args, ,
45  doc: /* -*- texinfo -*-
46 @deftypefn {} {} issparse (@var{x})
47 Return true if @var{x} is a sparse matrix.
48 @seealso{ismatrix}
49 @end deftypefn */)
50 {
51  if (args.length () != 1)
52  print_usage ();
53 
54  return ovl (args(0).issparse ());
55 }
56 
57 DEFUN (sparse, args, ,
58  doc: /* -*- texinfo -*-
59 @deftypefn {} {@var{s} =} sparse (@var{a})
60 @deftypefnx {} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n})
61 @deftypefnx {} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})
62 @deftypefnx {} {@var{s} =} sparse (@var{m}, @var{n})
63 @deftypefnx {} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, "unique")
64 @deftypefnx {} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})
65 Create a sparse matrix from a full matrix, or row, column, value triplets.
66 
67 If @var{a} is a full matrix, convert it to a sparse matrix representation,
68 removing all zero values in the process.
69 
70 Given the integer index vectors @var{i} and @var{j}, and a 1-by-@code{nnz}
71 vector of real or complex values @var{sv}, construct the sparse matrix
72 @code{S(@var{i}(@var{k}),@var{j}(@var{k})) = @var{sv}(@var{k})} with overall
73 dimensions @var{m} and @var{n}. If any of @var{sv}, @var{i} or @var{j} are
74 scalars, they are expanded to have a common size.
75 
76 If @var{m} or @var{n} are not specified their values are derived from the
77 maximum index in the vectors @var{i} and @var{j} as given by
78 @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.
79 
80 @strong{Note}: if multiple values are specified with the same @var{i},
81 @var{j} indices, the corresponding value in @var{s} will be the sum of the
82 values at the repeated location. See @code{accumarray} for an example of
83 how to produce different behavior, such as taking the minimum instead.
84 
85 If the option @qcode{"unique"} is given, and more than one value is
86 specified at the same @var{i}, @var{j} indices, then the last specified
87 value will be used.
88 
89 @code{sparse (@var{m}, @var{n})} will create an empty @var{m}x@var{n} sparse
90 matrix and is equivalent to @code{sparse ([], [], [], @var{m}, @var{n})}
91 
92 The argument @var{nzmax} is ignored but accepted for compatibility with
93 @sc{matlab}.
94 
95 Example 1 (sum at repeated indices):
96 
97 @example
98 @group
99 @var{i} = [1 1 2]; @var{j} = [1 1 2]; @var{sv} = [3 4 5];
100 sparse (@var{i}, @var{j}, @var{sv}, 3, 4)
101 @result{}
102 Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])
103 
104  (1, 1) -> 7
105  (2, 2) -> 5
106 @end group
107 @end example
108 
109 Example 2 ("unique" option):
110 
111 @example
112 @group
113 @var{i} = [1 1 2]; @var{j} = [1 1 2]; @var{sv} = [3 4 5];
114 sparse (@var{i}, @var{j}, @var{sv}, 3, 4, "unique")
115 @result{}
116 Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])
117 
118  (1, 1) -> 4
119  (2, 2) -> 5
120 @end group
121 @end example
122 @seealso{full, accumarray, spalloc, spdiags, speye, spones, sprand, sprandn, sprandsym, spconvert, spfun}
123 @end deftypefn */)
124 {
125  int nargin = args.length ();
126 
127  if (nargin == 0 || nargin > 6)
128  print_usage ();
129 
131 
132  // Temporarily disable sparse_auto_mutate if set (it's obsolete anyway).
135  Vsparse_auto_mutate = false;
136 
137  if (nargin == 1)
138  {
139  octave_value arg = args(0);
140  if (arg.islogical ())
142  else if (arg.iscomplex ())
144  else if (arg.isnumeric ())
146  else
147  err_wrong_type_arg ("sparse", arg);
148  }
149  else if (nargin == 2)
150  {
151  octave_idx_type m = 0;
152  octave_idx_type n = 0;
153 
154  get_dimensions (args(0), args(1), "sparse", m, n);
155 
156  if (m >= 0 && n >= 0)
157  retval = SparseMatrix (m, n);
158  else
159  error ("sparse: dimensions must be non-negative");
160  }
161  else if (nargin >= 3)
162  {
163  bool summation = true;
164  if (nargin > 3 && args(nargin-1).is_string ())
165  {
166  std::string opt = args(nargin-1).string_value ();
167  if (opt == "unique")
168  summation = false;
169  else if (opt == "sum" || opt == "summation")
170  summation = true;
171  else
172  error ("sparse: invalid option: %s", opt.c_str ());
173 
174  nargin -= 1;
175  }
176 
177  octave_idx_type m, n, nzmax;
178  m = n = nzmax = -1;
179  if (nargin == 6)
180  {
181  nzmax = args(5).idx_type_value ();
182  nargin--;
183  }
184 
185  if (nargin == 5)
186  {
187  get_dimensions (args(3), args(4), "sparse", m, n);
188 
189  if (m < 0 || n < 0)
190  error ("sparse: dimensions must be non-negative");
191  }
192 
193  int k = 0; // index we're checking when index_vector throws
194  try
195  {
196  idx_vector i = args(0).index_vector ();
197  k = 1;
198  idx_vector j = args(1).index_vector ();
199 
200  if (args(2).islogical ())
201  retval = SparseBoolMatrix (args(2).bool_array_value (), i,j,
202  m, n, summation, nzmax);
203  else if (args(2).iscomplex ())
205  i, j, m, n, summation, nzmax);
206  else if (args(2).isnumeric ())
207  retval = SparseMatrix (args(2).array_value (), i, j,
208  m, n, summation, nzmax);
209  else
210  err_wrong_type_arg ("sparse", args(2));
211  }
212  catch (octave::index_exception& e)
213  {
214  // Rethrow to allow more info to be reported later.
215  e.set_pos_if_unset (2, k+1);
216  throw;
217  }
218  }
219 
220  return retval;
221 }
222 
223 DEFUN (spalloc, args, ,
224  doc: /* -*- texinfo -*-
225 @deftypefn {} {@var{s} =} spalloc (@var{m}, @var{n}, @var{nz})
226 Create an @var{m}-by-@var{n} sparse matrix with pre-allocated space for at
227 most @var{nz} nonzero elements.
228 
229 This is useful for building a matrix incrementally by a sequence of indexed
230 assignments. Subsequent indexed assignments after @code{spalloc} will reuse
231 the pre-allocated memory, provided they are of one of the simple forms
232 
233 @itemize
234 @item @code{@var{s}(I:J) = @var{x}}
235 
236 @item @code{@var{s}(:,I:J) = @var{x}}
237 
238 @item @code{@var{s}(K:L,I:J) = @var{x}}
239 @end itemize
240 
241 @b{and} that the following conditions are met:
242 
243 @itemize
244 @item the assignment does not decrease nnz (@var{S}).
245 
246 @item after the assignment, nnz (@var{S}) does not exceed @var{nz}.
247 
248 @item no index is out of bounds.
249 @end itemize
250 
251 Partial movement of data may still occur, but in general the assignment will
252 be more memory and time efficient under these circumstances. In particular,
253 it is possible to efficiently build a pre-allocated sparse matrix from a
254 contiguous block of columns.
255 
256 The amount of pre-allocated memory for a given matrix may be queried using
257 the function @code{nzmax}.
258 @seealso{nzmax, sparse}
259 @end deftypefn */)
260 {
261  int nargin = args.length ();
262 
264  print_usage ();
265 
266  octave_idx_type m = args(0).idx_type_value ();
267  octave_idx_type n = args(1).idx_type_value ();
268 
269  octave_idx_type nz = 0;
270  if (nargin == 3)
271  nz = args(2).idx_type_value ();
272 
273  if (m >= 0 && n >= 0 && nz >= 0)
274  return ovl (SparseMatrix (dim_vector (m, n), nz));
275  else
276  error ("spalloc: M,N,NZ must be non-negative");
277 }
sparse(ar{i}, ar{j}, ar{sv}, 3, 4) esult
Definition: sparse.cc:123
bool islogical(void) const
Definition: ov.h:696
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
for large enough k
Definition: lu.cc:617
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void error(const char *fmt,...)
Definition: error.cc:578
i e
Definition: data.cc:2591
OCTAVE_EXPORT octave_value_list isnumeric
Definition: data.cc:3157
octave_value arg
Definition: pr-output.cc:3244
OCTAVE_EXPORT octave_value_list islogical
Definition: data.cc:3157
bool issparse(void) const
Definition: ov.h:730
octave_value retval
Definition: data.cc:6246
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:162
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:885
OCTINTERP_API void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
octave::unwind_protect frame
Definition: graphics.cc:12190
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:872
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:881
bool Vsparse_auto_mutate
Definition: ov-base.cc:101
args.length() nargin
Definition: file-io.cc:589
bool iscomplex(void) const
Definition: ov.h:710
for i
Definition: data.cc:5264
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
Definition: ov.h:888
bool is_string(void) const
Definition: ov.h:577
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:859
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:840
octave_idx_type nzmax(void) const
Definition: ov.h:498
bool isnumeric(void) const
Definition: ov.h:723