Mercurial > hg > octave-lyh
annotate src/ov-re-sparse.cc @ 9813:8fa32b527d9a
improve & partially revert previous change
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Fri, 13 Nov 2009 11:45:39 +0100 |
parents | f80c566bc751 |
children | 1bb1ed717d2f |
rev | line source |
---|---|
5164 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2004, 2005, 2006, 2007, 2008 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 <climits> | |
29 | |
30 #include <iostream> | |
31 #include <vector> | |
32 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
33 #include "lo-specfun.h" |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
34 #include "lo-mappers.h" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
35 #include "oct-locbuf.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
36 |
5164 | 37 #include "ov-base.h" |
38 #include "ov-scalar.h" | |
39 #include "gripes.h" | |
40 | |
41 #include "ls-hdf5.h" | |
42 | |
43 #include "ov-re-sparse.h" | |
44 | |
45 #include "ov-base-sparse.h" | |
46 #include "ov-base-sparse.cc" | |
47 | |
48 #include "ov-bool-sparse.h" | |
49 | |
6109 | 50 template class OCTINTERP_API octave_base_sparse<SparseMatrix>; |
5164 | 51 |
52 DEFINE_OCTAVE_ALLOCATOR (octave_sparse_matrix); | |
53 | |
6823 | 54 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix", "double"); |
5164 | 55 |
5282 | 56 idx_vector |
57 octave_sparse_matrix::index_vector (void) const | |
58 { | |
5604 | 59 if (matrix.numel () == matrix.nnz ()) |
5282 | 60 return idx_vector (array_value ()); |
61 else | |
62 { | |
63 std::string nm = type_name (); | |
64 error ("%s type invalid as index value", nm.c_str ()); | |
65 return idx_vector (); | |
66 } | |
67 } | |
68 | |
5759 | 69 octave_base_value * |
5164 | 70 octave_sparse_matrix::try_narrowing_conversion (void) |
71 { | |
5759 | 72 octave_base_value *retval = 0; |
5164 | 73 |
7193 | 74 if (Vsparse_auto_mutate) |
5164 | 75 { |
7193 | 76 // Don't use numel, since it can overflow for very large matrices |
77 // Note that for the second test, this means it becomes approximative | |
78 // since it involves a cast to double to avoid issues of overflow | |
79 if (matrix.rows () == 1 && matrix.cols () == 1) | |
80 { | |
81 // Const copy of the matrix, so the right version of () operator used | |
82 const SparseMatrix tmp (matrix); | |
5164 | 83 |
7193 | 84 retval = new octave_scalar (tmp (0)); |
85 } | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
86 else if (matrix.cols () > 0 && matrix.rows () > 0 |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
87 && (double (matrix.byte_size ()) > double (matrix.rows ()) |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
88 * double (matrix.cols ()) * sizeof (double))) |
7193 | 89 retval = new octave_matrix (matrix.matrix_value ()); |
5164 | 90 } |
91 | |
92 return retval; | |
93 } | |
94 | |
95 double | |
96 octave_sparse_matrix::double_value (bool) const | |
97 { | |
98 double retval = lo_ieee_nan_value (); | |
99 | |
100 if (numel () > 0) | |
101 { | |
6221 | 102 if (numel () > 1) |
103 gripe_implicit_conversion ("Octave:array-as-scalar", | |
104 "real sparse matrix", "real scalar"); | |
5164 | 105 |
106 retval = matrix (0, 0); | |
107 } | |
108 else | |
109 gripe_invalid_conversion ("real sparse matrix", "real scalar"); | |
110 | |
111 return retval; | |
112 } | |
113 | |
114 Complex | |
115 octave_sparse_matrix::complex_value (bool) const | |
116 { | |
117 double tmp = lo_ieee_nan_value (); | |
118 | |
119 Complex retval (tmp, tmp); | |
120 | |
5775 | 121 // FIXME -- maybe this should be a function, valid_as_scalar() |
5164 | 122 if (rows () > 0 && columns () > 0) |
123 { | |
6221 | 124 if (numel () > 1) |
125 gripe_implicit_conversion ("Octave:array-as-scalar", | |
126 "real sparse matrix", "complex scalar"); | |
5164 | 127 |
128 retval = matrix (0, 0); | |
129 } | |
130 else | |
131 gripe_invalid_conversion ("real sparse matrix", "complex scalar"); | |
132 | |
133 return retval; | |
134 } | |
135 | |
136 Matrix | |
137 octave_sparse_matrix::matrix_value (bool) const | |
138 { | |
139 return matrix.matrix_value (); | |
140 } | |
141 | |
5898 | 142 boolNDArray |
5943 | 143 octave_sparse_matrix::bool_array_value (bool warn) const |
5898 | 144 { |
5943 | 145 NDArray m = matrix.matrix_value (); |
146 | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7885
diff
changeset
|
147 if (m.any_element_is_nan ()) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7885
diff
changeset
|
148 error ("invalid conversion from NaN to logical"); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7885
diff
changeset
|
149 else if (warn && m.any_element_not_one_or_zero ()) |
5943 | 150 gripe_logical_conversion (); |
151 | |
152 return boolNDArray (m); | |
5898 | 153 } |
154 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
155 charNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
156 octave_sparse_matrix::char_array_value (bool) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
157 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
158 charNDArray retval (dims (), 0); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
159 octave_idx_type nc = matrix.cols (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
160 octave_idx_type nr = matrix.rows (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
161 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
162 for (octave_idx_type j = 0; j < nc; j++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
163 for (octave_idx_type i = matrix.cidx(j); i < matrix.cidx(j+1); i++) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
164 retval(matrix.ridx(i) + nr * j) = static_cast<char>(matrix.data (i)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
165 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
166 return retval; |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
167 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
168 |
5164 | 169 ComplexMatrix |
170 octave_sparse_matrix::complex_matrix_value (bool) const | |
171 { | |
172 return ComplexMatrix (matrix.matrix_value ()); | |
173 } | |
174 | |
175 ComplexNDArray | |
176 octave_sparse_matrix::complex_array_value (bool) const | |
177 { | |
178 return ComplexNDArray (ComplexMatrix (matrix.matrix_value ())); | |
179 } | |
180 | |
181 NDArray | |
182 octave_sparse_matrix::array_value (bool) const | |
183 { | |
184 return NDArray (matrix.matrix_value ()); | |
185 } | |
186 | |
5282 | 187 octave_value |
5322 | 188 octave_sparse_matrix::convert_to_str_internal (bool, bool, char type) const |
5282 | 189 { |
190 octave_value retval; | |
191 dim_vector dv = dims (); | |
192 octave_idx_type nel = dv.numel (); | |
193 | |
194 if (nel == 0) | |
195 { | |
196 char s = '\0'; | |
5322 | 197 retval = octave_value (&s, type); |
5282 | 198 } |
199 else | |
200 { | |
201 octave_idx_type nr = matrix.rows (); | |
202 octave_idx_type nc = matrix.cols (); | |
203 charNDArray chm (dv, static_cast<char> (0)); | |
204 | |
205 bool warned = false; | |
206 | |
207 for (octave_idx_type j = 0; j < nc; j++) | |
208 for (octave_idx_type i = matrix.cidx(j); | |
209 i < matrix.cidx(j+1); i++) | |
210 { | |
211 OCTAVE_QUIT; | |
212 | |
213 double d = matrix.data (i); | |
214 | |
215 if (xisnan (d)) | |
216 { | |
217 ::error ("invalid conversion from NaN to character"); | |
218 return retval; | |
219 } | |
220 else | |
221 { | |
222 int ival = NINT (d); | |
223 | |
224 if (ival < 0 || ival > UCHAR_MAX) | |
225 { | |
5775 | 226 // FIXME -- is there something |
5282 | 227 // better we could do? |
228 | |
229 ival = 0; | |
230 | |
231 if (! warned) | |
232 { | |
233 ::warning ("range error for conversion to character value"); | |
234 warned = true; | |
235 } | |
236 } | |
237 | |
238 chm (matrix.ridx(i) + j * nr) = | |
239 static_cast<char> (ival); | |
240 } | |
241 } | |
9689
34d6f005db4b
eliminate is_string argument from octave_value character array constructors
John W. Eaton <jwe@octave.org>
parents:
9470
diff
changeset
|
242 |
34d6f005db4b
eliminate is_string argument from octave_value character array constructors
John W. Eaton <jwe@octave.org>
parents:
9470
diff
changeset
|
243 retval = octave_value (chm, type); |
5282 | 244 } |
245 | |
246 return retval; | |
247 } | |
248 | |
5164 | 249 bool |
250 octave_sparse_matrix::save_binary (std::ostream& os, bool&save_as_floats) | |
251 { | |
252 dim_vector d = this->dims (); | |
253 if (d.length() < 1) | |
254 return false; | |
255 | |
256 // Ensure that additional memory is deallocated | |
257 matrix.maybe_compress (); | |
258 | |
259 int nr = d(0); | |
260 int nc = d(1); | |
5604 | 261 int nz = nzmax (); |
5164 | 262 |
5828 | 263 int32_t itmp; |
5164 | 264 // Use negative value for ndims to be consistent with other formats |
265 itmp= -2; | |
5760 | 266 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 267 |
268 itmp= nr; | |
5760 | 269 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 270 |
271 itmp= nc; | |
5760 | 272 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 273 |
274 itmp= nz; | |
5760 | 275 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 276 |
277 save_type st = LS_DOUBLE; | |
278 if (save_as_floats) | |
279 { | |
280 if (matrix.too_large_for_float ()) | |
281 { | |
282 warning ("save: some values too large to save as floats --"); | |
283 warning ("save: saving as doubles instead"); | |
284 } | |
285 else | |
286 st = LS_FLOAT; | |
287 } | |
5775 | 288 else if (matrix.nzmax () > 8192) // FIXME -- make this configurable. |
5164 | 289 { |
290 double max_val, min_val; | |
291 if (matrix.all_integers (max_val, min_val)) | |
292 st = get_save_type (max_val, min_val); | |
293 } | |
294 | |
295 // add one to the printed indices to go from | |
296 // zero-based to one-based arrays | |
297 for (int i = 0; i < nc+1; i++) | |
298 { | |
299 OCTAVE_QUIT; | |
300 itmp = matrix.cidx(i); | |
5760 | 301 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 302 } |
303 | |
304 for (int i = 0; i < nz; i++) | |
305 { | |
306 OCTAVE_QUIT; | |
307 itmp = matrix.ridx(i); | |
5760 | 308 os.write (reinterpret_cast<char *> (&itmp), 4); |
5164 | 309 } |
310 | |
311 write_doubles (os, matrix.data(), st, nz); | |
312 | |
313 return true; | |
314 } | |
315 | |
316 bool | |
317 octave_sparse_matrix::load_binary (std::istream& is, bool swap, | |
318 oct_mach_info::float_format fmt) | |
319 { | |
5828 | 320 int32_t nz, nc, nr, tmp; |
5327 | 321 char ctmp; |
322 | |
5760 | 323 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) |
5164 | 324 return false; |
325 | |
326 if (swap) | |
327 swap_bytes<4> (&tmp); | |
328 | |
329 if (tmp != -2) { | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
330 error ("load: only 2D sparse matrices are supported"); |
5164 | 331 return false; |
332 } | |
333 | |
5760 | 334 if (! is.read (reinterpret_cast<char *> (&nr), 4)) |
5164 | 335 return false; |
5760 | 336 if (! is.read (reinterpret_cast<char *> (&nc), 4)) |
5164 | 337 return false; |
5760 | 338 if (! is.read (reinterpret_cast<char *> (&nz), 4)) |
5164 | 339 return false; |
340 | |
341 if (swap) | |
342 { | |
343 swap_bytes<4> (&nr); | |
344 swap_bytes<4> (&nc); | |
345 swap_bytes<4> (&nz); | |
346 } | |
347 | |
5275 | 348 SparseMatrix m (static_cast<octave_idx_type> (nr), |
349 static_cast<octave_idx_type> (nc), | |
350 static_cast<octave_idx_type> (nz)); | |
5164 | 351 |
352 for (int i = 0; i < nc+1; i++) | |
353 { | |
354 OCTAVE_QUIT; | |
5760 | 355 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) |
5164 | 356 return false; |
357 if (swap) | |
358 swap_bytes<4> (&tmp); | |
359 m.xcidx(i) = tmp; | |
360 } | |
361 | |
362 for (int i = 0; i < nz; i++) | |
363 { | |
364 OCTAVE_QUIT; | |
5760 | 365 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) |
5164 | 366 return false; |
367 if (swap) | |
368 swap_bytes<4> (&tmp); | |
369 m.xridx(i) = tmp; | |
370 } | |
371 | |
5760 | 372 if (! is.read (reinterpret_cast<char *> (&ctmp), 1)) |
5164 | 373 return false; |
374 | |
5760 | 375 read_doubles (is, m.xdata (), static_cast<save_type> (ctmp), nz, swap, fmt); |
5164 | 376 |
377 if (error_state || ! is) | |
378 return false; | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
379 |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
380 if (! m.indices_ok ()) |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
381 return false; |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
382 |
5164 | 383 matrix = m; |
384 | |
385 return true; | |
386 } | |
387 | |
388 #if defined (HAVE_HDF5) | |
5900 | 389 |
5164 | 390 bool |
391 octave_sparse_matrix::save_hdf5 (hid_t loc_id, const char *name, | |
392 bool save_as_floats) | |
393 { | |
394 dim_vector dv = dims (); | |
395 int empty = save_hdf5_empty (loc_id, name, dv); | |
396 if (empty) | |
397 return (empty > 0); | |
398 | |
399 // Ensure that additional memory is deallocated | |
400 matrix.maybe_compress (); | |
401 | |
402 hid_t group_hid = H5Gcreate (loc_id, name, 0); | |
403 if (group_hid < 0) | |
404 return false; | |
405 | |
406 hid_t space_hid = -1, data_hid = -1; | |
407 bool retval = true; | |
408 SparseMatrix m = sparse_matrix_value (); | |
5351 | 409 octave_idx_type tmp; |
5164 | 410 hsize_t hdims[2]; |
411 | |
5760 | 412 space_hid = H5Screate_simple (0, hdims, 0); |
5164 | 413 if (space_hid < 0) |
414 { | |
415 H5Gclose (group_hid); | |
416 return false; | |
417 } | |
418 | |
5351 | 419 data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid, |
5164 | 420 H5P_DEFAULT); |
421 if (data_hid < 0) | |
422 { | |
423 H5Sclose (space_hid); | |
424 H5Gclose (group_hid); | |
425 return false; | |
426 } | |
427 | |
428 tmp = m.rows (); | |
5351 | 429 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, |
5760 | 430 &tmp) >= 0; |
5164 | 431 H5Dclose (data_hid); |
432 if (!retval) | |
433 { | |
434 H5Sclose (space_hid); | |
435 H5Gclose (group_hid); | |
436 return false; | |
437 } | |
438 | |
5351 | 439 data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid, |
5164 | 440 H5P_DEFAULT); |
441 if (data_hid < 0) | |
442 { | |
443 H5Sclose (space_hid); | |
444 H5Gclose (group_hid); | |
445 return false; | |
446 } | |
447 | |
448 tmp = m.cols (); | |
5351 | 449 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, |
5760 | 450 &tmp) >= 0; |
5164 | 451 H5Dclose (data_hid); |
452 if (!retval) | |
453 { | |
454 H5Sclose (space_hid); | |
455 H5Gclose (group_hid); | |
456 return false; | |
457 } | |
458 | |
5351 | 459 data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid, |
5164 | 460 H5P_DEFAULT); |
461 if (data_hid < 0) | |
462 { | |
463 H5Sclose (space_hid); | |
464 H5Gclose (group_hid); | |
465 return false; | |
466 } | |
467 | |
5604 | 468 tmp = m.nzmax (); |
5351 | 469 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, |
5760 | 470 &tmp) >= 0; |
5164 | 471 H5Dclose (data_hid); |
472 if (!retval) | |
473 { | |
474 H5Sclose (space_hid); | |
475 H5Gclose (group_hid); | |
476 return false; | |
477 } | |
478 | |
479 H5Sclose (space_hid); | |
480 | |
481 hdims[0] = m.cols() + 1; | |
482 hdims[1] = 1; | |
483 | |
484 space_hid = H5Screate_simple (2, hdims, 0); | |
485 | |
486 if (space_hid < 0) | |
487 { | |
488 H5Gclose (group_hid); | |
489 return false; | |
490 } | |
491 | |
5351 | 492 data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid, |
5164 | 493 H5P_DEFAULT); |
494 if (data_hid < 0) | |
495 { | |
496 H5Sclose (space_hid); | |
497 H5Gclose (group_hid); | |
498 return false; | |
499 } | |
500 | |
5351 | 501 octave_idx_type * itmp = m.xcidx (); |
502 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, | |
5760 | 503 itmp) >= 0; |
5164 | 504 H5Dclose (data_hid); |
505 if (!retval) | |
506 { | |
507 H5Sclose (space_hid); | |
508 H5Gclose (group_hid); | |
509 return false; | |
510 } | |
511 | |
512 H5Sclose (space_hid); | |
513 | |
5604 | 514 hdims[0] = m.nzmax (); |
5164 | 515 hdims[1] = 1; |
516 | |
517 space_hid = H5Screate_simple (2, hdims, 0); | |
518 | |
519 if (space_hid < 0) | |
520 { | |
521 H5Gclose (group_hid); | |
522 return false; | |
523 } | |
524 | |
5351 | 525 data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid, |
5164 | 526 H5P_DEFAULT); |
527 if (data_hid < 0) | |
528 { | |
529 H5Sclose (space_hid); | |
530 H5Gclose (group_hid); | |
531 return false; | |
532 } | |
533 | |
534 itmp = m.xridx (); | |
5351 | 535 retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT, |
5760 | 536 itmp) >= 0; |
5164 | 537 H5Dclose (data_hid); |
538 if (!retval) | |
539 { | |
540 H5Sclose (space_hid); | |
541 H5Gclose (group_hid); | |
542 return false; | |
543 } | |
544 | |
545 hid_t save_type_hid = H5T_NATIVE_DOUBLE; | |
546 | |
547 if (save_as_floats) | |
548 { | |
549 if (m.too_large_for_float ()) | |
550 { | |
551 warning ("save: some values too large to save as floats --"); | |
552 warning ("save: saving as doubles instead"); | |
553 } | |
554 else | |
555 save_type_hid = H5T_NATIVE_FLOAT; | |
556 } | |
557 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS | |
558 // hdf5 currently doesn't support float/integer conversions | |
559 else | |
560 { | |
561 double max_val, min_val; | |
562 | |
563 if (m.all_integers (max_val, min_val)) | |
564 save_type_hid | |
565 = save_type_to_hdf5 (get_save_type (max_val, min_val)); | |
566 } | |
567 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */ | |
568 | |
569 data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid, | |
570 H5P_DEFAULT); | |
571 if (data_hid < 0) | |
572 { | |
573 H5Sclose (space_hid); | |
574 H5Gclose (group_hid); | |
575 return false; | |
576 } | |
577 | |
578 double * dtmp = m.xdata (); | |
579 retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, | |
5760 | 580 H5P_DEFAULT, dtmp) >= 0; |
5164 | 581 H5Dclose (data_hid); |
582 H5Sclose (space_hid); | |
583 H5Gclose (group_hid); | |
584 | |
585 return retval; | |
586 } | |
587 | |
588 bool | |
589 octave_sparse_matrix::load_hdf5 (hid_t loc_id, const char *name, | |
5760 | 590 bool /* have_h5giterate_bug */) |
5164 | 591 { |
5351 | 592 octave_idx_type nr, nc, nz; |
5164 | 593 hid_t group_hid, data_hid, space_hid; |
594 hsize_t rank; | |
595 | |
596 dim_vector dv; | |
597 int empty = load_hdf5_empty (loc_id, name, dv); | |
598 if (empty > 0) | |
599 matrix.resize(dv); | |
600 if (empty) | |
601 return (empty > 0); | |
602 | |
603 group_hid = H5Gopen (loc_id, name); | |
5760 | 604 if (group_hid < 0) return false; |
5164 | 605 |
606 data_hid = H5Dopen (group_hid, "nr"); | |
607 space_hid = H5Dget_space (data_hid); | |
608 rank = H5Sget_simple_extent_ndims (space_hid); | |
609 | |
610 if (rank != 0) | |
611 { | |
612 H5Dclose (data_hid); | |
613 H5Gclose (group_hid); | |
614 return false; | |
615 } | |
616 | |
5351 | 617 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
5760 | 618 H5P_DEFAULT, &nr) < 0) |
5164 | 619 { |
620 H5Dclose (data_hid); | |
621 H5Gclose (group_hid); | |
622 return false; | |
623 } | |
624 | |
625 H5Dclose (data_hid); | |
626 | |
627 data_hid = H5Dopen (group_hid, "nc"); | |
628 space_hid = H5Dget_space (data_hid); | |
629 rank = H5Sget_simple_extent_ndims (space_hid); | |
630 | |
631 if (rank != 0) | |
632 { | |
633 H5Dclose (data_hid); | |
634 H5Gclose (group_hid); | |
635 return false; | |
636 } | |
637 | |
5351 | 638 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
5760 | 639 H5P_DEFAULT, &nc) < 0) |
5164 | 640 { |
641 H5Dclose (data_hid); | |
642 H5Gclose (group_hid); | |
643 return false; | |
644 } | |
645 | |
646 H5Dclose (data_hid); | |
647 | |
648 data_hid = H5Dopen (group_hid, "nz"); | |
649 space_hid = H5Dget_space (data_hid); | |
650 rank = H5Sget_simple_extent_ndims (space_hid); | |
651 | |
652 if (rank != 0) | |
653 { | |
654 H5Dclose (data_hid); | |
655 H5Gclose (group_hid); | |
656 return false; | |
657 } | |
658 | |
5351 | 659 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
5760 | 660 H5P_DEFAULT, &nz) < 0) |
5164 | 661 { |
662 H5Dclose (data_hid); | |
663 H5Gclose (group_hid); | |
664 return false; | |
665 } | |
666 | |
667 H5Dclose (data_hid); | |
668 | |
5275 | 669 SparseMatrix m (static_cast<octave_idx_type> (nr), |
670 static_cast<octave_idx_type> (nc), | |
671 static_cast<octave_idx_type> (nz)); | |
5164 | 672 |
673 data_hid = H5Dopen (group_hid, "cidx"); | |
674 space_hid = H5Dget_space (data_hid); | |
675 rank = H5Sget_simple_extent_ndims (space_hid); | |
676 | |
677 if (rank != 2) | |
678 { | |
679 H5Sclose (space_hid); | |
680 H5Dclose (data_hid); | |
681 H5Gclose (group_hid); | |
682 return false; | |
683 } | |
684 | |
685 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank); | |
686 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank); | |
687 | |
688 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
689 | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
690 if (static_cast<int> (hdims[0]) != nc + 1 |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
691 || static_cast<int> (hdims[1]) != 1) |
5164 | 692 { |
693 H5Sclose (space_hid); | |
694 H5Dclose (data_hid); | |
695 H5Gclose (group_hid); | |
696 return false; | |
697 } | |
698 | |
5351 | 699 octave_idx_type *itmp = m.xcidx (); |
700 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, | |
5760 | 701 H5P_DEFAULT, itmp) < 0) |
5164 | 702 { |
703 H5Sclose (space_hid); | |
704 H5Dclose (data_hid); | |
705 H5Gclose (group_hid); | |
706 return false; | |
707 } | |
708 | |
709 H5Sclose (space_hid); | |
710 H5Dclose (data_hid); | |
711 | |
712 data_hid = H5Dopen (group_hid, "ridx"); | |
713 space_hid = H5Dget_space (data_hid); | |
714 rank = H5Sget_simple_extent_ndims (space_hid); | |
715 | |
716 if (rank != 2) | |
717 { | |
718 H5Sclose (space_hid); | |
719 H5Dclose (data_hid); | |
720 H5Gclose (group_hid); | |
721 return false; | |
722 } | |
723 | |
724 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
725 | |
5322 | 726 if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1) |
5164 | 727 { |
728 H5Sclose (space_hid); | |
729 H5Dclose (data_hid); | |
730 H5Gclose (group_hid); | |
731 return false; | |
732 } | |
733 | |
734 itmp = m.xridx (); | |
5351 | 735 if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, |
5760 | 736 H5P_DEFAULT, itmp) < 0) |
5164 | 737 { |
738 H5Sclose (space_hid); | |
739 H5Dclose (data_hid); | |
740 H5Gclose (group_hid); | |
741 return false; | |
742 } | |
743 | |
744 H5Sclose (space_hid); | |
745 H5Dclose (data_hid); | |
746 | |
747 data_hid = H5Dopen (group_hid, "data"); | |
748 space_hid = H5Dget_space (data_hid); | |
749 rank = H5Sget_simple_extent_ndims (space_hid); | |
750 | |
751 if (rank != 2) | |
752 { | |
753 H5Sclose (space_hid); | |
754 H5Dclose (data_hid); | |
755 H5Gclose (group_hid); | |
756 return false; | |
757 } | |
758 | |
759 H5Sget_simple_extent_dims (space_hid, hdims, maxdims); | |
760 | |
5322 | 761 if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1) |
5164 | 762 { |
763 H5Sclose (space_hid); | |
764 H5Dclose (data_hid); | |
765 H5Gclose (group_hid); | |
766 return false; | |
767 } | |
768 | |
769 double *dtmp = m.xdata (); | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
770 bool retval = false; |
5164 | 771 if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
772 H5P_DEFAULT, dtmp) >= 0 |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
773 && m.indices_ok ()) |
5164 | 774 { |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
775 retval = true; |
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
776 matrix = m; |
5164 | 777 } |
778 | |
779 H5Sclose (space_hid); | |
780 H5Dclose (data_hid); | |
781 H5Gclose (group_hid); | |
782 | |
9469
c6edba80dfae
sanity checks for loading sparse matrices
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
783 return retval; |
5164 | 784 } |
5900 | 785 |
5164 | 786 #endif |
787 | |
5900 | 788 mxArray * |
789 octave_sparse_matrix::as_mxArray (void) const | |
790 { | |
6686 | 791 mwSize nz = nzmax(); |
792 mwSize nr = rows(); | |
793 mwSize nc = columns(); | |
5903 | 794 mxArray *retval = new mxArray (mxDOUBLE_CLASS, nr, nc, nz, mxREAL); |
795 double *pr = static_cast<double *> (retval->get_data ()); | |
6686 | 796 mwIndex *ir = retval->get_ir(); |
797 mwIndex *jc = retval->get_jc(); | |
5903 | 798 |
6686 | 799 for (mwIndex i = 0; i < nz; i++) |
5903 | 800 { |
801 pr[i] = matrix.data(i); | |
802 ir[i] = matrix.ridx(i); | |
803 } | |
804 | |
6686 | 805 for (mwIndex i = 0; i < nc + 1; i++) |
5903 | 806 jc[i] = matrix.cidx(i); |
807 | |
808 return retval; | |
5900 | 809 } |
810 | |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
811 octave_value |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
812 octave_sparse_matrix::map (unary_mapper_t umap) const |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
813 { |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
814 switch (umap) |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
815 { |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
816 case umap_imag: |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
817 return SparseMatrix (matrix.rows (), matrix.cols (), 0.0); |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
818 |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
819 case umap_real: |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
820 case umap_conj: |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
821 return matrix; |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
822 |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
823 // Mappers handled specially. |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
824 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \ |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
825 case umap_ ## UMAP: \ |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
826 return octave_value (matrix.FCN ()) |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
827 |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
828 ARRAY_METHOD_MAPPER (abs, abs); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
829 |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
830 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \ |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
831 case umap_ ## UMAP: \ |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
832 return octave_value (matrix.map<TYPE> (FCN)) |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
833 |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
834 ARRAY_MAPPER (acos, Complex, rc_acos); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
835 ARRAY_MAPPER (acosh, Complex, rc_acosh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
836 ARRAY_MAPPER (angle, double, ::arg); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
837 ARRAY_MAPPER (arg, double, ::arg); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
838 ARRAY_MAPPER (asin, Complex, rc_asin); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
839 ARRAY_MAPPER (asinh, double, ::asinh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
840 ARRAY_MAPPER (atan, double, ::atan); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
841 ARRAY_MAPPER (atanh, Complex, rc_atanh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
842 ARRAY_MAPPER (erf, double, ::erf); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
843 ARRAY_MAPPER (erfc, double, ::erfc); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
844 ARRAY_MAPPER (gamma, double, xgamma); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
845 ARRAY_MAPPER (lgamma, Complex, rc_lgamma); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
846 ARRAY_MAPPER (ceil, double, ::ceil); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
847 ARRAY_MAPPER (cos, double, ::cos); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
848 ARRAY_MAPPER (cosh, double, ::cosh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
849 ARRAY_MAPPER (exp, double, ::exp); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
850 ARRAY_MAPPER (expm1, double, ::expm1); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
851 ARRAY_MAPPER (fix, double, ::fix); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
852 ARRAY_MAPPER (floor, double, ::floor); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
853 ARRAY_MAPPER (log, Complex, rc_log); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
854 ARRAY_MAPPER (log2, Complex, rc_log2); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
855 ARRAY_MAPPER (log10, Complex, rc_log10); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
856 ARRAY_MAPPER (log1p, Complex, rc_log1p); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
857 ARRAY_MAPPER (round, double, xround); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
858 ARRAY_MAPPER (roundb, double, xroundb); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
859 ARRAY_MAPPER (signum, double, ::signum); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
860 ARRAY_MAPPER (sin, double, ::sin); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
861 ARRAY_MAPPER (sinh, double, ::sinh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
862 ARRAY_MAPPER (sqrt, Complex, rc_sqrt); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
863 ARRAY_MAPPER (tan, double, ::tan); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
864 ARRAY_MAPPER (tanh, double, ::tanh); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
865 ARRAY_MAPPER (isnan, bool, xisnan); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
866 ARRAY_MAPPER (isna, bool, octave_is_NA); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
867 ARRAY_MAPPER (isinf, bool, xisinf); |
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
868 ARRAY_MAPPER (finite, bool, xfinite); |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
869 |
9812
f80c566bc751
improve unary mapper system
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
870 default: // Attempt to go via dense matrix. |
9813
8fa32b527d9a
improve & partially revert previous change
Jaroslav Hajek <highegg@gmail.com>
parents:
9812
diff
changeset
|
871 return octave_base_sparse<SparseMatrix>::map (umap); |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
872 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
873 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
874 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7193
diff
changeset
|
875 |
5164 | 876 /* |
877 ;;; Local Variables: *** | |
878 ;;; mode: C++ *** | |
879 ;;; End: *** | |
880 */ |