Mercurial > hg > octave-nkf
annotate src/ov-base-sparse.cc @ 10160:cd96d29c5efa
remove Emacs local-variable settings from source files in src directory
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 20 Jan 2010 20:39:26 -0500 |
parents | 829e69ec3110 |
children | 57a59eae83cc |
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 | |
7644
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
28 #include <iomanip> |
5164 | 29 #include <iostream> |
30 | |
31 #include "oct-obj.h" | |
32 #include "ov-base.h" | |
33 #include "quit.h" | |
34 #include "pr-output.h" | |
35 | |
36 #include "byte-swap.h" | |
37 #include "ls-oct-ascii.h" | |
38 #include "ls-utils.h" | |
39 #include "ls-hdf5.h" | |
40 | |
41 #include "boolSparse.h" | |
42 #include "ov-base-sparse.h" | |
5731 | 43 #include "pager.h" |
5164 | 44 |
45 template <class T> | |
46 octave_value | |
47 octave_base_sparse<T>::do_index_op (const octave_value_list& idx, | |
5885 | 48 bool resize_ok) |
5164 | 49 { |
50 octave_value retval; | |
51 | |
5275 | 52 octave_idx_type n_idx = idx.length (); |
5164 | 53 |
54 int nd = matrix.ndims (); | |
55 | |
56 switch (n_idx) | |
57 { | |
58 case 0: | |
5539 | 59 retval = matrix; |
5164 | 60 break; |
61 | |
62 case 1: | |
63 { | |
64 idx_vector i = idx (0).index_vector (); | |
65 | |
66 if (! error_state) | |
67 retval = octave_value (matrix.index (i, resize_ok)); | |
68 } | |
69 break; | |
70 | |
71 default: | |
72 { | |
73 if (n_idx == 2 && nd == 2) | |
74 { | |
75 idx_vector i = idx (0).index_vector (); | |
76 | |
77 if (! error_state) | |
78 { | |
79 idx_vector j = idx (1).index_vector (); | |
80 | |
81 if (! error_state) | |
82 retval = octave_value (matrix.index (i, j, resize_ok)); | |
83 } | |
84 } | |
85 else | |
86 { | |
87 Array<idx_vector> idx_vec (n_idx); | |
88 | |
5275 | 89 for (octave_idx_type i = 0; i < n_idx; i++) |
5164 | 90 { |
91 idx_vec(i) = idx(i).index_vector (); | |
92 | |
93 if (error_state) | |
94 break; | |
95 } | |
96 | |
97 if (! error_state) | |
98 retval = octave_value (matrix.index (idx_vec, resize_ok)); | |
99 } | |
100 } | |
101 break; | |
102 } | |
103 | |
104 return retval; | |
105 } | |
106 | |
107 template <class T> | |
108 octave_value | |
109 octave_base_sparse<T>::subsref (const std::string& type, | |
110 const std::list<octave_value_list>& idx) | |
111 { | |
112 octave_value retval; | |
113 | |
114 switch (type[0]) | |
115 { | |
116 case '(': | |
117 retval = do_index_op (idx.front ()); | |
118 break; | |
119 | |
120 case '{': | |
121 case '.': | |
122 { | |
123 std::string nm = type_name (); | |
124 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); | |
125 } | |
126 break; | |
127 | |
128 default: | |
129 panic_impossible (); | |
130 } | |
131 | |
132 return retval.next_subsref (type, idx); | |
133 } | |
134 | |
135 template <class T> | |
136 octave_value | |
137 octave_base_sparse<T>::subsasgn (const std::string& type, | |
138 const std::list<octave_value_list>& idx, | |
139 const octave_value& rhs) | |
140 { | |
141 octave_value retval; | |
142 | |
143 switch (type[0]) | |
144 { | |
145 case '(': | |
146 { | |
147 if (type.length () == 1) | |
148 retval = numeric_assign (type, idx, rhs); | |
149 else | |
150 { | |
151 std::string nm = type_name (); | |
152 error ("in indexed assignment of %s, last lhs index must be ()", | |
153 nm.c_str ()); | |
154 } | |
155 } | |
156 break; | |
157 | |
158 case '{': | |
159 case '.': | |
160 { | |
161 if (is_empty ()) | |
162 { | |
163 octave_value tmp = octave_value::empty_conv (type, rhs); | |
164 | |
165 retval = tmp.subsasgn (type, idx, rhs); | |
166 } | |
167 else | |
168 { | |
169 std::string nm = type_name (); | |
170 error ("%s cannot be indexed with %c", nm.c_str (), type[0]); | |
171 } | |
172 } | |
173 break; | |
174 | |
175 default: | |
176 panic_impossible (); | |
177 } | |
178 | |
179 return retval; | |
180 } | |
181 | |
182 template <class T> | |
183 void | |
184 octave_base_sparse<T>::assign (const octave_value_list& idx, const T& rhs) | |
185 { | |
5275 | 186 octave_idx_type len = idx.length (); |
5164 | 187 |
5275 | 188 for (octave_idx_type i = 0; i < len; i++) |
5164 | 189 matrix.set_index (idx(i).index_vector ()); |
190 | |
191 ::assign (matrix, rhs); | |
5322 | 192 |
193 // Invalidate matrix type. | |
194 typ.invalidate_type (); | |
5164 | 195 } |
196 | |
8150
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
197 template <class MT> |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
198 void |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
199 octave_base_sparse<MT>::delete_elements (const octave_value_list& idx) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
200 { |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
201 octave_idx_type len = idx.length (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
202 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
203 Array<idx_vector> ra_idx (len); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
204 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
205 for (octave_idx_type i = 0; i < len; i++) |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
206 ra_idx(i) = idx(i).index_vector (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
207 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
208 matrix.maybe_delete_elements (ra_idx); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
209 |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
210 // Invalidate the matrix type |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
211 typ.invalidate_type (); |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
212 } |
283989f2da9b
make null assignment matlab compatible
Jaroslav Hajek <highegg@gmail.com>
parents:
7644
diff
changeset
|
213 |
5731 | 214 template <class T> |
215 octave_value | |
216 octave_base_sparse<T>::resize (const dim_vector& dv, bool) const | |
217 { | |
218 T retval (matrix); | |
219 retval.resize (dv); | |
220 return retval; | |
221 } | |
5164 | 222 |
223 template <class T> | |
224 bool | |
225 octave_base_sparse<T>::is_true (void) const | |
226 { | |
227 bool retval = false; | |
228 dim_vector dv = matrix.dims (); | |
5275 | 229 octave_idx_type nel = dv.numel (); |
5604 | 230 octave_idx_type nz = nzmax (); |
5164 | 231 |
232 if (nz == nel && nel > 0) | |
233 { | |
234 T t1 (matrix.reshape (dim_vector (nel, 1))); | |
235 | |
236 SparseBoolMatrix t2 = t1.all (); | |
237 | |
238 retval = t2(0); | |
239 } | |
240 | |
241 return retval; | |
242 } | |
243 | |
244 template <class T> | |
245 bool | |
246 octave_base_sparse<T>::print_as_scalar (void) const | |
247 { | |
248 dim_vector dv = dims (); | |
249 | |
250 return (dv.all_ones () || dv.any_zero ()); | |
251 } | |
252 | |
253 template <class T> | |
254 void | |
255 octave_base_sparse<T>::print (std::ostream& os, bool pr_as_read_syntax) const | |
256 { | |
257 print_raw (os, pr_as_read_syntax); | |
258 newline (os); | |
259 } | |
260 | |
261 template <class T> | |
262 void | |
263 octave_base_sparse<T>::print_info (std::ostream& os, | |
264 const std::string& prefix) const | |
265 { | |
266 matrix.print_info (os, prefix); | |
267 } | |
268 | |
269 template <class T> | |
270 void | |
271 octave_base_sparse<T>::print_raw (std::ostream& os, | |
5355 | 272 bool pr_as_read_syntax) const |
5164 | 273 { |
5275 | 274 octave_idx_type nr = matrix.rows (); |
275 octave_idx_type nc = matrix.cols (); | |
5604 | 276 octave_idx_type nz = nnz (); |
5164 | 277 |
5775 | 278 // FIXME -- this should probably all be handled by a |
5355 | 279 // separate octave_print_internal function that can handle format |
280 // compact, loose, etc. | |
281 | |
282 os << "Compressed Column Sparse (rows = " << nr | |
283 << ", cols = " << nc | |
7644
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
284 << ", nnz = " << nz; |
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
285 |
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
286 double dnel = matrix.numel (); |
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
287 |
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
288 if (dnel > 0) |
8848
7557cf34ffcd
ov-base-sparse.cc (octave_base_sparse<T>::print_raw): remove extra ")\n" from output
John W. Eaton <jwe@octave.org>
parents:
8676
diff
changeset
|
289 os << " [" << std::setprecision (2) << (nz / dnel * 100) << "%]"; |
7644
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
290 |
91d7440211e7
display percentage of elements that are nonzero when printing sparse matrices
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
291 os << ")\n"; |
5164 | 292 |
293 // add one to the printed indices to go from | |
294 // zero-based to one-based arrays | |
295 | |
296 if (nz != 0) | |
297 { | |
5275 | 298 for (octave_idx_type j = 0; j < nc; j++) |
5164 | 299 { |
10142
829e69ec3110
make OCTAVE_QUIT a function
Jaroslav Hajek <highegg@gmail.com>
parents:
9813
diff
changeset
|
300 octave_quit (); |
5355 | 301 |
5775 | 302 // FIXME -- is there an easy way to get the max row |
5355 | 303 // and column indices so we can set the width appropriately |
304 // and line up the columns here? Similarly, we should look | |
305 // at all the nonzero values and display them with the same | |
306 // formatting rules that apply to columns of a matrix. | |
307 | |
5275 | 308 for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++) |
5164 | 309 { |
310 os << "\n"; | |
311 os << " (" << matrix.ridx(i)+1 << | |
5355 | 312 ", " << j+1 << ") -> "; |
313 | |
314 octave_print_internal (os, matrix.data(i), pr_as_read_syntax); | |
5164 | 315 } |
316 } | |
317 } | |
318 } | |
319 | |
320 template <class T> | |
321 bool | |
6974 | 322 octave_base_sparse<T>::save_ascii (std::ostream& os) |
5164 | 323 { |
324 dim_vector dv = this->dims (); | |
325 | |
326 // Ensure that additional memory is deallocated | |
327 matrix.maybe_compress (); | |
328 | |
5604 | 329 os << "# nnz: " << nzmax () << "\n"; |
5164 | 330 os << "# rows: " << dv (0) << "\n"; |
331 os << "# columns: " << dv (1) << "\n"; | |
332 | |
333 os << this->matrix; | |
334 | |
335 return true; | |
336 } | |
337 | |
338 template <class T> | |
339 bool | |
340 octave_base_sparse<T>::load_ascii (std::istream& is) | |
341 { | |
5275 | 342 octave_idx_type nz = 0; |
343 octave_idx_type nr = 0; | |
344 octave_idx_type nc = 0; | |
5164 | 345 bool success = true; |
346 | |
347 if (extract_keyword (is, "nnz", nz, true) && | |
348 extract_keyword (is, "rows", nr, true) && | |
349 extract_keyword (is, "columns", nc, true)) | |
350 { | |
351 T tmp (nr, nc, nz); | |
352 | |
353 is >> tmp; | |
354 | |
355 if (!is) | |
356 { | |
357 error ("load: failed to load matrix constant"); | |
358 success = false; | |
359 } | |
360 | |
361 matrix = tmp; | |
362 } | |
363 else | |
364 { | |
365 error ("load: failed to extract number of rows and columns"); | |
366 success = false; | |
367 } | |
368 | |
369 return success; | |
370 } | |
371 | |
9813
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
372 template <class T> |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
373 octave_value |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
374 octave_base_sparse<T>::map (octave_base_value::unary_mapper_t umap) const |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
375 { |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
376 // Try the map on the dense value. |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
377 octave_value retval = this->full_value ().map (umap); |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
378 |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
379 // Sparsify the result if possible. |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
380 // FIXME: intentionally skip this step for string mappers. Is this wanted? |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
381 if (umap >= umap_xisalnum && umap <= umap_xtoupper) |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
382 return retval; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
383 |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
384 switch (retval.builtin_type ()) |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
385 { |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
386 case btyp_double: |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
387 retval = retval.sparse_matrix_value (); |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
388 break; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
389 case btyp_complex: |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
390 retval = retval.sparse_complex_matrix_value (); |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
391 break; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
392 case btyp_bool: |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
393 retval = retval.sparse_bool_matrix_value (); |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
394 break; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
395 default: |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
396 break; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
397 } |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
398 |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
399 return retval; |
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
400 } |