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
sparse.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2017 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 the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 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 <http://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).is_sparse_type ());
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 @code{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.is_bool_type ())
141  retval = arg.sparse_bool_matrix_value ();
142  else if (arg.is_complex_type ())
143  retval = arg.sparse_complex_matrix_value ();
144  else if (arg.is_numeric_type ())
145  retval = arg.sparse_matrix_value ();
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).is_bool_type ())
201  retval = SparseBoolMatrix (args(2).bool_array_value (), i,j,
202  m, n, summation, nzmax);
203  else if (args(2).is_complex_type ())
205  i, j, m, n, summation, nzmax);
206  else if (args(2).is_numeric_type ())
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 
263  if (nargin < 2 || nargin > 3)
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 }
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:812
sparse(ar{i}, ar{j}, ar{sv}, 3, 4) esult
Definition: sparse.cc:123
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
void set_pos_if_unset(octave_idx_type nd_arg, octave_idx_type dim_arg)
bool is_numeric_type(void) const
Definition: ov.h:679
for large enough k
Definition: lu.cc:606
void protect_var(T &var)
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
void error(const char *fmt,...)
Definition: error.cc:570
octave_idx_type nzmax(void) const
Definition: ov.h:511
i e
Definition: data.cc:2724
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:825
octave_value arg
Definition: pr-output.cc:3440
JNIEnv void * args
Definition: ov-java.cc:67
bool is_sparse_type(void) const
Definition: ov.h:682
bool is_bool_type(void) const
Definition: ov.h:661
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
int nargin
Definition: graphics.cc:10115
bool is_string(void) const
Definition: ov.h:578
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
Definition: ov.h:841
bool is_complex_type(void) const
Definition: ov.h:670
octave_value retval
Definition: data.cc:6294
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:838
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:156
OCTINTERP_API void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
octave::unwind_protect frame
Definition: graphics.cc:11584
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:793
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
bool Vsparse_auto_mutate
Definition: ov-base.cc:119
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:834
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:854