GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-re-sparse.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2013 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 <iostream>
29 #include <limits>
30 #include <vector>
31 
32 #include "lo-specfun.h"
33 #include "lo-mappers.h"
34 #include "oct-locbuf.h"
35 
36 #include "mxarray.h"
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 
51 
53 
55  "double");
56 
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 
72 {
73  octave_base_value *retval = 0;
74 
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
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
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
139 {
140  return matrix.matrix_value ();
141 }
142 
145 {
146  NDArray m = matrix.matrix_value ();
147 
148  if (m.any_element_is_nan ())
150  else if (warn && m.any_element_not_one_or_zero ())
152 
153  return boolNDArray (m);
154 }
155 
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 
172 {
173  return ComplexMatrix (matrix.matrix_value ());
174 }
175 
178 {
180 }
181 
182 NDArray
184 {
185  return NDArray (matrix.matrix_value ());
186 }
187 
190 {
191  if (matrix.any_element_is_nan ())
193  else if (warn && matrix.any_element_not_one_or_zero ())
195 
196  return mx_el_ne (matrix, 0.0);
197 }
198 
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  {
230  return retval;
231  }
232  else
233  {
234  int ival = NINT (d);
235 
236  if (ival < 0
238  {
239  // FIXME: is there something 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
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  {
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,
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  {
343  error ("load: only 2-D sparse matrices are supported");
344  return false;
345  }
346 
347  if (! is.read (reinterpret_cast<char *> (&nr), 4))
348  return false;
349  if (! is.read (reinterpret_cast<char *> (&nc), 4))
350  return false;
351  if (! is.read (reinterpret_cast<char *> (&nz), 4))
352  return false;
353 
354  if (swap)
355  {
356  swap_bytes<4> (&nr);
357  swap_bytes<4> (&nc);
358  swap_bytes<4> (&nz);
359  }
360 
361  SparseMatrix m (static_cast<octave_idx_type> (nr),
362  static_cast<octave_idx_type> (nc),
363  static_cast<octave_idx_type> (nz));
364 
365  for (int i = 0; i < nc+1; i++)
366  {
367  octave_quit ();
368  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
369  return false;
370  if (swap)
371  swap_bytes<4> (&tmp);
372  m.xcidx (i) = tmp;
373  }
374 
375  for (int i = 0; i < nz; i++)
376  {
377  octave_quit ();
378  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
379  return false;
380  if (swap)
381  swap_bytes<4> (&tmp);
382  m.xridx (i) = tmp;
383  }
384 
385  if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
386  return false;
387 
388  read_doubles (is, m.xdata (), static_cast<save_type> (ctmp), nz, swap, fmt);
389 
390  if (error_state || ! is)
391  return false;
392 
393  if (! m.indices_ok ())
394  return false;
395 
396  matrix = m;
397 
398  return true;
399 }
400 
401 #if defined (HAVE_HDF5)
402 
403 bool
404 octave_sparse_matrix::save_hdf5 (hid_t loc_id, const char *name,
405  bool save_as_floats)
406 {
407  dim_vector dv = dims ();
408  int empty = save_hdf5_empty (loc_id, name, dv);
409  if (empty)
410  return (empty > 0);
411 
412  // Ensure that additional memory is deallocated
414 
415 #if HAVE_HDF5_18
416  hid_t group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT,
417  H5P_DEFAULT);
418 #else
419  hid_t group_hid = H5Gcreate (loc_id, name, 0);
420 #endif
421  if (group_hid < 0)
422  return false;
423 
424  hid_t space_hid = -1, data_hid = -1;
425  bool retval = true;
427  octave_idx_type tmp;
428  hsize_t hdims[2];
429 
430  space_hid = H5Screate_simple (0, hdims, 0);
431  if (space_hid < 0)
432  {
433  H5Gclose (group_hid);
434  return false;
435  }
436 #if HAVE_HDF5_18
437  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
438  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
439 #else
440  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
441  H5P_DEFAULT);
442 #endif
443  if (data_hid < 0)
444  {
445  H5Sclose (space_hid);
446  H5Gclose (group_hid);
447  return false;
448  }
449 
450  tmp = m.rows ();
451  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
452  &tmp) >= 0;
453  H5Dclose (data_hid);
454  if (!retval)
455  {
456  H5Sclose (space_hid);
457  H5Gclose (group_hid);
458  return false;
459  }
460 #if HAVE_HDF5_18
461  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
462  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
463 #else
464  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
465  H5P_DEFAULT);
466 #endif
467  if (data_hid < 0)
468  {
469  H5Sclose (space_hid);
470  H5Gclose (group_hid);
471  return false;
472  }
473 
474  tmp = m.cols ();
475  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
476  &tmp) >= 0;
477  H5Dclose (data_hid);
478  if (!retval)
479  {
480  H5Sclose (space_hid);
481  H5Gclose (group_hid);
482  return false;
483  }
484 
485 #if HAVE_HDF5_18
486  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
487  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
488 #else
489  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
490  H5P_DEFAULT);
491 #endif
492  if (data_hid < 0)
493  {
494  H5Sclose (space_hid);
495  H5Gclose (group_hid);
496  return false;
497  }
498 
499  tmp = m.nnz ();
500  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
501  &tmp) >= 0;
502  H5Dclose (data_hid);
503  if (!retval)
504  {
505  H5Sclose (space_hid);
506  H5Gclose (group_hid);
507  return false;
508  }
509 
510  H5Sclose (space_hid);
511 
512  hdims[0] = m.cols () + 1;
513  hdims[1] = 1;
514 
515  space_hid = H5Screate_simple (2, hdims, 0);
516 
517  if (space_hid < 0)
518  {
519  H5Gclose (group_hid);
520  return false;
521  }
522 
523 #if HAVE_HDF5_18
524  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
525  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
526 #else
527  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
528  H5P_DEFAULT);
529 #endif
530  if (data_hid < 0)
531  {
532  H5Sclose (space_hid);
533  H5Gclose (group_hid);
534  return false;
535  }
536 
537  octave_idx_type * itmp = m.xcidx ();
538  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
539  itmp) >= 0;
540  H5Dclose (data_hid);
541  if (!retval)
542  {
543  H5Sclose (space_hid);
544  H5Gclose (group_hid);
545  return false;
546  }
547 
548  H5Sclose (space_hid);
549 
550  hdims[0] = m.nnz ();
551  hdims[1] = 1;
552 
553  space_hid = H5Screate_simple (2, hdims, 0);
554 
555  if (space_hid < 0)
556  {
557  H5Gclose (group_hid);
558  return false;
559  }
560 #if HAVE_HDF5_18
561  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
562  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
563 #else
564  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
565  H5P_DEFAULT);
566 #endif
567  if (data_hid < 0)
568  {
569  H5Sclose (space_hid);
570  H5Gclose (group_hid);
571  return false;
572  }
573 
574  itmp = m.xridx ();
575  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
576  itmp) >= 0;
577  H5Dclose (data_hid);
578  if (!retval)
579  {
580  H5Sclose (space_hid);
581  H5Gclose (group_hid);
582  return false;
583  }
584 
585  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
586 
587  if (save_as_floats)
588  {
589  if (m.too_large_for_float ())
590  {
591  warning ("save: some values too large to save as floats --");
592  warning ("save: saving as doubles instead");
593  }
594  else
595  save_type_hid = H5T_NATIVE_FLOAT;
596  }
597 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
598  // hdf5 currently doesn't support float/integer conversions
599  else
600  {
601  double max_val, min_val;
602 
603  if (m.all_integers (max_val, min_val))
604  save_type_hid
605  = save_type_to_hdf5 (get_save_type (max_val, min_val));
606  }
607 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
608 
609 #if HAVE_HDF5_18
610  data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid,
611  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
612 #else
613  data_hid = H5Dcreate (group_hid, "data", save_type_hid, space_hid,
614  H5P_DEFAULT);
615 #endif
616  if (data_hid < 0)
617  {
618  H5Sclose (space_hid);
619  H5Gclose (group_hid);
620  return false;
621  }
622 
623  double * dtmp = m.xdata ();
624  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
625  H5P_DEFAULT, dtmp) >= 0;
626  H5Dclose (data_hid);
627  H5Sclose (space_hid);
628  H5Gclose (group_hid);
629 
630  return retval;
631 }
632 
633 bool
634 octave_sparse_matrix::load_hdf5 (hid_t loc_id, const char *name)
635 {
636  octave_idx_type nr, nc, nz;
637  hid_t group_hid, data_hid, space_hid;
638  hsize_t rank;
639 
640  dim_vector dv;
641  int empty = load_hdf5_empty (loc_id, name, dv);
642  if (empty > 0)
643  matrix.resize (dv);
644  if (empty)
645  return (empty > 0);
646 
647 #if HAVE_HDF5_18
648  group_hid = H5Gopen (loc_id, name, H5P_DEFAULT);
649 #else
650  group_hid = H5Gopen (loc_id, name);
651 #endif
652  if (group_hid < 0) return false;
653 
654 #if HAVE_HDF5_18
655  data_hid = H5Dopen (group_hid, "nr", H5P_DEFAULT);
656 #else
657  data_hid = H5Dopen (group_hid, "nr");
658 #endif
659  space_hid = H5Dget_space (data_hid);
660  rank = H5Sget_simple_extent_ndims (space_hid);
661 
662  if (rank != 0)
663  {
664  H5Dclose (data_hid);
665  H5Gclose (group_hid);
666  return false;
667  }
668 
669  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
670  H5P_DEFAULT, &nr) < 0)
671  {
672  H5Dclose (data_hid);
673  H5Gclose (group_hid);
674  return false;
675  }
676 
677  H5Dclose (data_hid);
678 
679 #if HAVE_HDF5_18
680  data_hid = H5Dopen (group_hid, "nc", H5P_DEFAULT);
681 #else
682  data_hid = H5Dopen (group_hid, "nc");
683 #endif
684  space_hid = H5Dget_space (data_hid);
685  rank = H5Sget_simple_extent_ndims (space_hid);
686 
687  if (rank != 0)
688  {
689  H5Dclose (data_hid);
690  H5Gclose (group_hid);
691  return false;
692  }
693 
694  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
695  H5P_DEFAULT, &nc) < 0)
696  {
697  H5Dclose (data_hid);
698  H5Gclose (group_hid);
699  return false;
700  }
701 
702  H5Dclose (data_hid);
703 
704 #if HAVE_HDF5_18
705  data_hid = H5Dopen (group_hid, "nz", H5P_DEFAULT);
706 #else
707  data_hid = H5Dopen (group_hid, "nz");
708 #endif
709  space_hid = H5Dget_space (data_hid);
710  rank = H5Sget_simple_extent_ndims (space_hid);
711 
712  if (rank != 0)
713  {
714  H5Dclose (data_hid);
715  H5Gclose (group_hid);
716  return false;
717  }
718 
719  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
720  H5P_DEFAULT, &nz) < 0)
721  {
722  H5Dclose (data_hid);
723  H5Gclose (group_hid);
724  return false;
725  }
726 
727  H5Dclose (data_hid);
728 
729  SparseMatrix m (static_cast<octave_idx_type> (nr),
730  static_cast<octave_idx_type> (nc),
731  static_cast<octave_idx_type> (nz));
732 
733 #if HAVE_HDF5_18
734  data_hid = H5Dopen (group_hid, "cidx", H5P_DEFAULT);
735 #else
736  data_hid = H5Dopen (group_hid, "cidx");
737 #endif
738  space_hid = H5Dget_space (data_hid);
739  rank = H5Sget_simple_extent_ndims (space_hid);
740 
741  if (rank != 2)
742  {
743  H5Sclose (space_hid);
744  H5Dclose (data_hid);
745  H5Gclose (group_hid);
746  return false;
747  }
748 
749  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
750  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
751 
752  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
753 
754  if (static_cast<int> (hdims[0]) != nc + 1
755  || static_cast<int> (hdims[1]) != 1)
756  {
757  H5Sclose (space_hid);
758  H5Dclose (data_hid);
759  H5Gclose (group_hid);
760  return false;
761  }
762 
763  octave_idx_type *itmp = m.xcidx ();
764  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
765  H5P_DEFAULT, itmp) < 0)
766  {
767  H5Sclose (space_hid);
768  H5Dclose (data_hid);
769  H5Gclose (group_hid);
770  return false;
771  }
772 
773  H5Sclose (space_hid);
774  H5Dclose (data_hid);
775 
776 #if HAVE_HDF5_18
777  data_hid = H5Dopen (group_hid, "ridx", H5P_DEFAULT);
778 #else
779  data_hid = H5Dopen (group_hid, "ridx");
780 #endif
781  space_hid = H5Dget_space (data_hid);
782  rank = H5Sget_simple_extent_ndims (space_hid);
783 
784  if (rank != 2)
785  {
786  H5Sclose (space_hid);
787  H5Dclose (data_hid);
788  H5Gclose (group_hid);
789  return false;
790  }
791 
792  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
793 
794  if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
795  {
796  H5Sclose (space_hid);
797  H5Dclose (data_hid);
798  H5Gclose (group_hid);
799  return false;
800  }
801 
802  itmp = m.xridx ();
803  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
804  H5P_DEFAULT, itmp) < 0)
805  {
806  H5Sclose (space_hid);
807  H5Dclose (data_hid);
808  H5Gclose (group_hid);
809  return false;
810  }
811 
812  H5Sclose (space_hid);
813  H5Dclose (data_hid);
814 
815 #if HAVE_HDF5_18
816  data_hid = H5Dopen (group_hid, "data", H5P_DEFAULT);
817 #else
818  data_hid = H5Dopen (group_hid, "data");
819 #endif
820  space_hid = H5Dget_space (data_hid);
821  rank = H5Sget_simple_extent_ndims (space_hid);
822 
823  if (rank != 2)
824  {
825  H5Sclose (space_hid);
826  H5Dclose (data_hid);
827  H5Gclose (group_hid);
828  return false;
829  }
830 
831  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
832 
833  if (static_cast<int> (hdims[0]) != nz || static_cast<int> (hdims[1]) != 1)
834  {
835  H5Sclose (space_hid);
836  H5Dclose (data_hid);
837  H5Gclose (group_hid);
838  return false;
839  }
840 
841  double *dtmp = m.xdata ();
842  bool retval = false;
843  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
844  H5P_DEFAULT, dtmp) >= 0
845  && m.indices_ok ())
846  {
847  retval = true;
848  matrix = m;
849  }
850 
851  H5Sclose (space_hid);
852  H5Dclose (data_hid);
853  H5Gclose (group_hid);
854 
855  return retval;
856 }
857 
858 #endif
859 
860 mxArray *
862 {
863  mwSize nz = nzmax ();
864  mwSize nr = rows ();
865  mwSize nc = columns ();
866  mxArray *retval = new mxArray (mxDOUBLE_CLASS, nr, nc, nz, mxREAL);
867  double *pr = static_cast<double *> (retval->get_data ());
868  mwIndex *ir = retval->get_ir ();
869  mwIndex *jc = retval->get_jc ();
870 
871  for (mwIndex i = 0; i < nz; i++)
872  {
873  pr[i] = matrix.data (i);
874  ir[i] = matrix.ridx (i);
875  }
876 
877  for (mwIndex i = 0; i < nc + 1; i++)
878  jc[i] = matrix.cidx (i);
879 
880  return retval;
881 }
882 
885 {
886  switch (umap)
887  {
888  case umap_imag:
889  return SparseMatrix (matrix.rows (), matrix.cols (), 0.0);
890 
891  case umap_real:
892  case umap_conj:
893  return matrix;
894 
895  // Mappers handled specially.
896 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
897  case umap_ ## UMAP: \
898  return octave_value (matrix.FCN ())
899 
901 
902 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
903  case umap_ ## UMAP: \
904  return octave_value (matrix.map<TYPE> (FCN))
905 
908  ARRAY_MAPPER (angle, double, ::arg);
909  ARRAY_MAPPER (arg, double, ::arg);
911  ARRAY_MAPPER (asinh, double, ::asinh);
912  ARRAY_MAPPER (atan, double, ::atan);
914  ARRAY_MAPPER (erf, double, ::erf);
915  ARRAY_MAPPER (erfinv, double, ::erfinv);
916  ARRAY_MAPPER (erfcinv, double, ::erfcinv);
917  ARRAY_MAPPER (erfc, double, ::erfc);
918  ARRAY_MAPPER (erfcx, double, ::erfcx);
919  ARRAY_MAPPER (erfi, double, ::erfi);
920  ARRAY_MAPPER (dawson, double, ::dawson);
921  ARRAY_MAPPER (gamma, double, xgamma);
922  ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
923  ARRAY_MAPPER (cbrt, double, ::cbrt);
924  ARRAY_MAPPER (ceil, double, ::ceil);
925  ARRAY_MAPPER (cos, double, ::cos);
926  ARRAY_MAPPER (cosh, double, ::cosh);
927  ARRAY_MAPPER (exp, double, ::exp);
928  ARRAY_MAPPER (expm1, double, ::expm1);
929  ARRAY_MAPPER (fix, double, ::fix);
930  ARRAY_MAPPER (floor, double, ::floor);
931  ARRAY_MAPPER (log, Complex, rc_log);
932  ARRAY_MAPPER (log2, Complex, rc_log2);
933  ARRAY_MAPPER (log10, Complex, rc_log10);
935  ARRAY_MAPPER (round, double, xround);
936  ARRAY_MAPPER (roundb, double, xroundb);
937  ARRAY_MAPPER (signum, double, ::signum);
938  ARRAY_MAPPER (sin, double, ::sin);
939  ARRAY_MAPPER (sinh, double, ::sinh);
940  ARRAY_MAPPER (sqrt, Complex, rc_sqrt);
941  ARRAY_MAPPER (tan, double, ::tan);
942  ARRAY_MAPPER (tanh, double, ::tanh);
943  ARRAY_MAPPER (isnan, bool, xisnan);
944  ARRAY_MAPPER (isna, bool, octave_is_NA);
945  ARRAY_MAPPER (isinf, bool, xisinf);
946  ARRAY_MAPPER (finite, bool, xfinite);
947 
948  default: // Attempt to go via dense matrix.
950  }
951 }