comparison libinterp/octave-value/ov-re-sparse.cc @ 15195:2fc554ffbc28

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