Mercurial > octave-nkf
annotate src/DLD-FUNCTIONS/sparse.cc @ 8920:eb63fbe60fab
update copyright notices
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 07 Mar 2009 10:41:27 -0500 |
parents | 6e9f26506804 |
children | 7c02ec148a3c |
rev | line source |
---|---|
5164 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 David Bateman |
7016 | 4 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler |
5 | |
6 This file is part of Octave. | |
5164 | 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 | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
5164 | 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 | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
5164 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <cstdlib> | |
29 #include <string> | |
30 | |
31 #include "variables.h" | |
32 #include "utils.h" | |
33 #include "pager.h" | |
34 #include "defun-dld.h" | |
35 #include "gripes.h" | |
36 #include "quit.h" | |
37 | |
38 #include "ov-re-sparse.h" | |
39 #include "ov-cx-sparse.h" | |
40 #include "ov-bool-sparse.h" | |
41 | |
42 DEFUN_DLD (issparse, args, , | |
43 "-*- texinfo -*-\n\ | |
44 @deftypefn {Loadable Function} {} issparse (@var{expr})\n\ | |
45 Return 1 if the value of the expression @var{expr} is a sparse matrix.\n\ | |
46 @end deftypefn") | |
47 { | |
48 if (args.length() != 1) | |
49 { | |
5823 | 50 print_usage (); |
5164 | 51 return octave_value (); |
52 } | |
53 else | |
7515
f3c00dc0912b
Eliminate the rest of the dispatched sparse functions
David Bateman <dbateman@free.fr>
parents:
7505
diff
changeset
|
54 return octave_value (args(0).is_sparse_type ()); |
5164 | 55 } |
56 | |
57 DEFUN_DLD (sparse, args, , | |
58 "-*- texinfo -*-\n\ | |
6556 | 59 @deftypefn {Loadable Function} {@var{s} =} sparse (@var{a})\n\ |
8106
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
60 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv}, @var{m}, @var{n}, @var{nzmax})\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
61 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{sv})\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
62 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{i}, @var{j}, @var{s}, @var{m}, @var{n}, \"unique\")\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
63 @deftypefnx {Loadable Function} {@var{s} =} sparse (@var{m}, @var{n})\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
64 Create a sparse matrix from the full matrix or row, column, value triplets.\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
65 If @var{a} is a full matrix, convert it to a sparse matrix representation,\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
66 removing all zero values in the process.\n\ |
5164 | 67 \n\ |
8106
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
68 Given the integer index vectors @var{i} and @var{j}, a 1-by-@code{nnz} vector\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
69 of real of complex values @var{sv}, overall dimensions @var{m} and @var{n}\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
70 of the sparse matrix. The argument @code{nzmax} is ignored but accepted for\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
71 compatibility with @sc{Matlab}. If @var{m} or @var{n} are not specified their\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
72 values are derived from the maximum index in the vectors @var{i} and @var{j}\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
73 as given by @code{@var{m} = max (@var{i})}, @code{@var{n} = max (@var{j})}.\n\ |
5164 | 74 \n\ |
6556 | 75 @strong{Note}: if multiple values are specified with the same\n\ |
76 @var{i}, @var{j} indices, the corresponding values in @var{s} will\n\ | |
77 be added.\n\ | |
78 \n\ | |
6557 | 79 The following are all equivalent:\n\ |
5164 | 80 \n\ |
6556 | 81 @example\n\ |
82 @group\n\ | |
83 s = sparse (i, j, s, m, n)\n\ | |
84 s = sparse (i, j, s, m, n, \"summation\")\n\ | |
85 s = sparse (i, j, s, m, n, \"sum\")\n\ | |
86 @end group\n\ | |
87 @end example\n\ | |
5164 | 88 \n\ |
8106
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
89 Given the option \"unique\". if more than two values are specified for the\n\ |
6556 | 90 same @var{i}, @var{j} indices, the last specified value will be used.\n\ |
5164 | 91 \n\ |
8106
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
92 @code{sparse(@var{m}, @var{n})} is equivalent to\n\ |
8a42498edb30
Clarify doc for sparse function
David Bateman <dbateman@free.fr>
parents:
7515
diff
changeset
|
93 @code{sparse ([], [], [], @var{m}, @var{n}, 0)}\n\ |
6556 | 94 \n\ |
95 If any of @var{sv}, @var{i} or @var{j} are scalars, they are expanded\n\ | |
96 to have a common size.\n\ | |
5164 | 97 @seealso{full}\n\ |
98 @end deftypefn") | |
99 { | |
100 octave_value retval; | |
101 | |
102 // WARNING: This function should always use constructions like | |
103 // retval = new octave_sparse_matrix (sm); | |
104 // To avoid calling the maybe_mutate function. This is the only | |
7287 | 105 // function that should not call maybe_mutate |
5164 | 106 |
107 int nargin= args.length(); | |
108 if (nargin < 1 || (nargin == 4 && !args(3).is_string ()) || nargin > 6) | |
109 { | |
5823 | 110 print_usage (); |
5164 | 111 return retval; |
112 } | |
113 | |
114 bool use_complex = false; | |
115 bool use_bool = false; | |
116 if (nargin > 2) | |
117 { | |
118 use_complex= args(2).is_complex_type(); | |
119 use_bool = args(2).is_bool_type (); | |
120 } | |
121 else | |
122 { | |
123 use_complex= args(0).is_complex_type(); | |
124 use_bool = args(0).is_bool_type (); | |
125 } | |
126 | |
7287 | 127 if (nargin == 1) |
5164 | 128 { |
129 octave_value arg = args (0); | |
130 | |
7515
f3c00dc0912b
Eliminate the rest of the dispatched sparse functions
David Bateman <dbateman@free.fr>
parents:
7505
diff
changeset
|
131 if (arg.is_sparse_type ()) |
5164 | 132 { |
133 if (use_complex) | |
134 { | |
5760 | 135 SparseComplexMatrix sm = arg.sparse_complex_matrix_value (); |
5164 | 136 retval = new octave_sparse_complex_matrix (sm); |
137 } | |
138 else if (use_bool) | |
139 { | |
5760 | 140 SparseBoolMatrix sm = arg.sparse_bool_matrix_value (); |
5164 | 141 retval = new octave_sparse_bool_matrix (sm); |
142 } | |
143 else | |
144 { | |
5760 | 145 SparseMatrix sm = arg.sparse_matrix_value (); |
5164 | 146 retval = new octave_sparse_matrix (sm); |
147 } | |
148 } | |
8910
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
149 else if (arg.is_diag_matrix ()) |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
150 { |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
151 if (arg.is_complex_type ()) |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
152 { |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
153 SparseComplexMatrix sm = arg.sparse_complex_matrix_value (); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
154 retval = new octave_sparse_complex_matrix (sm); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
155 } |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
156 else |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
157 { |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
158 SparseMatrix sm = arg.sparse_matrix_value (); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
159 retval = new octave_sparse_matrix (sm); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
160 } |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
161 } |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
162 else if (arg.is_perm_matrix ()) |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
163 { |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
164 SparseMatrix sm = arg.sparse_matrix_value (); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
165 retval = new octave_sparse_matrix (sm); |
6e9f26506804
optimize diag -> sparse and perm -> sparse conversions
Jaroslav Hajek <highegg@gmail.com>
parents:
8458
diff
changeset
|
166 } |
5164 | 167 else |
168 { | |
169 if (use_complex) | |
170 { | |
171 SparseComplexMatrix sm (args (0).complex_matrix_value ()); | |
172 if (error_state) | |
173 return retval; | |
174 retval = new octave_sparse_complex_matrix (sm); | |
175 } | |
176 else if (use_bool) | |
177 { | |
178 SparseBoolMatrix sm (args (0).bool_matrix_value ()); | |
179 if (error_state) | |
180 return retval; | |
181 retval = new octave_sparse_bool_matrix (sm); | |
182 } | |
183 else | |
184 { | |
185 SparseMatrix sm (args (0).matrix_value ()); | |
186 if (error_state) | |
187 return retval; | |
188 retval = new octave_sparse_matrix (sm); | |
189 } | |
190 } | |
191 } | |
192 else | |
193 { | |
5275 | 194 octave_idx_type m = 1, n = 1; |
5164 | 195 if (nargin == 2) |
196 { | |
7308 | 197 if (args(0).numel () == 1 && args(1).numel () == 1) |
198 { | |
199 m = args(0).int_value(); | |
200 n = args(1).int_value(); | |
201 if (error_state) return retval; | |
5164 | 202 |
7308 | 203 if (use_complex) |
204 retval = new octave_sparse_complex_matrix | |
205 (SparseComplexMatrix (m, n)); | |
206 else if (use_bool) | |
207 retval = new octave_sparse_bool_matrix | |
208 (SparseBoolMatrix (m, n)); | |
209 else | |
210 retval = new octave_sparse_matrix | |
211 (SparseMatrix (m, n)); | |
212 } | |
5164 | 213 else |
7308 | 214 error ("sparse: expecting scalar values"); |
5164 | 215 } |
216 else | |
217 { | |
218 if (args(0).is_empty () || args (1).is_empty () | |
219 || args(2).is_empty ()) | |
220 { | |
221 if (nargin > 4) | |
222 { | |
223 m = args(3).int_value(); | |
224 n = args(4).int_value(); | |
225 } | |
226 | |
227 if (use_bool) | |
228 retval = new octave_sparse_bool_matrix | |
229 (SparseBoolMatrix (m, n)); | |
230 else | |
231 retval = new octave_sparse_matrix (SparseMatrix (m, n)); | |
232 } | |
233 else | |
234 { | |
235 // | |
236 // I use this clumsy construction so that we can use | |
237 // any orientation of args | |
238 ColumnVector ridxA = ColumnVector (args(0).vector_value | |
239 (false, true)); | |
240 ColumnVector cidxA = ColumnVector (args(1).vector_value | |
241 (false, true)); | |
242 ColumnVector coefA; | |
243 boolNDArray coefAB; | |
244 ComplexColumnVector coefAC; | |
245 bool assemble_do_sum = true; // this is the default in matlab6 | |
246 | |
247 if (use_complex) | |
248 { | |
249 if (args(2).is_empty ()) | |
250 coefAC = ComplexColumnVector (0); | |
251 else | |
252 coefAC = ComplexColumnVector | |
253 (args(2).complex_vector_value (false, true)); | |
254 } | |
255 else if (use_bool) | |
256 { | |
257 if (args(2).is_empty ()) | |
258 coefAB = boolNDArray (dim_vector (1, 0)); | |
259 else | |
260 coefAB = args(2).bool_array_value (); | |
261 dim_vector AB_dims = coefAB.dims (); | |
262 if (AB_dims.length() > 2 || (AB_dims(0) != 1 && | |
263 AB_dims(1) != 1)) | |
264 error ("sparse: vector arguments required"); | |
265 } | |
266 else | |
267 if (args(2).is_empty ()) | |
268 coefA = ColumnVector (0); | |
269 else | |
270 coefA = ColumnVector (args(2).vector_value (false, true)); | |
271 | |
272 if (error_state) | |
273 return retval; | |
274 | |
275 // Confirm that i,j,s all have the same number of elements | |
5275 | 276 octave_idx_type ns; |
5164 | 277 if (use_complex) |
278 ns = coefAC.length(); | |
279 else if (use_bool) | |
280 ns = coefAB.length(); | |
281 else | |
282 ns = coefA.length(); | |
283 | |
5275 | 284 octave_idx_type ni = ridxA.length(); |
285 octave_idx_type nj = cidxA.length(); | |
286 octave_idx_type nnz = (ni > nj ? ni : nj); | |
5164 | 287 if ((ns != 1 && ns != nnz) || |
288 (ni != 1 && ni != nnz) || | |
289 (nj != 1 && nj != nnz)) | |
290 { | |
291 error ("sparse i, j and s must have the same length"); | |
292 return retval; | |
293 } | |
294 | |
295 if (nargin == 3 || nargin == 4) | |
296 { | |
5275 | 297 m = static_cast<octave_idx_type> (ridxA.max()); |
298 n = static_cast<octave_idx_type> (cidxA.max()); | |
5164 | 299 |
300 // if args(3) is not string, then ignore the value | |
301 // otherwise check for summation or unique | |
302 if (nargin == 4 && args(3).is_string()) | |
303 { | |
304 std::string vv= args(3).string_value(); | |
305 if (error_state) return retval; | |
306 | |
307 if ( vv == "summation" || | |
308 vv == "sum" ) | |
309 assemble_do_sum = true; | |
310 else | |
311 if ( vv == "unique" ) | |
312 assemble_do_sum = false; | |
313 else { | |
314 error("sparse repeat flag must be 'sum' or 'unique'"); | |
315 return retval; | |
316 } | |
317 } | |
318 } | |
319 else | |
320 { | |
321 m = args(3).int_value(); | |
322 n = args(4).int_value(); | |
323 if (error_state) | |
324 return retval; | |
325 | |
326 // if args(5) is not string, then ignore the value | |
327 // otherwise check for summation or unique | |
328 if (nargin >= 6 && args(5).is_string()) | |
329 { | |
330 std::string vv= args(5).string_value(); | |
331 if (error_state) return retval; | |
332 | |
333 if ( vv == "summation" || | |
334 vv == "sum" ) | |
335 assemble_do_sum = true; | |
336 else | |
337 if ( vv == "unique" ) | |
338 assemble_do_sum = false; | |
339 else { | |
340 error("sparse repeat flag must be 'sum' or 'unique'"); | |
341 return retval; | |
342 } | |
343 } | |
344 | |
345 } | |
346 | |
347 // Convert indexing to zero-indexing used internally | |
348 ridxA -= 1.; | |
349 cidxA -= 1.; | |
350 | |
351 if (use_complex) | |
352 retval = new octave_sparse_complex_matrix | |
353 (SparseComplexMatrix (coefAC, ridxA, cidxA, m, n, | |
354 assemble_do_sum)); | |
355 else if (use_bool) | |
356 retval = new octave_sparse_bool_matrix | |
357 (SparseBoolMatrix (coefAB, ridxA, cidxA, m, n, | |
358 assemble_do_sum)); | |
359 else | |
360 retval = new octave_sparse_matrix | |
361 (SparseMatrix (coefA, ridxA, cidxA, m, n, | |
362 assemble_do_sum)); | |
363 } | |
364 } | |
365 } | |
366 | |
367 return retval; | |
368 } | |
369 | |
370 /* | |
371 ;;; Local Variables: *** | |
372 ;;; mode: C++ *** | |
373 ;;; End: *** | |
374 */ |