GNU Octave  4.0.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-cx-sparse.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2004-2015 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 "ov-complex.h"
40 #include "gripes.h"
41 
42 #include "oct-hdf5.h"
43 
44 #include "ov-re-sparse.h"
45 #include "ov-cx-sparse.h"
46 
47 #include "ov-base-sparse.h"
48 #include "ov-base-sparse.cc"
49 
50 #include "ov-bool-sparse.h"
51 
53 
54 
56  "sparse complex matrix", "double");
57 
60 {
61  octave_base_value *retval = 0;
62 
64  {
65  int nr = matrix.rows ();
66  int nc = matrix.cols ();
67 
68  // Don't use numel, since it can overflow for very large matrices
69  // Note that for the tests on matrix size, they become approximative
70  // since they involves a cast to double to avoid issues of overflow
71  if (matrix.rows () == 1 && matrix.cols () == 1)
72  {
73  // Const copy of the matrix, so the right version of () operator used
74  const SparseComplexMatrix tmp (matrix);
75 
76  Complex c = tmp (0, 0);
77 
78  if (std::imag (c) == 0.0)
79  retval = new octave_scalar (std::real (c));
80  else
81  retval = new octave_complex (c);
82  }
83  else if (nr == 0 || nc == 0)
84  retval = new octave_matrix (Matrix (nr, nc));
85  else if (matrix.all_elements_are_real ())
86  if (matrix.cols () > 0 && matrix.rows () > 0
87  && (double (matrix.byte_size ()) > double (matrix.rows ())
88  * double (matrix.cols ()) * sizeof (double)))
89  retval = new octave_matrix (::real (matrix.matrix_value ()));
90  else
91  retval = new octave_sparse_matrix (::real (matrix));
92  else if (matrix.cols () > 0 && matrix.rows () > 0
93  && (double (matrix.byte_size ()) > double (matrix.rows ())
94  * double (matrix.cols ()) * sizeof (Complex)))
95  retval = new octave_complex_matrix (matrix.matrix_value ());
96  }
97  else
98  {
100  retval = new octave_sparse_matrix (::real (matrix));
101  }
102 
103  return retval;
104 }
105 
106 double
107 octave_sparse_complex_matrix::double_value (bool force_conversion) const
108 {
109  double retval = lo_ieee_nan_value ();
110 
111  if (! force_conversion)
112  gripe_implicit_conversion ("Octave:imag-to-real",
113  "complex sparse matrix", "real scalar");
114 
115  // FIXME: maybe this should be a function, valid_as_scalar()
116  if (numel () > 0)
117  {
118  if (numel () > 1)
119  gripe_implicit_conversion ("Octave:array-to-scalar",
120  "complex sparse matrix", "real scalar");
121 
122  retval = std::real (matrix (0, 0));
123  }
124  else
125  gripe_invalid_conversion ("complex sparse matrix", "real scalar");
126 
127  return retval;
128 }
129 
130 Matrix
131 octave_sparse_complex_matrix::matrix_value (bool force_conversion) const
132 {
133  Matrix retval;
134 
135  if (! force_conversion)
136  gripe_implicit_conversion ("Octave:imag-to-real",
137  "complex sparse matrix", "real matrix");
138 
139  retval = ::real (matrix.matrix_value ());
140 
141  return retval;
142 }
143 
144 Complex
146 {
147  double tmp = lo_ieee_nan_value ();
148 
149  Complex retval (tmp, tmp);
150 
151  // FIXME: maybe this should be a function, valid_as_scalar()
152  if (numel () > 0)
153  {
154  if (numel () > 1)
155  gripe_implicit_conversion ("Octave:array-to-scalar",
156  "complex sparse matrix", "real scalar");
157 
158  retval = matrix (0, 0);
159  }
160  else
161  gripe_invalid_conversion ("complex sparse matrix", "real scalar");
162 
163  return retval;
164 }
165 
168 {
169  return matrix.matrix_value ();
170 }
171 
174 {
175  return ComplexNDArray (matrix.matrix_value ());
176 }
177 
180 {
181  charNDArray retval;
182 
183  if (! frc_str_conv)
184  gripe_implicit_conversion ("Octave:num-to-str",
185  "sparse complex matrix", "string");
186  else
187  {
188  retval = charNDArray (dims (), 0);
189  octave_idx_type nc = matrix.cols ();
190  octave_idx_type nr = matrix.rows ();
191 
192  for (octave_idx_type j = 0; j < nc; j++)
193  for (octave_idx_type i = matrix.cidx (j); i < matrix.cidx (j+1); i++)
194  retval(matrix.ridx (i) + nr * j) =
195  static_cast<char>(std::real (matrix.data (i)));
196  }
197 
198  return retval;
199 }
200 
203 {
204  SparseMatrix retval;
205 
206  if (! force_conversion)
207  gripe_implicit_conversion ("Octave:imag-to-real",
208  "complex sparse matrix",
209  "real sparse matrix");
210 
211  retval = ::real (matrix);
212 
213  return retval;
214 }
215 
218 {
219  if (matrix.any_element_is_nan ())
221  else if (warn && (! matrix.all_elements_are_real ()
222  || real (matrix).any_element_not_one_or_zero ()))
224 
225  return mx_el_ne (matrix, Complex (0.0));
226 }
227 
228 bool
230  bool&save_as_floats)
231 {
232  dim_vector d = this->dims ();
233  if (d.length () < 1)
234  return false;
235 
236  // Ensure that additional memory is deallocated
238 
239  int nr = d(0);
240  int nc = d(1);
241  int nz = nnz ();
242 
243  int32_t itmp;
244  // Use negative value for ndims to be consistent with other formats
245  itmp = -2;
246  os.write (reinterpret_cast<char *> (&itmp), 4);
247 
248  itmp = nr;
249  os.write (reinterpret_cast<char *> (&itmp), 4);
250 
251  itmp = nc;
252  os.write (reinterpret_cast<char *> (&itmp), 4);
253 
254  itmp = nz;
255  os.write (reinterpret_cast<char *> (&itmp), 4);
256 
257  save_type st = LS_DOUBLE;
258  if (save_as_floats)
259  {
261  {
262  warning ("save: some values too large to save as floats --");
263  warning ("save: saving as doubles instead");
264  }
265  else
266  st = LS_FLOAT;
267  }
268  else if (matrix.nnz () > 8192) // FIXME: make this configurable.
269  {
270  double max_val, min_val;
271  if (matrix.all_integers (max_val, min_val))
272  st = get_save_type (max_val, min_val);
273  }
274 
275  // add one to the printed indices to go from
276  // zero-based to one-based arrays
277  for (int i = 0; i < nc+1; i++)
278  {
279  octave_quit ();
280  itmp = matrix.cidx (i);
281  os.write (reinterpret_cast<char *> (&itmp), 4);
282  }
283 
284  for (int i = 0; i < nz; i++)
285  {
286  octave_quit ();
287  itmp = matrix.ridx (i);
288  os.write (reinterpret_cast<char *> (&itmp), 4);
289  }
290 
291  write_doubles (os, reinterpret_cast<const double *> (matrix.data ()), st,
292  2 * nz);
293 
294  return true;
295 }
296 
297 bool
298 octave_sparse_complex_matrix::load_binary (std::istream& is, bool swap,
300 {
301  int32_t nz, nc, nr, tmp;
302  char ctmp;
303 
304  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
305  return false;
306 
307  if (swap)
308  swap_bytes<4> (&tmp);
309 
310  if (tmp != -2)
311  {
312  error ("load: only 2-D sparse matrices are supported");
313  return false;
314  }
315 
316  if (! is.read (reinterpret_cast<char *> (&nr), 4))
317  return false;
318  if (! is.read (reinterpret_cast<char *> (&nc), 4))
319  return false;
320  if (! is.read (reinterpret_cast<char *> (&nz), 4))
321  return false;
322 
323  if (swap)
324  {
325  swap_bytes<4> (&nr);
326  swap_bytes<4> (&nc);
327  swap_bytes<4> (&nz);
328  }
329 
330  SparseComplexMatrix m (static_cast<octave_idx_type> (nr),
331  static_cast<octave_idx_type> (nc),
332  static_cast<octave_idx_type> (nz));
333 
334  for (int i = 0; i < nc+1; i++)
335  {
336  octave_quit ();
337  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
338  return false;
339  if (swap)
340  swap_bytes<4> (&tmp);
341  m.cidx (i) = tmp;
342  }
343 
344  for (int i = 0; i < nz; i++)
345  {
346  octave_quit ();
347  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
348  return false;
349  if (swap)
350  swap_bytes<4> (&tmp);
351  m.ridx (i) = tmp;
352  }
353 
354  if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
355  return false;
356 
357  read_doubles (is, reinterpret_cast<double *> (m.data ()),
358  static_cast<save_type> (ctmp), 2 * nz, swap, fmt);
359 
360  if (error_state || ! is)
361  return false;
362 
363  if (! m.indices_ok ())
364  return false;
365 
366  matrix = m;
367 
368  return true;
369 }
370 
371 bool
373  bool save_as_floats)
374 {
375  bool retval = false;
376 
377 #if defined (HAVE_HDF5)
378 
379  dim_vector dv = dims ();
380  int empty = save_hdf5_empty (loc_id, name, dv);
381  if (empty)
382  return (empty > 0);
383 
384  // Ensure that additional memory is deallocated
386 
387 #if HAVE_HDF5_18
388  hid_t group_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT,
389  H5P_DEFAULT);
390 #else
391  hid_t group_hid = H5Gcreate (loc_id, name, 0);
392 #endif
393  if (group_hid < 0)
394  return false;
395 
396  hid_t space_hid, data_hid;
397  space_hid = data_hid = -1;
399  octave_idx_type tmp;
400  hsize_t hdims[2];
401 
402  space_hid = H5Screate_simple (0, hdims, 0);
403  if (space_hid < 0)
404  {
405  H5Gclose (group_hid);
406  return false;
407  }
408 
409 #if HAVE_HDF5_18
410  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
411  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
412 #else
413  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
414  H5P_DEFAULT);
415 #endif
416  if (data_hid < 0)
417  {
418  H5Sclose (space_hid);
419  H5Gclose (group_hid);
420  return false;
421  }
422 
423  tmp = m.rows ();
424  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
425  H5P_DEFAULT, &tmp) >= 0;
426  H5Dclose (data_hid);
427  if (!retval)
428  {
429  H5Sclose (space_hid);
430  H5Gclose (group_hid);
431  return false;
432  }
433 
434 #if HAVE_HDF5_18
435  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
436  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
437 #else
438  data_hid = H5Dcreate (group_hid, "nc", 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.cols ();
449  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
450  H5P_DEFAULT, &tmp) >= 0;
451  H5Dclose (data_hid);
452  if (!retval)
453  {
454  H5Sclose (space_hid);
455  H5Gclose (group_hid);
456  return false;
457  }
458 
459 #if HAVE_HDF5_18
460  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
461  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
462 #else
463  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
464  H5P_DEFAULT);
465 #endif
466  if (data_hid < 0)
467  {
468  H5Sclose (space_hid);
469  H5Gclose (group_hid);
470  return false;
471  }
472 
473  tmp = m.nnz ();
474  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
475  H5P_DEFAULT, &tmp) >= 0;
476  H5Dclose (data_hid);
477  if (!retval)
478  {
479  H5Sclose (space_hid);
480  H5Gclose (group_hid);
481  return false;
482  }
483 
484  H5Sclose (space_hid);
485 
486  hdims[0] = m.cols () + 1;
487  hdims[1] = 1;
488 
489  space_hid = H5Screate_simple (2, hdims, 0);
490 
491  if (space_hid < 0)
492  {
493  H5Gclose (group_hid);
494  return false;
495  }
496 
497 #if HAVE_HDF5_18
498  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
499  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
500 #else
501  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
502  H5P_DEFAULT);
503 #endif
504  if (data_hid < 0)
505  {
506  H5Sclose (space_hid);
507  H5Gclose (group_hid);
508  return false;
509  }
510 
511  octave_idx_type * itmp = m.xcidx ();
512  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL,
513  H5P_DEFAULT, itmp) >= 0;
514  H5Dclose (data_hid);
515  if (!retval)
516  {
517  H5Sclose (space_hid);
518  H5Gclose (group_hid);
519  return false;
520  }
521 
522  H5Sclose (space_hid);
523 
524  hdims[0] = m.nnz ();
525  hdims[1] = 1;
526 
527  space_hid = H5Screate_simple (2, hdims, 0);
528 
529  if (space_hid < 0)
530  {
531  H5Gclose (group_hid);
532  return false;
533  }
534 
535 #if HAVE_HDF5_18
536  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
537  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
538 #else
539  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
540  H5P_DEFAULT);
541 #endif
542  if (data_hid < 0)
543  {
544  H5Sclose (space_hid);
545  H5Gclose (group_hid);
546  return false;
547  }
548 
549  itmp = m.xridx ();
550  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, H5S_ALL, H5S_ALL, H5P_DEFAULT,
551  itmp) >= 0;
552  H5Dclose (data_hid);
553  if (!retval)
554  {
555  H5Sclose (space_hid);
556  H5Gclose (group_hid);
557  return false;
558  }
559 
560  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
561 
562  if (save_as_floats)
563  {
564  if (m.too_large_for_float ())
565  {
566  warning ("save: some values too large to save as floats --");
567  warning ("save: saving as doubles instead");
568  }
569  else
570  save_type_hid = H5T_NATIVE_FLOAT;
571  }
572 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
573  // hdf5 currently doesn't support float/integer conversions
574  else
575  {
576  double max_val, min_val;
577 
578  if (m.all_integers (max_val, min_val))
579  save_type_hid
580  = save_type_to_hdf5 (get_save_type (max_val, min_val));
581  }
582 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
583 
584  hid_t type_hid = hdf5_make_complex_type (save_type_hid);
585  if (type_hid < 0)
586  {
587  H5Sclose (space_hid);
588  H5Gclose (group_hid);
589  return false;
590  }
591 #if HAVE_HDF5_18
592  data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid,
593  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
594 #else
595  data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid, H5P_DEFAULT);
596 #endif
597  if (data_hid < 0)
598  {
599  H5Sclose (space_hid);
600  H5Tclose (type_hid);
601  H5Gclose (group_hid);
602  return false;
603  }
604 
605  hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
606  retval = false;
607  if (complex_type_hid >= 0)
608  {
609  Complex * ctmp = m.xdata ();
610 
611  retval = H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL,
612  H5P_DEFAULT, ctmp) >= 0;
613  }
614 
615  H5Dclose (data_hid);
616  H5Sclose (space_hid);
617  H5Tclose (type_hid);
618  H5Gclose (group_hid);
619 
620 #else
621  gripe_save ("hdf5");
622 #endif
623 
624  return retval;
625 }
626 
627 bool
629 {
630  bool retval = false;
631 
632 #if defined (HAVE_HDF5)
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,
668  H5S_ALL, 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,
693  H5S_ALL, 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,
718  H5S_ALL, H5P_DEFAULT, &nz) < 0)
719  {
720  H5Dclose (data_hid);
721  H5Gclose (group_hid);
722  return false;
723  }
724 
725  H5Dclose (data_hid);
726 
727  SparseComplexMatrix 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,
763  H5S_ALL, 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
793  || static_cast<int> (hdims[1]) != 1)
794  {
795  H5Sclose (space_hid);
796  H5Dclose (data_hid);
797  H5Gclose (group_hid);
798  return false;
799  }
800 
801  itmp = m.xridx ();
802  if (H5Dread (data_hid, H5T_NATIVE_IDX, H5S_ALL,
803  H5S_ALL, H5P_DEFAULT, itmp) < 0)
804  {
805  H5Sclose (space_hid);
806  H5Dclose (data_hid);
807  H5Gclose (group_hid);
808  return false;
809  }
810 
811  H5Sclose (space_hid);
812  H5Dclose (data_hid);
813 
814 #if HAVE_HDF5_18
815  data_hid = H5Dopen (group_hid, "data", H5P_DEFAULT);
816 #else
817  data_hid = H5Dopen (group_hid, "data");
818 #endif
819  hid_t type_hid = H5Dget_type (data_hid);
820 
821  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
822 
823  if (! hdf5_types_compatible (type_hid, complex_type))
824  {
825  H5Tclose (complex_type);
826  H5Dclose (data_hid);
827  H5Gclose (group_hid);
828  return false;
829  }
830 
831  space_hid = H5Dget_space (data_hid);
832  rank = H5Sget_simple_extent_ndims (space_hid);
833 
834  if (rank != 2)
835  {
836  H5Sclose (space_hid);
837  H5Dclose (data_hid);
838  H5Gclose (group_hid);
839  return false;
840  }
841 
842  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
843 
844  if (static_cast<int> (hdims[0]) != nz
845  || static_cast<int> (hdims[1]) != 1)
846  {
847  H5Sclose (space_hid);
848  H5Dclose (data_hid);
849  H5Gclose (group_hid);
850  return false;
851  }
852 
853  Complex *ctmp = m.xdata ();
854 
855  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL,
856  H5P_DEFAULT, ctmp) >= 0
857  && m.indices_ok ())
858  {
859  retval = true;
860  matrix = m;
861  }
862 
863  H5Tclose (complex_type);
864  H5Sclose (space_hid);
865  H5Dclose (data_hid);
866  H5Gclose (group_hid);
867 
868 #else
869  gripe_load ("hdf5");
870 #endif
871 
872  return retval;
873 }
874 
875 mxArray *
877 {
878  mwSize nz = nzmax ();
879  mxArray *retval = new mxArray (mxDOUBLE_CLASS, rows (), columns (),
880  nz, mxCOMPLEX);
881  double *pr = static_cast<double *> (retval->get_data ());
882  double *pi = static_cast<double *> (retval->get_imag_data ());
883  mwIndex *ir = retval->get_ir ();
884  mwIndex *jc = retval->get_jc ();
885 
886  for (mwIndex i = 0; i < nz; i++)
887  {
888  Complex val = matrix.data (i);
889  pr[i] = std::real (val);
890  pi[i] = std::imag (val);
891  ir[i] = matrix.ridx (i);
892  }
893 
894  for (mwIndex i = 0; i < columns () + 1; i++)
895  jc[i] = matrix.cidx (i);
896 
897  return retval;
898 }
899 
902 {
903  switch (umap)
904  {
905  // Mappers handled specially.
906  case umap_real:
908  case umap_imag:
910 
911 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
912  case umap_ ## UMAP: \
913  return octave_value (matrix.FCN ())
914 
916 
917 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
918  case umap_ ## UMAP: \
919  return octave_value (matrix.map<TYPE> (FCN))
920 
923  ARRAY_MAPPER (angle, double, std::arg);
924  ARRAY_MAPPER (arg, double, std::arg);
929  ARRAY_MAPPER (erf, Complex, ::erf);
935  ARRAY_MAPPER (conj, Complex, std::conj<double>);
936  ARRAY_MAPPER (cos, Complex, std::cos);
937  ARRAY_MAPPER (cosh, Complex, std::cosh);
938  ARRAY_MAPPER (exp, Complex, std::exp);
940  ARRAY_MAPPER (fix, Complex, ::fix);
942  ARRAY_MAPPER (log, Complex, std::log);
943  ARRAY_MAPPER (log2, Complex, xlog2);
944  ARRAY_MAPPER (log10, Complex, std::log10);
946  ARRAY_MAPPER (round, Complex, xround);
947  ARRAY_MAPPER (roundb, Complex, xroundb);
949  ARRAY_MAPPER (sin, Complex, std::sin);
950  ARRAY_MAPPER (sinh, Complex, std::sinh);
951  ARRAY_MAPPER (sqrt, Complex, std::sqrt);
952  ARRAY_MAPPER (tan, Complex, std::tan);
953  ARRAY_MAPPER (tanh, Complex, std::tanh);
954  ARRAY_MAPPER (isnan, bool, xisnan);
955  ARRAY_MAPPER (isna, bool, octave_is_NA);
956  ARRAY_MAPPER (isinf, bool, xisinf);
957  ARRAY_MAPPER (finite, bool, xfinite);
958 
959  default: // Attempt to go via dense matrix.
961  }
962 }
save_type
Definition: data-conv.h:83
void gripe_implicit_conversion(const char *id, const char *from, const char *to)
Definition: gripes.cc:180
octave_idx_type * xridx(void)
Definition: Sparse.h:524
SparseMatrix sparse_matrix_value(bool=false) const
octave_idx_type cols(void) const
Definition: Sparse.h:264
bool hdf5_types_compatible(hid_t t1, hid_t t2)
Definition: ls-hdf5.cc:107
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
T * data(void)
Definition: Sparse.h:509
octave_idx_type rows(void) const
Definition: Sparse.h:263
double xround(double x)
Definition: lo-mappers.cc:63
ComplexMatrix matrix_value(void) const
Definition: CSparse.cc:673
octave_base_value * try_narrowing_conversion(void)
Definition: ov-cx-sparse.cc:59
bool xisnan(double x)
Definition: lo-mappers.cc:144
octave_idx_type columns(void) const
Definition: ov-base.h:301
double log1p(double x)
Definition: lo-specfun.cc:620
std::complex< double > erfi(std::complex< double > z, double relerr=0)
Complex complex_value(bool=false) const
void gripe_load(const char *type) const
Definition: ov-base.cc:1258
save_type get_save_type(double, double)
Definition: ls-utils.cc:35
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
function atanh(X)
Definition: atanh.f:2
octave_idx_type * xcidx(void)
Definition: Sparse.h:537
void error(const char *fmt,...)
Definition: error.cc:476
void * get_data(void) const
Definition: mxarray.h:433
bool xisinf(double x)
Definition: lo-mappers.cc:160
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
Definition: data-conv.cc:893
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:164
void gripe_save(const char *type) const
Definition: ov-base.cc:1267
bool load_binary(std::istream &is, bool swap, oct_mach_info::float_format fmt)
octave_idx_type * cidx(void)
Definition: Sparse.h:531
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:126
double expm1(double x)
Definition: lo-specfun.cc:510
SparseComplexMatrix sparse_complex_matrix_value(bool=false) const
Definition: ov-cx-sparse.h:123
double xlog2(double x)
Definition: lo-mappers.cc:93
bool indices_ok(void) const
Definition: Sparse.h:684
std::complex< double > erf(std::complex< double > z, double relerr=0)
octave_idx_type nzmax(void) const
F77_RET_T const double const double double * d
int load_hdf5_empty(hid_t loc_id, const char *name, dim_vector &d)
Definition: ls-hdf5.cc:790
octave_idx_type nnz(void) const
Definition: Sparse.h:248
hid_t hdf5_make_complex_type(hid_t num_type)
Definition: ls-hdf5.cc:228
double signum(double x)
Definition: lo-mappers.cc:80
mwIndex * get_ir(void) const
Definition: mxarray.h:442
#define ARRAY_MAPPER(UMAP, TYPE, FCN)
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:244
ComplexMatrix complex_matrix_value(bool=false) const
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:59
#define OCTINTERP_API
Definition: mexproto.h:66
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
octave_idx_type numel(void) const
function asinh(X)
Definition: asinh.f:2
Sparse< T > maybe_compress(bool remove_zeros=false)
Definition: Sparse.h:469
void gripe_nan_to_logical_conversion(void)
void resize(octave_idx_type r, octave_idx_type c)
Definition: Sparse.cc:944
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:275
double double_value(bool=false) const
octave_value map(octave_base_value::unary_mapper_t umap) const
int error_state
Definition: error.cc:101
size_t byte_size(void) const
Definition: Sparse.h:276
bool too_large_for_float(void) const
Definition: CSparse.cc:7257
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
double xroundb(double x)
Definition: lo-mappers.cc:69
boolMatrix mx_el_ne(const boolMatrix &m1, const boolMatrix &m2)
Definition: boolMatrix.cc:90
Definition: dMatrix.h:35
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, oct_mach_info::float_format fmt)
Definition: data-conv.cc:778
void mxArray
Definition: mex.h:53
function acosh(X)
Definition: acosh.f:2
charNDArray char_array_value(bool frc_str_conv=false) const
double arg(double x)
Definition: lo-mappers.h:37
mxArray * as_mxArray(void) const
void warning(const char *fmt,...)
Definition: error.cc:681
bool all_elements_are_real(void) const
Definition: CSparse.cc:7210
#define H5T_NATIVE_IDX
Definition: ls-hdf5.h:209
octave_idx_type * ridx(void)
Definition: Sparse.h:518
void gripe_logical_conversion(void)
Definition: gripes.cc:201
bool xfinite(double x)
Definition: lo-mappers.cc:152
bool any_element_is_nan(void) const
Definition: CSparse.cc:7178
void * get_imag_data(void) const
Definition: mxarray.h:435
void gripe_invalid_conversion(const std::string &from, const std::string &to)
Definition: gripes.cc:99
#define ARRAY_METHOD_MAPPER(UMAP, FCN)
T * xdata(void)
Definition: Sparse.h:511
int save_hdf5_empty(hid_t loc_id, const char *name, const dim_vector d)
Definition: ls-hdf5.cc:740
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:197
double fix(double x)
Definition: lo-mappers.h:39
mwIndex * get_jc(void) const
Definition: mxarray.h:444
bool Vsparse_auto_mutate
Definition: ov-base.cc:118
float dawson(float x)
Definition: lo-specfun.cc:349
Complex asin(const Complex &x)
Definition: lo-mappers.cc:204
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:162
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:282
octave_value map(unary_mapper_t umap) const
std::complex< double > Complex
Definition: oct-cmplx.h:29
Complex acos(const Complex &x)
Definition: lo-mappers.cc:177
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:156
Matrix matrix_value(bool=false) const
T abs(T x)
Definition: pr-output.cc:3062
bool save_binary(std::ostream &os, bool &save_as_floats)
int length(void) const
Definition: dim-vector.h:281
bool all_integers(double &max_val, double &min_val) const
Definition: CSparse.cc:7220
Complex atan(const Complex &x)
Definition: lo-mappers.cc:231
octave_idx_type rows(void) const
Definition: ov-base.h:294
ComplexNDArray complex_array_value(bool=false) const
bool octave_is_NA(double x)
Definition: lo-mappers.cc:167
std::complex< double > erfc(std::complex< double > z, double relerr=0)