From fa44566305be78f5b415f07e363b5707568b6b42 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 20 Jul 2009 10:35:47 +0200 Subject: [PATCH] bugfix for a = a * b; when a has to be resized (transplanted from a551107ccea8fe027d2672cb82f6b70e741bb996 ) --- Eigen/src/Core/Matrix.h | 21 +++++++++++++++++++-- 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 45b218af1..6b674c1a3 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -493,6 +493,9 @@ class Matrix else resize(other.rows(), other.cols()); } + template + 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), @@ -507,8 +510,8 @@ class Matrix template EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase& other) { - _resize_to_match(other); - return Base::operator=(other); + ei_matrix_set_selector::run(*this,other.derived()); + return *this; } /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which @@ -536,6 +539,20 @@ class Matrix } }; +template +template +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector +{ + static void run(MatrixType& dst, const OtherDerived& src) { dst._set_noalias(src.eval()); } +}; + +template +template +struct Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ei_matrix_set_selector +{ + 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 1c33578be..637e02b2a 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()); + } }