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 <iostream>
00028
00029 #include "mach-info.h"
00030 #include "lo-ieee.h"
00031
00032 #include "ov-base.h"
00033 #include "ov-base-mat.h"
00034 #include "pr-output.h"
00035 #include "error.h"
00036 #include "gripes.h"
00037 #include "oct-stream.h"
00038 #include "ops.h"
00039
00040 #include "ls-oct-ascii.h"
00041
00042 template <class DMT, class MT>
00043 octave_value
00044 octave_base_diag<DMT, MT>::subsref (const std::string& type,
00045 const std::list<octave_value_list>& idx)
00046 {
00047 octave_value retval;
00048
00049 switch (type[0])
00050 {
00051 case '(':
00052 retval = do_index_op (idx.front ());
00053 break;
00054
00055 case '{':
00056 case '.':
00057 {
00058 std::string nm = type_name ();
00059 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00060 }
00061 break;
00062
00063 default:
00064 panic_impossible ();
00065 }
00066
00067 return retval.next_subsref (type, idx);
00068 }
00069
00070
00071 template <class DMT, class MT>
00072 octave_value
00073 octave_base_diag<DMT,MT>::diag (octave_idx_type k) const
00074 {
00075 octave_value retval;
00076 if (matrix.rows () == 1 || matrix.cols () == 1)
00077 {
00078
00079
00080
00081
00082 if (k == 0)
00083
00084 retval = matrix.build_diag_matrix ();
00085 else
00086
00087 retval = matrix.array_value ().diag (k);
00088 }
00089 else
00090
00091 retval = matrix.extract_diag (k);
00092 return retval;
00093 }
00094
00095
00096 template <class DMT, class MT>
00097 octave_value
00098 octave_base_diag<DMT, MT>::do_index_op (const octave_value_list& idx,
00099 bool resize_ok)
00100 {
00101 octave_value retval;
00102 typedef typename DMT::element_type el_type;
00103
00104 if (idx.length () == 2 && ! resize_ok)
00105 {
00106 idx_vector idx0 = idx(0).index_vector ();
00107 idx_vector idx1 = idx(1).index_vector ();
00108
00109 if (idx0.is_scalar () && idx1.is_scalar ())
00110 {
00111 retval = matrix.elem (idx0(0), idx1(0));
00112 }
00113 else
00114 {
00115 octave_idx_type m = idx0.length (matrix.rows ());
00116 octave_idx_type n = idx1.length (matrix.columns ());
00117 if (idx0.is_colon_equiv (m) && idx1.is_colon_equiv (n)
00118 && m <= matrix.rows () && n <= matrix.rows ())
00119 {
00120 DMT rm (matrix);
00121 rm.resize (m, n);
00122 retval = rm;
00123 }
00124 else
00125 retval = to_dense ().do_index_op (idx, resize_ok);
00126 }
00127 }
00128 else
00129 retval = to_dense ().do_index_op (idx, resize_ok);
00130
00131 return retval;
00132 }
00133
00134 template <class DMT, class MT>
00135 octave_value
00136 octave_base_diag<DMT, MT>::subsasgn (const std::string& type,
00137 const std::list<octave_value_list>& idx,
00138 const octave_value& rhs)
00139 {
00140 octave_value retval;
00141
00142 switch (type[0])
00143 {
00144 case '(':
00145 {
00146 if (type.length () == 1)
00147 {
00148 octave_value_list jdx = idx.front ();
00149
00150
00151 if (jdx.length () == 2 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ())
00152 {
00153 typename DMT::element_type val;
00154 idx_vector i0 = jdx(0).index_vector (), i1 = jdx(1).index_vector ();
00155 if (! error_state && i0(0) == i1(0)
00156 && i0(0) < matrix.rows () && i1(0) < matrix.cols ()
00157 && chk_valid_scalar (rhs, val))
00158 {
00159 matrix.dgelem (i0(0)) = val;
00160 retval = this;
00161 this->count++;
00162
00163 dense_cache = octave_value ();
00164 }
00165 }
00166
00167 if (! error_state && ! retval.is_defined ())
00168 retval = numeric_assign (type, idx, rhs);
00169 }
00170 else
00171 {
00172 std::string nm = type_name ();
00173 error ("in indexed assignment of %s, last lhs index must be ()",
00174 nm.c_str ());
00175 }
00176 }
00177 break;
00178
00179 case '{':
00180 case '.':
00181 {
00182 if (is_empty ())
00183 {
00184 octave_value tmp = octave_value::empty_conv (type, rhs);
00185
00186 retval = tmp.subsasgn (type, idx, rhs);
00187 }
00188 else
00189 {
00190 std::string nm = type_name ();
00191 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00192 }
00193 }
00194 break;
00195
00196 default:
00197 panic_impossible ();
00198 }
00199
00200 return retval;
00201 }
00202
00203 template <class DMT, class MT>
00204 octave_value
00205 octave_base_diag<DMT, MT>::resize (const dim_vector& dv, bool fill) const
00206 {
00207 octave_value retval;
00208 if (dv.length () == 2)
00209 {
00210 DMT rm (matrix);
00211 rm.resize (dv(0), dv(1));
00212 retval = rm;
00213 }
00214 else
00215 retval = to_dense ().resize (dv, fill);
00216 return retval;
00217 }
00218
00219 template <class DMT, class MT>
00220 bool
00221 octave_base_diag<DMT, MT>::is_true (void) const
00222 {
00223 return to_dense ().is_true ();
00224 }
00225
00226
00227 template <class T> inline T helper_getreal (T x) { return x; }
00228 template <class T> inline T helper_getreal (std::complex<T> x) { return x.real (); }
00229
00230 template <class T> inline T helper_iscomplex (T) { return false; }
00231 template <class T> inline T helper_iscomplex (std::complex<T>) { return true; }
00232
00233 template <class DMT, class MT>
00234 double
00235 octave_base_diag<DMT, MT>::double_value (bool force_conversion) const
00236 {
00237 double retval = lo_ieee_nan_value ();
00238 typedef typename DMT::element_type el_type;
00239
00240 if (helper_iscomplex (el_type ()) && ! force_conversion)
00241 gripe_implicit_conversion ("Octave:imag-to-real",
00242 "complex matrix", "real scalar");
00243
00244 if (numel () > 0)
00245 {
00246 gripe_implicit_conversion ("Octave:array-as-scalar",
00247 type_name (), "real scalar");
00248
00249 retval = helper_getreal (el_type (matrix (0, 0)));
00250 }
00251 else
00252 gripe_invalid_conversion (type_name (), "real scalar");
00253
00254 return retval;
00255 }
00256
00257 template <class DMT, class MT>
00258 float
00259 octave_base_diag<DMT, MT>::float_value (bool force_conversion) const
00260 {
00261 float retval = lo_ieee_float_nan_value ();
00262 typedef typename DMT::element_type el_type;
00263
00264 if (helper_iscomplex (el_type ()) && ! force_conversion)
00265 gripe_implicit_conversion ("Octave:imag-to-real",
00266 "complex matrix", "real scalar");
00267
00268 if (numel () > 0)
00269 {
00270 gripe_implicit_conversion ("Octave:array-as-scalar",
00271 type_name (), "real scalar");
00272
00273 retval = helper_getreal (el_type (matrix (0, 0)));
00274 }
00275 else
00276 gripe_invalid_conversion (type_name (), "real scalar");
00277
00278 return retval;
00279 }
00280
00281 template <class DMT, class MT>
00282 Complex
00283 octave_base_diag<DMT, MT>::complex_value (bool) const
00284 {
00285 double tmp = lo_ieee_nan_value ();
00286
00287 Complex retval (tmp, tmp);
00288
00289 if (rows () > 0 && columns () > 0)
00290 {
00291 gripe_implicit_conversion ("Octave:array-as-scalar",
00292 type_name (), "complex scalar");
00293
00294 retval = matrix (0, 0);
00295 }
00296 else
00297 gripe_invalid_conversion (type_name (), "complex scalar");
00298
00299 return retval;
00300 }
00301
00302 template <class DMT, class MT>
00303 FloatComplex
00304 octave_base_diag<DMT, MT>::float_complex_value (bool) const
00305 {
00306 float tmp = lo_ieee_float_nan_value ();
00307
00308 FloatComplex retval (tmp, tmp);
00309
00310 if (rows () > 0 && columns () > 0)
00311 {
00312 gripe_implicit_conversion ("Octave:array-as-scalar",
00313 type_name (), "complex scalar");
00314
00315 retval = matrix (0, 0);
00316 }
00317 else
00318 gripe_invalid_conversion (type_name (), "complex scalar");
00319
00320 return retval;
00321 }
00322
00323 template <class DMT, class MT>
00324 Matrix
00325 octave_base_diag<DMT, MT>::matrix_value (bool) const
00326 {
00327 return Matrix (diag_matrix_value ());
00328 }
00329
00330 template <class DMT, class MT>
00331 FloatMatrix
00332 octave_base_diag<DMT, MT>::float_matrix_value (bool) const
00333 {
00334 return FloatMatrix (float_diag_matrix_value ());
00335 }
00336
00337 template <class DMT, class MT>
00338 ComplexMatrix
00339 octave_base_diag<DMT, MT>::complex_matrix_value (bool) const
00340 {
00341 return ComplexMatrix (complex_diag_matrix_value ());
00342 }
00343
00344 template <class DMT, class MT>
00345 FloatComplexMatrix
00346 octave_base_diag<DMT, MT>::float_complex_matrix_value (bool) const
00347 {
00348 return FloatComplexMatrix (float_complex_diag_matrix_value ());
00349 }
00350
00351 template <class DMT, class MT>
00352 NDArray
00353 octave_base_diag<DMT, MT>::array_value (bool) const
00354 {
00355 return NDArray (matrix_value ());
00356 }
00357
00358 template <class DMT, class MT>
00359 FloatNDArray
00360 octave_base_diag<DMT, MT>::float_array_value (bool) const
00361 {
00362 return FloatNDArray (float_matrix_value ());
00363 }
00364
00365 template <class DMT, class MT>
00366 ComplexNDArray
00367 octave_base_diag<DMT, MT>::complex_array_value (bool) const
00368 {
00369 return ComplexNDArray (complex_matrix_value ());
00370 }
00371
00372 template <class DMT, class MT>
00373 FloatComplexNDArray
00374 octave_base_diag<DMT, MT>::float_complex_array_value (bool) const
00375 {
00376 return FloatComplexNDArray (float_complex_matrix_value ());
00377 }
00378
00379 template <class DMT, class MT>
00380 boolNDArray
00381 octave_base_diag<DMT, MT>::bool_array_value (bool warn) const
00382 {
00383 return to_dense ().bool_array_value (warn);
00384 }
00385
00386 template <class DMT, class MT>
00387 charNDArray
00388 octave_base_diag<DMT, MT>::char_array_value (bool warn) const
00389 {
00390 return to_dense ().char_array_value (warn);
00391 }
00392
00393 template <class DMT, class MT>
00394 SparseMatrix
00395 octave_base_diag<DMT, MT>::sparse_matrix_value (bool) const
00396 {
00397 return SparseMatrix (diag_matrix_value ());
00398 }
00399
00400 template <class DMT, class MT>
00401 SparseComplexMatrix
00402 octave_base_diag<DMT, MT>::sparse_complex_matrix_value (bool) const
00403 {
00404 return SparseComplexMatrix (complex_diag_matrix_value ());
00405 }
00406
00407 template <class DMT, class MT>
00408 idx_vector
00409 octave_base_diag<DMT, MT>::index_vector (void) const
00410 {
00411 return to_dense ().index_vector ();
00412 }
00413
00414 template <class DMT, class MT>
00415 octave_value
00416 octave_base_diag<DMT, MT>::convert_to_str_internal (bool pad, bool force, char type) const
00417 {
00418 return to_dense ().convert_to_str_internal (pad, force, type);
00419 }
00420
00421 template <class DMT, class MT>
00422 bool
00423 octave_base_diag<DMT, MT>::save_ascii (std::ostream& os)
00424 {
00425 os << "# rows: " << matrix.rows () << "\n"
00426 << "# columns: " << matrix.columns () << "\n";
00427
00428 os << matrix.diag ();
00429
00430 return true;
00431 }
00432
00433 template <class DMT, class MT>
00434 bool
00435 octave_base_diag<DMT, MT>::load_ascii (std::istream& is)
00436 {
00437 octave_idx_type r = 0, c = 0;
00438 bool success = true;
00439
00440 if (extract_keyword (is, "rows", r, true)
00441 && extract_keyword (is, "columns", c, true))
00442 {
00443 octave_idx_type l = r < c ? r : c;
00444 MT tmp (l, 1);
00445 is >> tmp;
00446
00447 if (!is)
00448 {
00449 error ("load: failed to load diagonal matrix constant");
00450 success = false;
00451 }
00452 else
00453 {
00454
00455
00456
00457 typedef typename DMT::element_type el_type;
00458 matrix = DMT (MDiagArray2<el_type> (MArray<el_type> (tmp)));
00459 matrix.resize (r, c);
00460
00461
00462 dense_cache = octave_value ();
00463 }
00464 }
00465 else
00466 {
00467 error ("load: failed to extract number of rows and columns");
00468 success = false;
00469 }
00470
00471 return success;
00472 }
00473
00474 template <class DMT, class MT>
00475 void
00476 octave_base_diag<DMT, MT>::print_raw (std::ostream& os,
00477 bool pr_as_read_syntax) const
00478 {
00479 return octave_print_internal (os, matrix, pr_as_read_syntax,
00480 current_print_indent_level ());
00481 }
00482
00483 template <class DMT, class MT>
00484 mxArray *
00485 octave_base_diag<DMT, MT>::as_mxArray (void) const
00486 {
00487 return to_dense ().as_mxArray ();
00488 }
00489
00490 template <class DMT, class MT>
00491 bool
00492 octave_base_diag<DMT, MT>::print_as_scalar (void) const
00493 {
00494 dim_vector dv = dims ();
00495
00496 return (dv.all_ones () || dv.any_zero ());
00497 }
00498
00499 template <class DMT, class MT>
00500 void
00501 octave_base_diag<DMT, MT>::print (std::ostream& os, bool pr_as_read_syntax) const
00502 {
00503 print_raw (os, pr_as_read_syntax);
00504 newline (os);
00505 }
00506 template <class DMT, class MT>
00507 int
00508 octave_base_diag<DMT, MT>::write (octave_stream& os, int block_size,
00509 oct_data_conv::data_type output_type, int skip,
00510 oct_mach_info::float_format flt_fmt) const
00511 {
00512 return to_dense ().write (os, block_size, output_type, skip, flt_fmt);
00513 }
00514
00515 template <class DMT, class MT>
00516 void
00517 octave_base_diag<DMT, MT>::print_info (std::ostream& os,
00518 const std::string& prefix) const
00519 {
00520 matrix.print_info (os, prefix);
00521 }
00522
00523 template <class DMT, class MT>
00524 octave_value
00525 octave_base_diag<DMT, MT>::to_dense (void) const
00526 {
00527 if (! dense_cache.is_defined ())
00528 dense_cache = MT (matrix);
00529
00530 return dense_cache;
00531 }
00532