Mercurial > hg > octave-lojdl
changeset 9607:1be3c73ed7b5
reuse temporary arrays in nested expressions
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 03 Sep 2009 08:48:51 +0200 |
parents | a04352386a6b |
children | 1c76e806c2a7 |
files | liboctave/CNDArray.h liboctave/ChangeLog liboctave/MArrayN.cc liboctave/MArrayN.h liboctave/boolNDArray.cc liboctave/boolNDArray.h liboctave/dNDArray.h liboctave/fCNDArray.h liboctave/fNDArray.h liboctave/intNDArray.h liboctave/mx-inlines.cc src/ChangeLog src/OPERATORS/op-bm-bm.cc src/OPERATORS/op-cm-cm.cc src/OPERATORS/op-fcm-fcm.cc src/OPERATORS/op-fm-fm.cc src/OPERATORS/op-int.h src/OPERATORS/op-m-m.cc src/ov-bool-mat.h src/ov-cx-mat.h src/ov-flt-cx-mat.h src/ov-flt-re-mat.h src/ov-intx.h src/ov-re-mat.h src/ov.cc src/ov.h src/pt-binop.cc src/pt-unop.cc |
diffstat | 28 files changed, 296 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CNDArray.h +++ b/liboctave/CNDArray.h @@ -138,6 +138,12 @@ ComplexNDArray diag (octave_idx_type k = 0) const; + ComplexNDArray& changesign (void) + { + MArrayN<Complex>::changesign (); + return *this; + } + typedef double (*dmapper) (const Complex&); typedef Complex (*cmapper) (const Complex&); typedef bool (*bmapper) (const Complex&);
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,22 @@ +2009-09-03 Jaroslav Hajek <highegg@gmail.com> + + * mx-inlines.cc (DEFMXUNOPEQ): New macro. + (mx_inline_not2, mx_inline_uminus2): New loops. + * boolNDArray.cc (boolNDArray::invert): New method. + * boolNDArray.h: Declare it. + * MArrayN.cc (MArrayN<T>::changesign): New method. + * MArrayN.h: Declare it. + * dNDArray.cc (NDArray::changesign): New method. + * dNDArray.h: Declare it. + * fNDArray.cc (FloatNDArray::changesign): New method. + * fNDArray.h: Declare it. + * CNDArray.cc (ComplexNDArray::changesign): New method. + * CNDArray.h: Declare it. + * fCNDArray.cc (FloatComplexNDArray::changesign): New method. + * fCNDArray.h: Declare it. + * intNDArray.cc (intNDArray::changesign): New method. + * intNDArray.h: Declare it. + 2009-09-02 Jaroslav Hajek <highegg@gmail.com> * oct-cmplx.h: Rewrite the comaprison ops. Use FLOAT_TRUNCATE.
--- a/liboctave/MArrayN.cc +++ b/liboctave/MArrayN.cc @@ -29,8 +29,18 @@ #include "lo-error.h" #include "MArray-defs.h" +#include "mx-inlines.cc" // N-dimensional array with math ops. +template <class T> +void +MArrayN<T>::changesign (void) +{ + if (Array<T>::is_shared ()) + *this = - *this; + else + do_mx_inplace_op<MArrayN<T> > (*this, mx_inline_uminus2); +} // Element by element MArrayN by scalar ops.
--- a/liboctave/MArrayN.h +++ b/liboctave/MArrayN.h @@ -109,6 +109,8 @@ { return ArrayN<T>::template map<U> (fcn); } + + void changesign (void); }; #endif
--- a/liboctave/boolNDArray.cc +++ b/liboctave/boolNDArray.cc @@ -42,6 +42,17 @@ return do_mx_unary_op<boolNDArray> (*this, mx_inline_not); } +boolNDArray& +boolNDArray::invert (void) +{ + if (is_shared ()) + *this = ! *this; + else + do_mx_inplace_op<boolNDArray> (*this, mx_inline_not2); + + return *this; +} + // FIXME -- this is not quite the right thing. boolNDArray
--- a/liboctave/boolNDArray.h +++ b/liboctave/boolNDArray.h @@ -59,6 +59,8 @@ boolNDArray operator ! (void) const; + boolNDArray& invert (void); + bool any_element_is_nan (void) const { return false; } // FIXME -- this is not quite the right thing.
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -149,6 +149,12 @@ NDArray diag (octave_idx_type k = 0) const; + NDArray& changesign (void) + { + MArrayN<double>::changesign (); + return *this; + } + typedef double (*dmapper) (double); typedef Complex (*cmapper) (const Complex&); typedef bool (*bmapper) (double);
--- a/liboctave/fCNDArray.h +++ b/liboctave/fCNDArray.h @@ -138,6 +138,12 @@ FloatComplexNDArray diag (octave_idx_type k = 0) const; + FloatComplexNDArray& changesign (void) + { + MArrayN<FloatComplex>::changesign (); + return *this; + } + typedef float (*dmapper) (const FloatComplex&); typedef FloatComplex (*cmapper) (const FloatComplex&); typedef bool (*bmapper) (const FloatComplex&);
--- a/liboctave/fNDArray.h +++ b/liboctave/fNDArray.h @@ -146,6 +146,12 @@ FloatNDArray diag (octave_idx_type k = 0) const; + FloatNDArray& changesign (void) + { + MArrayN<float>::changesign (); + return *this; + } + typedef float (*dmapper) (float); typedef FloatComplex (*cmapper) (const FloatComplex&); typedef bool (*bmapper) (float);
--- a/liboctave/intNDArray.h +++ b/liboctave/intNDArray.h @@ -68,6 +68,12 @@ intNDArray diag (octave_idx_type k = 0) const; + intNDArray& changesign (void) + { + MArrayN<T>::changesign (); + return *this; + } + // FIXME -- this is not quite the right thing. boolNDArray all (int dim = -1) const;
--- a/liboctave/mx-inlines.cc +++ b/liboctave/mx-inlines.cc @@ -49,6 +49,13 @@ DEFMXUNOP (mx_inline_uminus, -) +#define DEFMXUNOPEQ(F, OP) \ +template <class R> \ +inline void F (size_t n, R *r) \ +{ for (size_t i = 0; i < n; i++) r[i] = OP r[i]; } + +DEFMXUNOPEQ (mx_inline_uminus2, -) + #define DEFMXUNBOOLOP(F, OP) \ template <class X> \ inline void F (size_t n, bool *r, const X *x) \ @@ -127,6 +134,11 @@ r[i] = ! logical_value (x[i]); } +inline void mx_inline_not2 (size_t n, bool *r) +{ + for (size_t i = 0; i < n; i++) r[i] = ! r[i]; +} + #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \ template <class X, class Y> \ inline void F (size_t n, bool *r, const X *x, const Y *y) \ @@ -222,6 +234,16 @@ return r; } +template <class RNDA> +inline RNDA& +do_mx_inplace_op (RNDA& r, + void (*op) (size_t, typename RNDA::element_type *)) +{ + op (r.numel (), r.fortran_vec ()); + return r; +} + + template <class RNDA, class XNDA, class YNDA> inline RNDA do_mm_binary_op (const XNDA& x, const YNDA& y,
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,28 @@ +2009-09-03 Jaroslav Hajek <highegg@gmail.com> + + * ov.cc (octave_value::do_non_const_unary_op): Split to + genuine/non-genuine case. + (octave_value::binary_op_to_assign_op): New method. + * ov.h: Declare it. + * ov-re-mat.h (octave_matrix::changesign): New method. + * ov-flt-re-mat.h (octave_float_matrix::changesign): New method. + * ov-cx-mat.h (octave_complex_matrix::changesign): New method. + * ov-flt-cx-mat.h (octave_float_complex_matrix::changesign): New + method. + * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::changesign): New method. + * ov-bool-mat.h (octave_bool_matrix::invert): New method. + * pt-unop.cc (tree_prefix_expression::rvalue1): Use + do_non_const_unary_op. + * pt-binop.cc (tree_binary_expression::rvalue1): If possible, + convert to computed assignment. + + * OPERATORS/op-m-m.cc: Define & install in-place minus operation. + * OPERATORS/op-fm-fm.cc: Ditto. + * OPERATORS/op-cm-cm.cc: Ditto. + * OPERATORS/op-fcm-fcm.cc: Ditto. + * OPERATORS/op-int.h: Ditto. + * OPERATORS/op-bm-bm.cc: Define & install in-place not operation. + 2009-09-03 Jaroslav Hajek <highegg@gmail.com> * ov-re-mat.h (octave_matrix::increment, octave_matrix::decrement):
--- a/src/OPERATORS/op-bm-bm.cc +++ b/src/OPERATORS/op-bm-bm.cc @@ -55,6 +55,8 @@ DEFNDUNOP_OP (uplus, bool_matrix, array, +) DEFNDUNOP_OP (uminus, bool_matrix, array, -) +DEFNCUNOP_METHOD (invert, bool_matrix, invert) + DEFUNOP (transpose, bool_matrix) { CAST_UNOP_ARG (const octave_bool_matrix&); @@ -133,6 +135,8 @@ INSTALL_UNOP (op_transpose, octave_bool_matrix, transpose); INSTALL_UNOP (op_hermitian, octave_bool_matrix, transpose); + INSTALL_NCUNOP (op_not, octave_bool_matrix, invert); + INSTALL_BINOP (op_eq, octave_bool_matrix, octave_bool_matrix, eq); INSTALL_BINOP (op_ne, octave_bool_matrix, octave_bool_matrix, ne);
--- a/src/OPERATORS/op-cm-cm.cc +++ b/src/OPERATORS/op-cm-cm.cc @@ -70,6 +70,7 @@ DEFNCUNOP_METHOD (incr, complex_matrix, increment) DEFNCUNOP_METHOD (decr, complex_matrix, decrement) +DEFNCUNOP_METHOD (changesign, complex_matrix, changesign) // complex matrix by complex matrix ops. @@ -186,6 +187,7 @@ INSTALL_NCUNOP (op_incr, octave_complex_matrix, incr); INSTALL_NCUNOP (op_decr, octave_complex_matrix, decr); + INSTALL_NCUNOP (op_uminus, octave_complex_matrix, changesign); INSTALL_BINOP (op_add, octave_complex_matrix, octave_complex_matrix, add); INSTALL_BINOP (op_sub, octave_complex_matrix, octave_complex_matrix, sub);
--- a/src/OPERATORS/op-fcm-fcm.cc +++ b/src/OPERATORS/op-fcm-fcm.cc @@ -70,6 +70,7 @@ DEFNCUNOP_METHOD (incr, float_complex_matrix, increment) DEFNCUNOP_METHOD (decr, float_complex_matrix, decrement) +DEFNCUNOP_METHOD (changesign, float_complex_matrix, changesign) // complex matrix by complex matrix ops. @@ -216,6 +217,7 @@ INSTALL_NCUNOP (op_incr, octave_float_complex_matrix, incr); INSTALL_NCUNOP (op_decr, octave_float_complex_matrix, decr); + INSTALL_NCUNOP (op_uminus, octave_float_complex_matrix, changesign); INSTALL_BINOP (op_add, octave_float_complex_matrix, octave_float_complex_matrix, add);
--- a/src/OPERATORS/op-fm-fm.cc +++ b/src/OPERATORS/op-fm-fm.cc @@ -57,6 +57,7 @@ DEFNCUNOP_METHOD (incr, float_matrix, increment) DEFNCUNOP_METHOD (decr, float_matrix, decrement) +DEFNCUNOP_METHOD (changesign, float_matrix, changesign) // matrix by matrix ops. @@ -188,6 +189,7 @@ INSTALL_NCUNOP (op_incr, octave_float_matrix, incr); INSTALL_NCUNOP (op_decr, octave_float_matrix, decr); + INSTALL_NCUNOP (op_uminus, octave_float_matrix, changesign); INSTALL_BINOP (op_add, octave_float_matrix, octave_float_matrix, add); INSTALL_BINOP (op_sub, octave_float_matrix, octave_float_matrix, sub);
--- a/src/OPERATORS/op-int.h +++ b/src/OPERATORS/op-int.h @@ -698,7 +698,8 @@ } \ \ DEFNCUNOP_METHOD (m_incr, TYPE ## _matrix, increment) \ - DEFNCUNOP_METHOD (m_decr, TYPE ## _matrix, decrement) + DEFNCUNOP_METHOD (m_decr, TYPE ## _matrix, decrement) \ + DEFNCUNOP_METHOD (m_changesign, TYPE ## _matrix, changesign) #define OCTAVE_MM_INT_ARITH_OPS(PFX, T1, T2, T3) \ /* matrix by matrix ops. */ \ @@ -1096,7 +1097,8 @@ INSTALL_UNOP (op_hermitian, octave_ ## TYPE ## _matrix, m_transpose); \ \ INSTALL_NCUNOP (op_incr, octave_ ## TYPE ## _matrix, m_incr); \ - INSTALL_NCUNOP (op_decr, octave_ ## TYPE ## _matrix, m_decr); + INSTALL_NCUNOP (op_decr, octave_ ## TYPE ## _matrix, m_decr); \ + INSTALL_NCUNOP (op_uminus, octave_ ## TYPE ## _matrix, m_changesign); #define OCTAVE_INSTALL_MM_INT_ARITH_OPS(PFX, T1, T2) \ INSTALL_BINOP (op_add, octave_ ## T1 ## matrix, octave_ ## T2 ## matrix, PFX ## _add); \
--- a/src/OPERATORS/op-m-m.cc +++ b/src/OPERATORS/op-m-m.cc @@ -57,6 +57,7 @@ DEFNCUNOP_METHOD (incr, matrix, increment) DEFNCUNOP_METHOD (decr, matrix, decrement) +DEFNCUNOP_METHOD (changesign, matrix, changesign) // matrix by matrix ops. @@ -161,6 +162,7 @@ INSTALL_NCUNOP (op_incr, octave_matrix, incr); INSTALL_NCUNOP (op_decr, octave_matrix, decr); + INSTALL_NCUNOP (op_uminus, octave_matrix, changesign); INSTALL_BINOP (op_add, octave_matrix, octave_matrix, add); INSTALL_BINOP (op_sub, octave_matrix, octave_matrix, sub);
--- a/src/ov-bool-mat.h +++ b/src/ov-bool-mat.h @@ -175,6 +175,9 @@ octave_value convert_to_str_internal (bool pad, bool force, char type) const; + // Use matrix_ref here to clear index cache. + void invert (void) { matrix_ref ().invert (); } + void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const; bool save_ascii (std::ostream& os);
--- a/src/ov-cx-mat.h +++ b/src/ov-cx-mat.h @@ -136,6 +136,8 @@ void decrement (void) { matrix -= Complex (1.0); } + void changesign (void) { matrix.changesign (); } + bool save_ascii (std::ostream& os); bool load_ascii (std::istream& is);
--- a/src/ov-flt-cx-mat.h +++ b/src/ov-flt-cx-mat.h @@ -134,6 +134,8 @@ void decrement (void) { matrix -= FloatComplex (1.0); } + void changesign (void) { matrix.changesign (); } + bool save_ascii (std::ostream& os); bool load_ascii (std::istream& is);
--- a/src/ov-flt-re-mat.h +++ b/src/ov-flt-re-mat.h @@ -168,6 +168,8 @@ void decrement (void) { matrix_ref () -= 1.0; } + void changesign (void) { matrix_ref ().changesign (); } + octave_value convert_to_str_internal (bool pad, bool force, char type) const; void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-intx.h +++ b/src/ov-intx.h @@ -317,6 +317,14 @@ OCTAVE_INT_T::clear_conv_flag (); } + void changesign (void) + { + matrix_ref ().changesign (); + if (OCTAVE_INT_T::get_math_trunc_flag ()) + gripe_unop_integer_math_truncated ("-", type_name (). c_str ()); + OCTAVE_INT_T::clear_conv_flag (); + } + idx_vector index_vector (void) const { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
--- a/src/ov-re-mat.h +++ b/src/ov-re-mat.h @@ -182,6 +182,8 @@ void decrement (void) { matrix_ref () -= 1.0; } + void changesign (void) { matrix_ref ().changesign (); } + octave_value convert_to_str_internal (bool pad, bool force, char type) const; void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov.cc +++ b/src/ov.cc @@ -474,6 +474,44 @@ return retval; } +octave_value::assign_op +octave_value::binary_op_to_assign_op (binary_op op) +{ + assign_op retval; + + switch (op) + { + case op_add: + retval = op_add_eq; + break; + case op_sub: + retval = op_sub_eq; + break; + case op_mul: + retval = op_mul_eq; + break; + case op_div: + retval = op_div_eq; + break; + case op_el_mul: + retval = op_el_mul_eq; + break; + case op_el_div: + retval = op_el_div_eq; + break; + case op_el_and: + retval = op_el_and_eq; + break; + case op_el_or: + retval = op_el_or_eq; + break; + default: + retval = unknown_assign_op; + } + + return retval; +} + octave_value::octave_value (short int i) : rep (new octave_scalar (i)) { @@ -2246,77 +2284,104 @@ const octave_value& octave_value::do_non_const_unary_op (unary_op op) { - octave_value retval; - - int t = type_id (); - - octave_value_typeinfo::non_const_unary_op_fcn f - = octave_value_typeinfo::lookup_non_const_unary_op (op, t); - - if (f) + if (op == op_incr || op == op_decr) { - make_unique (); - - try - { - f (*rep); - } - catch (octave_execution_exception) - { - gripe_library_execution_error (); - } + // Genuine. + int t = type_id (); + + octave_value_typeinfo::non_const_unary_op_fcn f + = octave_value_typeinfo::lookup_non_const_unary_op (op, t); + + if (f) + { + make_unique (); + + try + { + f (*rep); + } + catch (octave_execution_exception) + { + gripe_library_execution_error (); + } + } + else + { + octave_base_value::type_conv_fcn cf = numeric_conversion_function (); + + if (cf) + { + octave_base_value *tmp = cf (*rep); + + if (tmp) + { + octave_base_value *old_rep = rep; + rep = tmp; + + t = type_id (); + + f = octave_value_typeinfo::lookup_non_const_unary_op (op, t); + + if (f) + { + try + { + f (*rep); + } + catch (octave_execution_exception) + { + gripe_library_execution_error (); + } + + if (old_rep && --old_rep->count == 0) + delete old_rep; + } + else + { + if (old_rep) + { + if (--rep->count == 0) + delete rep; + + rep = old_rep; + } + + gripe_unary_op (octave_value::unary_op_as_string (op), + type_name ()); + } + } + else + gripe_unary_op_conversion_failed + (octave_value::unary_op_as_string (op), type_name ()); + } + else + gripe_unary_op (octave_value::unary_op_as_string (op), type_name ()); + } } else { - octave_base_value::type_conv_fcn cf = numeric_conversion_function (); - - if (cf) - { - octave_base_value *tmp = cf (*rep); - - if (tmp) - { - octave_base_value *old_rep = rep; - rep = tmp; - - t = type_id (); - - f = octave_value_typeinfo::lookup_non_const_unary_op (op, t); - - if (f) - { - try - { - f (*rep); - } - catch (octave_execution_exception) - { - gripe_library_execution_error (); - } - - if (old_rep && --old_rep->count == 0) - delete old_rep; - } - else - { - if (old_rep) - { - if (--rep->count == 0) - delete rep; - - rep = old_rep; - } - - gripe_unary_op (octave_value::unary_op_as_string (op), - type_name ()); - } - } - else - gripe_unary_op_conversion_failed - (octave_value::unary_op_as_string (op), type_name ()); - } + // Non-genuine. + int t = type_id (); + + octave_value_typeinfo::non_const_unary_op_fcn f = 0; + + // Only attempt to operate in-place if this variable is unshared. + if (rep->count == 1) + f = octave_value_typeinfo::lookup_non_const_unary_op (op, t); + + if (f) + { + try + { + f (*rep); + } + catch (octave_execution_exception) + { + gripe_library_execution_error (); + } + } else - gripe_unary_op (octave_value::unary_op_as_string (op), type_name ()); + *this = do_unary_op (op, *this); } return *this;
--- a/src/ov.h +++ b/src/ov.h @@ -141,6 +141,8 @@ unknown_assign_op }; + static assign_op binary_op_to_assign_op (binary_op); + static std::string unary_op_as_string (unary_op); static std::string unary_op_fcn_name (unary_op);
--- a/src/pt-binop.cc +++ b/src/pt-binop.cc @@ -66,7 +66,12 @@ if (! error_state && b.is_defined ()) { - retval = ::do_binary_op (etype, a, b); + octave_value::assign_op aop = octave_value::binary_op_to_assign_op (etype); + + if (aop == octave_value::unknown_assign_op) + retval = ::do_binary_op (etype, a, b); + else + retval = a.assign (aop, b); if (error_state) retval = octave_value ();