# HG changeset patch # User Jaroslav Hajek # Date 1228989840 -3600 # Node ID d95282fa057941c06d2299cede744b32a34d9547 # Parent 4780279e809445e91a7cab8218a622ffa70d81cc allow element assignment to diagonal matrices diff -r 4780279e8094 -r d95282fa0579 src/ChangeLog --- a/src/ChangeLog Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ChangeLog Thu Dec 11 11:04:00 2008 +0100 @@ -1,3 +1,22 @@ +2008-12-11 Jaroslav Hajek + + * ov-base-diag.cc (octave_base_diag::subsasgn): New method. + * ov-base-diag.h (octave_base_diag::subsasgn): Declare it. + (octave_base_diag::chk_valid_scalar): New method decl. + + * ov-re-diag.cc (octave_diag_matrix::chk_valid_scalar): New method + override. + * ov-re-diag.h: Declare it. + * ov-flt-re-diag.cc (octave_float_diag_matrix::chk_valid_scalar): New + method override. + * ov-flt-re-diag.h: Declare it. + * ov-cx-diag.cc (octave_complex_diag_matrix::chk_valid_scalar): New + method override. + * ov-cx-diag.h: Declare it. + * ov-flt-cx-diag.cc (octave_float_complex_diag_matrix::chk_valid_scalar): + New method override. + * ov-flt-cx-diag.h: Declare it. + 2008-12-10 Jaroslav Hajek * DLD-FUNCTIONS/expm.cc: Remove. diff -r 4780279e8094 -r d95282fa0579 src/ov-base-diag.cc --- a/src/ov-base-diag.cc Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-base-diag.cc Thu Dec 11 11:04:00 2008 +0100 @@ -128,6 +128,75 @@ } template +octave_value +octave_base_diag::subsasgn (const std::string& type, + const std::list& idx, + const octave_value& rhs) +{ + octave_value retval; + + switch (type[0]) + { + case '(': + { + if (type.length () == 1) + { + octave_value_list jdx = idx.front (); + // Check for a simple element assignment. That means, if D is a diagonal matrix, + // `D(i,i) = x' will not destroy its diagonality (provided i is a valid index). + if (jdx.length () == 2 && jdx(0).is_scalar_type () && jdx(1).is_scalar_type ()) + { + typename DMT::element_type val; + idx_vector i0 = jdx(0).index_vector (), i1 = jdx(1).index_vector (); + if (! error_state && i0(0) == i1(0) + && i0(0) < matrix.rows () && i1(0) < matrix.cols () + && chk_valid_scalar (rhs, val)) + { + matrix (i0(0), i1(0)) = val; + retval = this; + this->count++; + // invalidate cache + dense_cache = octave_value (); + } + } + + if (! error_state && ! retval.is_defined ()) + retval = numeric_assign (type, idx, rhs); + } + else + { + std::string nm = type_name (); + error ("in indexed assignment of %s, last lhs index must be ()", + nm.c_str ()); + } + } + break; + + case '{': + case '.': + { + if (is_empty ()) + { + octave_value tmp = octave_value::empty_conv (type, rhs); + + retval = tmp.subsasgn (type, idx, rhs); + } + else + { + std::string nm = type_name (); + error ("%s cannot be indexed with %c", nm.c_str (), type[0]); + } + } + break; + + default: + panic_impossible (); + } + + return retval; +} + +template octave_value octave_base_diag::resize (const dim_vector& dv, bool fill) const { diff -r 4780279e8094 -r d95282fa0579 src/ov-base-diag.h --- a/src/ov-base-diag.h Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-base-diag.h Thu Dec 11 11:04:00 2008 +0100 @@ -72,6 +72,10 @@ octave_value do_index_op (const octave_value_list& idx, bool resize_ok = false); + octave_value subsasgn (const std::string& type, + const std::list& idx, + const octave_value& rhs); + dim_vector dims (void) const { return matrix.dims (); } octave_idx_type nnz (void) const { return to_dense ().nnz (); } @@ -244,7 +248,10 @@ DMT matrix; - octave_value to_dense () const; + octave_value to_dense (void) const; + + virtual bool chk_valid_scalar (const octave_value&, + typename DMT::element_type&) const = 0; private: diff -r 4780279e8094 -r d95282fa0579 src/ov-cx-diag.cc --- a/src/ov-cx-diag.cc Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-cx-diag.cc Thu Dec 11 11:04:00 2008 +0100 @@ -220,3 +220,12 @@ return true; } +bool +octave_complex_diag_matrix::chk_valid_scalar (const octave_value& val, + Complex& x) const +{ + bool retval = val.is_complex_scalar () || val.is_real_scalar (); + if (retval) + x = val.complex_value (); + return retval; +} diff -r 4780279e8094 -r d95282fa0579 src/ov-cx-diag.h --- a/src/ov-cx-diag.h Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-cx-diag.h Thu Dec 11 11:04:00 2008 +0100 @@ -84,6 +84,10 @@ octave_value real (void) const; private: + + bool chk_valid_scalar (const octave_value&, + Complex&) const; + DECLARE_OCTAVE_ALLOCATOR DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA diff -r 4780279e8094 -r d95282fa0579 src/ov-flt-cx-diag.cc --- a/src/ov-flt-cx-diag.cc Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-flt-cx-diag.cc Thu Dec 11 11:04:00 2008 +0100 @@ -194,3 +194,13 @@ return true; } + +bool +octave_float_complex_diag_matrix::chk_valid_scalar (const octave_value& val, + FloatComplex& x) const +{ + bool retval = val.is_complex_scalar () || val.is_real_scalar (); + if (retval) + x = val.float_complex_value (); + return retval; +} diff -r 4780279e8094 -r d95282fa0579 src/ov-flt-cx-diag.h --- a/src/ov-flt-cx-diag.h Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-flt-cx-diag.h Thu Dec 11 11:04:00 2008 +0100 @@ -82,6 +82,10 @@ octave_value real (void) const; private: + + bool chk_valid_scalar (const octave_value&, + FloatComplex&) const; + DECLARE_OCTAVE_ALLOCATOR DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA diff -r 4780279e8094 -r d95282fa0579 src/ov-flt-re-diag.cc --- a/src/ov-flt-re-diag.cc Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-flt-re-diag.cc Thu Dec 11 11:04:00 2008 +0100 @@ -163,3 +163,13 @@ return true; } + +bool +octave_float_diag_matrix::chk_valid_scalar (const octave_value& val, + float& x) const +{ + bool retval = val.is_real_scalar (); + if (retval) + x = val.float_value (); + return retval; +} diff -r 4780279e8094 -r d95282fa0579 src/ov-flt-re-diag.h --- a/src/ov-flt-re-diag.h Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-flt-re-diag.h Thu Dec 11 11:04:00 2008 +0100 @@ -82,6 +82,10 @@ octave_value real (void) const; private: + + bool chk_valid_scalar (const octave_value&, + float&) const; + DECLARE_OCTAVE_ALLOCATOR DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA diff -r 4780279e8094 -r d95282fa0579 src/ov-re-diag.cc --- a/src/ov-re-diag.cc Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-re-diag.cc Thu Dec 11 11:04:00 2008 +0100 @@ -189,3 +189,12 @@ return true; } +bool +octave_diag_matrix::chk_valid_scalar (const octave_value& val, + double& x) const +{ + bool retval = val.is_real_scalar (); + if (retval) + x = val.double_value (); + return retval; +} diff -r 4780279e8094 -r d95282fa0579 src/ov-re-diag.h --- a/src/ov-re-diag.h Thu Dec 11 10:39:53 2008 +0100 +++ b/src/ov-re-diag.h Thu Dec 11 11:04:00 2008 +0100 @@ -84,6 +84,10 @@ octave_value real (void) const; private: + + bool chk_valid_scalar (const octave_value&, + double&) const; + DECLARE_OCTAVE_ALLOCATOR DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA