big improvement of the block-manipulation API

- reduction of sizeof(Block) for vector types
- variants of block() and fixedBlock() for vector blocks
- convenience methods start() and end() for vectors
- convenience method corner() for matrices
This commit is contained in:
Benoit Jacob 2008-01-13 22:48:57 +00:00
parent 95dc68dc86
commit 6ce996f219
6 changed files with 186 additions and 24 deletions

View File

@ -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<typename MatrixType> class Block
: public MatrixBase<typename MatrixType::Scalar, Block<MatrixType> >
@ -75,22 +79,27 @@ template<typename MatrixType> 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<MatrixType::Traits::RowsAtCompileTime == 1 ? 0 : Dynamic>
m_startRow;
IntAtRunTimeIfDynamic<MatrixType::Traits::ColsAtCompileTime == 1 ? 0 : Dynamic>
m_startCol;
IntAtRunTimeIfDynamic<RowsAtCompileTime> m_blockRows;
IntAtRunTimeIfDynamic<ColsAtCompileTime> m_blockCols;
};
/** \returns a dynamic-size expression of a block in *this.
@ -100,10 +109,10 @@ template<typename MatrixType> 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<typename Scalar, typename Derived>
Block<Derived> MatrixBase<Scalar, Derived>
@ -112,7 +121,7 @@ Block<Derived> MatrixBase<Scalar, Derived>
return Block<Derived>(ref(), startRow, startCol, blockRows, blockCols);
}
/** This is the const version of block(). */
/** This is the const version of block(int,int,int,int). */
template<typename Scalar, typename Derived>
const Block<Derived> MatrixBase<Scalar, Derived>
::block(int startRow, int startCol, int blockRows, int blockCols) const
@ -120,5 +129,141 @@ const Block<Derived> MatrixBase<Scalar, Derived>
return Block<Derived>(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<typename Scalar, typename Derived>
Block<Derived> MatrixBase<Scalar, Derived>
::block(int start, int size)
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(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<typename Scalar, typename Derived>
const Block<Derived> MatrixBase<Scalar, Derived>
::block(int start, int size) const
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(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<typename Scalar, typename Derived>
Block<Derived> MatrixBase<Scalar, Derived>
::start(int size)
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(ref(), 0, 0,
Traits::RowsAtCompileTime == 1 ? 1 : size,
Traits::ColsAtCompileTime == 1 ? 1 : size);
}
/** This is the const version of start(int).*/
template<typename Scalar, typename Derived>
const Block<Derived> MatrixBase<Scalar, Derived>
::start(int size) const
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(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<typename Scalar, typename Derived>
Block<Derived> MatrixBase<Scalar, Derived>
::end(int size)
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(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<typename Scalar, typename Derived>
const Block<Derived> MatrixBase<Scalar, Derived>
::end(int size) const
{
assert(Traits::IsVectorAtCompileTime);
return Block<Derived>(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<typename Scalar, typename Derived>
Block<Derived> MatrixBase<Scalar, Derived>
::corner(CornerType type, int cRows, int cCols)
{
if(type == TopLeft) return Block<Derived>(ref(), 0, 0, cRows, cCols);
else if(type == TopRight) return Block<Derived>(ref(), 0, cols() - cCols, cRows, cCols);
else if(type == BottomLeft) return Block<Derived>(ref(), rows() - cRows, 0, cRows, cCols);
else if(type == BottomRight)
return Block<Derived>(ref(), rows() - cRows, cols() - cCols, cRows, cCols);
}
/** This is the const version of corner(CornerType, int, int).*/
template<typename Scalar, typename Derived>
const Block<Derived> MatrixBase<Scalar, Derived>
::corner(CornerType type, int cRows, int cCols) const
{
if(type == TopLeft) return Block<Derived>(ref(), 0, 0, cRows, cCols);
else if(type == TopRight) return Block<Derived>(ref(), 0, cols() - cCols, cRows, cCols);
else if(type == BottomLeft) return Block<Derived>(ref(), rows() - cRows, 0, cRows, cCols);
else if(type == BottomRight)
return Block<Derived>(ref(), rows() - cRows, cols() - cCols, cRows, cCols);
}
#endif // EIGEN_BLOCK_H

View File

@ -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<typename MatrixType, int BlockRows, int BlockCols> class FixedBlock
: public MatrixBase<typename MatrixType::Scalar,
@ -75,36 +75,39 @@ template<typename MatrixType, int BlockRows, int BlockCols> 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<MatrixType::Traits::RowsAtCompileTime == 1 ? 0 : Dynamic>
m_startRow;
IntAtRunTimeIfDynamic<MatrixType::Traits::ColsAtCompileTime == 1 ? 0 : Dynamic>
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<typename Scalar, typename Derived>
template<int BlockRows, int BlockCols>
@ -114,7 +117,7 @@ FixedBlock<Derived, BlockRows, BlockCols> MatrixBase<Scalar, Derived>
return FixedBlock<Derived, BlockRows, BlockCols>(ref(), startRow, startCol);
}
/** This is the const version of fixedBlock(). */
/** This is the const version of fixedBlock(int, int). */
template<typename Scalar, typename Derived>
template<int BlockRows, int BlockCols>
const FixedBlock<Derived, BlockRows, BlockCols> MatrixBase<Scalar, Derived>

View File

@ -188,6 +188,18 @@ template<typename Scalar, typename Derived> class MatrixBase
const Block<Derived>
block(int startRow, int startCol, int blockRows, int blockCols) const;
Block<Derived> block(int start, int size);
const Block<Derived> block(int start, int size) const;
Block<Derived> start(int size);
const Block<Derived> start(int size) const;
Block<Derived> end(int size);
const Block<Derived> end(int size) const;
Block<Derived> corner(CornerType type, int cRows, int cCols);
const Block<Derived> corner(CornerType type, int cRows, int cCols) const;
template<int BlockRows, int BlockCols>
FixedBlock<Derived, BlockRows, BlockCols> fixedBlock(int startRow, int startCol);
template<int BlockRows, int BlockCols>

View File

@ -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
{