# HG changeset patch # User Jaroslav Hajek # Date 1250682479 -7200 # Node ID 1beb23d2b892a26dfd60087f598ee2a2217418b1 # Parent 8670e55078fd7a52119d9cfb8dbe637115a2c4af optimize op= in common cases diff --git a/liboctave/Array.cc b/liboctave/Array.cc --- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -111,6 +111,21 @@ } template +void +Array::clear (void) +{ + if (--rep->count <= 0) + delete rep; + + rep = nil_rep (); + rep->count++; + slice_data = rep->data; + slice_len = rep->len; + + dimensions = dim_vector (); +} + +template Array Array::squeeze (void) const { diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -238,6 +238,7 @@ Array& operator = (const Array& a); void fill (const T& val); + void clear (void); octave_idx_type capacity (void) const { return slice_len; } octave_idx_type length (void) const { return capacity (); } @@ -440,6 +441,8 @@ T *fortran_vec (void); + bool is_shared (void) { return rep->count > 1; } + int ndims (void) const { return dimensions.length (); } void maybe_delete_dims (void); diff --git a/liboctave/CNDArray.cc b/liboctave/CNDArray.cc --- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -36,6 +36,7 @@ #include "functor.h" #include "lo-ieee.h" #include "lo-mappers.h" +#include "MArray-defs.h" #include "mx-base.h" #include "mx-op-defs.h" #include "oct-fftw.h" @@ -1083,6 +1084,22 @@ NDND_CMP_OPS(ComplexNDArray, std::real, ComplexNDArray, std::real) NDND_BOOL_OPS(ComplexNDArray, ComplexNDArray, 0.0) +ComplexNDArray& operator *= (ComplexNDArray& a, double s) +{ + if (a.is_shared ()) + return a = a * s; + DO_VS_OP2 (Complex, a, *=, s) + return a; +} + +ComplexNDArray& operator /= (ComplexNDArray& a, double s) +{ + if (a.is_shared ()) + return a = a / s; + DO_VS_OP2 (Complex, a, /=, s) + return a; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/CNDArray.h b/liboctave/CNDArray.h --- a/liboctave/CNDArray.h +++ b/liboctave/CNDArray.h @@ -173,6 +173,9 @@ MARRAY_FORWARD_DEFS (MArrayN, ComplexNDArray, Complex) +extern OCTAVE_API ComplexNDArray& operator *= (ComplexNDArray& a, double s); +extern OCTAVE_API ComplexNDArray& operator /= (ComplexNDArray& a, double s); + #endif /* diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,26 @@ +2009-08-19 Jaroslav Hajek + + * Array.cc (Array::clear): New method. + * Array.h: Declare it. + * MArray-decl.h (MARRAY_OP_ASSIGN_DECLS1, MARRAY_OP_ASSIGN_FWD_DECLS1, + MARRAY_OP_ASSIGN_FRIENDS1, MARRAY_OP_ASSIGN_FWD_DEFS1): New macros. + (MARRAY_OPS_FORWARD_DECLS, MARRAY_OPS_FRIEND_DECLS): Use them. + * MArray-defs.h (MARRAY_OP_ASSIGN_DEFS1): New macro. + (INSTANTIATE_MARRAY_FRIENDS): Use it. + (INSTANTIATE_MARRAY2_FRIENDS): Use it. + (INSTANTIATE_MARRAYN_FRIENDS): Use it. + * MArray.cc (operator+=, operator-=): + Operate out-of-place when this is shared copy. + (operator*=, operator/=): New operator overloads. + * MArray2.cc: Ditto. + * MArrayN.cc: Ditto. + * CNDArray.cc (operator *= (ComplexNDArray&, double), + operator /= (ComplexNDArray&, double)): New operators. + * CNDArray.h: Declare them. + * fCNDArray.cc (operator *= (FloatComplexNDArray&, double), + operator /= (FloatComplexNDArray&, double)): New operators. + * fCNDArray.h: Declare them. + 2009-08-17 John W. Eaton * Makefile.in (LINK_DEPS): List LIBS last. diff --git a/liboctave/MArray-decl.h b/liboctave/MArray-decl.h --- a/liboctave/MArray-decl.h +++ b/liboctave/MArray-decl.h @@ -33,14 +33,26 @@ MARRAY_OP_ASSIGN_DECL (A_T, E_T, +=, PFX, API, LTGT, RHS_T); \ MARRAY_OP_ASSIGN_DECL (A_T, E_T, -=, PFX, API, LTGT, RHS_T); +#define MARRAY_OP_ASSIGN_DECLS1(A_T, E_T, PFX, API, LTGT, RHS_T) \ + MARRAY_OP_ASSIGN_DECL (A_T, E_T, +=, PFX, API, LTGT, RHS_T); \ + MARRAY_OP_ASSIGN_DECL (A_T, E_T, -=, PFX, API, LTGT, RHS_T); \ + MARRAY_OP_ASSIGN_DECL (A_T, E_T, *=, PFX, API, LTGT, RHS_T); \ + MARRAY_OP_ASSIGN_DECL (A_T, E_T, /=, PFX, API, LTGT, RHS_T); + // Generate forward declarations for OP= operators. #define MARRAY_OP_ASSIGN_FWD_DECLS(A_T, RHS_T, API) \ MARRAY_OP_ASSIGN_DECLS (A_T, T, template , API, , RHS_T) +#define MARRAY_OP_ASSIGN_FWD_DECLS1(A_T, RHS_T, API) \ + MARRAY_OP_ASSIGN_DECLS1 (A_T, T, template , API, , RHS_T) + // Generate friend declarations for the OP= operators. #define MARRAY_OP_ASSIGN_FRIENDS(A_T, RHS_T, API) \ MARRAY_OP_ASSIGN_DECLS (A_T, T, friend, API, <>, RHS_T) +#define MARRAY_OP_ASSIGN_FRIENDS1(A_T, RHS_T, API) \ + MARRAY_OP_ASSIGN_DECLS1 (A_T, T, friend, API, <>, RHS_T) + // A function that can be used to forward OP= operations from derived // classes back to us. #define MARRAY_OP_ASSIGN_FWD_FCN(R, F, T, C_X, X_T, C_Y, Y_T) \ @@ -55,6 +67,12 @@ MARRAY_OP_ASSIGN_FWD_FCN (R, operator +=, T, C_X, X_T, C_Y, Y_T) \ MARRAY_OP_ASSIGN_FWD_FCN (R, operator -=, T, C_X, X_T, C_Y, Y_T) +#define MARRAY_OP_ASSIGN_FWD_DEFS1(R, T, C_X, X_T, C_Y, Y_T) \ + MARRAY_OP_ASSIGN_FWD_FCN (R, operator +=, T, C_X, X_T, C_Y, Y_T) \ + MARRAY_OP_ASSIGN_FWD_FCN (R, operator -=, T, C_X, X_T, C_Y, Y_T) \ + MARRAY_OP_ASSIGN_FWD_FCN (R, operator *=, T, C_X, X_T, C_Y, Y_T) \ + MARRAY_OP_ASSIGN_FWD_FCN (R, operator /=, T, C_X, X_T, C_Y, Y_T) + // A macro that can be used to declare and instantiate unary operators. #define MARRAY_UNOP(A_T, E_T, F, PFX, API, LTGT) \ PFX API A_T \ @@ -182,7 +200,7 @@ template \ class A_T; \ \ - MARRAY_OP_ASSIGN_FWD_DECLS (A_T, T, API) \ + MARRAY_OP_ASSIGN_FWD_DECLS1 (A_T, T, API) \ MARRAY_OP_ASSIGN_FWD_DECLS (A_T, A_T, API) \ MARRAY_UNOP_FWD_DECLS (A_T, API) \ MARRAY_BINOP_FWD_DECLS (A_T, API) @@ -197,7 +215,7 @@ // Friend declarations for the MArray operators. #define MARRAY_OPS_FRIEND_DECLS(A_T, API) \ - MARRAY_OP_ASSIGN_FRIENDS (A_T, T, API) \ + MARRAY_OP_ASSIGN_FRIENDS1 (A_T, T, API) \ MARRAY_OP_ASSIGN_FRIENDS (A_T, A_T, API) \ MARRAY_UNOP_FRIENDS (A_T, API) \ MARRAY_BINOP_FRIENDS (A_T, API) diff --git a/liboctave/MArray-defs.h b/liboctave/MArray-defs.h --- a/liboctave/MArray-defs.h +++ b/liboctave/MArray-defs.h @@ -77,6 +77,9 @@ #define MARRAY_OP_ASSIGN_DEFS(A_T, E_T, RHS_T, API) \ MARRAY_OP_ASSIGN_DECLS (A_T, E_T, template, API, , RHS_T) +#define MARRAY_OP_ASSIGN_DEFS1(A_T, E_T, RHS_T, API) \ + MARRAY_OP_ASSIGN_DECLS1 (A_T, E_T, template, API, , RHS_T) + // Instantiate the unary operators. #define MARRAY_UNOP_DEFS(A_T, E_T, API) \ MARRAY_UNOP_DECLS (A_T, E_T, template, API, ) @@ -96,21 +99,21 @@ // Instantiate all the MArray friends for MArray element type T. #define INSTANTIATE_MARRAY_FRIENDS(T, API) \ - MARRAY_OP_ASSIGN_DEFS (MArray, T, T, API) \ + MARRAY_OP_ASSIGN_DEFS1 (MArray, T, T, API) \ MARRAY_OP_ASSIGN_DEFS (MArray, T, MArray, API) \ MARRAY_UNOP_DEFS (MArray, T, API) \ MARRAY_BINOP_DEFS (MArray, T, API) // Instantiate all the MArray2 friends for MArray2 element type T. #define INSTANTIATE_MARRAY2_FRIENDS(T, API) \ - MARRAY_OP_ASSIGN_DEFS (MArray2, T, T, API) \ + MARRAY_OP_ASSIGN_DEFS1 (MArray2, T, T, API) \ MARRAY_OP_ASSIGN_DEFS (MArray2, T, MArray2, API) \ MARRAY_UNOP_DEFS (MArray2, T, API) \ MARRAY_BINOP_DEFS (MArray2, T, API) // Instantiate all the MArrayN friends for MArrayN element type T. #define INSTANTIATE_MARRAYN_FRIENDS(T, API) \ - MARRAY_OP_ASSIGN_DEFS (MArrayN, T, T, API) \ + MARRAY_OP_ASSIGN_DEFS1 (MArrayN, T, T, API) \ MARRAY_OP_ASSIGN_DEFS (MArrayN, T, MArrayN, API) \ MARRAY_UNOP_DEFS (MArrayN, T, API) \ MARRAY_BINOP_DEFS (MArrayN, T, API) diff --git a/liboctave/MArray.cc b/liboctave/MArray.cc --- a/liboctave/MArray.cc +++ b/liboctave/MArray.cc @@ -116,6 +116,8 @@ MArray& operator += (MArray& a, const T& s) { + if (a.is_shared ()) + return a = a + s; DO_VS_OP2 (T, a, +=, s) return a; } @@ -124,16 +126,40 @@ MArray& operator -= (MArray& a, const T& s) { + if (a.is_shared ()) + return a = a - s; DO_VS_OP2 (T, a, -=, s) return a; } +template +MArray& +operator *= (MArray& a, const T& s) +{ + if (a.is_shared ()) + return a = a * s; + DO_VS_OP2 (T, a, *=, s) + return a; +} + +template +MArray& +operator /= (MArray& a, const T& s) +{ + if (a.is_shared ()) + return a = a / s; + DO_VS_OP2 (T, a, /=, s) + return a; +} + // Element by element MArray by MArray ops. template MArray& operator += (MArray& a, const MArray& b) { + if (a.is_shared ()) + return a = a + b; octave_idx_type l = a.length (); if (l > 0) { @@ -150,6 +176,8 @@ MArray& operator -= (MArray& a, const MArray& b) { + if (a.is_shared ()) + return a = a - b; octave_idx_type l = a.length (); if (l > 0) { diff --git a/liboctave/MArray2.cc b/liboctave/MArray2.cc --- a/liboctave/MArray2.cc +++ b/liboctave/MArray2.cc @@ -39,6 +39,8 @@ MArray2& operator += (MArray2& a, const T& s) { + if (a.is_shared ()) + return a = a + s; DO_VS_OP2 (T, a, +=, s) return a; } @@ -47,16 +49,40 @@ MArray2& operator -= (MArray2& a, const T& s) { + if (a.is_shared ()) + return a = a - s; DO_VS_OP2 (T, a, -=, s) return a; } +template +MArray2& +operator *= (MArray2& a, const T& s) +{ + if (a.is_shared ()) + return a = a * s; + DO_VS_OP2 (T, a, *=, s) + return a; +} + +template +MArray2& +operator /= (MArray2& a, const T& s) +{ + if (a.is_shared ()) + return a = a / s; + DO_VS_OP2 (T, a, /=, s) + return a; +} + // Element by element MArray2 by MArray2 ops. template MArray2& operator += (MArray2& a, const MArray2& b) { + if (a.is_shared ()) + return a = a + b; octave_idx_type r = a.rows (); octave_idx_type c = a.cols (); octave_idx_type br = b.rows (); @@ -78,6 +104,8 @@ MArray2& operator -= (MArray2& a, const MArray2& b) { + if (a.is_shared ()) + return a = a - b; octave_idx_type r = a.rows (); octave_idx_type c = a.cols (); octave_idx_type br = b.rows (); diff --git a/liboctave/MArrayN.cc b/liboctave/MArrayN.cc --- a/liboctave/MArrayN.cc +++ b/liboctave/MArrayN.cc @@ -38,6 +38,8 @@ MArrayN& operator += (MArrayN& a, const T& s) { + if (a.is_shared ()) + return a = a + s; DO_VS_OP2 (T, a, +=, s) return a; } @@ -46,16 +48,40 @@ MArrayN& operator -= (MArrayN& a, const T& s) { + if (a.is_shared ()) + return a = a - s; DO_VS_OP2 (T, a, -=, s) return a; } +template +MArrayN& +operator *= (MArrayN& a, const T& s) +{ + if (a.is_shared ()) + return a = a * s; + DO_VS_OP2 (T, a, *=, s) + return a; +} + +template +MArrayN& +operator /= (MArrayN& a, const T& s) +{ + if (a.is_shared ()) + return a = a / s; + DO_VS_OP2 (T, a, /=, s) + return a; +} + // Element by element MArrayN by MArrayN ops. template MArrayN& operator += (MArrayN& a, const MArrayN& b) { + if (a.is_shared ()) + return a = a + b; octave_idx_type l = a.length (); if (l > 0) @@ -76,6 +102,8 @@ MArrayN& operator -= (MArrayN& a, const MArrayN& b) { + if (a.is_shared ()) + return a = a - b; octave_idx_type l = a.length (); if (l > 0) diff --git a/liboctave/fCNDArray.cc b/liboctave/fCNDArray.cc --- a/liboctave/fCNDArray.cc +++ b/liboctave/fCNDArray.cc @@ -36,6 +36,7 @@ #include "functor.h" #include "lo-ieee.h" #include "lo-mappers.h" +#include "MArray-defs.h" #include "mx-base.h" #include "mx-op-defs.h" #include "oct-fftw.h" @@ -1078,6 +1079,22 @@ NDND_CMP_OPS(FloatComplexNDArray, std::real, FloatComplexNDArray, std::real) NDND_BOOL_OPS(FloatComplexNDArray, FloatComplexNDArray, static_cast (0.0)) +FloatComplexNDArray& operator *= (FloatComplexNDArray& a, float s) +{ + if (a.is_shared ()) + return a = a * s; + DO_VS_OP2 (FloatComplex, a, *=, s) + return a; +} + +FloatComplexNDArray& operator /= (FloatComplexNDArray& a, float s) +{ + if (a.is_shared ()) + return a = a / s; + DO_VS_OP2 (FloatComplex, a, /=, s) + return a; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/fCNDArray.h b/liboctave/fCNDArray.h --- a/liboctave/fCNDArray.h +++ b/liboctave/fCNDArray.h @@ -173,6 +173,9 @@ MARRAY_FORWARD_DEFS (MArrayN, FloatComplexNDArray, FloatComplex) +extern OCTAVE_API FloatComplexNDArray& operator *= (FloatComplexNDArray& a, float s); +extern OCTAVE_API FloatComplexNDArray& operator /= (FloatComplexNDArray& a, float s); + #endif /* diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2009-08-17 Jaroslav Hajek + + * OPERATORS/op-m-m.cc: Define and install += and -= operators. + * OPERATORS/op-fm-fm.cc: Ditto. + * OPERATORS/op-cm-cm.cc: Ditto. + * OPERATORS/op-fcm-fcm.cc: Ditto. + * OPERATORS/op-m-s.cc: Define and install +=,-=,*=,/= operators. + * OPERATORS/op-fm-fs.cc: Ditto. + * OPERATORS/op-cm-cs.cc: Ditto. + * OPERATORS/op-fcm-fcs.cc: Ditto. + * OPERATORS/op-cm-s.cc: Define and install *=,/= operators. + * OPERATORS/op-fcm-fs.cc: Ditto. + * ops.h (DEFNDASSIGNOP_OP): New macro. + * ov.cc (octave_value::assign (assign_op, const octave_value&)): + Try looking up specialized handlers if the value is not shared. + * ov-base-mat.h (octave_base_matrix::matrix_ref): New method. + 2009-08-17 Jaroslav Hajek * oct-obj.h (octave_value_list::octave_value_list (octave_idx_type)): diff --git a/src/OPERATORS/op-cm-cm.cc b/src/OPERATORS/op-cm-cm.cc --- a/src/OPERATORS/op-cm-cm.cc +++ b/src/OPERATORS/op-cm-cm.cc @@ -163,6 +163,9 @@ DEFNULLASSIGNOP_FN (null_assign, complex_matrix, delete_elements) +DEFNDASSIGNOP_OP (assign_add, complex_matrix, complex_matrix, complex_array, +=) +DEFNDASSIGNOP_OP (assign_sub, complex_matrix, complex_matrix, complex_array, -=) + CONVDECL (complex_matrix_to_float_complex_matrix) { CAST_CONV_ARG (const octave_complex_matrix&); @@ -213,6 +216,9 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_null_str, null_assign); INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_null_sq_str, null_assign); + INSTALL_ASSIGNOP (op_add_eq, octave_complex_matrix, octave_complex_matrix, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_complex_matrix, octave_complex_matrix, assign_sub); + INSTALL_CONVOP (octave_complex_matrix, octave_float_complex_matrix, complex_matrix_to_float_complex_matrix); } diff --git a/src/OPERATORS/op-cm-cs.cc b/src/OPERATORS/op-cm-cs.cc --- a/src/OPERATORS/op-cm-cs.cc +++ b/src/OPERATORS/op-cm-cs.cc @@ -107,6 +107,11 @@ DEFNDASSIGNOP_FN (assign, complex_matrix, complex, complex, assign) DEFNDASSIGNOP_FN (sgl_assign, float_complex_matrix, complex, float_complex, assign) +DEFNDASSIGNOP_OP (assign_add, complex_matrix, complex_scalar, complex, +=) +DEFNDASSIGNOP_OP (assign_sub, complex_matrix, complex_scalar, complex, -=) +DEFNDASSIGNOP_OP (assign_mul, complex_matrix, complex_scalar, complex, *=) +DEFNDASSIGNOP_OP (assign_div, complex_matrix, complex_scalar, complex, /=) + void install_cm_cs_ops (void) { @@ -133,6 +138,11 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_complex, assign); INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, octave_complex, sgl_assign); + + INSTALL_ASSIGNOP (op_add_eq, octave_complex_matrix, octave_complex_scalar, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_complex_matrix, octave_complex_scalar, assign_sub); + INSTALL_ASSIGNOP (op_mul_eq, octave_complex_matrix, octave_complex_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_complex_matrix, octave_complex_scalar, assign_div); } /* diff --git a/src/OPERATORS/op-cm-s.cc b/src/OPERATORS/op-cm-s.cc --- a/src/OPERATORS/op-cm-s.cc +++ b/src/OPERATORS/op-cm-s.cc @@ -110,6 +110,9 @@ DEFNDASSIGNOP_FN (assign, complex_matrix, scalar, complex_array, assign) +DEFNDASSIGNOP_OP (assign_mul, complex_matrix, scalar, scalar, *=) +DEFNDASSIGNOP_OP (assign_div, complex_matrix, scalar, scalar, /=) + void install_cm_s_ops (void) { @@ -135,6 +138,9 @@ INSTALL_CATOP (octave_complex_matrix, octave_scalar, cm_s); INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_scalar, assign); + + INSTALL_ASSIGNOP (op_mul_eq, octave_complex_matrix, octave_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_complex_matrix, octave_scalar, assign_div); } /* diff --git a/src/OPERATORS/op-fcm-fcm.cc b/src/OPERATORS/op-fcm-fcm.cc --- a/src/OPERATORS/op-fcm-fcm.cc +++ b/src/OPERATORS/op-fcm-fcm.cc @@ -189,6 +189,11 @@ DEFNULLASSIGNOP_FN (null_assign, float_complex_matrix, delete_elements) +DEFNDASSIGNOP_OP (assign_add, float_complex_matrix, + float_complex_matrix, float_complex_array, +=) +DEFNDASSIGNOP_OP (assign_sub, float_complex_matrix, + float_complex_matrix, float_complex_array, -=) + CONVDECL (float_complex_matrix_to_complex_matrix) { CAST_CONV_ARG (const octave_float_complex_matrix&); @@ -272,6 +277,11 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_float_complex_matrix, octave_null_sq_str, null_assign); + INSTALL_ASSIGNOP (op_add_eq, octave_float_complex_matrix, + octave_float_complex_matrix, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_float_complex_matrix, + octave_float_complex_matrix, assign_sub); + INSTALL_CONVOP (octave_float_complex_matrix, octave_complex_matrix, float_complex_matrix_to_complex_matrix); } diff --git a/src/OPERATORS/op-fcm-fcs.cc b/src/OPERATORS/op-fcm-fcs.cc --- a/src/OPERATORS/op-fcm-fcs.cc +++ b/src/OPERATORS/op-fcm-fcs.cc @@ -134,6 +134,15 @@ DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_complex, complex, assign) +DEFNDASSIGNOP_OP (assign_add, float_complex_matrix, float_complex_scalar, + float_complex, +=) +DEFNDASSIGNOP_OP (assign_sub, float_complex_matrix, float_complex_scalar, + float_complex, -=) +DEFNDASSIGNOP_OP (assign_mul, float_complex_matrix, float_complex_scalar, + float_complex, *=) +DEFNDASSIGNOP_OP (assign_div, float_complex_matrix, float_complex_scalar, + float_complex, /=) + void install_fcm_fcs_ops (void) { @@ -176,6 +185,15 @@ octave_float_complex, assign); INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_float_complex, dbl_assign); + + INSTALL_ASSIGNOP (op_add_eq, octave_float_complex_matrix, + octave_float_complex_scalar, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_float_complex_matrix, + octave_float_complex_scalar, assign_sub); + INSTALL_ASSIGNOP (op_mul_eq, octave_float_complex_matrix, + octave_float_complex_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_float_complex_matrix, + octave_float_complex_scalar, assign_div); } /* diff --git a/src/OPERATORS/op-fcm-fs.cc b/src/OPERATORS/op-fcm-fs.cc --- a/src/OPERATORS/op-fcm-fs.cc +++ b/src/OPERATORS/op-fcm-fs.cc @@ -130,6 +130,11 @@ DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_scalar, float_complex_array, assign) DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_scalar, complex_array, assign) +DEFNDASSIGNOP_OP (assign_mul, float_complex_matrix, float_scalar, + float_scalar, *=) +DEFNDASSIGNOP_OP (assign_div, float_complex_matrix, float_scalar, + float_scalar, /=) + void install_fcm_fs_ops (void) { @@ -160,6 +165,11 @@ octave_float_scalar, assign); INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_float_scalar, dbl_assign); + + INSTALL_ASSIGNOP (op_mul_eq, octave_float_complex_matrix, + octave_float_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_float_complex_matrix, + octave_float_scalar, assign_div); } /* diff --git a/src/OPERATORS/op-fm-fm.cc b/src/OPERATORS/op-fm-fm.cc --- a/src/OPERATORS/op-fm-fm.cc +++ b/src/OPERATORS/op-fm-fm.cc @@ -165,6 +165,9 @@ DEFNULLASSIGNOP_FN (null_assign, float_matrix, delete_elements) +DEFNDASSIGNOP_OP (assign_add, float_matrix, float_matrix, float_array, +=) +DEFNDASSIGNOP_OP (assign_sub, float_matrix, float_matrix, float_array, -=) + CONVDECL (float_matrix_to_matrix) { CAST_CONV_ARG (const octave_float_matrix&); @@ -224,6 +227,9 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_null_str, null_assign); INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_null_sq_str, null_assign); + INSTALL_ASSIGNOP (op_add_eq, octave_float_matrix, octave_float_matrix, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_float_matrix, octave_float_matrix, assign_sub); + INSTALL_CONVOP (octave_float_matrix, octave_matrix, float_matrix_to_matrix); } diff --git a/src/OPERATORS/op-fm-fs.cc b/src/OPERATORS/op-fm-fs.cc --- a/src/OPERATORS/op-fm-fs.cc +++ b/src/OPERATORS/op-fm-fs.cc @@ -122,6 +122,11 @@ DEFNDASSIGNOP_FN (assign, float_matrix, float_scalar, float_scalar, assign) DEFNDASSIGNOP_FN (dbl_assign, matrix, float_scalar, scalar, assign) +DEFNDASSIGNOP_OP (assign_add, float_matrix, float_scalar, float_scalar, +=) +DEFNDASSIGNOP_OP (assign_sub, float_matrix, float_scalar, float_scalar, -=) +DEFNDASSIGNOP_OP (assign_mul, float_matrix, float_scalar, float_scalar, *=) +DEFNDASSIGNOP_OP (assign_div, float_matrix, float_scalar, float_scalar, /=) + void install_fm_fs_ops (void) { @@ -150,6 +155,11 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_float_scalar, assign); INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_float_scalar, dbl_assign); + + INSTALL_ASSIGNOP (op_add_eq, octave_float_matrix, octave_float_scalar, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_float_matrix, octave_float_scalar, assign_sub); + INSTALL_ASSIGNOP (op_mul_eq, octave_float_matrix, octave_float_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_float_matrix, octave_float_scalar, assign_div); } /* diff --git a/src/OPERATORS/op-int.h b/src/OPERATORS/op-int.h --- a/src/OPERATORS/op-int.h +++ b/src/OPERATORS/op-int.h @@ -584,6 +584,12 @@ #define OCTAVE_MS_INT_ASSIGN_OPS(PFX, TM, TS, TE) \ DEFNDASSIGNOP_FN (PFX ## _assign, TM ## matrix, TS ## scalar, TM ## scalar, assign) +#define OCTAVE_MS_INT_ASSIGNEQ_OPS(PFX, TM) \ + DEFNDASSIGNOP_OP (PFX ## _assign_add, TM ## matrix, TM ## scalar, TM ## scalar, +=) \ + DEFNDASSIGNOP_OP (PFX ## _assign_sub, TM ## matrix, TM ## scalar, TM ## scalar, -=) \ + DEFNDASSIGNOP_OP (PFX ## _assign_mul, TM ## matrix, TM ## scalar, TM ## scalar, *=) \ + DEFNDASSIGNOP_OP (PFX ## _assign_div, TM ## matrix, TM ## scalar, TM ## scalar, /=) + #define OCTAVE_MS_POW_OPS(T1, T2) \ octave_value elem_xpow (T1 ## NDArray a, octave_ ## T2 b) \ { \ @@ -659,6 +665,7 @@ OCTAVE_MS_INT_BOOL_OPS (mfx, TYPE ## _, float_) \ OCTAVE_MS_INT_BOOL_OPS (mfxs, float_, TYPE ## _) \ OCTAVE_MS_INT_ASSIGN_OPS (ms, TYPE ## _, TYPE ## _, TYPE ## _) \ + OCTAVE_MS_INT_ASSIGNEQ_OPS (mse, TYPE ## _) \ OCTAVE_MS_INT_ASSIGN_OPS (mx, TYPE ## _, , ) \ OCTAVE_MS_INT_ASSIGN_OPS (mfx, TYPE ## _, float_, float_) @@ -747,6 +754,10 @@ #define OCTAVE_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS, TE) \ DEFNDASSIGNOP_FN (PFX ## _assign, TLHS ## matrix, TRHS ## matrix, TLHS ## array, assign) +#define OCTAVE_MM_INT_ASSIGNEQ_OPS(PFX, TM) \ + DEFNDASSIGNOP_OP (PFX ## _assign_add, TM ## matrix, TM ## matrix, TM ## array, +=) \ + DEFNDASSIGNOP_OP (PFX ## _assign_sub, TM ## matrix, TM ## matrix, TM ## array, -=) + #define OCTAVE_MM_POW_OPS(T1, T2) \ octave_value \ elem_xpow (const T1 ## NDArray& a, const T2 ## NDArray& b) \ @@ -871,6 +882,7 @@ OCTAVE_MM_INT_BOOL_OPS (mmfx, TYPE ## _, float_) \ OCTAVE_MM_INT_BOOL_OPS (mfxm, float_, TYPE ## _) \ OCTAVE_MM_INT_ASSIGN_OPS (mm, TYPE ## _, TYPE ## _, TYPE ## _) \ + OCTAVE_MM_INT_ASSIGNEQ_OPS (mme, TYPE ## _) \ OCTAVE_MM_INT_ASSIGN_OPS (mmx, TYPE ## _, , ) \ OCTAVE_MM_INT_ASSIGN_OPS (mmfx, TYPE ## _, float_, float_) \ OCTAVE_MM_CONV(TYPE ## _, complex_) \ @@ -1045,6 +1057,12 @@ #define OCTAVE_INSTALL_MS_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \ INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign) +#define OCTAVE_INSTALL_MS_INT_ASSIGNEQ_OPS(PFX, TLHS, TRHS) \ + INSTALL_ASSIGNOP (op_add_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign_add) \ + INSTALL_ASSIGNOP (op_sub_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign_sub) \ + INSTALL_ASSIGNOP (op_mul_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign_mul) \ + INSTALL_ASSIGNOP (op_div_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## scalar, PFX ## _assign_div) + #define OCTAVE_INSTALL_MS_INT_OPS(TYPE) \ OCTAVE_INSTALL_MS_INT_ARITH_OPS (ms, TYPE ## _, TYPE ## _) \ OCTAVE_INSTALL_MS_INT_ARITH_OPS (msx, TYPE ## _, ) \ @@ -1062,6 +1080,7 @@ OCTAVE_INSTALL_MS_INT_BOOL_OPS (mfx, TYPE ## _, float_) \ OCTAVE_INSTALL_MS_INT_BOOL_OPS (mfxs, float_, TYPE ## _) \ OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (ms, TYPE ## _, TYPE ## _) \ + OCTAVE_INSTALL_MS_INT_ASSIGNEQ_OPS (mse, TYPE ## _, TYPE ## _) \ OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mx, TYPE ## _, ) \ OCTAVE_INSTALL_MS_INT_ASSIGN_OPS (mfx, TYPE ## _, float_) \ INSTALL_ASSIGNCONV (octave_ ## TYPE ## _matrix, octave_complex_scalar, octave_complex_matrix) \ @@ -1108,6 +1127,10 @@ #define OCTAVE_INSTALL_MM_INT_ASSIGN_OPS(PFX, TLHS, TRHS) \ INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## matrix, PFX ## _assign) +#define OCTAVE_INSTALL_MM_INT_ASSIGNEQ_OPS(PFX, TLHS, TRHS) \ + INSTALL_ASSIGNOP (op_add_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## matrix, PFX ## _assign_add) \ + INSTALL_ASSIGNOP (op_sub_eq, octave_ ## TLHS ## matrix, octave_ ## TRHS ## matrix, PFX ## _assign_sub) + #define OCTAVE_INSTALL_MM_INT_OPS(TYPE) \ OCTAVE_INSTALL_M_INT_UNOPS (TYPE) \ OCTAVE_INSTALL_MM_INT_ARITH_OPS (mm, TYPE ##_, TYPE ## _) \ @@ -1126,6 +1149,7 @@ OCTAVE_INSTALL_MM_INT_BOOL_OPS (mmfx, TYPE ## _, float_) \ OCTAVE_INSTALL_MM_INT_BOOL_OPS (mfxm, float_, TYPE ## _) \ OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mm, TYPE ## _, TYPE ## _) \ + OCTAVE_INSTALL_MM_INT_ASSIGNEQ_OPS (mme, TYPE ## _, TYPE ## _) \ OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmx, TYPE ## _, ) \ OCTAVE_INSTALL_MM_INT_ASSIGN_OPS (mmfx, TYPE ## _, float_) \ INSTALL_WIDENOP (octave_ ## TYPE ## _matrix, octave_complex_matrix, TYPE ## _m_complex_m_conv) \ diff --git a/src/OPERATORS/op-m-m.cc b/src/OPERATORS/op-m-m.cc --- a/src/OPERATORS/op-m-m.cc +++ b/src/OPERATORS/op-m-m.cc @@ -138,6 +138,9 @@ DEFNULLASSIGNOP_FN (null_assign, matrix, delete_elements) +DEFNDASSIGNOP_OP (assign_add, matrix, matrix, array, +=) +DEFNDASSIGNOP_OP (assign_sub, matrix, matrix, array, -=) + CONVDECL (matrix_to_float_matrix) { CAST_CONV_ARG (const octave_matrix&); @@ -193,6 +196,9 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_null_str, null_assign); INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_null_sq_str, null_assign); + INSTALL_ASSIGNOP (op_add_eq, octave_matrix, octave_matrix, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_matrix, octave_matrix, assign_sub); + INSTALL_CONVOP (octave_matrix, octave_float_matrix, matrix_to_float_matrix); } diff --git a/src/OPERATORS/op-m-s.cc b/src/OPERATORS/op-m-s.cc --- a/src/OPERATORS/op-m-s.cc +++ b/src/OPERATORS/op-m-s.cc @@ -108,6 +108,11 @@ DEFNDASSIGNOP_FN (assign, matrix, scalar, scalar, assign) DEFNDASSIGNOP_FN (sgl_assign, float_matrix, scalar, float_scalar, assign) +DEFNDASSIGNOP_OP (assign_add, matrix, scalar, scalar, +=) +DEFNDASSIGNOP_OP (assign_sub, matrix, scalar, scalar, -=) +DEFNDASSIGNOP_OP (assign_mul, matrix, scalar, scalar, *=) +DEFNDASSIGNOP_OP (assign_div, matrix, scalar, scalar, /=) + void install_m_s_ops (void) { @@ -140,6 +145,11 @@ INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_scalar, assign); INSTALL_ASSIGNOP (op_asn_eq, octave_float_matrix, octave_scalar, sgl_assign); + + INSTALL_ASSIGNOP (op_add_eq, octave_matrix, octave_scalar, assign_add); + INSTALL_ASSIGNOP (op_sub_eq, octave_matrix, octave_scalar, assign_sub); + INSTALL_ASSIGNOP (op_mul_eq, octave_matrix, octave_scalar, assign_mul); + INSTALL_ASSIGNOP (op_div_eq, octave_matrix, octave_scalar, assign_div); } /* diff --git a/src/ops.h b/src/ops.h --- a/src/ops.h +++ b/src/ops.h @@ -201,6 +201,18 @@ return octave_value (); \ } +// FIXME: the following currently doesn't handle index. +#define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \ + ASSIGNOPDECL (name) \ + { \ + CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \ + \ + assert (idx.empty ()); \ + v1.matrix_ref () op v2.CONCAT2(f, _value) (); \ + \ + return octave_value (); \ + } + #define DEFASSIGNANYOP_FN(name, t1, f) \ ASSIGNANYOPDECL (name) \ { \ diff --git a/src/ov-base-mat.h b/src/ov-base-mat.h --- a/src/ov-base-mat.h +++ b/src/ov-base-mat.h @@ -154,6 +154,12 @@ void print_info (std::ostream& os, const std::string& prefix) const; + MT& matrix_ref (void) + { + clear_cached_info (); + return matrix; + } + protected: MT matrix; diff --git a/src/ov.cc b/src/ov.cc --- a/src/ov.cc +++ b/src/ov.cc @@ -1195,10 +1195,6 @@ if (op != op_asn_eq) { - // FIXME -- only do the following stuff if we can't find - // a specific function to call to handle the op= operation for - // the types we have. - octave_value t = subsref (type, idx); if (! error_state) @@ -1236,19 +1232,41 @@ operator = (rhs.storable_value ()); else { - // FIXME -- only do the following stuff if we can't find - // a specific function to call to handle the op= operation for - // the types we have. - - binary_op binop = op_eq_to_binary_op (op); - - if (! error_state) + octave_value_typeinfo::assign_op_fcn f = 0; + + // Only attempt to operate in-place if this variable is unshared. + if (rep->count == 1) + { + int tthis = this->type_id (); + int trhs = rhs.type_id (); + + f = octave_value_typeinfo::lookup_assign_op (op, tthis, trhs); + } + + if (f) { - octave_value t = do_binary_op (binop, *this, rhs); - - if (! error_state) - operator = (t); + try + { + f (*rep, octave_value_list (), *rhs.rep); + } + catch (octave_execution_exception) + { + gripe_library_execution_error (); + } } + else + { + + binary_op binop = op_eq_to_binary_op (op); + + if (! error_state) + { + octave_value t = do_binary_op (binop, *this, rhs); + + if (! error_state) + operator = (t); + } + } if (error_state) gripe_assign_failed_or_no_method (assign_op_as_string (op),