From c3731b36d1fc37546d00f52b3ccaa1c690646cf1 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 7 Sep 2007 07:41:10 +0000 Subject: [PATCH] Add operator += and operator -= between matrices/vectors/expressions --- src/MatrixBase.h | 10 +++++++++ src/MatrixOps.h | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/MatrixXpr.h | 11 ++++++++++ test/matrixmanip.cpp | 3 ++- test/matrixops.cpp | 4 ++++ test/vectorops.cpp | 5 +++++ 6 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/MatrixBase.h b/src/MatrixBase.h index 860b9272d..93552b467 100644 --- a/src/MatrixBase.h +++ b/src/MatrixBase.h @@ -202,6 +202,16 @@ class MatrixBase MatrixConstXpr > block(int startRow, int endRow, int startCol = 0, int endCol = 0) const; + template + MatrixBase& operator+=(const MatrixConstXpr &xpr); + template + MatrixBase& operator-=(const MatrixConstXpr &xpr); + template + MatrixBase& operator+=(const MatrixBase &other); + template + MatrixBase& operator-=(const MatrixBase &other); + + protected: MatrixBase() {}; diff --git a/src/MatrixOps.h b/src/MatrixOps.h index e4975daca..cf205e7cd 100644 --- a/src/MatrixOps.h +++ b/src/MatrixOps.h @@ -167,6 +167,54 @@ EIGEN_MAKE_MATRIX_OP(Product, *) #undef EIGEN_MAKE_MATRIX_OP +#define EIGEN_MAKE_MATRIX_OP_EQ(SYMBOL) \ +template \ +template \ +MatrixBase & \ +MatrixBase::operator SYMBOL##=(const MatrixBase &mat2) \ +{ \ + return *this = *this SYMBOL mat2; \ +} \ +\ +template \ +template \ +MatrixBase & \ +MatrixBase::operator SYMBOL##=(const MatrixConstXpr &xpr) \ +{ \ + return *this = *this SYMBOL xpr; \ +} \ +\ +template \ +template \ +MatrixXpr & \ +MatrixXpr::operator SYMBOL##=(const MatrixBase &mat) \ +{ \ + assert(rows() == mat.rows() && cols() == mat.cols()); \ + for(int i = 0; i < rows(); i++) \ + for(int j = 0; j < cols(); j++) \ + this->operator()(i, j) SYMBOL##= mat(i, j); \ + return *this; \ +} \ +\ +template \ +template \ +MatrixXpr & \ +MatrixXpr::operator SYMBOL##=(const MatrixConstXpr &other) \ +{ \ + assert(rows() == other.rows() && cols() == other.cols()); \ + for(int i = 0; i < rows(); i++) \ + for(int j = 0; j < cols(); j++) \ + this->operator()(i, j) SYMBOL##= other(i, j); \ + return *this; \ +} + +EIGEN_MAKE_MATRIX_OP_EQ(+) +EIGEN_MAKE_MATRIX_OP_EQ(-) + +#undef EIGEN_MAKE_MATRIX_OP_EQ + + + } // namespace Eigen #endif // EIGEN_MATRIXOPS_H diff --git a/src/MatrixXpr.h b/src/MatrixXpr.h index 937d4e280..843cb214d 100644 --- a/src/MatrixXpr.h +++ b/src/MatrixXpr.h @@ -114,6 +114,17 @@ template class MatrixXpr MatrixXpr > > minor(int row, int col); MatrixXpr > > block(int startRow, int endRow, int startCol= 0, int endCol = 0); + + template + MatrixXpr& operator+=(const MatrixConstXpr &other); + template + MatrixXpr& operator-=(const MatrixConstXpr &other); + template + MatrixXpr& operator+=(const MatrixBase &matrix); + template + MatrixXpr& operator-=(const MatrixBase &matrix); + + private: void operator=(const MatrixXpr &other) diff --git a/test/matrixmanip.cpp b/test/matrixmanip.cpp index 5ce8fa615..aa55d02cf 100644 --- a/test/matrixmanip.cpp +++ b/test/matrixmanip.cpp @@ -36,8 +36,9 @@ template void matrixManip(const MatrixType& m) a.minor(i, j); a.block(1, rows-1, 1, cols-1); a.xpr().row(i) = b.row(i); + a.xpr().row(i) += b.row(i); a.xpr().minor(i, j) = b.block(1, rows-1, 1, cols-1); - a.alias().xpr().minor(i, j) = a.block(1, rows-1, 1, cols-1); + a.alias().xpr().minor(i, j) -= a.block(1, rows-1, 1, cols-1); } void EigenTest::testMatrixManip() diff --git a/test/matrixops.cpp b/test/matrixops.cpp index a9034dcf2..56b252287 100644 --- a/test/matrixops.cpp +++ b/test/matrixops.cpp @@ -46,6 +46,10 @@ template void vectorOps(const VectorType& v) a = b + c; a = s * (b - c); a.alias() = a + b; + + a += b; + a += b + b; + a.xpr() -= b; + a.xpr() -= b + b; } void EigenTest::testVectorOps()