GNU Octave  4.0.0
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-2015 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 #ifdef 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 "gripes.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  "-*- texinfo -*-\n\
46 @deftypefn {Built-in Function} {} issparse (@var{x})\n\
47 Return true if @var{x} is a sparse matrix.\n\
48 @seealso{ismatrix}\n\
49 @end deftypefn")
50 {
51  if (args.length () != 1)
52  {
53  print_usage ();
54  return octave_value ();
55  }
56  else
57  return octave_value (args(0).is_sparse_type ());
58 }
59 
60 DEFUN (sparse, args, ,
61  "-*- texinfo -*-\n\
62 @deftypefn {Built-in Function} {@var{s} =} sparse (@var{a})\n\
63 @deftypefnx {Built-in Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n})\n\
64 @deftypefnx {Built-in Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})\n\
65 @deftypefnx {Built-in Function} {@var{s} =} sparse (@var{m}, @var{n})\n\
66 @deftypefnx {Built-in Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, \"unique\")\n\
67 @deftypefnx {Built-in Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})\n\
68 Create a sparse matrix from a full matrix, or row, column, value triplets.\n\
69 \n\
70 If @var{a} is a full matrix, convert it to a sparse matrix representation,\n\
71 removing all zero values in the process.\n\
72 \n\
73 Given the integer index vectors @var{i} and @var{j}, and a 1-by-@code{nnz}\n\
74 vector of real or complex values @var{sv}, construct the sparse matrix\n\
75 @code{S(@var{i}(@var{k}),@var{j}(@var{k})) = @var{sv}(@var{k})} with overall\n\
76 dimensions @var{m} and @var{n}. If any of @var{sv}, @var{i} or @var{j} are\n\
77 scalars, they are expanded to have a common size.\n\
78 \n\
79 If @var{m} or @var{n} are not specified their values are derived from the\n\
80 maximum index in the vectors @var{i} and @var{j} as given by\n\
81 @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.\n\
82 \n\
83 @strong{Note}: if multiple values are specified with the same @var{i},\n\
84 @var{j} indices, the corresponding value in @var{s} will be the sum of the\n\
85 values at the repeated location. See @code{accumarray} for an example of how\n\
86 to produce different behavior, such as taking the minimum instead.\n\
87 \n\
88 If the option @qcode{\"unique\"} is given, and more than one value is\n\
89 specified at the same @var{i}, @var{j} indices, then the last specified\n\
90 value will be used.\n\
91 \n\
92 @code{sparse (@var{m}, @var{n})} will create an empty @var{m}x@var{n} sparse\n\
93 matrix and is equivalent to @code{sparse ([], [], [], @var{m}, @var{n})}\n\
94 \n\
95 The argument @code{nzmax} is ignored but accepted for compatibility with\n\
96 @sc{matlab}.\n\
97 \n\
98 Example 1 (sum at repeated indices):\n\
99 \n\
100 @example\n\
101 @group\n\
102 @var{i} = [1 1 2]; @var{j} = [1 1 2]; @var{sv} = [3 4 5];\n\
103 sparse (@var{i}, @var{j}, @var{sv}, 3, 4)\n\
104 @result{}\n\
105 Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])\n\
106 \n\
107  (1, 1) -> 7\n\
108  (2, 2) -> 5\n\
109 @end group\n\
110 @end example\n\
111 \n\
112 Example 2 (\"unique\" option):\n\
113 \n\
114 @example\n\
115 @group\n\
116 @var{i} = [1 1 2]; @var{j} = [1 1 2]; @var{sv} = [3 4 5];\n\
117 sparse (@var{i}, @var{j}, @var{sv}, 3, 4, \"unique\")\n\
118 @result{}\n\
119 Compressed Column Sparse (rows = 3, cols = 4, nnz = 2 [17%])\n\
120 \n\
121  (1, 1) -> 4\n\
122  (2, 2) -> 5\n\
123 @end group\n\
124 @end example\n\
125 @seealso{full, accumarray, spalloc, spdiags, speye, spones, sprand, sprandn, sprandsym, spconvert, spfun}\n\
126 @end deftypefn")
127 {
128  octave_value retval;
129  int nargin = args.length ();
130 
131  // Temporarily disable sparse_auto_mutate if set (it's obsolete anyway).
132  unwind_protect frame;
134  Vsparse_auto_mutate = false;
135 
136  if (nargin == 1)
137  {
138  octave_value arg = args(0);
139  if (arg.is_bool_type ())
140  retval = arg.sparse_bool_matrix_value ();
141  else if (arg.is_complex_type ())
142  retval = arg.sparse_complex_matrix_value ();
143  else if (arg.is_numeric_type ())
144  retval = arg.sparse_matrix_value ();
145  else
146  gripe_wrong_type_arg ("sparse", arg);
147  }
148  else if (nargin == 2)
149  {
150  octave_idx_type m = 0;
151  octave_idx_type n = 0;
152 
153  get_dimensions (args(0), args(1), "sparse", m, n);
154 
155  if (! error_state)
156  {
157  if (m >= 0 && n >= 0)
158  retval = SparseMatrix (m, n);
159  else
160  error ("sparse: dimensions must be non-negative");
161  }
162  }
163  else if (nargin >= 3)
164  {
165  bool summation = true;
166  if (nargin > 3 && args(nargin-1).is_string ())
167  {
168  std::string opt = args(nargin-1).string_value ();
169  if (opt == "unique")
170  summation = false;
171  else if (opt == "sum" || opt == "summation")
172  summation = true;
173  else
174  error ("sparse: invalid option: %s", opt.c_str ());
175 
176  nargin -= 1;
177  }
178 
179  if (! error_state)
180  {
181  octave_idx_type m, n, nzmax;
182  m = n = nzmax = -1;
183  if (nargin == 6)
184  {
185  nzmax = args(5).idx_type_value ();
186  nargin --;
187  }
188 
189  if (nargin == 5)
190  {
191  get_dimensions (args(3), args(4), "sparse", m, n);
192 
193  if (! error_state && (m < 0 || n < 0))
194  error ("sparse: dimensions must be non-negative");
195  }
196  else if (nargin != 3)
197  print_usage ();
198 
199  if (! error_state)
200  {
201  idx_vector i = args(0).index_vector ();
202  idx_vector j = args(1).index_vector ();
203 
204  if (args(2).is_bool_type ())
205  retval = SparseBoolMatrix (args(2).bool_array_value (), i, j,
206  m, n, summation, nzmax);
207  else if (args(2).is_complex_type ())
208  retval = SparseComplexMatrix (args(2).complex_array_value (),
209  i, j, m, n, summation, nzmax);
210  else if (args(2).is_numeric_type ())
211  retval = SparseMatrix (args(2).array_value (), i, j,
212  m, n, summation, nzmax);
213  else
214  gripe_wrong_type_arg ("sparse", args(2));
215  }
216 
217  }
218  }
219 
220  return retval;
221 }
222 
223 DEFUN (spalloc, args, ,
224  "-*- texinfo -*-\n\
225 @deftypefn {Built-in Function} {@var{s} =} spalloc (@var{m}, @var{n}, @var{nz})\n\
226 Create an @var{m}-by-@var{n} sparse matrix with pre-allocated space for at\n\
227 most @var{nz} nonzero elements.\n\
228 \n\
229 This is useful for building a matrix incrementally by a sequence of indexed\n\
230 assignments. Subsequent indexed assignments after @code{spalloc} will reuse\n\
231 the pre-allocated memory, provided they are of one of the simple forms\n\
232 \n\
233 @itemize\n\
234 @item @code{@var{s}(I:J) = @var{x}}\n\
235 \n\
236 @item @code{@var{s}(:,I:J) = @var{x}}\n\
237 \n\
238 @item @code{@var{s}(K:L,I:J) = @var{x}}\n\
239 @end itemize\n\
240 \n\
241 @b{and} that the following conditions are met:\n\
242 \n\
243 @itemize\n\
244 @item the assignment does not decrease nnz (@var{S}).\n\
245 \n\
246 @item after the assignment, nnz (@var{S}) does not exceed @var{nz}.\n\
247 \n\
248 @item no index is out of bounds.\n\
249 @end itemize\n\
250 \n\
251 Partial movement of data may still occur, but in general the assignment will\n\
252 be more memory and time efficient under these circumstances. In particular,\n\
253 it is possible to efficiently build a pre-allocated sparse matrix from a\n\
254 contiguous block of columns.\n\
255 \n\
256 The amount of pre-allocated memory for a given matrix may be queried using\n\
257 the function @code{nzmax}.\n\
258 @seealso{nzmax, sparse}\n\
259 @end deftypefn")
260 {
261  octave_value retval;
262  int nargin = args.length ();
263 
264  if (nargin == 2 || nargin == 3)
265  {
266  octave_idx_type m = args(0).idx_type_value ();
267  octave_idx_type n = args(1).idx_type_value ();
268  octave_idx_type nz = 0;
269  if (nargin == 3)
270  nz = args(2).idx_type_value ();
271  if (error_state)
272  ;
273  else if (m >= 0 && n >= 0 && nz >= 0)
274  retval = SparseMatrix (dim_vector (m, n), nz);
275  else
276  error ("spalloc: M,N,NZ must be non-negative");
277  }
278  else
279  print_usage ();
280 
281  return retval;
282 }
void get_dimensions(const octave_value &a, const char *warn_for, dim_vector &dim)
Definition: utils.cc:1141
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
Definition: ov.h:798
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
Definition: gripes.cc:135
OCTINTERP_API void print_usage(void)
Definition: defun.cc:51
bool is_numeric_type(void) const
Definition: ov.h:663
void protect_var(T &var)
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:44
void error(const char *fmt,...)
Definition: error.cc:476
octave_idx_type nzmax(void) const
Definition: ov.h:494
boolNDArray bool_array_value(bool warn=false) const
Definition: ov.h:811
bool is_sparse_type(void) const
Definition: ov.h:666
bool is_bool_type(void) const
Definition: ov.h:645
bool is_string(void) const
Definition: ov.h:562
int error_state
Definition: error.cc:101
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
Definition: ov.h:827
bool is_complex_type(void) const
Definition: ov.h:654
octave_idx_type length(void) const
Definition: ov.cc:1525
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:824
double arg(double x)
Definition: lo-mappers.h:37
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:779
bool Vsparse_auto_mutate
Definition: ov-base.cc:118
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:820
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))