diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-07-20 10:35:47 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-07-20 10:35:47 +0200 |
commit | a551107ccea8fe027d2672cb82f6b70e741bb996 (patch) | |
tree | 0fe2b75eda258f9b455a5ff10cab4d79981aee68 | |
parent | 32b08ac971b2ab66cf83360a9e2d42a99bfe3b70 (diff) |
bugfix for a = a * b; when a has to be resized
-rw-r--r-- | Eigen/src/Core/Matrix.h | 21 | ||||
-rw-r--r-- | test/product_large.cpp | 6 |
2 files changed, 25 insertions, 2 deletions
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 5301f4849..32b526ef3 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -536,6 +536,9 @@ class Matrix resizeLike(other); } + template<typename MatrixType, typename OtherDerived, bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0> + struct ei_matrix_set_selector; + /** \internal Copies the value of the expression \a other into \c *this with automatic resizing. * * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), @@ -550,8 +553,8 @@ class Matrix template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other) { - _resize_to_match(other); - return Base::operator=(other); + ei_matrix_set_selector<Matrix,OtherDerived>::run(*this,other.derived()); + return *this; } /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which @@ -600,6 +603,20 @@ class Matrix } }; +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +template<typename MatrixType, typename OtherDerived> +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector<MatrixType,OtherDerived,true> +{ + static void run(MatrixType& dst, const OtherDerived& src) { dst._set_noalias(src.eval()); } +}; + +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +template<typename MatrixType, typename OtherDerived> +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector<MatrixType,OtherDerived,false> +{ + static void run(MatrixType& dst, const OtherDerived& src) { dst._set_noalias(src); } +}; + /** \defgroup matrixtypedefs Global matrix typedefs * * \ingroup Core_Module diff --git a/test/product_large.cpp b/test/product_large.cpp index 77ae7b587..9b53e7b89 100644 --- a/test/product_large.cpp +++ b/test/product_large.cpp @@ -42,4 +42,10 @@ void test_product_large() m = (v+v).asDiagonal() * m; VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2)); } + + { + // test deferred resizing in Matrix::operator= + MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a; + VERIFY_IS_APPROX((a = a * b), (c * b).eval()); + } } |