Mercurial > hg > octave-lyh
annotate src/DLD-FUNCTIONS/sparse.cc @ 8458:d254a21e0120
reimplement full as method of octave_base_value
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Mon, 12 Jan 2009 13:06:06 +0100 |
parents | aaf2b6d6813c |
children | 6e9f26506804 |
rev | line source |
---|---|
5164 | 1 /* |
2 | |
7017 | 3 Copyright (C) 2004, 2005, 2006, 2007 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 } | |
149 else | |
150 { | |
151 if (use_complex) | |
152 { | |
153 SparseComplexMatrix sm (args (0).complex_matrix_value ()); | |
154 if (error_state) | |
155 return retval; | |
156 retval = new octave_sparse_complex_matrix (sm); | |
157 } | |
158 else if (use_bool) | |
159 { | |
160 SparseBoolMatrix sm (args (0).bool_matrix_value ()); | |
161 if (error_state) | |
162 return retval; | |
163 retval = new octave_sparse_bool_matrix (sm); | |
164 } | |
165 else | |
166 { | |
167 SparseMatrix sm (args (0).matrix_value ()); | |
168 if (error_state) | |
169 return retval; | |
170 retval = new octave_sparse_matrix (sm); | |
171 } | |
172 } | |
173 } | |
174 else | |
175 { | |
5275 | 176 octave_idx_type m = 1, n = 1; |
5164 | 177 if (nargin == 2) |
178 { | |
7308 | 179 if (args(0).numel () == 1 && args(1).numel () == 1) |
180 { | |
181 m = args(0).int_value(); | |
182 n = args(1).int_value(); | |
183 if (error_state) return retval; | |
5164 | 184 |
7308 | 185 if (use_complex) |
186 retval = new octave_sparse_complex_matrix | |
187 (SparseComplexMatrix (m, n)); | |
188 else if (use_bool) | |
189 retval = new octave_sparse_bool_matrix | |
190 (SparseBoolMatrix (m, n)); | |
191 else | |
192 retval = new octave_sparse_matrix | |
193 (SparseMatrix (m, n)); | |
194 } | |
5164 | 195 else |
7308 | 196 error ("sparse: expecting scalar values"); |
5164 | 197 } |
198 else | |
199 { | |
200 if (args(0).is_empty () || args (1).is_empty () | |
201 || args(2).is_empty ()) | |
202 { | |
203 if (nargin > 4) | |
204 { | |
205 m = args(3).int_value(); | |
206 n = args(4).int_value(); | |
207 } | |
208 | |
209 if (use_bool) | |
210 retval = new octave_sparse_bool_matrix | |
211 (SparseBoolMatrix (m, n)); | |
212 else | |
213 retval = new octave_sparse_matrix (SparseMatrix (m, n)); | |
214 } | |
215 else | |
216 { | |
217 // | |
218 // I use this clumsy construction so that we can use | |
219 // any orientation of args | |
220 ColumnVector ridxA = ColumnVector (args(0).vector_value | |
221 (false, true)); | |
222 ColumnVector cidxA = ColumnVector (args(1).vector_value | |
223 (false, true)); | |
224 ColumnVector coefA; | |
225 boolNDArray coefAB; | |
226 ComplexColumnVector coefAC; | |
227 bool assemble_do_sum = true; // this is the default in matlab6 | |
228 | |
229 if (use_complex) | |
230 { | |
231 if (args(2).is_empty ()) | |
232 coefAC = ComplexColumnVector (0); | |
233 else | |
234 coefAC = ComplexColumnVector | |
235 (args(2).complex_vector_value (false, true)); | |
236 } | |
237 else if (use_bool) | |
238 { | |
239 if (args(2).is_empty ()) | |
240 coefAB = boolNDArray (dim_vector (1, 0)); | |
241 else | |
242 coefAB = args(2).bool_array_value (); | |
243 dim_vector AB_dims = coefAB.dims (); | |
244 if (AB_dims.length() > 2 || (AB_dims(0) != 1 && | |
245 AB_dims(1) != 1)) | |
246 error ("sparse: vector arguments required"); | |
247 } | |
248 else | |
249 if (args(2).is_empty ()) | |
250 coefA = ColumnVector (0); | |
251 else | |
252 coefA = ColumnVector (args(2).vector_value (false, true)); | |
253 | |
254 if (error_state) | |
255 return retval; | |
256 | |
257 // Confirm that i,j,s all have the same number of elements | |
5275 | 258 octave_idx_type ns; |
5164 | 259 if (use_complex) |
260 ns = coefAC.length(); | |
261 else if (use_bool) | |
262 ns = coefAB.length(); | |
263 else | |
264 ns = coefA.length(); | |
265 | |
5275 | 266 octave_idx_type ni = ridxA.length(); |
267 octave_idx_type nj = cidxA.length(); | |
268 octave_idx_type nnz = (ni > nj ? ni : nj); | |
5164 | 269 if ((ns != 1 && ns != nnz) || |
270 (ni != 1 && ni != nnz) || | |
271 (nj != 1 && nj != nnz)) | |
272 { | |
273 error ("sparse i, j and s must have the same length"); | |
274 return retval; | |
275 } | |
276 | |
277 if (nargin == 3 || nargin == 4) | |
278 { | |
5275 | 279 m = static_cast<octave_idx_type> (ridxA.max()); |
280 n = static_cast<octave_idx_type> (cidxA.max()); | |
5164 | 281 |
282 // if args(3) is not string, then ignore the value | |
283 // otherwise check for summation or unique | |
284 if (nargin == 4 && args(3).is_string()) | |
285 { | |
286 std::string vv= args(3).string_value(); | |
287 if (error_state) return retval; | |
288 | |
289 if ( vv == "summation" || | |
290 vv == "sum" ) | |
291 assemble_do_sum = true; | |
292 else | |
293 if ( vv == "unique" ) | |
294 assemble_do_sum = false; | |
295 else { | |
296 error("sparse repeat flag must be 'sum' or 'unique'"); | |
297 return retval; | |
298 } | |
299 } | |
300 } | |
301 else | |
302 { | |
303 m = args(3).int_value(); | |
304 n = args(4).int_value(); | |
305 if (error_state) | |
306 return retval; | |
307 | |
308 // if args(5) is not string, then ignore the value | |
309 // otherwise check for summation or unique | |
310 if (nargin >= 6 && args(5).is_string()) | |
311 { | |
312 std::string vv= args(5).string_value(); | |
313 if (error_state) return retval; | |
314 | |
315 if ( vv == "summation" || | |
316 vv == "sum" ) | |
317 assemble_do_sum = true; | |
318 else | |
319 if ( vv == "unique" ) | |
320 assemble_do_sum = false; | |
321 else { | |
322 error("sparse repeat flag must be 'sum' or 'unique'"); | |
323 return retval; | |
324 } | |
325 } | |
326 | |
327 } | |
328 | |
329 // Convert indexing to zero-indexing used internally | |
330 ridxA -= 1.; | |
331 cidxA -= 1.; | |
332 | |
333 if (use_complex) | |
334 retval = new octave_sparse_complex_matrix | |
335 (SparseComplexMatrix (coefAC, ridxA, cidxA, m, n, | |
336 assemble_do_sum)); | |
337 else if (use_bool) | |
338 retval = new octave_sparse_bool_matrix | |
339 (SparseBoolMatrix (coefAB, ridxA, cidxA, m, n, | |
340 assemble_do_sum)); | |
341 else | |
342 retval = new octave_sparse_matrix | |
343 (SparseMatrix (coefA, ridxA, cidxA, m, n, | |
344 assemble_do_sum)); | |
345 } | |
346 } | |
347 } | |
348 | |
349 return retval; | |
350 } | |
351 | |
352 /* | |
353 ;;; Local Variables: *** | |
354 ;;; mode: C++ *** | |
355 ;;; End: *** | |
356 */ |