00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <iostream>
00029
00030 #include "Cell.h"
00031 #include "oct-obj.h"
00032 #include "oct-map.h"
00033 #include "ov-base.h"
00034 #include "ov-base-mat.h"
00035 #include "ov-base-scalar.h"
00036 #include "pr-output.h"
00037
00038 template <class MT>
00039 octave_value
00040 octave_base_matrix<MT>::subsref (const std::string& type,
00041 const std::list<octave_value_list>& idx)
00042 {
00043 octave_value retval;
00044
00045 switch (type[0])
00046 {
00047 case '(':
00048 retval = do_index_op (idx.front ());
00049 break;
00050
00051 case '{':
00052 case '.':
00053 {
00054 std::string nm = type_name ();
00055 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00056 }
00057 break;
00058
00059 default:
00060 panic_impossible ();
00061 }
00062
00063 return retval.next_subsref (type, idx);
00064 }
00065
00066 template <class MT>
00067 octave_value
00068 octave_base_matrix<MT>::subsasgn (const std::string& type,
00069 const std::list<octave_value_list>& idx,
00070 const octave_value& rhs)
00071 {
00072 octave_value retval;
00073
00074 switch (type[0])
00075 {
00076 case '(':
00077 {
00078 if (type.length () == 1)
00079 retval = numeric_assign (type, idx, rhs);
00080 else if (is_empty ())
00081 {
00082
00083
00084
00085
00086
00087 if (type[1] == '.')
00088 {
00089 octave_value tmp = octave_value::empty_conv (type, rhs);
00090
00091 retval = tmp.subsasgn (type, idx, rhs);
00092 }
00093 else
00094 error ("invalid assignment expression");
00095 }
00096 else
00097 {
00098 std::string nm = type_name ();
00099 error ("in indexed assignment of %s, last lhs index must be ()",
00100 nm.c_str ());
00101 }
00102 }
00103 break;
00104
00105 case '{':
00106 case '.':
00107 {
00108 if (is_empty ())
00109 {
00110 octave_value tmp = octave_value::empty_conv (type, rhs);
00111
00112 retval = tmp.subsasgn (type, idx, rhs);
00113 }
00114 else
00115 {
00116 std::string nm = type_name ();
00117 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00118 }
00119 }
00120 break;
00121
00122 default:
00123 panic_impossible ();
00124 }
00125
00126 return retval;
00127 }
00128
00129 template <class MT>
00130 octave_value
00131 octave_base_matrix<MT>::do_index_op (const octave_value_list& idx,
00132 bool resize_ok)
00133 {
00134 octave_value retval;
00135
00136 octave_idx_type n_idx = idx.length ();
00137
00138 int nd = matrix.ndims ();
00139 const MT& cmatrix = matrix;
00140
00141 switch (n_idx)
00142 {
00143 case 0:
00144 retval = matrix;
00145 break;
00146
00147 case 1:
00148 {
00149 idx_vector i = idx (0).index_vector ();
00150
00151 if (! error_state)
00152 {
00153
00154 if (! resize_ok && i.is_scalar ())
00155 retval = cmatrix.checkelem (i(0));
00156 else
00157 retval = MT (matrix.index (i, resize_ok));
00158 }
00159 }
00160 break;
00161
00162 case 2:
00163 {
00164 idx_vector i = idx (0).index_vector ();
00165
00166 if (! error_state)
00167 {
00168 idx_vector j = idx (1).index_vector ();
00169
00170 if (! error_state)
00171 {
00172
00173 if (! resize_ok && i.is_scalar () && j.is_scalar ())
00174 retval = cmatrix.checkelem (i(0), j(0));
00175 else
00176 retval = MT (matrix.index (i, j, resize_ok));
00177 }
00178 }
00179 }
00180 break;
00181
00182 default:
00183 {
00184 Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
00185 bool scalar_opt = n_idx == nd && ! resize_ok;
00186 const dim_vector dv = matrix.dims ();
00187
00188 for (octave_idx_type i = 0; i < n_idx; i++)
00189 {
00190 idx_vec(i) = idx(i).index_vector ();
00191
00192 if (error_state)
00193 break;
00194
00195 scalar_opt = (scalar_opt && idx_vec(i).is_scalar ());
00196 }
00197
00198 if (! error_state)
00199 {
00200 if (scalar_opt)
00201 retval = cmatrix.checkelem (conv_to_int_array (idx_vec));
00202 else
00203 retval = MT (matrix.index (idx_vec, resize_ok));
00204 }
00205 }
00206 break;
00207 }
00208
00209 return retval;
00210 }
00211
00212 template <class MT>
00213 void
00214 octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs)
00215 {
00216 octave_idx_type n_idx = idx.length ();
00217
00218 switch (n_idx)
00219 {
00220 case 0:
00221 panic_impossible ();
00222 break;
00223
00224 case 1:
00225 {
00226 idx_vector i = idx (0).index_vector ();
00227
00228 if (! error_state)
00229 matrix.assign (i, rhs);
00230 }
00231 break;
00232
00233 case 2:
00234 {
00235 idx_vector i = idx (0).index_vector ();
00236
00237 if (! error_state)
00238 {
00239 idx_vector j = idx (1).index_vector ();
00240
00241 if (! error_state)
00242 matrix.assign (i, j, rhs);
00243 }
00244 }
00245 break;
00246
00247 default:
00248 {
00249 Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
00250
00251 for (octave_idx_type i = 0; i < n_idx; i++)
00252 {
00253 idx_vec(i) = idx(i).index_vector ();
00254
00255 if (error_state)
00256 break;
00257 }
00258
00259 if (! error_state)
00260 matrix.assign (idx_vec, rhs);
00261 }
00262 break;
00263 }
00264
00265
00266 clear_cached_info ();
00267 }
00268
00269 template <class MT>
00270 MatrixType
00271 octave_base_matrix<MT>::matrix_type (const MatrixType& _typ) const
00272 {
00273 delete typ;
00274 typ = new MatrixType (_typ);
00275 return *typ;
00276 }
00277
00278 template <class MT>
00279 void
00280 octave_base_matrix<MT>::assign (const octave_value_list& idx,
00281 typename MT::element_type rhs)
00282 {
00283 octave_idx_type n_idx = idx.length ();
00284
00285 int nd = matrix.ndims ();
00286
00287 MT mrhs (dim_vector (1, 1), rhs);
00288
00289 switch (n_idx)
00290 {
00291 case 0:
00292 panic_impossible ();
00293 break;
00294
00295 case 1:
00296 {
00297 idx_vector i = idx (0).index_vector ();
00298
00299 if (! error_state)
00300 {
00301
00302 if (i.is_scalar () && i(0) < matrix.numel ())
00303 matrix(i(0)) = rhs;
00304 else
00305 matrix.assign (i, mrhs);
00306 }
00307 }
00308 break;
00309
00310 case 2:
00311 {
00312 idx_vector i = idx (0).index_vector ();
00313
00314 if (! error_state)
00315 {
00316 idx_vector j = idx (1).index_vector ();
00317
00318 if (! error_state)
00319 {
00320
00321 if (i.is_scalar () && j.is_scalar () && nd == 2
00322 && i(0) < matrix.rows () && j(0) < matrix.columns ())
00323 matrix(i(0), j(0)) = rhs;
00324 else
00325 matrix.assign (i, j, mrhs);
00326 }
00327 }
00328 }
00329 break;
00330
00331 default:
00332 {
00333 Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
00334 bool scalar_opt = n_idx == nd;
00335 const dim_vector dv = matrix.dims ().redim (n_idx);
00336
00337 for (octave_idx_type i = 0; i < n_idx; i++)
00338 {
00339 idx_vec(i) = idx(i).index_vector ();
00340
00341 if (error_state)
00342 break;
00343
00344 scalar_opt = (scalar_opt && idx_vec(i).is_scalar ()
00345 && idx_vec(i)(0) < dv(i));
00346 }
00347
00348 if (! error_state)
00349 {
00350 if (scalar_opt)
00351 {
00352
00353
00354 octave_idx_type k = 1, j = 0;
00355 for (octave_idx_type i = 0; i < n_idx; i++)
00356 {
00357 j += idx_vec(i)(0) * k;
00358 k *= dv (i);
00359 }
00360 matrix(j) = rhs;
00361 }
00362 else
00363 matrix.assign (idx_vec, mrhs);
00364 }
00365 }
00366 break;
00367 }
00368
00369
00370 clear_cached_info ();
00371 }
00372
00373 template <class MT>
00374 void
00375 octave_base_matrix<MT>::delete_elements (const octave_value_list& idx)
00376 {
00377 octave_idx_type len = idx.length ();
00378
00379 Array<idx_vector> ra_idx (dim_vector (len, 1));
00380
00381 for (octave_idx_type i = 0; i < len; i++)
00382 ra_idx(i) = idx(i).index_vector ();
00383
00384 matrix.delete_elements (ra_idx);
00385
00386
00387 clear_cached_info ();
00388 }
00389
00390 template <class MT>
00391 octave_value
00392 octave_base_matrix<MT>::resize (const dim_vector& dv, bool fill) const
00393 {
00394 MT retval (matrix);
00395 if (fill)
00396 retval.resize (dv, 0);
00397 else
00398 retval.resize (dv);
00399 return retval;
00400 }
00401
00402 template <class MT>
00403 bool
00404 octave_base_matrix<MT>::is_true (void) const
00405 {
00406 bool retval = false;
00407 dim_vector dv = matrix.dims ();
00408 int nel = dv.numel ();
00409
00410 if (nel > 0)
00411 {
00412 MT t1 (matrix.reshape (dim_vector (nel, 1)));
00413
00414 if (t1.any_element_is_nan ())
00415 gripe_nan_to_logical_conversion ();
00416 else
00417 {
00418 boolNDArray t2 = t1.all ();
00419
00420 retval = t2(0);
00421 }
00422 }
00423
00424 return retval;
00425 }
00426
00427 template <class MT>
00428 bool
00429 octave_base_matrix<MT>::print_as_scalar (void) const
00430 {
00431 dim_vector dv = dims ();
00432
00433 return (dv.all_ones () || dv.any_zero ());
00434 }
00435
00436 template <class MT>
00437 void
00438 octave_base_matrix<MT>::print (std::ostream& os, bool pr_as_read_syntax) const
00439 {
00440 print_raw (os, pr_as_read_syntax);
00441 newline (os);
00442 }
00443
00444 template <class MT>
00445 void
00446 octave_base_matrix<MT>::print_info (std::ostream& os,
00447 const std::string& prefix) const
00448 {
00449 matrix.print_info (os, prefix);
00450 }
00451
00452 template <class MT>
00453 octave_value
00454 octave_base_matrix<MT>::fast_elem_extract (octave_idx_type n) const
00455 {
00456 if (n < matrix.numel ())
00457 return matrix(n);
00458 else
00459 return octave_value ();
00460 }
00461
00462 template <class MT>
00463 bool
00464 octave_base_matrix<MT>::fast_elem_insert (octave_idx_type n,
00465 const octave_value& x)
00466 {
00467 if (n < matrix.numel ())
00468 {
00469
00470 typedef typename MT::element_type ET;
00471 const builtin_type_t btyp = class_to_btyp<ET>::btyp;
00472 if (btyp == btyp_unknown)
00473 return false;
00474
00475
00476 void *here = reinterpret_cast<void *> (&matrix(n));
00477
00478 return x.get_rep().fast_elem_insert_self (here, btyp);
00479 }
00480 else
00481 return false;
00482 }