diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-04-22 14:11:18 -0400 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-04-22 14:11:18 -0400 |
commit | 9962c59b56960569c8df332144190e62c1eb3b01 (patch) | |
tree | a3efa574460c6a08f4ed17a3896b497d5bfc374f /doc | |
parent | 28dde19e40a3d758faa94f0fc228857f7b3192ea (diff) |
* implement the corner() API change: new methods topLeftCorner() etc
* get rid of BlockReturnType: it was not needed, and code was not always using it consistently anyway
* add topRows(), leftCols(), bottomRows(), rightCols()
* add corners unit-test covering all of that
* adapt docs, expand "porting from eigen 2 to 3"
* adapt Eigen2Support
Diffstat (limited to 'doc')
-rw-r--r-- | doc/A05_PortingFrom2To3.dox | 29 | ||||
-rw-r--r-- | doc/AsciiQuickReference.txt | 17 | ||||
-rw-r--r-- | doc/C01_QuickStartGuide.dox | 27 | ||||
-rw-r--r-- | doc/C03_TutorialGeometry.dox | 2 | ||||
-rw-r--r-- | doc/Overview.dox | 2 | ||||
-rw-r--r-- | doc/echelon.cpp | 121 | ||||
-rw-r--r-- | doc/snippets/MatrixBase_corner_enum_int_int.cpp | 6 | ||||
-rw-r--r-- | doc/snippets/MatrixBase_template_int_int_corner_enum.cpp | 6 |
8 files changed, 49 insertions, 161 deletions
diff --git a/doc/A05_PortingFrom2To3.dox b/doc/A05_PortingFrom2To3.dox index 57f801f84..554ca7f2c 100644 --- a/doc/A05_PortingFrom2To3.dox +++ b/doc/A05_PortingFrom2To3.dox @@ -9,6 +9,7 @@ and to help porting an application from Eigen2 to Eigen3. - \ref CompatibilitySupport - \ref ChangeList - \ref CoefficientWiseOperations + - \ref Corners - \ref LazyVsNoalias \section CompatibilitySupport Eigen2 compatibility support @@ -81,6 +82,34 @@ With Eigen2 you would have written: c = (a.cwise().abs().cwise().pow(3)).cwise() * (b.cwise().abs().cwise().sin()); \endcode +\section Corners Corners + +<table> +<tr><td>Eigen 2</td><td>Eigen 3</td></tr> +<tr><td>\code +matrix.corner(TopLeft,r,c) +matrix.corner(TopRight,r,c) +matrix.corner(BottomLeft,r,c) +matrix.corner(BottomRight,r,c) +matrix.corner<r,c>(TopLeft) +matrix.corner<r,c>(TopRight) +matrix.corner<r,c>(BottomLeft) +matrix.corner<r,c>(BottomRight) +\endcode</td><td>\code +matrix.topLeftCorner(r,c) +matrix.topRightCorner(r,c) +matrix.bottomLeftCorner(r,c) +matrix.bottomRightCorner(r,c) +matrix.topLeftCorner<r,c>() +matrix.topRightCorner<r,c>() +matrix.bottomLeftCorner<r,c>() +matrix.bottomRightCorner<r,c>() +\endcode</td> +</tr> +</table> + +Notice that Eigen3 also provides these new convenience methods: topRows(), bottomRows(), leftCols(), rightCols(). See in class DenseBase. + \section LazyVsNoalias Lazy evaluation and noalias In Eigen all operations are performed in a lazy fashion except the matrix products which are always evaluated into a temporary by default. diff --git a/doc/AsciiQuickReference.txt b/doc/AsciiQuickReference.txt index 74de7344b..d2e973f5d 100644 --- a/doc/AsciiQuickReference.txt +++ b/doc/AsciiQuickReference.txt @@ -47,15 +47,14 @@ x.segment(i, n) // x(i+1 : i+n) x.segment<n>(i) // x(i+1 : i+n) P.block(i, j, rows, cols) // P(i+1 : i+rows, j+1 : j+cols) P.block<rows, cols>(i, j) // P(i+1 : i+rows, j+1 : j+cols) -P.corner(TopLeft, rows, cols) // P(1:rows, 1:cols) -P.corner(TopRight, rows, cols) // [m n]=size(P); P(1:rows, n-cols+1:n) -P.corner(BottomLeft, rows, cols) // [m n]=size(P); P(m-rows+1:m, 1:cols) -P.corner(BottomRight, rows, cols) // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) -P.corner<rows,cols>(TopLeft) // P(1:rows, 1:cols) -P.corner<rows,cols>(TopRight) // [m n]=size(P); P(1:rows, n-cols+1:n) -P.corner<rows,cols>(BottomLeft) // [m n]=size(P); P(m-rows+1:m, 1:cols) -P.corner<rows,cols>(BottomRight) // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) -P.minor(i, j) // Something nasty. +P.topLeftCorner(rows, cols) // P(1:rows, 1:cols) +P.topRightCorner(rows, cols) // [m n]=size(P); P(1:rows, n-cols+1:n) +P.bottomLeftCorner(rows, cols) // [m n]=size(P); P(m-rows+1:m, 1:cols) +P.bottomRightCorner(rows, cols) // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) +P.topLeftCorner<rows,cols>() // P(1:rows, 1:cols) +P.topRightCorner<rows,cols>() // [m n]=size(P); P(1:rows, n-cols+1:n) +P.bottomLeftCorner<rows,cols>() // [m n]=size(P); P(m-rows+1:m, 1:cols) +P.bottomRightCorner<rows,cols>() // [m n]=size(P); P(m-rows+1:m, n-cols+1:n) // Of particular note is Eigen's swap function which is highly optimized. // Eigen // Matlab diff --git a/doc/C01_QuickStartGuide.dox b/doc/C01_QuickStartGuide.dox index b346e2371..79705aa9d 100644 --- a/doc/C01_QuickStartGuide.dox +++ b/doc/C01_QuickStartGuide.dox @@ -577,29 +577,22 @@ Read-write access to sub-matrices:</td><td></td><td></td></tr> \link DenseBase::block(int,int) (more) \endlink</td> <td>the \c rows x \c cols sub-matrix \n starting from position (\c i,\c j)</td></tr><tr> <td>\code - mat1.corner(TopLeft,rows,cols) - mat1.corner(TopRight,rows,cols) - mat1.corner(BottomLeft,rows,cols) - mat1.corner(BottomRight,rows,cols)\endcode - \link DenseBase::corner(CornerType,int,int) (more) \endlink</td> + mat1.topLeftCorner(rows,cols) + mat1.topRightCorner(rows,cols) + mat1.bottomLeftCorner(rows,cols) + mat1.bottomRightCorner(rows,cols)\endcode <td>\code - mat1.corner<rows,cols>(TopLeft) - mat1.corner<rows,cols>(TopRight) - mat1.corner<rows,cols>(BottomLeft) - mat1.corner<rows,cols>(BottomRight)\endcode - \link DenseBase::corner(CornerType) (more) \endlink</td> + mat1.topLeftCorner<rows,cols>() + mat1.topRightCorner<rows,cols>() + mat1.bottomLeftCorner<rows,cols>() + mat1.bottomRightCorner<rows,cols>()\endcode <td>the \c rows x \c cols sub-matrix \n taken in one of the four corners</td></tr> -<tr><td>\code -mat4x4.minor(i,j) = mat3x3; -mat3x3 = mat4x4.minor(i,j);\endcode -</td><td></td><td> -\link DenseBase::minor() minor \endlink (read-write)</td> -</tr> </table> -<a href="#" class="top">top</a>\section TutorialCoreDiagonalMatrices Diagonal matrices \matrixworld +<a href="#" class="top">top</a>\section TutorialCoreDiagonalMatrices Diagonal matrices +\matrixworld <table class="tutorial_code"> <tr><td> diff --git a/doc/C03_TutorialGeometry.dox b/doc/C03_TutorialGeometry.dox index e349c68ce..6d02df40c 100644 --- a/doc/C03_TutorialGeometry.dox +++ b/doc/C03_TutorialGeometry.dox @@ -153,7 +153,7 @@ glLoadMatrixf(t.data());\endcode</td></tr> <tr><td> OpenGL compatibility \b 2D </td><td>\code Transform3f aux(Transform3f::Identity); -aux.linear().corner<2,2>(TopLeft) = t.linear(); +aux.linear().topLeftCorner<2,2>() = t.linear(); aux.translation().start<2>() = t.translation(); glLoadMatrixf(aux.data());\endcode</td></tr> </table> diff --git a/doc/Overview.dox b/doc/Overview.dox index 10463900e..6b7000c4d 100644 --- a/doc/Overview.dox +++ b/doc/Overview.dox @@ -11,7 +11,7 @@ o /** \mainpage Eigen This is the API documentation for Eigen3. -You come from Eigen2? Here is a \ref Eigen2ToEigen3 guide for porting your application from Eigen2 to Eigen3. +Eigen2 users: here is a \ref Eigen2ToEigen3 guide to help porting your application. For a first contact with Eigen, the best place is to have a look at the \ref TutorialCore "tutorial". For an even shorter overview, we have an <a href="AsciiQuickReference.txt">ASCII quick reference</a> with Matlab translations. diff --git a/doc/echelon.cpp b/doc/echelon.cpp deleted file mode 100644 index c95be6f3b..000000000 --- a/doc/echelon.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include <Eigen/Core> - -USING_PART_OF_NAMESPACE_EIGEN - -namespace Eigen { - -/* Echelon a matrix in-place: - * - * Meta-Unrolled version, for small fixed-size matrices - */ -template<typename Derived, int Step> -struct unroll_echelon -{ - enum { k = Step - 1, - Rows = Derived::RowsAtCompileTime, - Cols = Derived::ColsAtCompileTime, - CornerRows = Rows - k, - CornerCols = Cols - k - }; - static void run(MatrixBase<Derived>& m) - { - unroll_echelon<Derived, Step-1>::run(m); - int rowOfBiggest, colOfBiggest; - m.template corner<CornerRows, CornerCols>(BottomRight) - .cwise().abs() - .maxCoeff(&rowOfBiggest, &colOfBiggest); - m.row(k).swap(m.row(k+rowOfBiggest)); - m.col(k).swap(m.col(k+colOfBiggest)); - m.template corner<CornerRows-1, CornerCols>(BottomRight) - -= m.col(k).template tail<CornerRows-1>() - * (m.row(k).template tail<CornerCols>() / m(k,k)); - } -}; - -template<typename Derived> -struct unroll_echelon<Derived, 0> -{ - static void run(MatrixBase<Derived>& m) {} -}; - -/* Echelon a matrix in-place: - * - * Non-unrolled version, for dynamic-size matrices. - * (this version works for all matrices, but in the fixed-size case the other - * version is faster). - */ -template<typename Derived> -struct unroll_echelon<Derived, Dynamic> -{ - static void run(MatrixBase<Derived>& m) - { - for(int k = 0; k < m.diagonal().size() - 1; k++) - { - int rowOfBiggest, colOfBiggest; - int cornerRows = m.rows()-k, cornerCols = m.cols()-k; - m.corner(BottomRight, cornerRows, cornerCols) - .cwise().abs() - .maxCoeff(&rowOfBiggest, &colOfBiggest); - m.row(k).swap(m.row(k+rowOfBiggest)); - m.col(k).swap(m.col(k+colOfBiggest)); - m.corner(BottomRight, cornerRows-1, cornerCols) - -= m.col(k).tail(cornerRows-1) * (m.row(k).tail(cornerCols) / m(k,k)); - } - } -}; - -using namespace std; -template<typename Derived> -void echelon(MatrixBase<Derived>& m) -{ - const int size = DiagonalCoeffs<Derived>::SizeAtCompileTime; - const bool unroll = size <= 4; - unroll_echelon<Derived, unroll ? size-1 : Dynamic>::run(m); -} - -template<typename Derived> -void doSomeRankPreservingOperations(MatrixBase<Derived>& m) -{ - for(int a = 0; a < 3*(m.rows()+m.cols()); a++) - { - double d = ei_random<double>(-1,1); - int i = ei_random<int>(0,m.rows()-1); // i is a random row number - int j; - do { - j = ei_random<int>(0,m.rows()-1); - } while (i==j); // j is another one (must be different) - m.row(i) += d * m.row(j); - - i = ei_random<int>(0,m.cols()-1); // i is a random column number - do { - j = ei_random<int>(0,m.cols()-1); - } while (i==j); // j is another one (must be different) - m.col(i) += d * m.col(j); - } -} - -} // namespace Eigen - -using namespace std; - -int main(int, char **) -{ - srand((unsigned int)time(0)); - const int Rows = 6, Cols = 4; - typedef Matrix<double, Rows, Cols> Mat; - const int N = Rows < Cols ? Rows : Cols; - - // start with a matrix m that's obviously of rank N-1 - Mat m = Mat::identity(Rows, Cols); // args just in case of dyn. size - m.row(0) = m.row(1) = m.row(0) + m.row(1); - - doSomeRankPreservingOperations(m); - - // now m is still a matrix of rank N-1 - cout << "Here's the matrix m:" << endl << m << endl; - - cout << "Now let's echelon m (repeating many times for benchmarking purposes):" << endl; - for(int i = 0; i < 1000000; i++) echelon(m); - - cout << "Now m is:" << endl << m << endl; -} diff --git a/doc/snippets/MatrixBase_corner_enum_int_int.cpp b/doc/snippets/MatrixBase_corner_enum_int_int.cpp deleted file mode 100644 index fd6c950cc..000000000 --- a/doc/snippets/MatrixBase_corner_enum_int_int.cpp +++ /dev/null @@ -1,6 +0,0 @@ -Matrix4i m = Matrix4i::Random(); -cout << "Here is the matrix m:" << endl << m << endl; -cout << "Here is the bottom-right 2x3 corner in m:" << endl - << m.corner(Eigen::BottomRight, 2, 3) << endl; -m.corner(Eigen::BottomRight, 2, 3).setZero(); -cout << "Now the matrix m is:" << endl << m << endl; diff --git a/doc/snippets/MatrixBase_template_int_int_corner_enum.cpp b/doc/snippets/MatrixBase_template_int_int_corner_enum.cpp deleted file mode 100644 index 05ed0ad2f..000000000 --- a/doc/snippets/MatrixBase_template_int_int_corner_enum.cpp +++ /dev/null @@ -1,6 +0,0 @@ -Matrix4i m = Matrix4i::Random(); -cout << "Here is the matrix m:" << endl << m << endl; -cout << "Here is the bottom-right 2x3 corner in m:" << endl - << m.corner<2,3>(Eigen::BottomRight) << endl; -m.corner<2,3>(Eigen::BottomRight).setZero(); -cout << "Now the matrix m is:" << endl << m << endl; |