diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index 28c39f3d0..52bdbc9ac 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -33,7 +33,7 @@ * \param MatrixType the type of the object in which we are taking a block * * This class represents an expression of a dynamic-size block. It is the return - * type of MatrixBase::block() and most of the time this is the only way it + * type of MatrixBase::block(int,int,int,int) and most of the time this is the only way it * is used. * * However, if you want to directly maniputate dynamic-size block expressions, @@ -44,7 +44,11 @@ * \include class_Block.cpp * Output: \verbinclude class_Block.out * - * \sa MatrixBase::block() + * \note Even though this expression has dynamic size, in the case where the \a MatrixType + * has fixed size, this expression inherits a fixed maximal size which means that evaluating + * it does not cause a dynamic memory allocation. + * + * \sa MatrixBase::block(int,int,int,int), class VectorBlock */ template class Block : public MatrixBase > @@ -75,22 +79,27 @@ template class Block }; const Block& _ref() const { return *this; } - int _rows() const { return m_blockRows; } - int _cols() const { return m_blockCols; } + int _rows() const { return m_blockRows.value(); } + int _cols() const { return m_blockCols.value(); } Scalar& _coeffRef(int row, int col) { - return m_matrix.coeffRef(row + m_startRow, col + m_startCol); + return m_matrix.coeffRef(row + m_startRow.value(), col + m_startCol.value()); } Scalar _coeff(int row, int col) const { - return m_matrix.coeff(row + m_startRow, col + m_startCol); + return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value()); } protected: MatRef m_matrix; - const int m_startRow, m_startCol, m_blockRows, m_blockCols; + IntAtRunTimeIfDynamic + m_startRow; + IntAtRunTimeIfDynamic + m_startCol; + IntAtRunTimeIfDynamic m_blockRows; + IntAtRunTimeIfDynamic m_blockCols; }; /** \returns a dynamic-size expression of a block in *this. @@ -100,10 +109,10 @@ template class Block * \param blockRows the number of rows in the block * \param blockCols the number of columns in the block * - * Example: \include MatrixBase_block.cpp - * Output: \verbinclude MatrixBase_block.out + * Example: \include MatrixBase_block_int_int_int_int.cpp + * Output: \verbinclude MatrixBase_block_int_int_int_int.out * - * \sa class Block, fixedBlock() + * \sa class Block, fixedBlock(int,int) */ template Block MatrixBase @@ -112,7 +121,7 @@ Block MatrixBase return Block(ref(), startRow, startCol, blockRows, blockCols); } -/** This is the const version of block(). */ +/** This is the const version of block(int,int,int,int). */ template const Block MatrixBase ::block(int startRow, int startCol, int blockRows, int blockCols) const @@ -120,5 +129,141 @@ const Block MatrixBase return Block(ref(), startRow, startCol, blockRows, blockCols); } +/** \returns a dynamic-size expression of a block in *this. + * + * \only_for_vectors + * + * \param start the first coefficient in the block + * \param size the number of coefficients in the block + * + * Example: \include MatrixBase_block_int_int.cpp + * Output: \verbinclude MatrixBase_block_int_int.out + * + * \sa class Block, fixedBlock(int) + */ +template +Block MatrixBase + ::block(int start, int size) +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), Traits::RowsAtCompileTime == 1 ? 0 : start, + Traits::ColsAtCompileTime == 1 ? 0 : start, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** This is the const version of block(int,int).*/ +template +const Block MatrixBase + ::block(int start, int size) const +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), Traits::RowsAtCompileTime == 1 ? 0 : start, + Traits::ColsAtCompileTime == 1 ? 0 : start, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** \returns a dynamic-size expression of the first coefficients of *this. + * + * \only_for_vectors + * + * \param size the number of coefficients in the block + * + * Example: \include MatrixBase_start_int.cpp + * Output: \verbinclude MatrixBase_start_int.out + * + * \sa class Block, block(int,int) + */ +template +Block MatrixBase + ::start(int size) +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), 0, 0, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** This is the const version of start(int).*/ +template +const Block MatrixBase + ::start(int size) const +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), 0, 0, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** \returns a dynamic-size expression of the last coefficients of *this. + * + * \only_for_vectors + * + * \param size the number of coefficients in the block + * + * Example: \include MatrixBase_end_int.cpp + * Output: \verbinclude MatrixBase_end_int.out + * + * \sa class Block, block(int,int) + */ +template +Block MatrixBase + ::end(int size) +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), + Traits::RowsAtCompileTime == 1 ? 0 : rows() - size, + Traits::ColsAtCompileTime == 1 ? 0 : cols() - size, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** This is the const version of end(int).*/ +template +const Block MatrixBase + ::end(int size) const +{ + assert(Traits::IsVectorAtCompileTime); + return Block(ref(), + Traits::RowsAtCompileTime == 1 ? 0 : rows() - size, + Traits::ColsAtCompileTime == 1 ? 0 : cols() - size, + Traits::RowsAtCompileTime == 1 ? 1 : size, + Traits::ColsAtCompileTime == 1 ? 1 : size); +} + +/** \returns a dynamic-size expression of a corner of *this. + * + * \param type the type of corner. Can be \a TopLeft, \a TopRight, \a BottomLeft, \a BottomRight. + * \param cRows the number of rows in the corner + * \param cCols the number of columns in the corner + * + * Example: \include MatrixBase_corner_enum_int_int.cpp + * Output: \verbinclude MatrixBase_corner_enum_int_int.out + * + * \sa class Block, block(int,int,int,int) + */ +template +Block MatrixBase + ::corner(CornerType type, int cRows, int cCols) +{ + if(type == TopLeft) return Block(ref(), 0, 0, cRows, cCols); + else if(type == TopRight) return Block(ref(), 0, cols() - cCols, cRows, cCols); + else if(type == BottomLeft) return Block(ref(), rows() - cRows, 0, cRows, cCols); + else if(type == BottomRight) + return Block(ref(), rows() - cRows, cols() - cCols, cRows, cCols); +} + +/** This is the const version of corner(CornerType, int, int).*/ +template +const Block MatrixBase + ::corner(CornerType type, int cRows, int cCols) const +{ + if(type == TopLeft) return Block(ref(), 0, 0, cRows, cCols); + else if(type == TopRight) return Block(ref(), 0, cols() - cCols, cRows, cCols); + else if(type == BottomLeft) return Block(ref(), rows() - cRows, 0, cRows, cCols); + else if(type == BottomRight) + return Block(ref(), rows() - cRows, cols() - cCols, cRows, cCols); +} #endif // EIGEN_BLOCK_H diff --git a/Eigen/src/Core/FixedBlock.h b/Eigen/src/Core/FixedBlock.h index 00d7e558a..27e966b09 100644 --- a/Eigen/src/Core/FixedBlock.h +++ b/Eigen/src/Core/FixedBlock.h @@ -46,7 +46,7 @@ * \include class_FixedBlock.cpp * Output: \verbinclude class_FixedBlock.out * - * \sa MatrixBase::fixedBlock(), class Block + * \sa MatrixBase::fixedBlock(int,int), MatrixBase::fixedBlock(int), class Block */ template class FixedBlock : public MatrixBase class FixedBlock }; const FixedBlock& _ref() const { return *this; } - int _rows() const { return BlockRows; } - int _cols() const { return BlockCols; } + static int _rows() { return BlockRows; } + static int _cols() { return BlockCols; } Scalar& _coeffRef(int row, int col) { - return m_matrix.coeffRef(row + m_startRow, col + m_startCol); + return m_matrix.coeffRef(row + m_startRow.value(), col + m_startCol.value()); } Scalar _coeff(int row, int col) const { - return m_matrix.coeff(row + m_startRow, col + m_startCol); + return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value()); } protected: MatRef m_matrix; - const int m_startRow, m_startCol; + IntAtRunTimeIfDynamic + m_startRow; + IntAtRunTimeIfDynamic + m_startCol; }; /** \returns a fixed-size expression of a block in *this. * - * The template parameters \a blockRows and \a blockCols are the number of - * rows and columns in the block + * The template parameters \a BlockRows and \a BlockCols are the number of + * rows and columns in the block. * * \param startRow the first row in the block * \param startCol the first column in the block * - * Example: \include MatrixBase_block.cpp - * Output: \verbinclude MatrixBase_block.out + * Example: \include MatrixBase_fixedBlock_int_int.cpp + * Output: \verbinclude MatrixBase_fixedBlock_int_int.out * - * \sa class FixedBlock, block() + * \sa class FixedBlock, fixedBlock(int), block(int,int,int,int) */ template template @@ -114,7 +117,7 @@ FixedBlock MatrixBase return FixedBlock(ref(), startRow, startCol); } -/** This is the const version of fixedBlock(). */ +/** This is the const version of fixedBlock(int, int). */ template template const FixedBlock MatrixBase diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index dc0292f97..193a86263 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -188,11 +188,23 @@ template class MatrixBase const Block block(int startRow, int startCol, int blockRows, int blockCols) const; + Block block(int start, int size); + const Block block(int start, int size) const; + + Block start(int size); + const Block start(int size) const; + + Block end(int size); + const Block end(int size) const; + + Block corner(CornerType type, int cRows, int cCols); + const Block corner(CornerType type, int cRows, int cCols) const; + template FixedBlock fixedBlock(int startRow, int startCol); template const FixedBlock fixedBlock(int startRow, int startCol) const; - + Transpose transpose(); const Transpose transpose() const; diff --git a/Eigen/src/Core/Util.h b/Eigen/src/Core/Util.h index 935a3dea6..8104201e6 100644 --- a/Eigen/src/Core/Util.h +++ b/Eigen/src/Core/Util.h @@ -94,6 +94,8 @@ const int Dynamic = -10; const int ColumnMajor = 0; const int RowMajor = 1; +enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; + //classes inheriting NoOperatorEquals don't generate a default operator=. class NoOperatorEquals { diff --git a/doc/snippets/MatrixBase_dynBlock.cpp b/doc/snippets/MatrixBase_block_int_int_int_int.cpp similarity index 100% rename from doc/snippets/MatrixBase_dynBlock.cpp rename to doc/snippets/MatrixBase_block_int_int_int_int.cpp diff --git a/doc/snippets/MatrixBase_block.cpp b/doc/snippets/MatrixBase_fixedBlock_int_int.cpp similarity index 100% rename from doc/snippets/MatrixBase_block.cpp rename to doc/snippets/MatrixBase_fixedBlock_int_int.cpp