diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2007-09-07 08:18:21 +0000 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2007-09-07 08:18:21 +0000 |
commit | 61158b1922e2aeeb132fbf6ceea551f61c400cde (patch) | |
tree | f1aef2afd4517a78bf597d4886e4df6508423091 | |
parent | c030e570fd266cfa5d7a8439de4845c82369667d (diff) |
add operator *= between matrices, with automatic aliasing.
add tutorial in doc/ subdirectory.
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | doc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | doc/tutorial.cpp | 60 | ||||
-rw-r--r-- | src/MatrixBase.h | 5 | ||||
-rw-r--r-- | src/MatrixOps.h | 16 |
5 files changed, 82 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a45fff6a7..4bfe11c6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,3 +16,4 @@ include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ) add_subdirectory(src) add_subdirectory(test) +add_subdirectory(doc) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 000000000..919e4a44b --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(tutorial tutorial.cpp) diff --git a/doc/tutorial.cpp b/doc/tutorial.cpp new file mode 100644 index 000000000..51847460f --- /dev/null +++ b/doc/tutorial.cpp @@ -0,0 +1,60 @@ +#include"../src/All.h" + +using namespace std; +using namespace Eigen; + +int main(int, char **) +{ + Matrix<double,2,2> m; // 2x2 fixed-size matrix with uninitialized entries + m(0,0) = 1; + m(0,1) = 2; + m(1,0) = 3; + m(1,1) = 4; + cout << "Here is a 2x2 matrix m:" << endl << m << endl; + cout << "Let us now build a 4x4 matrix m2 by assembling together four 2x2 blocks." << endl; + MatrixX<double> m2(4, 4); // dynamic matrix with initial size 4x4 and uninitialized entries + // notice how we are mixing fixed-size and dynamic-size types. + + cout << "In the top-left block, we put the matrix m shown above." << endl; + // here we need to use .xpr() to allow write access to the block. + m2.xpr().block(0,1,0,1) = m; + cout << "In the bottom-left block, we put the matrix m*m, which is:" << endl << m*m << endl; + m2.xpr().block(2,3,0,1) = m * m; + cout << "In the top-right block, we put the matrix m+m, which is:" << endl << m+m << endl; + m2.xpr().block(0,1,2,3) = m + m; + cout << "In the bottom-right block, we put the matrix m-m, which is:" << endl << m-m << endl; + m2.xpr().block(2,3,2,3) = m - m; + cout << "Now the 4x4 matrix m2 is:" << endl << m2 << endl; + + // here we don't need to use .xpr() because we only need read access. + cout << "The central 2x2 block of m2 is:" << endl << m2.block(1,2,1,2) << endl; + cout << "Row 0 of m2, written as a column vector, is:" << endl << m2.row(0) << endl; + cout << "Column 1 of m2 is:" << endl << m2.col(1) << endl; + cout << "The matrix m2 with row 0 and column 1 removed is:" << endl << m2.minor(0,1) << endl; + + cout << endl << "Now let us study a tricky issue." << endl; + cout << "Recall that the matrix product m*m is:" << endl << m*m << endl; + cout << "We want to store that into m, i.e. do \"m = m * m;\"" << endl; + cout << "Here we must be very careful. For if we do \"m = m * m;\"," << endl + << "the matrix m becomes" << endl; + Matrix<double,2,2> m_save = m; + m = m * m; // the bogus operation + cout << m << "," << endl; + cout << "which is not what was wanted!" << endl + << "Explanation: because of the way expression templates work, the matrix m gets" << endl + << "overwritten _while_ the matrix product m * m is being computed." << endl + << "This is the counterpart of eliminating temporary objects!" << endl + << "Anyway, if you want to store m * m into m, you can do this:" << endl + << " m.alias() = m * m;" << endl; + m = m_save; + m.alias() = m * m; + cout << "And m is now:" << endl << m << endl << "as was expected." << endl; + cout << "To make your life easier, operator*= between matrices automatically" << endl + << "creates an alias. So a *= b is equivalent to a.alias() *= b," << endl + << "when a and b are matrices. So, coming back to the original matrix m," << endl + << "if we do m *= m, the matrix m becomes:" << endl; + m = m_save; + m *= m; + cout << m << endl << "as expected." << endl; + return 0; +} diff --git a/src/MatrixBase.h b/src/MatrixBase.h index 7c817bda3..ab86f3289 100644 --- a/src/MatrixBase.h +++ b/src/MatrixBase.h @@ -206,11 +206,14 @@ class MatrixBase MatrixBase& operator+=(const MatrixConstXpr<Content> &xpr); template<typename Content> MatrixBase& operator-=(const MatrixConstXpr<Content> &xpr); + template<typename Content> + MatrixBase& operator*=(const MatrixConstXpr<Content> &xpr); template<typename Derived2> MatrixBase& operator+=(const MatrixBase<Derived2> &other); template<typename Derived2> MatrixBase& operator-=(const MatrixBase<Derived2> &other); - + template<typename Derived2> + MatrixBase& operator*=(const MatrixBase<Derived2> &other); protected: diff --git a/src/MatrixOps.h b/src/MatrixOps.h index cf205e7cd..8c2d5cda3 100644 --- a/src/MatrixOps.h +++ b/src/MatrixOps.h @@ -213,7 +213,23 @@ EIGEN_MAKE_MATRIX_OP_EQ(-) #undef EIGEN_MAKE_MATRIX_OP_EQ +template<typename Derived1> +template<typename Derived2> +MatrixBase<Derived1> & +MatrixBase<Derived1>::operator *=(const MatrixBase<Derived2> &mat2) +{ + alias() = *this * mat2; + return *this; +} +template<typename Derived> +template<typename Content> +MatrixBase<Derived> & +MatrixBase<Derived>::operator *=(const MatrixConstXpr<Content> &xpr) +{ + alias() = *this * xpr; + return *this; +} } // namespace Eigen |