ov-flt-cx-mat.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 Copyright (C) 2009-2010 VZLU Prague
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
00021 
00022 */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027 
00028 #include <iostream>
00029 #include <vector>
00030 
00031 #include "data-conv.h"
00032 #include "lo-ieee.h"
00033 #include "lo-specfun.h"
00034 #include "lo-mappers.h"
00035 #include "mx-base.h"
00036 #include "mach-info.h"
00037 #include "oct-locbuf.h"
00038 
00039 #include "gripes.h"
00040 #include "oct-obj.h"
00041 #include "oct-stream.h"
00042 #include "ops.h"
00043 #include "ov-base.h"
00044 #include "ov-base-mat.h"
00045 #include "ov-base-mat.cc"
00046 #include "ov-complex.h"
00047 #include "ov-flt-complex.h"
00048 #include "ov-cx-mat.h"
00049 #include "ov-flt-cx-mat.h"
00050 #include "ov-re-mat.h"
00051 #include "ov-flt-re-mat.h"
00052 #include "ov-scalar.h"
00053 #include "ov-float.h"
00054 #include "pr-output.h"
00055 #include "ops.h"
00056 
00057 #include "byte-swap.h"
00058 #include "ls-oct-ascii.h"
00059 #include "ls-hdf5.h"
00060 #include "ls-utils.h"
00061 
00062 template class octave_base_matrix<FloatComplexNDArray>;
00063 
00064 DEFINE_OCTAVE_ALLOCATOR (octave_float_complex_matrix);
00065 
00066 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_matrix,
00067                                      "float complex matrix", "single");
00068 
00069 octave_base_value *
00070 octave_float_complex_matrix::try_narrowing_conversion (void)
00071 {
00072   octave_base_value *retval = 0;
00073 
00074   if (matrix.numel () == 1)
00075     {
00076       FloatComplex c = matrix (0);
00077 
00078       if (std::imag (c) == 0.0)
00079         retval = new octave_float_scalar (std::real (c));
00080       else
00081         retval = new octave_float_complex (c);
00082     }
00083   else if (matrix.all_elements_are_real ())
00084     retval = new octave_float_matrix (::real (matrix));
00085 
00086   return retval;
00087 }
00088 
00089 double
00090 octave_float_complex_matrix::double_value (bool force_conversion) const
00091 {
00092   double retval = lo_ieee_nan_value ();
00093 
00094   if (! force_conversion)
00095     gripe_implicit_conversion ("Octave:imag-to-real",
00096                                "complex matrix", "real scalar");
00097 
00098   if (rows () > 0 && columns () > 0)
00099     {
00100       gripe_implicit_conversion ("Octave:array-as-scalar",
00101                                  "complex matrix", "real scalar");
00102 
00103       retval = std::real (matrix (0, 0));
00104     }
00105   else
00106     gripe_invalid_conversion ("complex matrix", "real scalar");
00107 
00108   return retval;
00109 }
00110 
00111 float
00112 octave_float_complex_matrix::float_value (bool force_conversion) const
00113 {
00114   float retval = lo_ieee_float_nan_value ();
00115 
00116   if (! force_conversion)
00117     gripe_implicit_conversion ("Octave:imag-to-real",
00118                                "complex matrix", "real scalar");
00119 
00120   if (rows () > 0 && columns () > 0)
00121     {
00122       gripe_implicit_conversion ("Octave:array-as-scalar",
00123                                  "complex matrix", "real scalar");
00124 
00125       retval = std::real (matrix (0, 0));
00126     }
00127   else
00128     gripe_invalid_conversion ("complex matrix", "real scalar");
00129 
00130   return retval;
00131 }
00132 
00133 Matrix
00134 octave_float_complex_matrix::matrix_value (bool force_conversion) const
00135 {
00136   Matrix retval;
00137 
00138   if (! force_conversion)
00139     gripe_implicit_conversion ("Octave:imag-to-real",
00140                                "complex matrix", "real matrix");
00141 
00142   retval = ::real (matrix.matrix_value ());
00143 
00144   return retval;
00145 }
00146 
00147 FloatMatrix
00148 octave_float_complex_matrix::float_matrix_value (bool force_conversion) const
00149 {
00150   FloatMatrix retval;
00151 
00152   if (! force_conversion)
00153     gripe_implicit_conversion ("Octave:imag-to-real",
00154                                "complex matrix", "real matrix");
00155 
00156   retval = ::real (matrix.matrix_value ());
00157 
00158   return retval;
00159 }
00160 
00161 Complex
00162 octave_float_complex_matrix::complex_value (bool) const
00163 {
00164   double tmp = lo_ieee_nan_value ();
00165 
00166   Complex retval (tmp, tmp);
00167 
00168   if (rows () > 0 && columns () > 0)
00169     {
00170       gripe_implicit_conversion ("Octave:array-as-scalar",
00171                                  "complex matrix", "complex scalar");
00172 
00173       retval = matrix (0, 0);
00174     }
00175   else
00176     gripe_invalid_conversion ("complex matrix", "complex scalar");
00177 
00178   return retval;
00179 }
00180 
00181 FloatComplex
00182 octave_float_complex_matrix::float_complex_value (bool) const
00183 {
00184   float tmp = lo_ieee_float_nan_value ();
00185 
00186   FloatComplex retval (tmp, tmp);
00187 
00188   if (rows () > 0 && columns () > 0)
00189     {
00190       gripe_implicit_conversion ("Octave:array-as-scalar",
00191                                  "complex matrix", "complex scalar");
00192 
00193       retval = matrix (0, 0);
00194     }
00195   else
00196     gripe_invalid_conversion ("complex matrix", "complex scalar");
00197 
00198   return retval;
00199 }
00200 
00201 ComplexMatrix
00202 octave_float_complex_matrix::complex_matrix_value (bool) const
00203 {
00204   return matrix.matrix_value ();
00205 }
00206 
00207 FloatComplexMatrix
00208 octave_float_complex_matrix::float_complex_matrix_value (bool) const
00209 {
00210   return FloatComplexMatrix (matrix.matrix_value ());
00211 }
00212 
00213 boolNDArray
00214 octave_float_complex_matrix::bool_array_value (bool warn) const
00215 {
00216   if (matrix.any_element_is_nan ())
00217     gripe_nan_to_logical_conversion ();
00218   else if (warn && (! matrix.all_elements_are_real ()
00219                     || real (matrix).any_element_not_one_or_zero ()))
00220     gripe_logical_conversion ();
00221 
00222   return mx_el_ne (matrix, FloatComplex (0.0));
00223 }
00224 
00225 charNDArray
00226 octave_float_complex_matrix::char_array_value (bool frc_str_conv) const
00227 {
00228   charNDArray retval;
00229 
00230   if (! frc_str_conv)
00231     gripe_implicit_conversion ("Octave:num-to-str",
00232                                "complex matrix", "string");
00233   else
00234     {
00235       retval = charNDArray (dims ());
00236       octave_idx_type nel = numel ();
00237 
00238       for (octave_idx_type i = 0; i < nel; i++)
00239         retval.elem (i) = static_cast<char>(std::real (matrix.elem (i)));
00240     }
00241 
00242   return retval;
00243 }
00244 
00245 FloatComplexNDArray
00246 octave_float_complex_matrix::float_complex_array_value (bool) const
00247 {
00248   return FloatComplexNDArray (matrix);
00249 }
00250 
00251 SparseMatrix
00252 octave_float_complex_matrix::sparse_matrix_value (bool force_conversion) const
00253 {
00254   SparseMatrix retval;
00255 
00256   if (! force_conversion)
00257     gripe_implicit_conversion ("Octave:imag-to-real",
00258                                "complex matrix", "real matrix");
00259 
00260   retval = SparseMatrix (::real (complex_matrix_value ()));
00261 
00262   return retval;
00263 }
00264 
00265 SparseComplexMatrix
00266 octave_float_complex_matrix::sparse_complex_matrix_value (bool) const
00267 {
00268   return SparseComplexMatrix (complex_matrix_value ());
00269 }
00270 
00271 octave_value
00272 octave_float_complex_matrix::diag (octave_idx_type k) const
00273 {
00274   octave_value retval;
00275   if (k == 0 && matrix.ndims () == 2
00276       && (matrix.rows () == 1 || matrix.columns () == 1))
00277     retval = FloatComplexDiagMatrix (DiagArray2<FloatComplex> (matrix));
00278   else
00279     retval = octave_base_matrix<FloatComplexNDArray>::diag (k);
00280 
00281   return retval;
00282 }
00283 
00284 bool
00285 octave_float_complex_matrix::save_ascii (std::ostream& os)
00286 {
00287   dim_vector d = dims ();
00288   if (d.length () > 2)
00289     {
00290       FloatComplexNDArray tmp = complex_array_value ();
00291 
00292       os << "# ndims: " << d.length () << "\n";
00293 
00294       for (int i = 0; i < d.length (); i++)
00295         os << " " << d (i);
00296 
00297       os << "\n" << tmp;
00298     }
00299   else
00300     {
00301       // Keep this case, rather than use generic code above for backward
00302       // compatiability. Makes load_ascii much more complex!!
00303       os << "# rows: " << rows () << "\n"
00304          << "# columns: " << columns () << "\n";
00305 
00306       os << complex_matrix_value ();
00307     }
00308 
00309   return true;
00310 }
00311 
00312 bool
00313 octave_float_complex_matrix::load_ascii (std::istream& is)
00314 {
00315   bool success = true;
00316 
00317   string_vector keywords(2);
00318 
00319   keywords[0] = "ndims";
00320   keywords[1] = "rows";
00321 
00322   std::string kw;
00323   octave_idx_type val = 0;
00324 
00325   if (extract_keyword (is, keywords, kw, val, true))
00326     {
00327       if (kw == "ndims")
00328         {
00329           int mdims = static_cast<int> (val);
00330 
00331           if (mdims >= 0)
00332             {
00333               dim_vector dv;
00334               dv.resize (mdims);
00335 
00336               for (int i = 0; i < mdims; i++)
00337                 is >> dv(i);
00338 
00339               if (is)
00340                 {
00341                   FloatComplexNDArray tmp(dv);
00342 
00343                   is >> tmp;
00344 
00345                   if (is)
00346                     matrix = tmp;
00347                   else
00348                     {
00349                       error ("load: failed to load matrix constant");
00350                       success = false;
00351                     }
00352                 }
00353               else
00354                 {
00355                   error ("load: failed to read dimensions");
00356                   success = false;
00357                 }
00358             }
00359           else
00360             {
00361               error ("load: failed to extract number of dimensions");
00362               success = false;
00363             }
00364         }
00365       else if (kw == "rows")
00366         {
00367           octave_idx_type nr = val;
00368           octave_idx_type nc = 0;
00369 
00370           if (nr >= 0 && extract_keyword (is, "columns", nc) && nc >= 0)
00371             {
00372               if (nr > 0 && nc > 0)
00373                 {
00374                   FloatComplexMatrix tmp (nr, nc);
00375                   is >> tmp;
00376                   if (is)
00377                     matrix = tmp;
00378                   else
00379                     {
00380                       error ("load: failed to load matrix constant");
00381                       success = false;
00382                     }
00383                 }
00384               else if (nr == 0 || nc == 0)
00385                 matrix = FloatComplexMatrix (nr, nc);
00386               else
00387                 panic_impossible ();
00388             }
00389           else
00390             {
00391               error ("load: failed to extract number of rows and columns");
00392               success = false;
00393             }
00394         }
00395       else
00396         panic_impossible ();
00397     }
00398   else
00399     {
00400       error ("load: failed to extract number of rows and columns");
00401       success = false;
00402     }
00403 
00404   return success;
00405 }
00406 
00407 bool
00408 octave_float_complex_matrix::save_binary (std::ostream& os, bool&)
00409 {
00410   dim_vector d = dims ();
00411   if (d.length() < 1)
00412     return false;
00413 
00414   // Use negative value for ndims to differentiate with old format!!
00415   int32_t tmp = - d.length();
00416   os.write (reinterpret_cast<char *> (&tmp), 4);
00417   for (int i = 0; i < d.length (); i++)
00418     {
00419       tmp = d(i);
00420       os.write (reinterpret_cast<char *> (&tmp), 4);
00421     }
00422 
00423   FloatComplexNDArray m = complex_array_value ();
00424   save_type st = LS_FLOAT;
00425   if (d.numel () > 4096) // FIXME -- make this configurable.
00426     {
00427       float max_val, min_val;
00428       if (m.all_integers (max_val, min_val))
00429         st = get_save_type (max_val, min_val);
00430     }
00431 
00432   const FloatComplex *mtmp = m.data ();
00433   write_floats (os, reinterpret_cast<const float *> (mtmp), st, 2 * d.numel ());
00434 
00435   return true;
00436 }
00437 
00438 bool
00439 octave_float_complex_matrix::load_binary (std::istream& is, bool swap,
00440                                  oct_mach_info::float_format fmt)
00441 {
00442   char tmp;
00443   int32_t mdims;
00444   if (! is.read (reinterpret_cast<char *> (&mdims), 4))
00445     return false;
00446   if (swap)
00447     swap_bytes<4> (&mdims);
00448   if (mdims < 0)
00449     {
00450       mdims = - mdims;
00451       int32_t di;
00452       dim_vector dv;
00453       dv.resize (mdims);
00454 
00455       for (int i = 0; i < mdims; i++)
00456         {
00457           if (! is.read (reinterpret_cast<char *> (&di), 4))
00458             return false;
00459           if (swap)
00460             swap_bytes<4> (&di);
00461           dv(i) = di;
00462         }
00463 
00464       // Convert an array with a single dimension to be a row vector.
00465       // Octave should never write files like this, other software
00466       // might.
00467 
00468       if (mdims == 1)
00469         {
00470           mdims = 2;
00471           dv.resize (mdims);
00472           dv(1) = dv(0);
00473           dv(0) = 1;
00474         }
00475 
00476       if (! is.read (reinterpret_cast<char *> (&tmp), 1))
00477         return false;
00478 
00479       FloatComplexNDArray m(dv);
00480       FloatComplex *im = m.fortran_vec ();
00481       read_floats (is, reinterpret_cast<float *> (im),
00482                     static_cast<save_type> (tmp), 2 * dv.numel (), swap, fmt);
00483       if (error_state || ! is)
00484         return false;
00485       matrix = m;
00486     }
00487   else
00488     {
00489       int32_t nr, nc;
00490       nr = mdims;
00491       if (! is.read (reinterpret_cast<char *> (&nc), 4))
00492         return false;
00493       if (swap)
00494         swap_bytes<4> (&nc);
00495       if (! is.read (reinterpret_cast<char *> (&tmp), 1))
00496         return false;
00497       FloatComplexMatrix m (nr, nc);
00498       FloatComplex *im = m.fortran_vec ();
00499       octave_idx_type len = nr * nc;
00500       read_floats (is, reinterpret_cast<float *> (im),
00501                     static_cast<save_type> (tmp), 2*len, swap, fmt);
00502       if (error_state || ! is)
00503         return false;
00504       matrix = m;
00505     }
00506   return true;
00507 }
00508 
00509 #if defined (HAVE_HDF5)
00510 
00511 bool
00512 octave_float_complex_matrix::save_hdf5 (hid_t loc_id, const char *name, bool)
00513 {
00514   dim_vector dv = dims ();
00515   int empty = save_hdf5_empty (loc_id, name, dv);
00516   if (empty)
00517     return (empty > 0);
00518 
00519   int rank = dv.length ();
00520   hid_t space_hid = -1, data_hid = -1, type_hid = -1;
00521   bool retval = true;
00522   FloatComplexNDArray m = complex_array_value ();
00523 
00524   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
00525 
00526   // Octave uses column-major, while HDF5 uses row-major ordering
00527   for (int i = 0; i < rank; i++)
00528     hdims[i] = dv (rank-i-1);
00529 
00530   space_hid = H5Screate_simple (rank, hdims, 0);
00531   if (space_hid < 0) return false;
00532 
00533   hid_t save_type_hid = H5T_NATIVE_FLOAT;
00534 
00535 #if HAVE_HDF5_INT2FLOAT_CONVERSIONS
00536   // hdf5 currently doesn't support float/integer conversions
00537   else
00538     {
00539       float max_val, min_val;
00540 
00541       if (m.all_integers (max_val, min_val))
00542         save_type_hid
00543           = save_type_to_hdf5 (get_save_type (max_val, min_val));
00544     }
00545 #endif /* HAVE_HDF5_INT2FLOAT_CONVERSIONS */
00546 
00547   type_hid = hdf5_make_complex_type (save_type_hid);
00548   if (type_hid < 0)
00549     {
00550       H5Sclose (space_hid);
00551       return false;
00552     }
00553 #if HAVE_HDF5_18
00554   data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
00555                         H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00556 #else
00557   data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
00558 #endif
00559   if (data_hid < 0)
00560     {
00561       H5Sclose (space_hid);
00562       H5Tclose (type_hid);
00563       return false;
00564     }
00565 
00566   hid_t complex_type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
00567   if (complex_type_hid < 0) retval = false;
00568 
00569   if (retval)
00570     {
00571       FloatComplex *mtmp = m.fortran_vec ();
00572       if (H5Dwrite (data_hid, complex_type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00573                     mtmp) < 0)
00574         {
00575           H5Tclose (complex_type_hid);
00576           retval = false;
00577         }
00578     }
00579 
00580   H5Tclose (complex_type_hid);
00581   H5Dclose (data_hid);
00582   H5Tclose (type_hid);
00583   H5Sclose (space_hid);
00584 
00585   return retval;
00586 }
00587 
00588 bool
00589 octave_float_complex_matrix::load_hdf5 (hid_t loc_id, const char *name)
00590 {
00591   bool retval = false;
00592 
00593   dim_vector dv;
00594   int empty = load_hdf5_empty (loc_id, name, dv);
00595   if (empty > 0)
00596     matrix.resize(dv);
00597   if (empty)
00598       return (empty > 0);
00599 
00600 #if HAVE_HDF5_18
00601   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
00602 #else
00603   hid_t data_hid = H5Dopen (loc_id, name);
00604 #endif
00605   hid_t type_hid = H5Dget_type (data_hid);
00606 
00607   hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
00608 
00609   if (! hdf5_types_compatible (type_hid, complex_type))
00610     {
00611       H5Tclose (complex_type);
00612       H5Dclose (data_hid);
00613       return false;
00614     }
00615 
00616   hid_t space_id = H5Dget_space (data_hid);
00617 
00618   hsize_t rank = H5Sget_simple_extent_ndims (space_id);
00619 
00620   if (rank < 1)
00621     {
00622       H5Tclose (complex_type);
00623       H5Sclose (space_id);
00624       H5Dclose (data_hid);
00625       return false;
00626     }
00627 
00628   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
00629   OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
00630 
00631   H5Sget_simple_extent_dims (space_id, hdims, maxdims);
00632 
00633   // Octave uses column-major, while HDF5 uses row-major ordering
00634   if (rank == 1)
00635     {
00636       dv.resize (2);
00637       dv(0) = 1;
00638       dv(1) = hdims[0];
00639     }
00640   else
00641     {
00642       dv.resize (rank);
00643       for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
00644         dv(j) = hdims[i];
00645     }
00646 
00647   FloatComplexNDArray m (dv);
00648   FloatComplex *reim = m.fortran_vec ();
00649   if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
00650                reim) >= 0)
00651     {
00652       retval = true;
00653       matrix = m;
00654     }
00655 
00656   H5Tclose (complex_type);
00657   H5Sclose (space_id);
00658   H5Dclose (data_hid);
00659 
00660   return retval;
00661 }
00662 
00663 #endif
00664 
00665 void
00666 octave_float_complex_matrix::print_raw (std::ostream& os,
00667                                   bool pr_as_read_syntax) const
00668 {
00669   octave_print_internal (os, matrix, pr_as_read_syntax,
00670                          current_print_indent_level ());
00671 }
00672 
00673 mxArray *
00674 octave_float_complex_matrix::as_mxArray (void) const
00675 {
00676   mxArray *retval = new mxArray (mxSINGLE_CLASS, dims (), mxCOMPLEX);
00677 
00678   float *pr = static_cast<float *> (retval->get_data ());
00679   float *pi = static_cast<float *> (retval->get_imag_data ());
00680 
00681   mwSize nel = numel ();
00682 
00683   const FloatComplex *p = matrix.data ();
00684 
00685   for (mwIndex i = 0; i < nel; i++)
00686     {
00687       pr[i] = std::real (p[i]);
00688       pi[i] = std::imag (p[i]);
00689     }
00690 
00691   return retval;
00692 }
00693 
00694 octave_value
00695 octave_float_complex_matrix::map (unary_mapper_t umap) const
00696 {
00697   switch (umap)
00698     {
00699     // Mappers handled specially.
00700     case umap_real:
00701       return ::real (matrix);
00702     case umap_imag:
00703       return ::imag (matrix);
00704     case umap_conj:
00705       return ::conj (matrix);
00706 
00707 #define ARRAY_METHOD_MAPPER(UMAP, FCN) \
00708     case umap_ ## UMAP: \
00709       return octave_value (matrix.FCN ())
00710 
00711       ARRAY_METHOD_MAPPER (abs, abs);
00712       ARRAY_METHOD_MAPPER (isnan, isnan);
00713       ARRAY_METHOD_MAPPER (isinf, isinf);
00714       ARRAY_METHOD_MAPPER (finite, isfinite);
00715 
00716 #define ARRAY_MAPPER(UMAP, TYPE, FCN) \
00717     case umap_ ## UMAP: \
00718       return octave_value (matrix.map<TYPE> (FCN))
00719 
00720       ARRAY_MAPPER (acos, FloatComplex, ::acos);
00721       ARRAY_MAPPER (acosh, FloatComplex, ::acosh);
00722       ARRAY_MAPPER (angle, float, std::arg);
00723       ARRAY_MAPPER (arg, float, std::arg);
00724       ARRAY_MAPPER (asin, FloatComplex, ::asin);
00725       ARRAY_MAPPER (asinh, FloatComplex, ::asinh);
00726       ARRAY_MAPPER (atan, FloatComplex, ::atan);
00727       ARRAY_MAPPER (atanh, FloatComplex, ::atanh);
00728       ARRAY_MAPPER (ceil, FloatComplex, ::ceil);
00729       ARRAY_MAPPER (cos, FloatComplex, std::cos);
00730       ARRAY_MAPPER (cosh, FloatComplex, std::cosh);
00731       ARRAY_MAPPER (exp, FloatComplex, std::exp);
00732       ARRAY_MAPPER (expm1, FloatComplex, ::expm1);
00733       ARRAY_MAPPER (fix, FloatComplex, ::fix);
00734       ARRAY_MAPPER (floor, FloatComplex, ::floor);
00735       ARRAY_MAPPER (log, FloatComplex, std::log);
00736       ARRAY_MAPPER (log2, FloatComplex, xlog2);
00737       ARRAY_MAPPER (log10, FloatComplex, std::log10);
00738       ARRAY_MAPPER (log1p, FloatComplex, ::log1p);
00739       ARRAY_MAPPER (round, FloatComplex, xround);
00740       ARRAY_MAPPER (roundb, FloatComplex, xroundb);
00741       ARRAY_MAPPER (signum, FloatComplex, ::signum);
00742       ARRAY_MAPPER (sin, FloatComplex, std::sin);
00743       ARRAY_MAPPER (sinh, FloatComplex, std::sinh);
00744       ARRAY_MAPPER (sqrt, FloatComplex, std::sqrt);
00745       ARRAY_MAPPER (tan, FloatComplex, std::tan);
00746       ARRAY_MAPPER (tanh, FloatComplex, std::tanh);
00747       ARRAY_MAPPER (isna, bool, octave_is_NA);
00748 
00749     default:
00750       return octave_base_value::map (umap);
00751     }
00752 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines