ov-cx-diag.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2008-2012 Jaroslav Hajek
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "byte-swap.h"
00028 
00029 #include "ov-cx-diag.h"
00030 #include "ov-flt-cx-diag.h"
00031 #include "ov-re-diag.h"
00032 #include "ov-base-diag.cc"
00033 #include "ov-complex.h"
00034 #include "ov-cx-mat.h"
00035 #include "ls-utils.h"
00036 
00037 template class octave_base_diag<ComplexDiagMatrix, ComplexMatrix>;
00038 
00039 DEFINE_OCTAVE_ALLOCATOR (octave_complex_diag_matrix);
00040 
00041 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_diag_matrix,
00042                                      "complex diagonal matrix", "double");
00043 
00044 static octave_base_value *
00045 default_numeric_conversion_function (const octave_base_value& a)
00046 {
00047   CAST_CONV_ARG (const octave_complex_diag_matrix&);
00048 
00049   return new octave_complex_matrix (v.complex_matrix_value ());
00050 }
00051 
00052 octave_base_value::type_conv_info
00053 octave_complex_diag_matrix::numeric_conversion_function (void) const
00054 {
00055   return octave_base_value::type_conv_info (default_numeric_conversion_function,
00056                                             octave_complex_matrix::static_type_id ());
00057 }
00058 
00059 static octave_base_value *
00060 default_numeric_demotion_function (const octave_base_value& a)
00061 {
00062   CAST_CONV_ARG (const octave_complex_diag_matrix&);
00063 
00064   return new octave_float_complex_diag_matrix (v.float_complex_diag_matrix_value ());
00065 }
00066 
00067 octave_base_value::type_conv_info
00068 octave_complex_diag_matrix::numeric_demotion_function (void) const
00069 {
00070   return octave_base_value::type_conv_info (default_numeric_demotion_function,
00071                                             octave_float_complex_diag_matrix::static_type_id ());
00072 }
00073 
00074 octave_base_value *
00075 octave_complex_diag_matrix::try_narrowing_conversion (void)
00076 {
00077   octave_base_value *retval = 0;
00078 
00079   if (matrix.nelem () == 1)
00080     {
00081       retval = new octave_complex (matrix (0, 0));
00082       octave_base_value *rv2 = retval->try_narrowing_conversion ();
00083       if (rv2)
00084         {
00085           delete retval;
00086           retval = rv2;
00087         }
00088     }
00089   else if (matrix.all_elements_are_real ())
00090     {
00091       return new octave_diag_matrix (::real (matrix));
00092     }
00093 
00094   return retval;
00095 }
00096 
00097 DiagMatrix
00098 octave_complex_diag_matrix::diag_matrix_value (bool force_conversion) const
00099 {
00100   DiagMatrix retval;
00101 
00102   if (! force_conversion)
00103     gripe_implicit_conversion ("Octave:imag-to-real",
00104                                type_name (), "real matrix");
00105 
00106   retval = ::real (matrix);
00107 
00108   return retval;
00109 }
00110 
00111 FloatDiagMatrix
00112 octave_complex_diag_matrix::float_diag_matrix_value (bool force_conversion) const
00113 {
00114   DiagMatrix retval;
00115 
00116   if (! force_conversion)
00117     gripe_implicit_conversion ("Octave:imag-to-real",
00118                                type_name (), "real matrix");
00119 
00120   retval = ::real (matrix);
00121 
00122   return retval;
00123 }
00124 
00125 ComplexDiagMatrix
00126 octave_complex_diag_matrix::complex_diag_matrix_value (bool) const
00127 {
00128   return matrix;
00129 }
00130 
00131 FloatComplexDiagMatrix
00132 octave_complex_diag_matrix::float_complex_diag_matrix_value (bool) const
00133 {
00134   return FloatComplexDiagMatrix (matrix);
00135 }
00136 
00137 octave_value
00138 octave_complex_diag_matrix::map (unary_mapper_t umap) const
00139 {
00140   switch (umap)
00141     {
00142     case umap_abs:
00143       return matrix.abs ();
00144     case umap_real:
00145       return ::real (matrix);
00146     case umap_conj:
00147       return ::conj (matrix);
00148     case umap_imag:
00149       return ::imag (matrix);
00150     case umap_sqrt:
00151       {
00152         ComplexColumnVector tmp = matrix.diag ().map<Complex> (std::sqrt);
00153         ComplexDiagMatrix retval (tmp);
00154         retval.resize (matrix.rows (), matrix.columns ());
00155         return retval;
00156       }
00157     default:
00158       return to_dense ().map (umap);
00159     }
00160 }
00161 
00162 bool
00163 octave_complex_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
00164 {
00165 
00166   int32_t r = matrix.rows (), c = matrix.cols ();
00167   os.write (reinterpret_cast<char *> (&r), 4);
00168   os.write (reinterpret_cast<char *> (&c), 4);
00169 
00170   ComplexMatrix m = ComplexMatrix (matrix.diag ());
00171   save_type st = LS_DOUBLE;
00172   if (save_as_floats)
00173     {
00174       if (m.too_large_for_float ())
00175         {
00176           warning ("save: some values too large to save as floats --");
00177           warning ("save: saving as doubles instead");
00178         }
00179       else
00180         st = LS_FLOAT;
00181     }
00182   else if (matrix.length () > 4096) // FIXME -- make this configurable.
00183     {
00184       double max_val, min_val;
00185       if (m.all_integers (max_val, min_val))
00186         st = get_save_type (max_val, min_val);
00187     }
00188 
00189   const Complex *mtmp = m.data ();
00190   write_doubles (os, reinterpret_cast<const double *> (mtmp), st, 2 * m.numel ());
00191 
00192   return true;
00193 }
00194 
00195 bool
00196 octave_complex_diag_matrix::load_binary (std::istream& is, bool swap,
00197                                  oct_mach_info::float_format fmt)
00198 {
00199   int32_t r, c;
00200   char tmp;
00201   if (! (is.read (reinterpret_cast<char *> (&r), 4)
00202          && is.read (reinterpret_cast<char *> (&c), 4)
00203          && is.read (reinterpret_cast<char *> (&tmp), 1)))
00204     return false;
00205   if (swap)
00206     {
00207       swap_bytes<4> (&r);
00208       swap_bytes<4> (&c);
00209     }
00210 
00211   ComplexDiagMatrix m (r, c);
00212   Complex *im = m.fortran_vec ();
00213   octave_idx_type len = m.length ();
00214   read_doubles (is, reinterpret_cast<double *> (im),
00215                 static_cast<save_type> (tmp), 2 * len, swap, fmt);
00216   if (error_state || ! is)
00217     return false;
00218   matrix = m;
00219 
00220   return true;
00221 }
00222 
00223 bool
00224 octave_complex_diag_matrix::chk_valid_scalar (const octave_value& val,
00225                                               Complex& x) const
00226 {
00227   bool retval = val.is_complex_scalar () || val.is_real_scalar ();
00228   if (retval)
00229     x = val.complex_value ();
00230   return retval;
00231 }
00232 
00233 /*
00234 
00235 %% bug #36368
00236 %!assert (diag ([1+i, 1-i])^2 , diag ([2i, -2i]), 4*eps);
00237 
00238 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines