GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-cx-sparse.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1998-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <istream>
31 #include <ostream>
32 #include <vector>
33 
34 #include "lo-specfun.h"
35 #include "lo-mappers.h"
36 #include "oct-locbuf.h"
37 
38 #include "mxarray.h"
39 #include "ov-base.h"
40 #include "ov-scalar.h"
41 #include "ov-complex.h"
42 #include "errwarn.h"
43 
44 #include "oct-hdf5.h"
45 
46 #include "ov-re-sparse.h"
47 #include "ov-cx-sparse.h"
48 
49 #include "ov-base-sparse.h"
50 #include "ov-base-sparse.cc"
51 
52 #include "ov-bool-sparse.h"
53 
54 
56 
58  "sparse complex matrix", "double");
59 
62 {
63  return (matrix.all_elements_are_real ()
64  ? new octave_sparse_matrix (::real (matrix)) : nullptr);
65 }
66 
67 double
68 octave_sparse_complex_matrix::double_value (bool force_conversion) const
69 {
70  if (! force_conversion)
71  warn_implicit_conversion ("Octave:imag-to-real",
72  "complex sparse matrix", "real scalar");
73 
74  // FIXME: maybe this should be a function, valid_as_scalar()
75  if (isempty ())
76  err_invalid_conversion ("complex sparse matrix", "real scalar");
77 
78  if (numel () > 1)
79  warn_implicit_conversion ("Octave:array-to-scalar",
80  "complex sparse matrix", "real scalar");
81 
82  return std::real (matrix(0, 0));
83 }
84 
85 Matrix
86 octave_sparse_complex_matrix::matrix_value (bool force_conversion) const
87 {
88  Matrix retval;
89 
90  if (! force_conversion)
91  warn_implicit_conversion ("Octave:imag-to-real",
92  "complex sparse matrix", "real matrix");
93 
94  retval = ::real (matrix.matrix_value ());
95 
96  return retval;
97 }
98 
99 Complex
101 {
102  // FIXME: maybe this should be a function, valid_as_scalar()
103  if (isempty ())
104  err_invalid_conversion ("complex sparse matrix", "real scalar");
105 
106  if (numel () > 1)
107  warn_implicit_conversion ("Octave:array-to-scalar",
108  "complex sparse matrix", "real scalar");
109 
110  return matrix(0, 0);
111 }
112 
115 {
116  return matrix.matrix_value ();
117 }
118 
121 {
122  return ComplexNDArray (matrix.matrix_value ());
123 }
124 
127 {
128  charNDArray retval;
129 
130  if (! frc_str_conv)
131  warn_implicit_conversion ("Octave:num-to-str",
132  "sparse complex matrix", "string");
133  else
134  {
135  retval = charNDArray (dims (), 0);
136  octave_idx_type nc = matrix.cols ();
137  octave_idx_type nr = matrix.rows ();
138 
139  for (octave_idx_type j = 0; j < nc; j++)
140  for (octave_idx_type i = matrix.cidx (j); i < matrix.cidx (j+1); i++)
141  retval(matrix.ridx (i) + nr * j)
142  = static_cast<char> (std::real (matrix.data (i)));
143  }
144 
145  return retval;
146 }
147 
150 {
151  SparseMatrix retval;
152 
153  if (! force_conversion)
154  warn_implicit_conversion ("Octave:imag-to-real",
155  "complex sparse matrix",
156  "real sparse matrix");
157 
158  retval = ::real (matrix);
159 
160  return retval;
161 }
162 
165 {
166  if (matrix.any_element_is_nan ())
168  if (warn && (! matrix.all_elements_are_real ()
169  || real (matrix).any_element_not_one_or_zero ()))
171 
172  return mx_el_ne (matrix, Complex (0.0));
173 }
174 
177 {
178  return this->matrix;
179 }
180 
181 bool
183  bool save_as_floats)
184 {
185  dim_vector dv = this->dims ();
186  if (dv.ndims () < 1)
187  return false;
188 
189  // Ensure that additional memory is deallocated
191 
192  int nr = dv(0);
193  int nc = dv(1);
194  int nz = nnz ();
195 
196  int32_t itmp;
197  // Use negative value for ndims to be consistent with other formats
198  itmp = -2;
199  os.write (reinterpret_cast<char *> (&itmp), 4);
200 
201  itmp = nr;
202  os.write (reinterpret_cast<char *> (&itmp), 4);
203 
204  itmp = nc;
205  os.write (reinterpret_cast<char *> (&itmp), 4);
206 
207  itmp = nz;
208  os.write (reinterpret_cast<char *> (&itmp), 4);
209 
210  save_type st = LS_DOUBLE;
211  if (save_as_floats)
212  {
214  {
215  warning ("save: some values too large to save as floats --");
216  warning ("save: saving as doubles instead");
217  }
218  else
219  st = LS_FLOAT;
220  }
221  else if (matrix.nnz () > 8192) // FIXME: make this configurable.
222  {
223  double max_val, min_val;
224  if (matrix.all_integers (max_val, min_val))
225  st = octave::get_save_type (max_val, min_val);
226  }
227 
228  // add one to the printed indices to go from
229  // zero-based to one-based arrays
230  for (int i = 0; i < nc+1; i++)
231  {
232  octave_quit ();
233  itmp = matrix.cidx (i);
234  os.write (reinterpret_cast<char *> (&itmp), 4);
235  }
236 
237  for (int i = 0; i < nz; i++)
238  {
239  octave_quit ();
240  itmp = matrix.ridx (i);
241  os.write (reinterpret_cast<char *> (&itmp), 4);
242  }
243 
244  write_doubles (os, reinterpret_cast<const double *> (matrix.data ()), st,
245  2 * nz);
246 
247  return true;
248 }
249 
250 bool
251 octave_sparse_complex_matrix::load_binary (std::istream& is, bool swap,
253 {
254  int32_t nz, nc, nr, tmp;
255  char ctmp;
256 
257  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
258  return false;
259 
260  if (swap)
261  swap_bytes<4> (&tmp);
262 
263  if (tmp != -2)
264  error ("load: only 2-D sparse matrices are supported");
265 
266  if (! is.read (reinterpret_cast<char *> (&nr), 4))
267  return false;
268  if (! is.read (reinterpret_cast<char *> (&nc), 4))
269  return false;
270  if (! is.read (reinterpret_cast<char *> (&nz), 4))
271  return false;
272 
273  if (swap)
274  {
275  swap_bytes<4> (&nr);
276  swap_bytes<4> (&nc);
277  swap_bytes<4> (&nz);
278  }
279 
280  SparseComplexMatrix m (static_cast<octave_idx_type> (nr),
281  static_cast<octave_idx_type> (nc),
282  static_cast<octave_idx_type> (nz));
283 
284  for (int i = 0; i < nc+1; i++)
285  {
286  octave_quit ();
287  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
288  return false;
289  if (swap)
290  swap_bytes<4> (&tmp);
291  m.cidx (i) = tmp;
292  }
293 
294  for (int i = 0; i < nz; i++)
295  {
296  octave_quit ();
297  if (! is.read (reinterpret_cast<char *> (&tmp), 4))
298  return false;
299  if (swap)
300  swap_bytes<4> (&tmp);
301  m.ridx (i) = tmp;
302  }
303 
304  if (! is.read (reinterpret_cast<char *> (&ctmp), 1))
305  return false;
306 
307  read_doubles (is, reinterpret_cast<double *> (m.data ()),
308  static_cast<save_type> (ctmp), 2 * nz, swap, fmt);
309 
310  if (! is)
311  return false;
312 
313  if (! m.indices_ok ())
314  return false;
315 
316  matrix = m;
317 
318  return true;
319 }
320 
321 bool
323  const char *name,
324  bool save_as_floats)
325 {
326  bool retval = false;
327 
328 #if defined (HAVE_HDF5)
329 
330  dim_vector dv = dims ();
331  int empty = save_hdf5_empty (loc_id, name, dv);
332  if (empty)
333  return (empty > 0);
334 
335  // Ensure that additional memory is deallocated
337 
338 #if defined (HAVE_HDF5_18)
339  hid_t group_hid = H5Gcreate (loc_id, name, octave_H5P_DEFAULT,
341 #else
342  hid_t group_hid = H5Gcreate (loc_id, name, 0);
343 #endif
344  if (group_hid < 0)
345  return false;
346 
347  hid_t space_hid, data_hid;
348  space_hid = data_hid = -1;
350  octave_idx_type tmp;
351  hsize_t hdims[2];
352 
353  space_hid = H5Screate_simple (0, hdims, nullptr);
354  if (space_hid < 0)
355  {
356  H5Gclose (group_hid);
357  return false;
358  }
359 
360 #if defined (HAVE_HDF5_18)
361  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
364 #else
365  data_hid = H5Dcreate (group_hid, "nr", H5T_NATIVE_IDX, space_hid,
367 #endif
368  if (data_hid < 0)
369  {
370  H5Sclose (space_hid);
371  H5Gclose (group_hid);
372  return false;
373  }
374 
375  tmp = m.rows ();
376  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
377  octave_H5P_DEFAULT, &tmp) >= 0;
378  H5Dclose (data_hid);
379  if (! retval)
380  {
381  H5Sclose (space_hid);
382  H5Gclose (group_hid);
383  return false;
384  }
385 
386 #if defined (HAVE_HDF5_18)
387  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
390 #else
391  data_hid = H5Dcreate (group_hid, "nc", H5T_NATIVE_IDX, space_hid,
393 #endif
394  if (data_hid < 0)
395  {
396  H5Sclose (space_hid);
397  H5Gclose (group_hid);
398  return false;
399  }
400 
401  tmp = m.cols ();
402  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
403  octave_H5P_DEFAULT, &tmp) >= 0;
404  H5Dclose (data_hid);
405  if (! retval)
406  {
407  H5Sclose (space_hid);
408  H5Gclose (group_hid);
409  return false;
410  }
411 
412 #if defined (HAVE_HDF5_18)
413  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
416 #else
417  data_hid = H5Dcreate (group_hid, "nz", H5T_NATIVE_IDX, space_hid,
419 #endif
420  if (data_hid < 0)
421  {
422  H5Sclose (space_hid);
423  H5Gclose (group_hid);
424  return false;
425  }
426 
427  tmp = m.nnz ();
428  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
429  octave_H5P_DEFAULT, &tmp) >= 0;
430  H5Dclose (data_hid);
431  if (! retval)
432  {
433  H5Sclose (space_hid);
434  H5Gclose (group_hid);
435  return false;
436  }
437 
438  H5Sclose (space_hid);
439 
440  hdims[0] = m.cols () + 1;
441  hdims[1] = 1;
442 
443  space_hid = H5Screate_simple (2, hdims, nullptr);
444 
445  if (space_hid < 0)
446  {
447  H5Gclose (group_hid);
448  return false;
449  }
450 
451 #if defined (HAVE_HDF5_18)
452  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
455 #else
456  data_hid = H5Dcreate (group_hid, "cidx", H5T_NATIVE_IDX, space_hid,
458 #endif
459  if (data_hid < 0)
460  {
461  H5Sclose (space_hid);
462  H5Gclose (group_hid);
463  return false;
464  }
465 
466  octave_idx_type *itmp = m.xcidx ();
467  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
468  octave_H5P_DEFAULT, itmp) >= 0;
469  H5Dclose (data_hid);
470  if (! retval)
471  {
472  H5Sclose (space_hid);
473  H5Gclose (group_hid);
474  return false;
475  }
476 
477  H5Sclose (space_hid);
478 
479  hdims[0] = m.nnz ();
480  hdims[1] = 1;
481 
482  space_hid = H5Screate_simple (2, hdims, nullptr);
483 
484  if (space_hid < 0)
485  {
486  H5Gclose (group_hid);
487  return false;
488  }
489 
490 #if defined (HAVE_HDF5_18)
491  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
494 #else
495  data_hid = H5Dcreate (group_hid, "ridx", H5T_NATIVE_IDX, space_hid,
497 #endif
498  if (data_hid < 0)
499  {
500  H5Sclose (space_hid);
501  H5Gclose (group_hid);
502  return false;
503  }
504 
505  itmp = m.xridx ();
506  retval = H5Dwrite (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL, octave_H5S_ALL,
507  octave_H5P_DEFAULT, itmp) >= 0;
508  H5Dclose (data_hid);
509  if (! retval)
510  {
511  H5Sclose (space_hid);
512  H5Gclose (group_hid);
513  return false;
514  }
515 
516  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
517 
518  if (save_as_floats)
519  {
520  if (m.too_large_for_float ())
521  {
522  warning ("save: some values too large to save as floats --");
523  warning ("save: saving as doubles instead");
524  }
525  else
526  save_type_hid = H5T_NATIVE_FLOAT;
527  }
528 #if defined (HAVE_HDF5_INT2FLOAT_CONVERSIONS)
529  // hdf5 currently doesn't support float/integer conversions
530  else
531  {
532  double max_val, min_val;
533 
534  if (m.all_integers (max_val, min_val))
535  save_type_hid
536  = save_type_to_hdf5 (octave::get_save_type (max_val, min_val));
537  }
538 #endif
539 
540  hid_t type_hid = hdf5_make_complex_type (save_type_hid);
541  if (type_hid < 0)
542  {
543  H5Sclose (space_hid);
544  H5Gclose (group_hid);
545  return false;
546  }
547 #if defined (HAVE_HDF5_18)
548  data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid,
551 #else
552  data_hid = H5Dcreate (group_hid, "data", type_hid, space_hid,
554 #endif
555  if (data_hid < 0)
556  {
557  H5Sclose (space_hid);
558  H5Tclose (type_hid);
559  H5Gclose (group_hid);
560  return false;
561  }
562 
563  hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
564  retval = false;
565  if (complex_type_hid >= 0)
566  {
567  Complex *ctmp = m.xdata ();
568 
569  retval = H5Dwrite (data_hid, complex_type_hid, octave_H5S_ALL,
570  octave_H5S_ALL, octave_H5P_DEFAULT, ctmp) >= 0;
571  }
572 
573  H5Dclose (data_hid);
574  H5Sclose (space_hid);
575  H5Tclose (type_hid);
576  H5Gclose (group_hid);
577 
578 #else
579  octave_unused_parameter (loc_id);
580  octave_unused_parameter (name);
581  octave_unused_parameter (save_as_floats);
582 
583  warn_save ("hdf5");
584 #endif
585 
586  return retval;
587 }
588 
589 bool
591  const char *name)
592 {
593  bool retval = false;
594 
595 #if defined (HAVE_HDF5)
596 
597  octave_idx_type nr, nc, nz;
598  hid_t group_hid, data_hid, space_hid;
599  hsize_t rank;
600 
601  dim_vector dv;
602  int empty = load_hdf5_empty (loc_id, name, dv);
603  if (empty > 0)
604  matrix.resize (dv);
605  if (empty)
606  return (empty > 0);
607 
608 #if defined (HAVE_HDF5_18)
609  group_hid = H5Gopen (loc_id, name, octave_H5P_DEFAULT);
610 #else
611  group_hid = H5Gopen (loc_id, name);
612 #endif
613  if (group_hid < 0) return false;
614 
615 #if defined (HAVE_HDF5_18)
616  data_hid = H5Dopen (group_hid, "nr", octave_H5P_DEFAULT);
617 #else
618  data_hid = H5Dopen (group_hid, "nr");
619 #endif
620  space_hid = H5Dget_space (data_hid);
621  rank = H5Sget_simple_extent_ndims (space_hid);
622 
623  if (rank != 0)
624  {
625  H5Dclose (data_hid);
626  H5Gclose (group_hid);
627  return false;
628  }
629 
630  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL,
632  {
633  H5Dclose (data_hid);
634  H5Gclose (group_hid);
635  return false;
636  }
637 
638  H5Dclose (data_hid);
639 
640 #if defined (HAVE_HDF5_18)
641  data_hid = H5Dopen (group_hid, "nc", octave_H5P_DEFAULT);
642 #else
643  data_hid = H5Dopen (group_hid, "nc");
644 #endif
645  space_hid = H5Dget_space (data_hid);
646  rank = H5Sget_simple_extent_ndims (space_hid);
647 
648  if (rank != 0)
649  {
650  H5Dclose (data_hid);
651  H5Gclose (group_hid);
652  return false;
653  }
654 
655  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL,
657  {
658  H5Dclose (data_hid);
659  H5Gclose (group_hid);
660  return false;
661  }
662 
663  H5Dclose (data_hid);
664 
665 #if defined (HAVE_HDF5_18)
666  data_hid = H5Dopen (group_hid, "nz", octave_H5P_DEFAULT);
667 #else
668  data_hid = H5Dopen (group_hid, "nz");
669 #endif
670  space_hid = H5Dget_space (data_hid);
671  rank = H5Sget_simple_extent_ndims (space_hid);
672 
673  if (rank != 0)
674  {
675  H5Dclose (data_hid);
676  H5Gclose (group_hid);
677  return false;
678  }
679 
680  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL,
682  {
683  H5Dclose (data_hid);
684  H5Gclose (group_hid);
685  return false;
686  }
687 
688  H5Dclose (data_hid);
689 
690  SparseComplexMatrix m (static_cast<octave_idx_type> (nr),
691  static_cast<octave_idx_type> (nc),
692  static_cast<octave_idx_type> (nz));
693 
694 #if defined (HAVE_HDF5_18)
695  data_hid = H5Dopen (group_hid, "cidx", octave_H5P_DEFAULT);
696 #else
697  data_hid = H5Dopen (group_hid, "cidx");
698 #endif
699  space_hid = H5Dget_space (data_hid);
700  rank = H5Sget_simple_extent_ndims (space_hid);
701 
702  if (rank != 2)
703  {
704  H5Sclose (space_hid);
705  H5Dclose (data_hid);
706  H5Gclose (group_hid);
707  return false;
708  }
709 
710  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
711  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
712 
713  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
714 
715  if (static_cast<int> (hdims[0]) != nc + 1
716  || static_cast<int> (hdims[1]) != 1)
717  {
718  H5Sclose (space_hid);
719  H5Dclose (data_hid);
720  H5Gclose (group_hid);
721  return false;
722  }
723 
724  octave_idx_type *itmp = m.xcidx ();
725  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL,
727  {
728  H5Sclose (space_hid);
729  H5Dclose (data_hid);
730  H5Gclose (group_hid);
731  return false;
732  }
733 
734  H5Sclose (space_hid);
735  H5Dclose (data_hid);
736 
737 #if defined (HAVE_HDF5_18)
738  data_hid = H5Dopen (group_hid, "ridx", octave_H5P_DEFAULT);
739 #else
740  data_hid = H5Dopen (group_hid, "ridx");
741 #endif
742  space_hid = H5Dget_space (data_hid);
743  rank = H5Sget_simple_extent_ndims (space_hid);
744 
745  if (rank != 2)
746  {
747  H5Sclose (space_hid);
748  H5Dclose (data_hid);
749  H5Gclose (group_hid);
750  return false;
751  }
752 
753  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
754 
755  if (static_cast<int> (hdims[0]) != nz
756  || static_cast<int> (hdims[1]) != 1)
757  {
758  H5Sclose (space_hid);
759  H5Dclose (data_hid);
760  H5Gclose (group_hid);
761  return false;
762  }
763 
764  itmp = m.xridx ();
765  if (H5Dread (data_hid, H5T_NATIVE_IDX, octave_H5S_ALL,
767  {
768  H5Sclose (space_hid);
769  H5Dclose (data_hid);
770  H5Gclose (group_hid);
771  return false;
772  }
773 
774  H5Sclose (space_hid);
775  H5Dclose (data_hid);
776 
777 #if defined (HAVE_HDF5_18)
778  data_hid = H5Dopen (group_hid, "data", octave_H5P_DEFAULT);
779 #else
780  data_hid = H5Dopen (group_hid, "data");
781 #endif
782  hid_t type_hid = H5Dget_type (data_hid);
783 
784  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
785 
786  if (! hdf5_types_compatible (type_hid, complex_type))
787  {
788  H5Tclose (complex_type);
789  H5Dclose (data_hid);
790  H5Gclose (group_hid);
791  return false;
792  }
793 
794  space_hid = H5Dget_space (data_hid);
795  rank = H5Sget_simple_extent_ndims (space_hid);
796 
797  if (rank != 2)
798  {
799  H5Sclose (space_hid);
800  H5Dclose (data_hid);
801  H5Gclose (group_hid);
802  return false;
803  }
804 
805  H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
806 
807  if (static_cast<int> (hdims[0]) != nz
808  || static_cast<int> (hdims[1]) != 1)
809  {
810  H5Sclose (space_hid);
811  H5Dclose (data_hid);
812  H5Gclose (group_hid);
813  return false;
814  }
815 
816  Complex *ctmp = m.xdata ();
817 
818  if (H5Dread (data_hid, complex_type, octave_H5S_ALL, octave_H5S_ALL,
819  octave_H5P_DEFAULT, ctmp) >= 0
820  && m.indices_ok ())
821  {
822  retval = true;
823  matrix = m;
824  }
825 
826  H5Tclose (complex_type);
827  H5Sclose (space_hid);
828  H5Dclose (data_hid);
829  H5Gclose (group_hid);
830 
831 #else
832  octave_unused_parameter (loc_id);
833  octave_unused_parameter (name);
834 
835  warn_load ("hdf5");
836 #endif
837 
838  return retval;
839 }
840 
841 mxArray *
843 {
844  mwSize nz = nzmax ();
845  mwSize nr = rows ();
846  mwSize nc = columns ();
847 
848  mxArray *retval = new mxArray (interleaved, mxDOUBLE_CLASS, nr, nc, nz,
849  mxCOMPLEX);
850 
851  mwIndex *ir = retval->get_ir ();
852 
853  const Complex *pdata = matrix.data ();
854  const octave_idx_type *pridx = matrix.ridx ();
855 
856  if (interleaved)
857  {
858  mxComplexDouble *pd
859  = static_cast<mxComplexDouble *> (retval->get_data ());
860 
861  for (mwIndex i = 0; i < nz; i++)
862  {
863  pd[i].real = pdata[i].real ();
864  pd[i].imag = pdata[i].imag ();
865 
866  ir[i] = pridx[i];
867  }
868  }
869  else
870  {
871  mxDouble *pr = static_cast<mxDouble *> (retval->get_data ());
872  mxDouble *pi = static_cast<mxDouble *> (retval->get_imag_data ());
873 
874  for (mwIndex i = 0; i < nz; i++)
875  {
876  pr[i] = pdata[i].real ();
877  pi[i] = pdata[i].imag ();
878 
879  ir[i] = pridx[i];
880  }
881  }
882 
883  mwIndex *jc = retval->get_jc ();
884 
885  const octave_idx_type *pcidx = matrix.cidx ();
886 
887  for (mwIndex i = 0; i < nc + 1; i++)
888  jc[i] = pcidx[i];
889 
890  return retval;
891 }
892 
895 {
896  switch (umap)
897  {
898  // Mappers handled specially.
899  case umap_real:
901  case umap_imag:
903 
904 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
905  case umap_ ## UMAP: \
906  return octave_value (matrix.FCN ())
907 
909 
910 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
911  case umap_ ## UMAP: \
912  return octave_value (matrix.map<TYPE> (FCN))
913 
916  ARRAY_MAPPER (angle, double, std::arg);
917  ARRAY_MAPPER (arg, double, std::arg);
928  ARRAY_MAPPER (conj, Complex, std::conj<double>);
929  ARRAY_MAPPER (cos, Complex, std::cos);
930  ARRAY_MAPPER (cosh, Complex, std::cosh);
931  ARRAY_MAPPER (exp, Complex, std::exp);
935  ARRAY_MAPPER (log, Complex, std::log);
937  ARRAY_MAPPER (log10, Complex, std::log10);
942  ARRAY_MAPPER (sin, Complex, std::sin);
943  ARRAY_MAPPER (sinh, Complex, std::sinh);
944  ARRAY_MAPPER (sqrt, Complex, std::sqrt);
945  ARRAY_MAPPER (tan, Complex, std::tan);
946  ARRAY_MAPPER (tanh, Complex, std::tanh);
951 
952  default: // Attempt to go via dense matrix.
954  }
955 }
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:217
boolMatrix mx_el_ne(const boolMatrix &m1, const boolMatrix &m2)
Definition: boolMatrix.cc:91
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:63
Definition: dMatrix.h:42
bool too_large_for_float() const
Definition: CSparse.cc:7357
ComplexMatrix matrix_value() const
Definition: CSparse.cc:600
bool all_elements_are_real() const
Definition: CSparse.cc:7309
bool any_element_is_nan() const
Definition: CSparse.cc:7277
bool all_integers(double &max_val, double &min_val) const
Definition: CSparse.cc:7319
octave_idx_type cols() const
Definition: Sparse.h:352
octave_idx_type * cidx()
Definition: Sparse.h:596
void resize(octave_idx_type r, octave_idx_type c)
Definition: Sparse.cc:993
T * data()
Definition: Sparse.h:574
octave_idx_type * ridx()
Definition: Sparse.h:583
Sparse< T, Alloc > maybe_compress(bool remove_zeros=false)
Definition: Sparse.h:531
octave_idx_type nnz() const
Actual number of nonzero terms.
Definition: Sparse.h:339
octave_idx_type rows() const
Definition: Sparse.h:351
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
octave_idx_type ndims() const
Number of dimensions.
Definition: dim-vector.h:257
mwIndex * get_ir() const
Definition: mxarray.h:554
void * get_imag_data() const
Definition: mxarray.h:511
mwIndex * get_jc() const
Definition: mxarray.h:556
void * get_data() const
Definition: mxarray.h:473
octave_value map(octave_base_value::unary_mapper_t umap) const
octave_idx_type rows() const
Definition: ov-base.h:374
octave_idx_type columns() const
Definition: ov-base.h:381
void warn_load(const char *type) const
Definition: ov-base.cc:1157
bool isempty() const
Definition: ov-base.h:417
void warn_save(const char *type) const
Definition: ov-base.cc:1166
SparseComplexMatrix sparse_complex_matrix_value(bool=false) const
Definition: ov-cx-sparse.h:125
octave_value map(unary_mapper_t umap) const
Complex complex_value(bool=false) const
SparseBoolMatrix sparse_bool_matrix_value(bool warn=false) const
octave_base_value * try_narrowing_conversion()
Definition: ov-cx-sparse.cc:61
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
ComplexNDArray complex_array_value(bool=false) const
octave_value as_double() const
Matrix matrix_value(bool=false) const
Definition: ov-cx-sparse.cc:86
double double_value(bool=false) const
Definition: ov-cx-sparse.cc:68
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
ComplexMatrix complex_matrix_value(bool=false) const
mxArray * as_mxArray(bool interleaved) const
SparseMatrix sparse_matrix_value(bool=false) const
charNDArray char_array_value(bool frc_str_conv=false) const
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
bool save_binary(std::ostream &os, bool save_as_floats)
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:143
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:776
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
Definition: data-conv.cc:892
save_type
Definition: data-conv.h:87
@ LS_DOUBLE
Definition: data-conv.h:95
@ LS_FLOAT
Definition: data-conv.h:94
void warning(const char *fmt,...)
Definition: error.cc:1063
void() error(const char *fmt,...)
Definition: error.cc:988
void err_invalid_conversion(const std::string &from, const std::string &to)
Definition: errwarn.cc:71
void warn_logical_conversion()
Definition: errwarn.cc:365
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:344
void err_nan_to_logical_conversion()
Complex log2(const Complex &x)
Definition: lo-mappers.cc:141
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
bool isna(double x)
Definition: lo-mappers.cc:47
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
Complex atan(const Complex &x)
Definition: lo-mappers.h:71
double roundb(double x)
Definition: lo-mappers.h:147
bool isfinite(double x)
Definition: lo-mappers.h:192
bool isinf(double x)
Definition: lo-mappers.h:203
double signum(double x)
Definition: lo-mappers.h:229
double round(double x)
Definition: lo-mappers.h:136
bool isnan(bool)
Definition: lo-mappers.h:178
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:130
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:103
double fix(double x)
Definition: lo-mappers.h:118
double dawson(double x)
Definition: lo-specfun.cc:1467
Complex expm1(const Complex &x)
Definition: lo-specfun.cc:1835
Complex log1p(const Complex &x)
Definition: lo-specfun.cc:1919
double asinh(double x)
Definition: lo-specfun.h:58
double atanh(double x)
Definition: lo-specfun.h:63
double acosh(double x)
Definition: lo-specfun.h:40
int save_hdf5_empty(octave_hdf5_id loc_id, const char *name, const dim_vector &d)
Definition: ls-hdf5.cc:1249
int load_hdf5_empty(octave_hdf5_id loc_id, const char *name, dim_vector &d)
Definition: ls-hdf5.cc:1306
octave_hdf5_id save_type_to_hdf5(save_type st)
Definition: ls-hdf5.cc:1350
octave_hdf5_id hdf5_make_complex_type(octave_hdf5_id num_type)
Definition: ls-hdf5.cc:405
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition: ls-hdf5.cc:269
save_type get_save_type(double, double)
Definition: ls-utils.cc:40
float_format
Definition: mach-info.h:38
void mxArray
Definition: mex.h:58
T octave_idx_type m
Definition: mx-inlines.cc:781
@ mxDOUBLE_CLASS
Definition: mxtypes.h:64
int64_t mwIndex
Definition: mxtypes.h:125
double mxDouble
Definition: mxtypes.h:91
@ mxCOMPLEX
Definition: mxtypes.h:81
int64_t mwSize
Definition: mxtypes.h:124
std::complex< double > erfc(std::complex< double > z, double relerr=0)
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
std::complex< double > erfi(std::complex< double > z, double relerr=0)
std::complex< double > erf(std::complex< double > z, double relerr=0)
std::complex< double > Complex
Definition: oct-cmplx.h:33
int64_t octave_hdf5_id
#define H5T_NATIVE_IDX
Definition: oct-hdf5.h:42
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:235
#define ARRAY_MAPPER(UMAP, TYPE, FCN)
#define ARRAY_METHOD_MAPPER(UMAP, FCN)
template int8_t abs(int8_t)
mxDouble real
Definition: mxtypes.h:104
mxDouble imag
Definition: mxtypes.h:104