Mercurial > hg > octave-lyh
comparison src/octave-value/ov-cx-sparse.cc @ 15057:46b19589b593
maint: Partition src/ directory with more code in subdirs.
Create new octave-value dir for ov* code.
Create new parse-tre dir for pt* code.
Move OPERATORS and TEMPLATE-INST directories to lowercase names
* octave-value/module.mk: Hook code in octave-value dir into build system.
* octave-value/ov-base-diag.cc,
octave-value/ov-base-diag.h, octave-value/ov-base-int.cc,
octave-value/ov-base-int.h, octave-value/ov-base-mat.cc,
octave-value/ov-base-mat.h, octave-value/ov-base-scalar.cc,
octave-value/ov-base-scalar.h, octave-value/ov-base-sparse.cc,
octave-value/ov-base-sparse.h, octave-value/ov-base.cc, octave-value/ov-base.h,
octave-value/ov-bool-mat.cc, octave-value/ov-bool-mat.h,
octave-value/ov-bool-sparse.cc, octave-value/ov-bool-sparse.h,
octave-value/ov-bool.cc, octave-value/ov-bool.h, octave-value/ov-builtin.cc,
octave-value/ov-builtin.h, octave-value/ov-cell.cc, octave-value/ov-cell.h,
octave-value/ov-ch-mat.cc, octave-value/ov-ch-mat.h, octave-value/ov-class.cc,
octave-value/ov-class.h, octave-value/ov-colon.cc, octave-value/ov-colon.h,
octave-value/ov-complex.cc, octave-value/ov-complex.h,
octave-value/ov-cs-list.cc, octave-value/ov-cs-list.h,
octave-value/ov-cx-diag.cc, octave-value/ov-cx-diag.h,
octave-value/ov-cx-mat.cc, octave-value/ov-cx-mat.h,
octave-value/ov-cx-sparse.cc, octave-value/ov-cx-sparse.h,
octave-value/ov-dld-fcn.cc, octave-value/ov-dld-fcn.h,
octave-value/ov-fcn-handle.cc, octave-value/ov-fcn-handle.h,
octave-value/ov-fcn-inline.cc, octave-value/ov-fcn-inline.h,
octave-value/ov-fcn.cc, octave-value/ov-fcn.h, octave-value/ov-float.cc,
octave-value/ov-float.h, octave-value/ov-flt-complex.cc,
octave-value/ov-flt-complex.h, octave-value/ov-flt-cx-diag.cc,
octave-value/ov-flt-cx-diag.h, octave-value/ov-flt-cx-mat.cc,
octave-value/ov-flt-cx-mat.h, octave-value/ov-flt-re-diag.cc,
octave-value/ov-flt-re-diag.h, octave-value/ov-flt-re-mat.cc,
octave-value/ov-flt-re-mat.h, octave-value/ov-int-traits.h,
octave-value/ov-int16.cc, octave-value/ov-int16.h, octave-value/ov-int32.cc,
octave-value/ov-int32.h, octave-value/ov-int64.cc, octave-value/ov-int64.h,
octave-value/ov-int8.cc, octave-value/ov-int8.h, octave-value/ov-intx.h,
octave-value/ov-lazy-idx.cc, octave-value/ov-lazy-idx.h,
octave-value/ov-mex-fcn.cc, octave-value/ov-mex-fcn.h,
octave-value/ov-null-mat.cc, octave-value/ov-null-mat.h,
octave-value/ov-oncleanup.cc, octave-value/ov-oncleanup.h,
octave-value/ov-perm.cc, octave-value/ov-perm.h, octave-value/ov-range.cc,
octave-value/ov-range.h, octave-value/ov-re-diag.cc, octave-value/ov-re-diag.h,
octave-value/ov-re-mat.cc, octave-value/ov-re-mat.h,
octave-value/ov-re-sparse.cc, octave-value/ov-re-sparse.h,
octave-value/ov-scalar.cc, octave-value/ov-scalar.h,
octave-value/ov-str-mat.cc, octave-value/ov-str-mat.h,
octave-value/ov-struct.cc, octave-value/ov-struct.h,
octave-value/ov-type-conv.h, octave-value/ov-typeinfo.cc,
octave-value/ov-typeinfo.h, octave-value/ov-uint16.cc,
octave-value/ov-uint16.h, octave-value/ov-uint32.cc, octave-value/ov-uint32.h,
octave-value/ov-uint64.cc, octave-value/ov-uint64.h, octave-value/ov-uint8.cc,
octave-value/ov-uint8.h, octave-value/ov-usr-fcn.cc, octave-value/ov-usr-fcn.h,
octave-value/ov.cc, octave-value/ov.h: Moved from src/ dir to octave-value dir.
* operators/module.mk, operators/op-b-b.cc, operators/op-b-bm.cc,
operators/op-b-sbm.cc, operators/op-bm-b.cc, operators/op-bm-bm.cc,
operators/op-bm-sbm.cc, operators/op-cdm-cdm.cc, operators/op-cdm-cm.cc,
operators/op-cdm-cs.cc, operators/op-cdm-dm.cc, operators/op-cdm-m.cc,
operators/op-cdm-s.cc, operators/op-cell.cc, operators/op-chm.cc,
operators/op-class.cc, operators/op-cm-cdm.cc, operators/op-cm-cm.cc,
operators/op-cm-cs.cc, operators/op-cm-dm.cc, operators/op-cm-m.cc,
operators/op-cm-pm.cc, operators/op-cm-s.cc, operators/op-cm-scm.cc,
operators/op-cm-sm.cc, operators/op-cs-cm.cc, operators/op-cs-cs.cc,
operators/op-cs-m.cc, operators/op-cs-s.cc, operators/op-cs-scm.cc,
operators/op-cs-sm.cc, operators/op-dm-cdm.cc, operators/op-dm-cm.cc,
operators/op-dm-cs.cc, operators/op-dm-dm.cc, operators/op-dm-m.cc,
operators/op-dm-s.cc, operators/op-dm-scm.cc, operators/op-dm-sm.cc,
operators/op-dm-template.cc, operators/op-dms-template.cc,
operators/op-double-conv.cc, operators/op-fcdm-fcdm.cc,
operators/op-fcdm-fcm.cc, operators/op-fcdm-fcs.cc, operators/op-fcdm-fdm.cc,
operators/op-fcdm-fm.cc, operators/op-fcdm-fs.cc, operators/op-fcm-fcdm.cc,
operators/op-fcm-fcm.cc, operators/op-fcm-fcs.cc, operators/op-fcm-fdm.cc,
operators/op-fcm-fm.cc, operators/op-fcm-fs.cc, operators/op-fcm-pm.cc,
operators/op-fcn.cc, operators/op-fcs-fcm.cc, operators/op-fcs-fcs.cc,
operators/op-fcs-fm.cc, operators/op-fcs-fs.cc, operators/op-fdm-fcdm.cc,
operators/op-fdm-fcm.cc, operators/op-fdm-fcs.cc, operators/op-fdm-fdm.cc,
operators/op-fdm-fm.cc, operators/op-fdm-fs.cc, operators/op-float-conv.cc,
operators/op-fm-fcdm.cc, operators/op-fm-fcm.cc, operators/op-fm-fcs.cc,
operators/op-fm-fdm.cc, operators/op-fm-fm.cc, operators/op-fm-fs.cc,
operators/op-fm-pm.cc, operators/op-fs-fcm.cc, operators/op-fs-fcs.cc,
operators/op-fs-fm.cc, operators/op-fs-fs.cc, operators/op-i16-i16.cc,
operators/op-i32-i32.cc, operators/op-i64-i64.cc, operators/op-i8-i8.cc,
operators/op-int-concat.cc, operators/op-int-conv.cc, operators/op-int.h,
operators/op-m-cdm.cc, operators/op-m-cm.cc, operators/op-m-cs.cc,
operators/op-m-dm.cc, operators/op-m-m.cc, operators/op-m-pm.cc,
operators/op-m-s.cc, operators/op-m-scm.cc, operators/op-m-sm.cc,
operators/op-pm-cm.cc, operators/op-pm-fcm.cc, operators/op-pm-fm.cc,
operators/op-pm-m.cc, operators/op-pm-pm.cc, operators/op-pm-scm.cc,
operators/op-pm-sm.cc, operators/op-pm-template.cc, operators/op-range.cc,
operators/op-s-cm.cc, operators/op-s-cs.cc, operators/op-s-m.cc,
operators/op-s-s.cc, operators/op-s-scm.cc, operators/op-s-sm.cc,
operators/op-sbm-b.cc, operators/op-sbm-bm.cc, operators/op-sbm-sbm.cc,
operators/op-scm-cm.cc, operators/op-scm-cs.cc, operators/op-scm-m.cc,
operators/op-scm-s.cc, operators/op-scm-scm.cc, operators/op-scm-sm.cc,
operators/op-sm-cm.cc, operators/op-sm-cs.cc, operators/op-sm-m.cc,
operators/op-sm-s.cc, operators/op-sm-scm.cc, operators/op-sm-sm.cc,
operators/op-str-m.cc, operators/op-str-s.cc, operators/op-str-str.cc,
operators/op-struct.cc, operators/op-ui16-ui16.cc, operators/op-ui32-ui32.cc,
operators/op-ui64-ui64.cc, operators/op-ui8-ui8.cc: Moved from OPERATORS/
dir to operators/ directory.
* mkops: Correctly print comment in generated file ops.cc that it is made by
mkops. Change sed expression for OPERATORS/ to operators/.
* parse-tree/module.mk: Hook code in parse-tree dir into build system.
* parse-tree/pt-all.h, parse-tree/pt-arg-list.cc, parse-tree/pt-arg-list.h,
parse-tree/pt-assign.cc, parse-tree/pt-assign.h, parse-tree/pt-binop.cc,
parse-tree/pt-binop.h, parse-tree/pt-bp.cc, parse-tree/pt-bp.h,
parse-tree/pt-cbinop.cc, parse-tree/pt-cbinop.h, parse-tree/pt-cell.cc,
parse-tree/pt-cell.h, parse-tree/pt-check.cc, parse-tree/pt-check.h,
parse-tree/pt-cmd.cc, parse-tree/pt-cmd.h, parse-tree/pt-colon.cc,
parse-tree/pt-colon.h, parse-tree/pt-const.cc, parse-tree/pt-const.h,
parse-tree/pt-decl.cc, parse-tree/pt-decl.h, parse-tree/pt-eval.cc,
parse-tree/pt-eval.h, parse-tree/pt-except.cc, parse-tree/pt-except.h,
parse-tree/pt-exp.cc, parse-tree/pt-exp.h, parse-tree/pt-fcn-handle.cc,
parse-tree/pt-fcn-handle.h, parse-tree/pt-id.cc, parse-tree/pt-id.h,
parse-tree/pt-idx.cc, parse-tree/pt-idx.h, parse-tree/pt-jump.cc,
parse-tree/pt-jump.h, parse-tree/pt-loop.cc, parse-tree/pt-loop.h,
parse-tree/pt-mat.cc, parse-tree/pt-mat.h, parse-tree/pt-misc.cc,
parse-tree/pt-misc.h, parse-tree/pt-pr-code.cc, parse-tree/pt-pr-code.h,
parse-tree/pt-select.cc, parse-tree/pt-select.h, parse-tree/pt-stmt.cc,
parse-tree/pt-stmt.h, parse-tree/pt-unop.cc, parse-tree/pt-unop.h,
parse-tree/pt-walk.h, parse-tree/pt.cc, parse-tree/pt.h:
Moved from src/ dir to parse-tree dir.
* template-inst/Array-jit.cc, template-inst/Array-os.cc,
template-inst/Array-sym.cc, template-inst/Array-tc.cc, template-inst/module.mk:
Moved from TEMPLATE-INST dir to template-inst/ directory.
* src/Makefile.am: Add new directories to build system.
* corefcn/module.mk: Use COREFCN_SRC with all capitals to indicate it is not an
Automake special target.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 30 Jul 2012 15:29:19 -0700 |
parents | src/ov-cx-sparse.cc@f7afecdd87ef |
children | 62a35ae7d6a2 |
comparison
equal
deleted
inserted
replaced
15056:bc32288f4a42 | 15057:46b19589b593 |
---|---|
1 /* | |
2 | |
3 Copyright (C) 2004-2012 David Bateman | |
4 Copyright (C) 1998-2004 Andy Adler | |
5 | |
6 This file is part of Octave. | |
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 | |
10 Free Software Foundation; either version 3 of the License, or (at your | |
11 option) any later version. | |
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 | |
19 along with Octave; see the file COPYING. If not, see | |
20 <http://www.gnu.org/licenses/>. | |
21 | |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <climits> | |
29 | |
30 #include <iostream> | |
31 #include <vector> | |
32 | |
33 #include "lo-specfun.h" | |
34 #include "lo-mappers.h" | |
35 #include "oct-locbuf.h" | |
36 | |
37 #include "ov-base.h" | |
38 #include "ov-scalar.h" | |
39 #include "ov-complex.h" | |
40 #include "gripes.h" | |
41 | |
42 #include "ov-re-sparse.h" | |
43 #include "ov-cx-sparse.h" | |
44 | |
45 #include "ov-base-sparse.h" | |
46 #include "ov-base-sparse.cc" | |
47 | |
48 #include "ov-bool-sparse.h" | |
49 | |
50 template class OCTINTERP_API octave_base_sparse<SparseComplexMatrix>; | |
51 | |
52 DEFINE_OCTAVE_ALLOCATOR (octave_sparse_complex_matrix); | |
53 | |
54 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_complex_matrix, "sparse complex matrix", "double"); | |
55 | |
56 octave_base_value * | |
57 octave_sparse_complex_matrix::try_narrowing_conversion (void) | |
58 { | |
59 octave_base_value *retval = 0; | |
60 | |
61 if (Vsparse_auto_mutate) | |
62 { | |
63 int nr = matrix.rows (); | |
64 int nc = matrix.cols (); | |
65 | |
66 // Don't use numel, since it can overflow for very large matrices | |
67 // Note that for the tests on matrix size, they become approximative | |
68 // since they involves a cast to double to avoid issues of overflow | |
69 if (matrix.rows () == 1 && matrix.cols () == 1) | |
70 { | |
71 // Const copy of the matrix, so the right version of () operator used | |
72 const SparseComplexMatrix tmp (matrix); | |
73 | |
74 Complex c = tmp (0, 0); | |
75 | |
76 if (std::imag (c) == 0.0) | |
77 retval = new octave_scalar (std::real (c)); | |
78 else | |
79 retval = new octave_complex (c); | |
80 } | |
81 else if (nr == 0 || nc == 0) | |
82 retval = new octave_matrix (Matrix (nr, nc)); | |
83 else if (matrix.all_elements_are_real ()) | |
84 if (matrix.cols () > 0 && matrix.rows () > 0 | |
85 && (double (matrix.byte_size ()) > double (matrix.rows ()) | |
86 * double (matrix.cols ()) * sizeof (double))) | |
87 retval = new octave_matrix (::real (matrix.matrix_value ())); | |
88 else | |
89 retval = new octave_sparse_matrix (::real (matrix)); | |
90 else if (matrix.cols () > 0 && matrix.rows () > 0 | |
91 && (double (matrix.byte_size ()) > double (matrix.rows ()) | |
92 * double (matrix.cols ()) * sizeof (Complex))) | |
93 retval = new octave_complex_matrix (matrix.matrix_value ()); | |
94 } | |
95 else | |
96 { | |
97 if (matrix.all_elements_are_real ()) | |
98 retval = new octave_sparse_matrix (::real (matrix)); | |
99 } | |
100 | |
101 return retval; | |
102 } | |
103 | |
104 double | |
105 octave_sparse_complex_matrix::double_value (bool force_conversion) const | |
106 { | |
107 double retval = lo_ieee_nan_value (); | |
108 | |
109 if (! force_conversion) | |
110 gripe_implicit_conversion ("Octave:imag-to-real", | |
111 "complex sparse matrix", "real scalar"); | |
112 | |
113 // FIXME -- maybe this should be a function, valid_as_scalar() | |
114 if (numel () > 0) | |
115 { | |
116 if (numel () > 1) | |
117 gripe_implicit_conversion ("Octave:array-to-scalar", | |
118 "complex sparse matrix", "real scalar"); | |
119 | |
120 retval = std::real (matrix (0, 0)); | |
121 } | |
122 else | |
123 gripe_invalid_conversion ("complex sparse matrix", "real scalar"); | |
124 | |
125 return retval; | |
126 } | |
127 | |
128 Matrix | |
129 octave_sparse_complex_matrix::matrix_value (bool force_conversion) const | |
130 { | |
131 Matrix retval; | |
132 | |
133 if (! force_conversion) | |
134 gripe_implicit_conversion ("Octave:imag-to-real", | |
135 "complex sparse matrix", "real matrix"); | |
136 | |
137 retval = ::real (matrix.matrix_value ()); | |
138 | |
139 return retval; | |
140 } | |
141 | |
142 Complex | |
143 octave_sparse_complex_matrix::complex_value (bool) const | |
144 { | |
145 double tmp = lo_ieee_nan_value (); | |
146 | |
147 Complex retval (tmp, tmp); | |
148 | |
149 // FIXME -- maybe this should be a function, valid_as_scalar() | |
150 if (numel () > 0) | |
151 { | |
152 if (numel () > 1) | |
153 gripe_implicit_conversion ("Octave:array-to-scalar", | |
154 "complex sparse matrix", "real scalar"); | |
155 | |
156 retval = matrix (0, 0); | |
157 } | |
158 else | |
159 gripe_invalid_conversion ("complex sparse matrix", "real scalar"); | |
160 | |
161 return retval; | |
162 } | |
163 | |
164 ComplexMatrix | |
165 octave_sparse_complex_matrix::complex_matrix_value (bool) const | |
166 { | |
167 return matrix.matrix_value (); | |
168 } | |
169 | |
170 ComplexNDArray | |
171 octave_sparse_complex_matrix::complex_array_value (bool) const | |
172 { | |
173 return ComplexNDArray (matrix.matrix_value ()); | |
174 } | |
175 | |
176 charNDArray | |
177 octave_sparse_complex_matrix::char_array_value (bool frc_str_conv) const | |
178 { | |
179 charNDArray retval; | |
180 | |
181 if (! frc_str_conv) | |
182 gripe_implicit_conversion ("Octave:num-to-str", | |
183 "sparse complex matrix", "string"); | |
184 else | |
185 { | |
186 retval = charNDArray (dims (), 0); | |
187 octave_idx_type nc = matrix.cols (); | |
188 octave_idx_type nr = matrix.rows (); | |
189 | |
190 for (octave_idx_type j = 0; j < nc; j++) | |
191 for (octave_idx_type i = matrix.cidx (j); i < matrix.cidx (j+1); i++) | |
192 retval(matrix.ridx (i) + nr * j) = | |
193 static_cast<char>(std::real (matrix.data (i))); | |
194 } | |
195 | |
196 return retval; | |
197 } | |
198 | |
199 SparseMatrix | |
200 octave_sparse_complex_matrix::sparse_matrix_value (bool force_conversion) const | |
201 { | |
202 SparseMatrix retval; | |
203 | |
204 if (! force_conversion) | |
205 gripe_implicit_conversion ("Octave:imag-to-real", | |
206 "complex sparse matrix", | |
207 "real sparse matrix"); | |
208 | |
209 retval = ::real (matrix); | |
210 | |
211 return retval; | |
212 } | |
213 | |
214 SparseBoolMatrix | |
215 octave_sparse_complex_matrix::sparse_bool_matrix_value (bool warn) const | |
216 { | |
217 if (matrix.any_element_is_nan ()) | |
218 gripe_nan_to_logical_conversion (); | |
219 else if (warn && (! matrix.all_elements_are_real () | |
220 || real (matrix).any_element_not_one_or_zero ())) | |
221 gripe_logical_conversion (); | |
222 | |
223 return mx_el_ne (matrix, Complex (0.0)); | |
224 } | |
225 | |
226 bool | |
227 octave_sparse_complex_matrix::save_binary (std::ostream& os, | |
228 bool&save_as_floats) | |
229 { | |
230 dim_vector d = this->dims (); | |
231 if (d.length () < 1) | |
232 return false; | |
233 | |
234 // Ensure that additional memory is deallocated | |
235 matrix.maybe_compress (); | |
236 | |
237 int nr = d(0); | |
238 int nc = d(1); | |
239 int nz = nnz (); | |
240 | |
241 int32_t itmp; | |
242 // Use negative value for ndims to be consistent with other formats | |
243 itmp= -2; | |
244 os.write (reinterpret_cast<char *> (&itmp), 4); | |
245 | |
246 itmp= nr; | |
247 os.write (reinterpret_cast<char *> (&itmp), 4); | |
248 | |
249 itmp= nc; | |
250 os.write (reinterpret_cast<char *> (&itmp), 4); | |
251 | |
252 itmp= nz; | |
253 os.write (reinterpret_cast<char *> (&itmp), 4); | |
254 | |
255 save_type st = LS_DOUBLE; | |
256 if (save_as_floats) | |
257 { | |
258 if (matrix.too_large_for_float ()) | |
259 { | |
260 warning ("save: some values too large to save as floats --"); | |
261 warning ("save: saving as doubles instead"); | |
262 } | |
263 else | |
264 st = LS_FLOAT; | |
265 } | |
266 else if (matrix.nnz () > 8192) // FIXME -- make this configurable. | |
267 { | |
268 double max_val, min_val; | |
269 if (matrix.all_integers (max_val, min_val)) | |
270 st = get_save_type (max_val, min_val); | |
271 } | |
272 | |
273 // add one to the printed indices to go from | |
274 // zero-based to one-based arrays | |
275 for (int i = 0; i < nc+1; i++) | |
276 { | |
277 octave_quit (); | |
278 itmp = matrix.cidx (i); | |
279 os.write (reinterpret_cast<char *> (&itmp), 4); | |
280 } | |
281 | |
282 for (int i = 0; i < nz; i++) | |
283 { | |
284 octave_quit (); | |
285 itmp = matrix.ridx (i); | |
286 os.write (reinterpret_cast<char *> (&itmp), 4); | |
287 } | |
288 | |
289 write_doubles (os, reinterpret_cast<const double *> (matrix.data ()), st, 2 * nz); | |
290 | |
291 return true; | |
292 } | |
293 | |
294 bool | |
295 octave_sparse_complex_matrix::load_binary (std::istream& is, bool swap, | |
296 oct_mach_info::float_format fmt) | |
297 { | |
298 int32_t nz, nc, nr, tmp; | |
299 char ctmp; | |
300 | |
301 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) | |
302 return false; | |
303 | |
304 if (swap) | |
305 swap_bytes<4> (&tmp); | |
306 | |
307 if (tmp != -2) { | |
308 error ("load: only 2D sparse matrices are supported"); | |
309 return false; | |
310 } | |
311 | |
312 if (! is.read (reinterpret_cast<char *> (&nr), 4)) | |
313 return false; | |
314 if (! is.read (reinterpret_cast<char *> (&nc), 4)) | |
315 return false; | |
316 if (! is.read (reinterpret_cast<char *> (&nz), 4)) | |
317 return false; | |
318 | |
319 if (swap) | |
320 { | |
321 swap_bytes<4> (&nr); | |
322 swap_bytes<4> (&nc); | |
323 swap_bytes<4> (&nz); | |
324 } | |
325 | |
326 SparseComplexMatrix m (static_cast<octave_idx_type> (nr), | |
327 static_cast<octave_idx_type> (nc), | |
328 static_cast<octave_idx_type> (nz)); | |
329 | |
330 for (int i = 0; i < nc+1; i++) | |
331 { | |
332 octave_quit (); | |
333 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) | |
334 return false; | |
335 if (swap) | |
336 swap_bytes<4> (&tmp); | |
337 m.cidx (i) = tmp; | |
338 } | |
339 | |
340 for (int i = 0; i < nz; i++) | |
341 { | |
342 octave_quit (); | |
343 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) | |
344 return false; | |
345 if (swap) | |
346 swap_bytes<4> (&tmp); | |
347 m.ridx (i) = tmp; | |
348 } | |
349 | |
350 if (! is.read (reinterpret_cast<char *> (&ctmp), 1)) | |
351 return false; | |
352 | |
353 read_doubles (is, reinterpret_cast<double *> (m.data ()), | |
354 static_cast<save_type> (ctmp), 2 * nz, swap, fmt); | |
355 | |
356 if (error_state || ! is) | |
357 return false; | |
358 | |
359 if (! m.indices_ok ()) | |
360 return false; | |
361 | |
362 matrix = m; | |
363 | |
364 return true; | |
365 } | |
366 | |
367 #if defined (HAVE_HDF5) | |
368 | |
369 bool | |
370 octave_sparse_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, | |
371 bool save_as_floats) | |
372 { | |
373 dim_vector dv = dims (); | |
374 int empty = save_hdf5_empty (loc_id, name, dv); | |
375 if (empty) | |
376 return (empty > 0); | |
377 | |
378 // Ensure that additional memory is deallocated | |
379 matrix.maybe_compress (); | |
380 | |
381 #if HAVE_HDF5_18 | |
382 hid_t group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
383 #else | |
384 hid_t group_hid = H5Gcreate (loc_id, name, 0); | |
385 #endif | |
386 if (group_hid < 0) | |
387 return false; | |
388 | |
389 hid_t space_hid = -1, data_hid = -1; | |
390 bool retval = true; | |
391 SparseComplexMatrix m = sparse_complex_matrix_value (); | |
392 octave_idx_type tmp; | |
393 hsize_t hdims[2]; | |
394 | |
395 space_hid = H5Screate_simple (0, hdims, 0); | |
396 if (space_hid < 0) | |
397 { | |
398 H5Gclose (group_hid); | |
399 return false; | |
400 } | |
401 | |
402 #if HAVE_HDF5_18 | |
403 data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid, | |
404 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
405 #else | |
406 data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid, | |
407 H5P_DEFAULT); | |
408 #endif | |
409 if (data_hid < 0) | |
410 { | |
411 H5Sclose (space_hid); | |
412 H5Gclose (group_hid); | |
413 return false; | |
414 } | |
415 | |
416 tmp = m.rows (); | |
417 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, | |
418 H5P_DEFAULT, &tmp) >= 0; | |
419 H5Dclose (data_hid); | |
420 if (!retval) | |
421 { | |
422 H5Sclose (space_hid); | |
423 H5Gclose (group_hid); | |
424 return false; | |
425 } | |
426 | |
427 #if HAVE_HDF5_18 | |
428 data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid, | |
429 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
430 #else | |
431 data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid, | |
432 H5P_DEFAULT); | |
433 #endif | |
434 if (data_hid < 0) | |
435 { | |
436 H5Sclose (space_hid); | |
437 H5Gclose (group_hid); | |
438 return false; | |
439 } | |
440 | |
441 tmp = m.cols (); | |
442 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, | |
443 H5P_DEFAULT, &tmp) >= 0; | |
444 H5Dclose (data_hid); | |
445 if (!retval) | |
446 { | |
447 H5Sclose (space_hid); | |
448 H5Gclose (group_hid); | |
449 return false; | |
450 } | |
451 | |
452 #if HAVE_HDF5_18 | |
453 data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, | |
454 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
455 #else | |
456 data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, | |
457 H5P_DEFAULT); | |
458 #endif | |
459 if (data_hid < 0) | |
460 { | |
461 H5Sclose (space_hid); | |
462 H5Gclose (group_hid); | |
463 return false; | |
464 } | |
465 | |
466 tmp = m.nnz (); | |
467 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, | |
468 H5P_DEFAULT, &tmp) >= 0; | |
469 H5Dclose (data_hid); | |
470 if (!retval) | |
471 { | |
472 H5Sclose (space_hid); | |
473 H5Gclose (group_hid); | |
474 return false; | |
475 } | |
476 | |
477 H5Sclose (space_hid); | |
478 | |
479 hdims[0] = m.cols () + 1; | |
480 hdims[1] = 1; | |
481 | |
482 space_hid = H5Screate_simple (2, hdims, 0); | |
483 | |
484 if (space_hid < 0) | |
485 { | |
486 H5Gclose (group_hid); | |
487 return false; | |
488 } | |
489 | |
490 #if HAVE_HDF5_18 | |
491 data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, | |
492 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
493 #else | |
494 data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, | |
495 H5P_DEFAULT); | |
496 #endif | |
497 if (data_hid < 0) | |
498 { | |
499 H5Sclose (space_hid); | |
500 H5Gclose (group_hid); | |
501 return false; | |
502 } | |
503 | |
504 octave_idx_type * itmp = m.xcidx (); | |
505 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, | |
506 H5P_DEFAULT, itmp) >= 0; | |
507 H5Dclose (data_hid); | |
508 if (!retval) | |
509 { | |
510 H5Sclose (space_hid); | |
511 H5Gclose (group_hid); | |
512 return false; | |
513 } | |
514 | |
515 H5Sclose (space_hid); | |
516 | |
517 hdims[0] = m.nnz (); | |
518 hdims[1] = 1; | |
519 | |
520 space_hid = H5Screate_simple (2, hdims, 0); | |
521 | |
522 if (space_hid < 0) | |
523 { | |
524 H5Gclose (group_hid); | |
525 return false; | |
526 } | |
527 | |
528 #if HAVE_HDF5_18 | |
529 data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, | |
530 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
531 #else | |
532 data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, | |
533 H5P_DEFAULT); | |
534 #endif | |
535 if (data_hid < 0) | |
536 { | |
537 H5Sclose (space_hid); | |
538 H5Gclose (group_hid); | |
539 return false; | |
540 } | |
541 | |
542 itmp = m.xridx (); | |
543 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) >= 0; | |
544 H5Dclose (data_hid); | |
545 if (!retval) | |
546 { | |
547 H5Sclose (space_hid); | |
548 H5Gclose (group_hid); | |
549 return false; | |
550 } | |
551 | |
552 hid_t save_type_hid = H5T_NATIVE_DOUBLE; | |
553 | |
554 if (save_as_floats) | |
555 { | |
556 if (m.too_large_for_float ()) | |
557 { | |
558 warning ("save: some values too large to save as floats --"); | |
559 warning ("save: saving as doubles instead"); | |
560 } | |
561 else | |
562 save_type_hid = H5T_NATIVE_FLOAT; | |
563 } | |
564 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS | |
565 // hdf5 currently doesn't support float/integer conversions | |
566 else | |
567 { | |
568 double max_val, min_val; | |
569 | |
570 if (m.all_integers (max_val, min_val)) | |
571 save_type_hid | |
572 = save_type_to_hdf5 (get_save_type (max_val, min_val)); | |
573 } | |
574 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */ | |
575 | |
576 hid_t type_hid = hdf5_make_complex_type (save_type_hid); | |
577 if (type_hid < 0) | |
578 { | |
579 H5Sclose (space_hid); | |
580 H5Gclose (group_hid); | |
581 return false; | |
582 } | |
583 #if HAVE_HDF5_18 | |
584 data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid, | |
585 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); | |
586 #else | |
587 data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid, H5P_DEFAULT); | |
588 #endif | |
589 if (data_hid < 0) | |
590 { | |
591 H5Sclose (space_hid); | |
592 H5Tclose (type_hid); | |
593 H5Gclose (group_hid); | |
594 return false; | |
595 } | |
596 | |
597 hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); | |
598 retval = false; | |
599 if (complex_type_hid >= 0) | |
600 { | |
601 Complex * ctmp = m.xdata (); | |
602 | |
603 retval = H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL, | |
604 H5P_DEFAULT, ctmp) >= 0; | |
605 } | |
606 | |
607 H5Dclose (data_hid); | |
608 H5Sclose (space_hid); | |
609 H5Tclose (type_hid); | |
610 H5Gclose (group_hid); | |
611 | |
612 return retval; | |
613 } | |
614 | |
615 bool | |
616 octave_sparse_complex_matrix::load_hdf5 (hid_t loc_id, const char *name) | |
617 { | |
618 octave_idx_type nr, nc, nz; | |
619 hid_t group_hid, data_hid, space_hid; | |
620 hsize_t rank; | |
621 | |
622 dim_vector dv; | |
623 int empty = load_hdf5_empty (loc_id, name, dv); | |
624 if (empty > 0) | |
625 matrix.resize (dv); | |
626 if (empty) | |
627 return (empty > 0); | |
628 | |
629 #if HAVE_HDF5_18 | |
630 group_hid = H5Gopen (loc_id, name, H5P_DEFAULT); | |
631 #else | |
632 group_hid = H5Gopen (loc_id, name); | |
633 #endif | |
634 if (group_hid < 0 ) return false; | |
635 | |
636 #if HAVE_HDF5_18 | |
637 data_hid = H5Dopen (group_hid, "nr", H5P_DEFAULT); | |
638 #else | |
639 data_hid = H5Dopen (group_hid, "nr"); | |
640 #endif | |
641 space_hid = H5Dget_space (data_hid); | |
642 rank = H5Sget_simple_extent_ndims (space_hid); | |
643 | |
644 if (rank != 0) | |
645 { | |
646 H5Dclose (data_hid); | |
647 H5Gclose (group_hid); | |
648 return false; | |
649 } | |
650 | |
651 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nr) < 0) | |
652 { | |
653 H5Dclose (data_hid); | |
654 H5Gclose (group_hid); | |
655 return false; | |
656 } | |
657 | |
658 H5Dclose (data_hid); | |
659 | |
660 #if HAVE_HDF5_18 | |
661 data_hid = H5Dopen (group_hid, "nc", H5P_DEFAULT); | |
662 #else | |
663 data_hid = H5Dopen (group_hid, "nc"); | |
664 #endif | |
665 space_hid = H5Dget_space (data_hid); | |
666 rank = H5Sget_simple_extent_ndims (space_hid); | |
667 | |
668 if (rank != 0) | |
669 { | |
670 H5Dclose (data_hid); | |
671 H5Gclose (group_hid); | |
672 return false; | |
673 } | |
674 | |
675 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nc) < 0) | |
676 { | |
677 H5Dclose (data_hid); | |
678 H5Gclose (group_hid); | |
679 return false; | |
680 } | |
681 | |
682 H5Dclose (data_hid); | |
683 | |
684 #if HAVE_HDF5_18 | |
685 data_hid = H5Dopen (group_hid, "nz", H5P_DEFAULT); | |
686 #else | |
687 data_hid = H5Dopen (group_hid, "nz"); | |
688 #endif | |
689 space_hid = H5Dget_space (data_hid); | |
690 rank = H5Sget_simple_extent_ndims (space_hid); | |
691 | |
692 if (rank != 0) | |
693 { | |
694 H5Dclose (data_hid); | |
695 H5Gclose (group_hid); | |
696 return false; | |
697 } | |
698 | |
699 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, &nz) < 0) | |
700 { | |
701 H5Dclose (data_hid); | |
702 H5Gclose (group_hid); | |
703 return false; | |
704 } | |
705 | |
706 H5Dclose (data_hid); | |
707 | |
708 SparseComplexMatrix m (static_cast<octave_idx_type> (nr), | |
709 static_cast<octave_idx_type> (nc), | |
710 static_cast<octave_idx_type> (nz)); | |
711 | |
712 #if HAVE_HDF5_18 | |
713 data_hid = H5Dopen (group_hid, "cidx", H5P_DEFAULT); | |
714 #else | |
715 data_hid = H5Dopen (group_hid, "cidx"); | |
716 #endif | |
717 space_hid = H5Dget_space (data_hid); | |
718 rank = H5Sget_simple_extent_ndims (space_hid); | |
719 | |
720 if (rank != 2) | |
721 { | |
722 H5Sclose (space_hid); | |
723 H5Dclose (data_hid); | |
724 H5Gclose (group_hid); | |
725 return false; | |
726 } | |
727 | |
728 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); | |
729 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank); | |
730 | |
731 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
732 | |
733 if (static_cast<int> (hdims[0]) != nc + 1 | |
734 || static_cast<int> (hdims[1]) != 1) | |
735 { | |
736 H5Sclose (space_hid); | |
737 H5Dclose (data_hid); | |
738 H5Gclose (group_hid); | |
739 return false; | |
740 } | |
741 | |
742 octave_idx_type *itmp = m.xcidx (); | |
743 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) | |
744 { | |
745 H5Sclose (space_hid); | |
746 H5Dclose (data_hid); | |
747 H5Gclose (group_hid); | |
748 return false; | |
749 } | |
750 | |
751 H5Sclose (space_hid); | |
752 H5Dclose (data_hid); | |
753 | |
754 #if HAVE_HDF5_18 | |
755 data_hid = H5Dopen (group_hid, "ridx", H5P_DEFAULT); | |
756 #else | |
757 data_hid = H5Dopen (group_hid, "ridx"); | |
758 #endif | |
759 space_hid = H5Dget_space (data_hid); | |
760 rank = H5Sget_simple_extent_ndims (space_hid); | |
761 | |
762 if (rank != 2) | |
763 { | |
764 H5Sclose (space_hid); | |
765 H5Dclose (data_hid); | |
766 H5Gclose (group_hid); | |
767 return false; | |
768 } | |
769 | |
770 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
771 | |
772 if (static_cast<int> (hdims[0]) != nz | |
773 || static_cast<int> (hdims[1]) != 1) | |
774 { | |
775 H5Sclose (space_hid); | |
776 H5Dclose (data_hid); | |
777 H5Gclose (group_hid); | |
778 return false; | |
779 } | |
780 | |
781 itmp = m.xridx (); | |
782 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, itmp) < 0) | |
783 { | |
784 H5Sclose (space_hid); | |
785 H5Dclose (data_hid); | |
786 H5Gclose (group_hid); | |
787 return false; | |
788 } | |
789 | |
790 H5Sclose (space_hid); | |
791 H5Dclose (data_hid); | |
792 | |
793 #if HAVE_HDF5_18 | |
794 data_hid = H5Dopen (group_hid, "data", H5P_DEFAULT); | |
795 #else | |
796 data_hid = H5Dopen (group_hid, "data"); | |
797 #endif | |
798 hid_t type_hid = H5Dget_type (data_hid); | |
799 | |
800 hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); | |
801 | |
802 if (! hdf5_types_compatible (type_hid, complex_type)) | |
803 { | |
804 H5Tclose (complex_type); | |
805 H5Dclose (data_hid); | |
806 H5Gclose (group_hid); | |
807 return false; | |
808 } | |
809 | |
810 space_hid = H5Dget_space (data_hid); | |
811 rank = H5Sget_simple_extent_ndims (space_hid); | |
812 | |
813 if (rank != 2) | |
814 { | |
815 H5Sclose (space_hid); | |
816 H5Dclose (data_hid); | |
817 H5Gclose (group_hid); | |
818 return false; | |
819 } | |
820 | |
821 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
822 | |
823 if (static_cast<int> (hdims[0]) != nz | |
824 || static_cast<int> (hdims[1]) != 1) | |
825 { | |
826 H5Sclose (space_hid); | |
827 H5Dclose (data_hid); | |
828 H5Gclose (group_hid); | |
829 return false; | |
830 } | |
831 | |
832 Complex *ctmp = m.xdata (); | |
833 bool retval = false; | |
834 if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, | |
835 H5P_DEFAULT, ctmp) >= 0 | |
836 && m.indices_ok ()) | |
837 { | |
838 retval = true; | |
839 matrix = m; | |
840 } | |
841 | |
842 H5Tclose (complex_type); | |
843 H5Sclose (space_hid); | |
844 H5Dclose (data_hid); | |
845 H5Gclose (group_hid); | |
846 | |
847 return retval; | |
848 } | |
849 | |
850 #endif | |
851 | |
852 mxArray * | |
853 octave_sparse_complex_matrix::as_mxArray (void) const | |
854 { | |
855 mwSize nz = nzmax (); | |
856 mxArray *retval = new mxArray (mxDOUBLE_CLASS, rows (), columns (), | |
857 nz, mxCOMPLEX); | |
858 double *pr = static_cast<double *> (retval->get_data ()); | |
859 double *pi = static_cast<double *> (retval->get_imag_data ()); | |
860 mwIndex *ir = retval->get_ir (); | |
861 mwIndex *jc = retval->get_jc (); | |
862 | |
863 for (mwIndex i = 0; i < nz; i++) | |
864 { | |
865 Complex val = matrix.data (i); | |
866 pr[i] = std::real (val); | |
867 pi[i] = std::imag (val); | |
868 ir[i] = matrix.ridx (i); | |
869 } | |
870 | |
871 for (mwIndex i = 0; i < columns () + 1; i++) | |
872 jc[i] = matrix.cidx (i); | |
873 | |
874 return retval; | |
875 } | |
876 | |
877 octave_value | |
878 octave_sparse_complex_matrix::map (unary_mapper_t umap) const | |
879 { | |
880 switch (umap) | |
881 { | |
882 // Mappers handled specially. | |
883 case umap_real: | |
884 return ::real (matrix); | |
885 case umap_imag: | |
886 return ::imag (matrix); | |
887 | |
888 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \ | |
889 case umap_ ## UMAP: \ | |
890 return octave_value (matrix.FCN ()) | |
891 | |
892 ARRAY_METHOD_MAPPER (abs, abs); | |
893 | |
894 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \ | |
895 case umap_ ## UMAP: \ | |
896 return octave_value (matrix.map<TYPE> (FCN)) | |
897 | |
898 ARRAY_MAPPER (acos, Complex, ::acos); | |
899 ARRAY_MAPPER (acosh, Complex, ::acosh); | |
900 ARRAY_MAPPER (angle, double, std::arg); | |
901 ARRAY_MAPPER (arg, double, std::arg); | |
902 ARRAY_MAPPER (asin, Complex, ::asin); | |
903 ARRAY_MAPPER (asinh, Complex, ::asinh); | |
904 ARRAY_MAPPER (atan, Complex, ::atan); | |
905 ARRAY_MAPPER (atanh, Complex, ::atanh); | |
906 ARRAY_MAPPER (ceil, Complex, ::ceil); | |
907 ARRAY_MAPPER (conj, Complex, std::conj<double>); | |
908 ARRAY_MAPPER (cos, Complex, std::cos); | |
909 ARRAY_MAPPER (cosh, Complex, std::cosh); | |
910 ARRAY_MAPPER (exp, Complex, std::exp); | |
911 ARRAY_MAPPER (expm1, Complex, ::expm1); | |
912 ARRAY_MAPPER (fix, Complex, ::fix); | |
913 ARRAY_MAPPER (floor, Complex, ::floor); | |
914 ARRAY_MAPPER (log, Complex, std::log); | |
915 ARRAY_MAPPER (log2, Complex, xlog2); | |
916 ARRAY_MAPPER (log10, Complex, std::log10); | |
917 ARRAY_MAPPER (log1p, Complex, ::log1p); | |
918 ARRAY_MAPPER (round, Complex, xround); | |
919 ARRAY_MAPPER (roundb, Complex, xroundb); | |
920 ARRAY_MAPPER (signum, Complex, ::signum); | |
921 ARRAY_MAPPER (sin, Complex, std::sin); | |
922 ARRAY_MAPPER (sinh, Complex, std::sinh); | |
923 ARRAY_MAPPER (sqrt, Complex, std::sqrt); | |
924 ARRAY_MAPPER (tan, Complex, std::tan); | |
925 ARRAY_MAPPER (tanh, Complex, std::tanh); | |
926 ARRAY_MAPPER (isnan, bool, xisnan); | |
927 ARRAY_MAPPER (isna, bool, octave_is_NA); | |
928 ARRAY_MAPPER (isinf, bool, xisinf); | |
929 ARRAY_MAPPER (finite, bool, xfinite); | |
930 | |
931 default: // Attempt to go via dense matrix. | |
932 return octave_base_sparse<SparseComplexMatrix>::map (umap); | |
933 } | |
934 } |