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