Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "byte-swap.h"
00028
00029 #include "ov-re-diag.h"
00030 #include "ov-flt-re-diag.h"
00031 #include "ov-base-diag.cc"
00032 #include "ov-scalar.h"
00033 #include "ov-re-mat.h"
00034 #include "ls-utils.h"
00035
00036 template class octave_base_diag<DiagMatrix, Matrix>;
00037
00038 DEFINE_OCTAVE_ALLOCATOR (octave_diag_matrix);
00039
00040 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_diag_matrix, "diagonal matrix", "double");
00041
00042 static octave_base_value *
00043 default_numeric_conversion_function (const octave_base_value& a)
00044 {
00045 CAST_CONV_ARG (const octave_diag_matrix&);
00046
00047 return new octave_matrix (v.matrix_value ());
00048 }
00049
00050 octave_base_value::type_conv_info
00051 octave_diag_matrix::numeric_conversion_function (void) const
00052 {
00053 return octave_base_value::type_conv_info (default_numeric_conversion_function,
00054 octave_matrix::static_type_id ());
00055 }
00056
00057 static octave_base_value *
00058 default_numeric_demotion_function (const octave_base_value& a)
00059 {
00060 CAST_CONV_ARG (const octave_diag_matrix&);
00061
00062 return new octave_float_diag_matrix (v.float_diag_matrix_value ());
00063 }
00064
00065 octave_base_value::type_conv_info
00066 octave_diag_matrix::numeric_demotion_function (void) const
00067 {
00068 return octave_base_value::type_conv_info (default_numeric_demotion_function,
00069 octave_float_diag_matrix::static_type_id ());
00070 }
00071
00072 octave_base_value *
00073 octave_diag_matrix::try_narrowing_conversion (void)
00074 {
00075 octave_base_value *retval = 0;
00076
00077 if (matrix.nelem () == 1)
00078 retval = new octave_scalar (matrix (0, 0));
00079
00080 return retval;
00081 }
00082
00083 octave_value
00084 octave_diag_matrix::do_index_op (const octave_value_list& idx,
00085 bool resize_ok)
00086 {
00087 octave_value retval;
00088
00089
00090
00091
00092 if (! resize_ok && idx.length () == 2 && matrix.is_multiple_of_identity (1))
00093 {
00094 idx_vector idx0 = idx(0).index_vector ();
00095 idx_vector idx1 = idx(1).index_vector ();
00096
00097 if (! error_state)
00098 {
00099 bool left = idx0.is_permutation (matrix.rows ());
00100 bool right = idx1.is_permutation (matrix.cols ());
00101
00102 if (left && right)
00103 {
00104 if (idx0.is_colon ()) left = false;
00105 if (idx1.is_colon ()) right = false;
00106 if (left && right)
00107 retval = PermMatrix (idx0, false) * PermMatrix (idx1, true);
00108 else if (left)
00109 retval = PermMatrix (idx0, false);
00110 else if (right)
00111 retval = PermMatrix (idx1, true);
00112 else
00113 {
00114 retval = this;
00115 this->count++;
00116 }
00117 }
00118 }
00119 }
00120
00121
00122 if (! error_state && retval.is_undefined ())
00123 retval = octave_base_diag<DiagMatrix, Matrix>::do_index_op (idx, resize_ok);
00124
00125 return retval;
00126 }
00127
00128 DiagMatrix
00129 octave_diag_matrix::diag_matrix_value (bool) const
00130 {
00131 return matrix;
00132 }
00133
00134 FloatDiagMatrix
00135 octave_diag_matrix::float_diag_matrix_value (bool) const
00136 {
00137 return FloatDiagMatrix (matrix);
00138 }
00139
00140 ComplexDiagMatrix
00141 octave_diag_matrix::complex_diag_matrix_value (bool) const
00142 {
00143 return ComplexDiagMatrix (matrix);
00144 }
00145
00146 FloatComplexDiagMatrix
00147 octave_diag_matrix::float_complex_diag_matrix_value (bool) const
00148 {
00149 return FloatComplexDiagMatrix (matrix);
00150 }
00151
00152 octave_value
00153 octave_diag_matrix::map (unary_mapper_t umap) const
00154 {
00155 switch (umap)
00156 {
00157 case umap_abs:
00158 return matrix.abs ();
00159 case umap_real:
00160 case umap_conj:
00161 return matrix;
00162 case umap_imag:
00163 return DiagMatrix (matrix.rows (), matrix.cols (), 0.0);
00164 case umap_sqrt:
00165 {
00166 ComplexColumnVector tmp = matrix.diag ().map<Complex> (rc_sqrt);
00167 ComplexDiagMatrix retval (tmp);
00168 retval.resize (matrix.rows (), matrix.columns ());
00169 return retval;
00170 }
00171 default:
00172 return to_dense ().map (umap);
00173 }
00174 }
00175
00176 bool
00177 octave_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
00178 {
00179
00180 int32_t r = matrix.rows (), c = matrix.cols ();
00181 os.write (reinterpret_cast<char *> (&r), 4);
00182 os.write (reinterpret_cast<char *> (&c), 4);
00183
00184 Matrix m = Matrix (matrix.diag ());
00185 save_type st = LS_DOUBLE;
00186 if (save_as_floats)
00187 {
00188 if (m.too_large_for_float ())
00189 {
00190 warning ("save: some values too large to save as floats --");
00191 warning ("save: saving as doubles instead");
00192 }
00193 else
00194 st = LS_FLOAT;
00195 }
00196 else if (matrix.length () > 8192)
00197 {
00198 double max_val, min_val;
00199 if (m.all_integers (max_val, min_val))
00200 st = get_save_type (max_val, min_val);
00201 }
00202
00203 const double *mtmp = m.data ();
00204 write_doubles (os, mtmp, st, m.numel ());
00205
00206 return true;
00207 }
00208
00209 bool
00210 octave_diag_matrix::load_binary (std::istream& is, bool swap,
00211 oct_mach_info::float_format fmt)
00212 {
00213 int32_t r, c;
00214 char tmp;
00215 if (! (is.read (reinterpret_cast<char *> (&r), 4)
00216 && is.read (reinterpret_cast<char *> (&c), 4)
00217 && is.read (reinterpret_cast<char *> (&tmp), 1)))
00218 return false;
00219 if (swap)
00220 {
00221 swap_bytes<4> (&r);
00222 swap_bytes<4> (&c);
00223 }
00224
00225 DiagMatrix m (r, c);
00226 double *re = m.fortran_vec ();
00227 octave_idx_type len = m.length ();
00228 read_doubles (is, re, static_cast<save_type> (tmp), len, swap, fmt);
00229 if (error_state || ! is)
00230 return false;
00231 matrix = m;
00232
00233 return true;
00234 }
00235
00236 bool
00237 octave_diag_matrix::chk_valid_scalar (const octave_value& val,
00238 double& x) const
00239 {
00240 bool retval = val.is_real_scalar ();
00241 if (retval)
00242 x = val.double_value ();
00243 return retval;
00244 }