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-re-mat.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2015 John W. Eaton
4 Copyright (C) 2009-2010 VZLU Prague
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 "data-conv.h"
33 #include "lo-ieee.h"
34 #include "lo-utils.h"
35 #include "lo-specfun.h"
36 #include "lo-mappers.h"
37 #include "mach-info.h"
38 #include "mx-base.h"
39 #include "quit.h"
40 #include "oct-locbuf.h"
41 
42 #include "defun.h"
43 #include "gripes.h"
44 #include "mxarray.h"
45 #include "oct-obj.h"
46 #include "oct-lvalue.h"
47 #include "oct-hdf5.h"
48 #include "oct-stream.h"
49 #include "ops.h"
50 #include "ov-base.h"
51 #include "ov-base-mat.h"
52 #include "ov-base-mat.cc"
53 #include "ov-scalar.h"
54 #include "ov-re-mat.h"
55 #include "ov-flt-re-mat.h"
56 #include "ov-complex.h"
57 #include "ov-cx-mat.h"
58 #include "ov-re-sparse.h"
59 #include "ov-re-diag.h"
60 #include "ov-cx-diag.h"
61 #include "ov-lazy-idx.h"
62 #include "ov-perm.h"
63 #include "ov-type-conv.h"
64 #include "pr-output.h"
65 #include "variables.h"
66 
67 #include "byte-swap.h"
68 #include "ls-oct-ascii.h"
69 #include "ls-utils.h"
70 #include "ls-hdf5.h"
71 
72 template class octave_base_matrix<NDArray>;
73 
74 
76 
77 static octave_base_value *
79 {
81 
82  return new octave_float_matrix (v.float_array_value ());
83 }
84 
87 {
91 }
92 
95 {
96  octave_base_value *retval = 0;
97 
98  if (matrix.nelem () == 1)
99  retval = new octave_scalar (matrix (0));
100 
101  return retval;
102 }
103 
104 double
106 {
107  double retval = lo_ieee_nan_value ();
108 
109  if (numel () > 0)
110  {
111  gripe_implicit_conversion ("Octave:array-to-scalar",
112  "real matrix", "real scalar");
113 
114  retval = matrix (0, 0);
115  }
116  else
117  gripe_invalid_conversion ("real matrix", "real scalar");
118 
119  return retval;
120 }
121 
122 float
124 {
125  float retval = lo_ieee_float_nan_value ();
126 
127  if (numel () > 0)
128  {
129  gripe_implicit_conversion ("Octave:array-to-scalar",
130  "real matrix", "real scalar");
131 
132  retval = matrix (0, 0);
133  }
134  else
135  gripe_invalid_conversion ("real matrix", "real scalar");
136 
137  return retval;
138 }
139 
140 // FIXME
141 
142 Matrix
144 {
145  return Matrix (matrix);
146 }
147 
150 {
151  return FloatMatrix (Matrix (matrix));
152 }
153 
154 Complex
156 {
157  double tmp = lo_ieee_nan_value ();
158 
159  Complex retval (tmp, tmp);
160 
161  if (rows () > 0 && columns () > 0)
162  {
163  gripe_implicit_conversion ("Octave:array-to-scalar",
164  "real matrix", "complex scalar");
165 
166  retval = matrix (0, 0);
167  }
168  else
169  gripe_invalid_conversion ("real matrix", "complex scalar");
170 
171  return retval;
172 }
173 
176 {
177  float tmp = lo_ieee_float_nan_value ();
178 
179  FloatComplex retval (tmp, tmp);
180 
181  if (rows () > 0 && columns () > 0)
182  {
183  gripe_implicit_conversion ("Octave:array-to-scalar",
184  "real matrix", "complex scalar");
185 
186  retval = matrix (0, 0);
187  }
188  else
189  gripe_invalid_conversion ("real matrix", "complex scalar");
190 
191  return retval;
192 }
193 
194 // FIXME
195 
198 {
199  return ComplexMatrix (Matrix (matrix));
200 }
201 
204 {
205  return FloatComplexMatrix (Matrix (matrix));
206 }
207 
210 {
211  return ComplexNDArray (matrix);
212 }
213 
216 {
217  return FloatComplexNDArray (matrix);
218 }
219 
222 {
223  if (matrix.any_element_is_nan ())
225  else if (warn && matrix.any_element_not_one_or_zero ())
227 
228  return boolNDArray (matrix);
229 }
230 
233 {
234  charNDArray retval (dims ());
235 
236  octave_idx_type nel = numel ();
237 
238  for (octave_idx_type i = 0; i < nel; i++)
239  retval.elem (i) = static_cast<char>(matrix.elem (i));
240 
241  return retval;
242 }
243 
246 {
247  return SparseMatrix (Matrix (matrix));
248 }
249 
252 {
253  // FIXME: Need a SparseComplexMatrix (Matrix) constructor to make
254  // this function more efficient. Then this should become
255  // return SparseComplexMatrix (matrix.matrix_value ());
257 }
258 
261 {
262  octave_value retval;
263  if (k == 0 && matrix.ndims () == 2
264  && (matrix.rows () == 1 || matrix.columns () == 1))
265  retval = DiagMatrix (DiagArray2<double> (matrix));
266  else
268 
269  return retval;
270 }
271 
274 {
275  octave_value retval;
276 
277  if (matrix.ndims () == 2
278  && (matrix.rows () == 1 || matrix.columns () == 1))
279  {
280  Matrix mat (matrix);
281 
282  retval = mat.diag (m, n);
283  }
284  else
285  error ("diag: expecting vector argument");
286 
287  return retval;
288 }
289 
290 // We override these two functions to allow reshaping both
291 // the matrix and the index cache.
293 octave_matrix::reshape (const dim_vector& new_dims) const
294 {
295  if (idx_cache)
296  {
297  return new octave_matrix (matrix.reshape (new_dims),
298  idx_vector (idx_cache->as_array ().reshape (new_dims),
299  idx_cache->extent (0)));
300  }
301  else
302  return octave_base_matrix<NDArray>::reshape (new_dims);
303 }
304 
307 {
308  if (idx_cache)
309  {
310  return new octave_matrix (matrix.squeeze (),
312  idx_cache->extent (0)));
313  }
314  else
316 }
317 
320 {
321  if (idx_cache)
322  {
323  // This is a valid index matrix, so sort via integers because it's
324  // generally more efficient.
325  return octave_lazy_index (*idx_cache).sort (dim, mode);
326  }
327  else
328  return octave_base_matrix<NDArray>::sort (dim, mode);
329 }
330 
333  sortmode mode) const
334 {
335  if (idx_cache)
336  {
337  // This is a valid index matrix, so sort via integers because it's
338  // generally more efficient.
339  return octave_lazy_index (*idx_cache).sort (sidx, dim, mode);
340  }
341  else
342  return octave_base_matrix<NDArray>::sort (sidx, dim, mode);
343 }
344 
345 sortmode
347 {
348  if (idx_cache)
349  {
350  // This is a valid index matrix, so check via integers because it's
351  // generally more efficient.
352  return idx_cache->as_array ().is_sorted (mode);
353  }
354  else
356 }
359 {
360  if (idx_cache)
361  {
362  // This is a valid index matrix, so sort via integers because it's
363  // generally more efficient.
364  return octave_lazy_index (*idx_cache).sort_rows_idx (mode);
365  }
366  else
368 }
369 
370 sortmode
372 {
373  if (idx_cache)
374  {
375  // This is a valid index matrix, so check via integers because it's
376  // generally more efficient.
377  return idx_cache->as_array ().is_sorted_rows (mode);
378  }
379  else
381 }
382 
385 {
386  octave_value retval;
387  dim_vector dv = dims ();
388  octave_idx_type nel = dv.numel ();
389 
390  charNDArray chm (dv);
391 
392  bool warned = false;
393 
394  for (octave_idx_type i = 0; i < nel; i++)
395  {
396  octave_quit ();
397 
398  double d = matrix (i);
399 
400  if (xisnan (d))
401  {
403  return retval;
404  }
405  else
406  {
407  int ival = NINT (d);
408 
409  if (ival < 0 || ival > std::numeric_limits<unsigned char>::max ())
410  {
411  // FIXME: is there something better we could do?
412 
413  ival = 0;
414 
415  if (! warned)
416  {
417  ::warning ("range error for conversion to character value");
418  warned = true;
419  }
420  }
421 
422  chm (i) = static_cast<char> (ival);
423  }
424  }
425 
426  retval = octave_value (chm, type);
427 
428  return retval;
429 }
430 
431 bool
432 octave_matrix::save_ascii (std::ostream& os)
433 {
434  dim_vector d = dims ();
435 
436  if (d.length () > 2)
437  {
438  NDArray tmp = array_value ();
439 
440  os << "# ndims: " << d.length () << "\n";
441 
442  for (int i=0; i < d.length (); i++)
443  os << " " << d (i);
444 
445  os << "\n" << tmp;
446  }
447  else
448  {
449  // Keep this case, rather than use generic code above for backward
450  // compatiability. Makes load_ascii much more complex!!
451  os << "# rows: " << rows () << "\n"
452  << "# columns: " << columns () << "\n";
453 
454  os << matrix_value ();
455  }
456 
457  return true;
458 }
459 
460 bool
461 octave_matrix::load_ascii (std::istream& is)
462 {
463  bool success = true;
464 
466 
467  keywords[0] = "ndims";
468  keywords[1] = "rows";
469 
470  std::string kw;
471  octave_idx_type val = 0;
472 
473  if (extract_keyword (is, keywords, kw, val, true))
474  {
475  if (kw == "ndims")
476  {
477  int mdims = static_cast<int> (val);
478 
479  if (mdims >= 0)
480  {
481  dim_vector dv;
482  dv.resize (mdims);
483 
484  for (int i = 0; i < mdims; i++)
485  is >> dv(i);
486 
487  if (is)
488  {
489  NDArray tmp(dv);
490 
491  is >> tmp;
492 
493  if (is)
494  matrix = tmp;
495  else
496  {
497  error ("load: failed to load matrix constant");
498  success = false;
499  }
500  }
501  else
502  {
503  error ("load: failed to read dimensions");
504  success = false;
505  }
506  }
507  else
508  {
509  error ("load: failed to extract number of dimensions");
510  success = false;
511  }
512  }
513  else if (kw == "rows")
514  {
515  octave_idx_type nr = val;
516  octave_idx_type nc = 0;
517 
518  if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
519  {
520  if (nr > 0 && nc > 0)
521  {
522  Matrix tmp (nr, nc);
523  is >> tmp;
524  if (is)
525  matrix = tmp;
526  else
527  {
528  error ("load: failed to load matrix constant");
529  success = false;
530  }
531  }
532  else if (nr == 0 || nc == 0)
533  matrix = Matrix (nr, nc);
534  else
535  panic_impossible ();
536  }
537  else
538  {
539  error ("load: failed to extract number of rows and columns");
540  success = false;
541  }
542  }
543  else
544  panic_impossible ();
545  }
546  else
547  {
548  error ("load: failed to extract number of rows and columns");
549  success = false;
550  }
551 
552  return success;
553 }
554 
555 bool
556 octave_matrix::save_binary (std::ostream& os, bool& save_as_floats)
557 {
558 
559  dim_vector d = dims ();
560  if (d.length () < 1)
561  return false;
562 
563  // Use negative value for ndims to differentiate with old format!!
564  int32_t tmp = - d.length ();
565  os.write (reinterpret_cast<char *> (&tmp), 4);
566  for (int i = 0; i < d.length (); i++)
567  {
568  tmp = d(i);
569  os.write (reinterpret_cast<char *> (&tmp), 4);
570  }
571 
572  NDArray m = array_value ();
573  save_type st = LS_DOUBLE;
574  if (save_as_floats)
575  {
576  if (m.too_large_for_float ())
577  {
578  warning ("save: some values too large to save as floats --");
579  warning ("save: saving as doubles instead");
580  }
581  else
582  st = LS_FLOAT;
583  }
584  else if (d.numel () > 8192) // FIXME: make this configurable.
585  {
586  double max_val, min_val;
587  if (m.all_integers (max_val, min_val))
588  st = get_save_type (max_val, min_val);
589  }
590 
591  const double *mtmp = m.data ();
592  write_doubles (os, mtmp, st, d.numel ());
593 
594  return true;
595 }
596 
597 bool
598 octave_matrix::load_binary (std::istream& is, bool swap,
600 {
601  char tmp;
602  int32_t mdims;
603  if (! is.read (reinterpret_cast<char *> (&mdims), 4))
604  return false;
605  if (swap)
606  swap_bytes<4> (&mdims);
607  if (mdims < 0)
608  {
609  mdims = - mdims;
610  int32_t di;
611  dim_vector dv;
612  dv.resize (mdims);
613 
614  for (int i = 0; i < mdims; i++)
615  {
616  if (! is.read (reinterpret_cast<char *> (&di), 4))
617  return false;
618  if (swap)
619  swap_bytes<4> (&di);
620  dv(i) = di;
621  }
622 
623  // Convert an array with a single dimension to be a row vector.
624  // Octave should never write files like this, other software
625  // might.
626 
627  if (mdims == 1)
628  {
629  mdims = 2;
630  dv.resize (mdims);
631  dv(1) = dv(0);
632  dv(0) = 1;
633  }
634 
635  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
636  return false;
637 
638  NDArray m(dv);
639  double *re = m.fortran_vec ();
640  read_doubles (is, re, static_cast<save_type> (tmp), dv.numel (),
641  swap, fmt);
642  if (error_state || ! is)
643  return false;
644  matrix = m;
645  }
646  else
647  {
648  int32_t nr, nc;
649  nr = mdims;
650  if (! is.read (reinterpret_cast<char *> (&nc), 4))
651  return false;
652  if (swap)
653  swap_bytes<4> (&nc);
654  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
655  return false;
656  Matrix m (nr, nc);
657  double *re = m.fortran_vec ();
658  octave_idx_type len = nr * nc;
659  read_doubles (is, re, static_cast<save_type> (tmp), len, swap, fmt);
660  if (error_state || ! is)
661  return false;
662  matrix = m;
663  }
664  return true;
665 }
666 
667 bool
668 octave_matrix::save_hdf5 (octave_hdf5_id loc_id, const char *name, bool save_as_floats)
669 {
670  bool retval = false;
671 
672 #if defined (HAVE_HDF5)
673 
674  dim_vector dv = dims ();
675  int empty = save_hdf5_empty (loc_id, name, dv);
676  if (empty)
677  return (empty > 0);
678 
679  int rank = dv.length ();
680  hid_t space_hid, data_hid;
681  space_hid = data_hid = -1;
682  NDArray m = array_value ();
683 
684  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
685 
686  // Octave uses column-major, while HDF5 uses row-major ordering
687  for (int i = 0; i < rank; i++)
688  hdims[i] = dv (rank-i-1);
689 
690  space_hid = H5Screate_simple (rank, hdims, 0);
691 
692  if (space_hid < 0) return false;
693 
694  hid_t save_type_hid = H5T_NATIVE_DOUBLE;
695 
696  if (save_as_floats)
697  {
698  if (m.too_large_for_float ())
699  {
700  warning ("save: some values too large to save as floats --");
701  warning ("save: saving as doubles instead");
702  }
703  else
704  save_type_hid = H5T_NATIVE_FLOAT;
705  }
706 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
707  // hdf5 currently doesn't support float/integer conversions
708  else
709  {
710  double max_val, min_val;
711 
712  if (m.all_integers (max_val, min_val))
713  save_type_hid
714  = save_type_to_hdf5 (get_save_type (max_val, min_val));
715  }
716 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
717 
718 #if HAVE_HDF5_18
719  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid,
720  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
721 #else
722  data_hid = H5Dcreate (loc_id, name, save_type_hid, space_hid,
723  H5P_DEFAULT);
724 #endif
725  if (data_hid < 0)
726  {
727  H5Sclose (space_hid);
728  return false;
729  }
730 
731  double *mtmp = m.fortran_vec ();
732  retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
733  H5P_DEFAULT, mtmp) >= 0;
734 
735  H5Dclose (data_hid);
736  H5Sclose (space_hid);
737 
738 #else
739  gripe_save ("hdf5");
740 #endif
741 
742  return retval;
743 }
744 
745 bool
746 octave_matrix::load_hdf5 (octave_hdf5_id loc_id, const char *name)
747 {
748  bool retval = false;
749 
750 #if defined (HAVE_HDF5)
751 
752  dim_vector dv;
753  int empty = load_hdf5_empty (loc_id, name, dv);
754  if (empty > 0)
755  matrix.resize (dv);
756  if (empty)
757  return (empty > 0);
758 
759 #if HAVE_HDF5_18
760  hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
761 #else
762  hid_t data_hid = H5Dopen (loc_id, name);
763 #endif
764  hid_t space_id = H5Dget_space (data_hid);
765 
766  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
767 
768  if (rank < 1)
769  {
770  H5Sclose (space_id);
771  H5Dclose (data_hid);
772  return false;
773  }
774 
775  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
776  OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
777 
778  H5Sget_simple_extent_dims (space_id, hdims, maxdims);
779 
780  // Octave uses column-major, while HDF5 uses row-major ordering
781  if (rank == 1)
782  {
783  dv.resize (2);
784  dv(0) = 1;
785  dv(1) = hdims[0];
786  }
787  else
788  {
789  dv.resize (rank);
790  for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
791  dv(j) = hdims[i];
792  }
793 
794  NDArray m (dv);
795  double *re = m.fortran_vec ();
796  if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
797  H5P_DEFAULT, re) >= 0)
798  {
799  retval = true;
800  matrix = m;
801  }
802 
803  H5Sclose (space_id);
804  H5Dclose (data_hid);
805 
806 #else
807  gripe_load ("hdf5");
808 #endif
809 
810  return retval;
811 }
812 
813 void
814 octave_matrix::print_raw (std::ostream& os,
815  bool pr_as_read_syntax) const
816 {
817  octave_print_internal (os, matrix, pr_as_read_syntax,
819 }
820 
821 mxArray *
823 {
824  mxArray *retval = new mxArray (mxDOUBLE_CLASS, dims (), mxREAL);
825 
826  double *pr = static_cast<double *> (retval->get_data ());
827 
828  mwSize nel = numel ();
829 
830  const double *p = matrix.data ();
831 
832  for (mwIndex i = 0; i < nel; i++)
833  pr[i] = p[i];
834 
835  return retval;
836 }
837 
838 // This uses a smarter strategy for doing the complex->real mappers. We
839 // allocate an array for a real result and keep filling it until a complex
840 // result is produced.
841 static octave_value
842 do_rc_map (const NDArray& a, Complex (&fcn) (double))
843 {
844  octave_idx_type n = a.numel ();
845  NoAlias<NDArray> rr (a.dims ());
846 
847  for (octave_idx_type i = 0; i < n; i++)
848  {
849  octave_quit ();
850 
851  Complex tmp = fcn (a(i));
852  if (tmp.imag () == 0.0)
853  rr(i) = tmp.real ();
854  else
855  {
856  NoAlias<ComplexNDArray> rc (a.dims ());
857 
858  for (octave_idx_type j = 0; j < i; j++)
859  rc(j) = rr(j);
860 
861  rc(i) = tmp;
862 
863  for (octave_idx_type j = i+1; j < n; j++)
864  {
865  octave_quit ();
866 
867  rc(j) = fcn (a(j));
868  }
869 
870  return new octave_complex_matrix (rc);
871  }
872  }
873 
874  return rr;
875 }
876 
879 {
880  switch (umap)
881  {
882  case umap_imag:
883  return NDArray (matrix.dims (), 0.0);
884 
885  case umap_real:
886  case umap_conj:
887  return matrix;
888 
889  // Mappers handled specially.
890 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
891  case umap_ ## UMAP: \
892  return octave_value (matrix.FCN ())
893 
895  ARRAY_METHOD_MAPPER (isnan, isnan);
896  ARRAY_METHOD_MAPPER (isinf, isinf);
897  ARRAY_METHOD_MAPPER (finite, isfinite);
898 
899 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
900  case umap_ ## UMAP: \
901  return octave_value (matrix.map<TYPE> (FCN))
902 
903 #define RC_ARRAY_MAPPER(UMAP, TYPE, FCN) \
904  case umap_ ## UMAP: \
905  return do_rc_map (matrix, FCN)
906 
909  ARRAY_MAPPER (angle, double, ::arg);
910  ARRAY_MAPPER (arg, double, ::arg);
912  ARRAY_MAPPER (asinh, double, ::asinh);
913  ARRAY_MAPPER (atan, double, ::atan);
915  ARRAY_MAPPER (erf, double, ::erf);
916  ARRAY_MAPPER (erfinv, double, ::erfinv);
917  ARRAY_MAPPER (erfcinv, double, ::erfcinv);
918  ARRAY_MAPPER (erfc, double, ::erfc);
919  ARRAY_MAPPER (erfcx, double, ::erfcx);
920  ARRAY_MAPPER (erfi, double, ::erfi);
921  ARRAY_MAPPER (dawson, double, ::dawson);
922  ARRAY_MAPPER (gamma, double, xgamma);
923  RC_ARRAY_MAPPER (lgamma, Complex, rc_lgamma);
924  ARRAY_MAPPER (cbrt, double, ::cbrt);
925  ARRAY_MAPPER (ceil, double, ::ceil);
926  ARRAY_MAPPER (cos, double, ::cos);
927  ARRAY_MAPPER (cosh, double, ::cosh);
928  ARRAY_MAPPER (exp, double, ::exp);
929  ARRAY_MAPPER (expm1, double, ::expm1);
930  ARRAY_MAPPER (fix, double, ::fix);
931  ARRAY_MAPPER (floor, double, ::floor);
934  RC_ARRAY_MAPPER (log10, Complex, rc_log10);
936  ARRAY_MAPPER (round, double, xround);
937  ARRAY_MAPPER (roundb, double, xroundb);
938  ARRAY_MAPPER (signum, double, ::signum);
939  ARRAY_MAPPER (sin, double, ::sin);
940  ARRAY_MAPPER (sinh, double, ::sinh);
942  ARRAY_MAPPER (tan, double, ::tan);
943  ARRAY_MAPPER (tanh, double, ::tanh);
944  ARRAY_MAPPER (isna, bool, octave_is_NA);
945  ARRAY_MAPPER (xsignbit, double, xsignbit);
946 
947  // Special cases for Matlab compatibility.
948  case umap_xtolower:
949  case umap_xtoupper:
950  return matrix;
951 
952  case umap_xisalnum:
953  case umap_xisalpha:
954  case umap_xisascii:
955  case umap_xiscntrl:
956  case umap_xisdigit:
957  case umap_xisgraph:
958  case umap_xislower:
959  case umap_xisprint:
960  case umap_xispunct:
961  case umap_xisspace:
962  case umap_xisupper:
963  case umap_xisxdigit:
964  case umap_xtoascii:
965  {
966  octave_value str_conv = convert_to_str (true, true);
967  return error_state ? octave_value () : str_conv.map (umap);
968  }
969 
970  default:
971  return octave_base_value::map (umap);
972  }
973 }
974 
975 DEFUN (double, args, ,
976  "-*- texinfo -*-\n\
977 @deftypefn {Built-in Function} {} double (@var{x})\n\
978 Convert @var{x} to double precision type.\n\
979 @seealso{single}\n\
980 @end deftypefn")
981 {
982  // The OCTAVE_TYPE_CONV_BODY3 macro declares retval, so they go
983  // inside their own scopes, and we don't declare retval here to
984  // avoid a shadowed declaration warning.
985 
986  if (args.length () == 1)
987  {
988  if (args(0).is_perm_matrix ())
989  {
991  }
992  else if (args(0).is_diag_matrix ())
993  {
994  if (args(0).is_complex_type ())
995  {
998  }
999  else
1000  {
1002  octave_scalar);
1003  }
1004  }
1005  else if (args(0).is_sparse_type ())
1006  {
1007  if (args(0).is_complex_type ())
1008  {
1010  octave_complex);
1011  }
1012  else
1013  {
1015  octave_scalar);
1016  }
1017  }
1018  else if (args(0).is_complex_type ())
1019  {
1021  octave_complex);
1022  }
1023  else
1024  {
1026  }
1027  }
1028  else
1029  print_usage ();
1030 
1031  return octave_value ();
1032 }
1033 
1034 /*
1035 %!assert (class (double (single (1))), "double")
1036 %!assert (class (double (single (1 + i))), "double")
1037 %!assert (class (double (int8 (1))), "double")
1038 %!assert (class (double (uint8 (1))), "double")
1039 %!assert (class (double (int16 (1))), "double")
1040 %!assert (class (double (uint16 (1))), "double")
1041 %!assert (class (double (int32 (1))), "double")
1042 %!assert (class (double (uint32 (1))), "double")
1043 %!assert (class (double (int64 (1))), "double")
1044 %!assert (class (double (uint64 (1))), "double")
1045 %!assert (class (double (true)), "double")
1046 %!assert (class (double ("A")), "double")
1047 %!test
1048 %! x = sparse (logical ([1 0; 0 1]));
1049 %! y = double (x);
1050 %! assert (class (x), "logical");
1051 %! assert (class (y), "double");
1052 %! assert (issparse (y));
1053 %!test
1054 %! x = diag (single ([1 3 2]));
1055 %! y = double (x);
1056 %! assert (class (x), "single");
1057 %! assert (class (y), "double");
1058 %!test
1059 %! x = diag (single ([i 3 2]));
1060 %! y = double (x);
1061 %! assert (class (x), "single");
1062 %! assert (class (y), "double");
1063 */
save_type
Definition: data-conv.h:83
Matrix diag(octave_idx_type k=0) const
Definition: dMatrix.cc:2712
void gripe_implicit_conversion(const char *id, const char *from, const char *to)
Definition: gripes.cc:180
Complex rc_asin(double x)
Definition: lo-mappers.cc:536
T xsignbit(T x)
Definition: lo-mappers.h:378
octave_value squeeze(void) const
Definition: ov-base-mat.h:72
NDArray array_value(bool=false) const
Definition: ov-re-mat.h:170
charNDArray char_array_value(bool=false) const
Definition: ov-re-mat.cc:232
double xround(double x)
Definition: lo-mappers.cc:63
sortmode is_sorted(sortmode mode=UNSORTED) const
Definition: ov-base-mat.h:135
bool xisnan(double x)
Definition: lo-mappers.cc:144
sortmode is_sorted(sortmode mode=UNSORTED) const
Definition: ov-re-mat.cc:346
octave_idx_type columns(void) const
Definition: ov-base.h:301
double cbrt(double x)
Definition: lo-specfun.cc:662
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition: ov-re-mat.cc:384
double log1p(double x)
Definition: lo-specfun.cc:620
double erfcinv(double x)
Definition: lo-specfun.cc:3151
int ndims(void) const
Definition: Array.h:487
OCTINTERP_API void print_usage(void)
Definition: defun.cc:51
sortmode
Definition: oct-sort.h:103
std::complex< double > erfi(std::complex< double > z, double relerr=0)
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:275
void gripe_load(const char *type) const
Definition: ov-base.cc:1258
static octave_value do_rc_map(const NDArray &a, Complex(&fcn)(double))
Definition: ov-re-mat.cc:842
save_type get_save_type(double, double)
Definition: ls-utils.cc:35
Complex rc_acos(double x)
Definition: lo-mappers.cc:512
octave_value reshape(const dim_vector &new_dims) const
Definition: ov-re-mat.cc:293
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Definition: ov-base-mat.h:141
octave_idx_type numel(void) const
Definition: ov-base-mat.h:103
void resize(int n, int fill_value=0)
Definition: dim-vector.h:287
function atanh(X)
Definition: atanh.f:2
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:44
void error(const char *fmt,...)
Definition: error.cc:476
octave_value diag(octave_idx_type k=0) const
Definition: ov-re-mat.cc:260
double double_value(bool=false) const
Definition: ov-re-mat.cc:105
void * get_data(void) const
Definition: mxarray.h:433
octave_value map(octave_base_value::unary_mapper_t umap) const
Definition: ov.h:1226
octave_value diag(octave_idx_type k=0) const
Definition: ov-base-mat.h:123
static octave_base_value * default_numeric_demotion_function(const octave_base_value &a)
Definition: ov-re-mat.cc:78
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
octave_matrix(void)
Definition: ov-re-mat.h:55
T & elem(octave_idx_type n)
Definition: Array.h:380
double lo_ieee_nan_value(void)
Definition: lo-ieee.cc:126
double expm1(double x)
Definition: lo-specfun.cc:510
Matrix matrix_value(bool=false) const
Definition: ov-re-mat.cc:143
bool any_element_is_nan(void) const
Definition: dNDArray.cc:564
FloatMatrix float_matrix_value(bool=false) const
Definition: ov-re-mat.cc:149
FloatComplexMatrix float_complex_matrix_value(bool=false) const
Definition: ov-re-mat.cc:203
FloatComplex float_complex_value(bool=false) const
Definition: ov-re-mat.cc:175
#define RC_ARRAY_MAPPER(UMAP, TYPE, FCN)
FloatComplexNDArray float_complex_array_value(bool=false) const
Definition: ov-re-mat.cc:215
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition: ov-re-mat.cc:358
std::complex< double > erf(std::complex< double > z, double relerr=0)
type_conv_info numeric_demotion_function(void) const
Definition: ov-re-mat.cc:86
octave_idx_type rows(void) const
Definition: Array.h:313
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:361
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
subroutine xgamma(x, result)
Definition: xgamma.f:1
octave_idx_type nelem(void) const
Number of elements in the array.
Definition: Array.h:271
octave_value map(unary_mapper_t umap) const
Definition: ov-re-mat.cc:878
void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition: ov-re-mat.cc:814
bool any_element_not_one_or_zero(void) const
Definition: dNDArray.cc:576
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
Definition: ov-re-mat.cc:746
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:337
octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition: ov-lazy-idx.cc:104
double signum(double x)
Definition: lo-mappers.cc:80
octave_base_value * try_narrowing_conversion(void)
Definition: ov-re-mat.cc:94
Complex rc_log1p(double x)
Definition: lo-specfun.cc:2977
bool all_integers(double &max_val, double &min_val) const
Definition: dNDArray.cc:597
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
Definition: ls-oct-ascii.cc:80
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:59
Complex rc_lgamma(double x)
Definition: lo-specfun.cc:411
#define CAST_CONV_ARG(t)
Definition: ops.h:83
NDArray squeeze(void) const
Definition: dNDArray.h:139
SparseComplexMatrix sparse_complex_matrix_value(bool=false) const
Definition: ov-re-mat.cc:251
function asinh(X)
Definition: asinh.f:2
boolNDArray bool_array_value(bool warn=false) const
Definition: ov-re-mat.cc:221
void gripe_nan_to_logical_conversion(void)
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:275
#define OCTAVE_TYPE_CONV_BODY3(NAME, MATRIX_RESULT_T, SCALAR_RESULT_T)
Definition: ov-type-conv.h:77
const T * data(void) const
Definition: Array.h:479
int error_state
Definition: error.cc:101
void resize(const dim_vector &dv, const T &rfv)
Definition: Array.cc:1033
Array< T > squeeze(void) const
Chop off leading singleton dimensions.
Definition: Array.cc:114
Complex rc_sqrt(double x)
Definition: lo-mappers.cc:606
#define panic_impossible()
Definition: error.h:33
void gripe_nan_to_character_conversion(void)
Complex rc_log(double x)
Definition: lo-mappers.cc:561
Complex rc_log2(double x)
Definition: lo-mappers.cc:577
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
double xroundb(double x)
Definition: lo-mappers.cc:69
bool save_ascii(std::ostream &os)
Definition: ov-re-mat.cc:432
octave_value reshape(const dim_vector &new_dims) const
Definition: ov-base-mat.h:109
Complex rc_atanh(double x)
Definition: lo-mappers.cc:548
Complex complex_value(bool=false) const
Definition: ov-re-mat.cc:155
Definition: dMatrix.h:35
ComplexMatrix complex_matrix_value(bool=false) const
Definition: ov-re-mat.cc:197
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
int NINT(double x)
Definition: lo-mappers.cc:657
double erfinv(double x)
Definition: lo-specfun.cc:3063
float lo_ieee_float_nan_value(void)
Definition: lo-ieee.cc:202
Complex rc_log10(double x)
Definition: lo-mappers.cc:591
void mxArray
Definition: mex.h:53
function acosh(X)
Definition: acosh.f:2
Array< octave_idx_type > as_array(void) const
Definition: idx-vector.cc:1277
double arg(double x)
Definition: lo-mappers.h:37
friend class octave_value
Definition: ov-base.h:206
void warning(const char *fmt,...)
Definition: error.cc:681
dim_vector dims(void) const
Definition: ov-base-mat.h:101
sortmode is_sorted(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
Definition: Array.cc:2051
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:233
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:554
This is a simple wrapper template that will subclass an Array type or any later type derived from ...
Definition: Array.h:762
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
Definition: ov-re-mat.cc:668
void gripe_logical_conversion(void)
Definition: gripes.cc:201
Complex rc_acosh(double x)
Definition: lo-mappers.cc:524
void gripe_invalid_conversion(const std::string &from, const std::string &to)
Definition: gripes.cc:99
int current_print_indent_level(void) const
Definition: ov-base.h:805
function gamma(X)
Definition: gamma.f:2
bool save_binary(std::ostream &os, bool &save_as_floats)
Definition: ov-re-mat.cc:556
void octave_print_internal(std::ostream &, char, bool)
Definition: pr-output.cc:1715
bool load_binary(std::istream &is, bool swap, oct_mach_info::float_format fmt)
Definition: ov-re-mat.cc:598
octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition: ov-re-mat.cc:319
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
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1276
mxArray * as_mxArray(void) const
Definition: ov-re-mat.cc:822
double fix(double x)
Definition: lo-mappers.h:39
Array< T > reshape(octave_idx_type nr, octave_idx_type nc) const
Definition: Array.h:460
float float_value(bool=false) const
Definition: ov-re-mat.cc:123
float dawson(float x)
Definition: lo-specfun.cc:349
static const pair_type keywords[]
Definition: help.cc:445
Complex asin(const Complex &x)
Definition: lo-mappers.cc:204
static int static_type_id(void)
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Definition: ov-re-mat.cc:371
octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition: ov-base-mat.h:129
std::complex< float > FloatComplex
Definition: oct-cmplx.h:30
#define ARRAY_MAPPER(UMAP, TYPE, FCN)
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:282
Definition: mxarray.h:52
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition: ov-base-mat.h:138
std::complex< double > Complex
Definition: oct-cmplx.h:29
Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition: ov-lazy-idx.cc:149
const T * fortran_vec(void) const
Definition: Array.h:481
bool load_ascii(std::istream &is)
Definition: ov-re-mat.cc:461
MArray< T > reshape(const dim_vector &new_dims) const
Definition: MArray.h:71
Complex acos(const Complex &x)
Definition: lo-mappers.cc:177
#define ARRAY_METHOD_MAPPER(UMAP, FCN)
ComplexNDArray complex_array_value(bool=false) const
Definition: ov-re-mat.cc:209
virtual octave_value convert_to_str(bool pad=false, bool force=false, char type= '\'') const
Definition: ov-base.cc:373
T abs(T x)
Definition: pr-output.cc:3062
int length(void) const
Definition: dim-vector.h:281
Complex atan(const Complex &x)
Definition: lo-mappers.cc:231
sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Ordering is auto-detected or can be specified.
Definition: Array.cc:2105
octave_value squeeze(void) const
Definition: ov-re-mat.cc:306
octave_idx_type columns(void) const
Definition: Array.h:322
octave_idx_type rows(void) const
Definition: ov-base.h:294
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
bool too_large_for_float(void) const
Definition: dNDArray.cc:633
SparseMatrix sparse_matrix_value(bool=false) const
Definition: ov-re-mat.cc:245
bool octave_is_NA(double x)
Definition: lo-mappers.cc:167
std::complex< double > erfc(std::complex< double > z, double relerr=0)