mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-21 12:24:25 +08:00
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:
parent
95dc68dc86
commit
6ce996f219
@ -33,7 +33,7 @@
|
|||||||
* \param MatrixType the type of the object in which we are taking a block
|
* \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
|
* 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.
|
* is used.
|
||||||
*
|
*
|
||||||
* However, if you want to directly maniputate dynamic-size block expressions,
|
* However, if you want to directly maniputate dynamic-size block expressions,
|
||||||
@ -44,7 +44,11 @@
|
|||||||
* \include class_Block.cpp
|
* \include class_Block.cpp
|
||||||
* Output: \verbinclude class_Block.out
|
* 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
|
template<typename MatrixType> class Block
|
||||||
: public MatrixBase<typename MatrixType::Scalar, Block<MatrixType> >
|
: public MatrixBase<typename MatrixType::Scalar, Block<MatrixType> >
|
||||||
@ -75,22 +79,27 @@ template<typename MatrixType> class Block
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Block& _ref() const { return *this; }
|
const Block& _ref() const { return *this; }
|
||||||
int _rows() const { return m_blockRows; }
|
int _rows() const { return m_blockRows.value(); }
|
||||||
int _cols() const { return m_blockCols; }
|
int _cols() const { return m_blockCols.value(); }
|
||||||
|
|
||||||
Scalar& _coeffRef(int row, int col)
|
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
|
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:
|
protected:
|
||||||
MatRef m_matrix;
|
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.
|
/** \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 blockRows the number of rows in the block
|
||||||
* \param blockCols the number of columns in the block
|
* \param blockCols the number of columns in the block
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_block.cpp
|
* Example: \include MatrixBase_block_int_int_int_int.cpp
|
||||||
* Output: \verbinclude MatrixBase_block.out
|
* Output: \verbinclude MatrixBase_block_int_int_int_int.out
|
||||||
*
|
*
|
||||||
* \sa class Block, fixedBlock()
|
* \sa class Block, fixedBlock(int,int)
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, typename Derived>
|
template<typename Scalar, typename Derived>
|
||||||
Block<Derived> MatrixBase<Scalar, Derived>
|
Block<Derived> MatrixBase<Scalar, Derived>
|
||||||
@ -112,7 +121,7 @@ Block<Derived> MatrixBase<Scalar, Derived>
|
|||||||
return Block<Derived>(ref(), startRow, startCol, blockRows, blockCols);
|
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>
|
template<typename Scalar, typename Derived>
|
||||||
const Block<Derived> MatrixBase<Scalar, Derived>
|
const Block<Derived> MatrixBase<Scalar, Derived>
|
||||||
::block(int startRow, int startCol, int blockRows, int blockCols) const
|
::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);
|
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
|
#endif // EIGEN_BLOCK_H
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
* \include class_FixedBlock.cpp
|
* \include class_FixedBlock.cpp
|
||||||
* Output: \verbinclude class_FixedBlock.out
|
* 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
|
template<typename MatrixType, int BlockRows, int BlockCols> class FixedBlock
|
||||||
: public MatrixBase<typename MatrixType::Scalar,
|
: public MatrixBase<typename MatrixType::Scalar,
|
||||||
@ -75,36 +75,39 @@ template<typename MatrixType, int BlockRows, int BlockCols> class FixedBlock
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FixedBlock& _ref() const { return *this; }
|
const FixedBlock& _ref() const { return *this; }
|
||||||
int _rows() const { return BlockRows; }
|
static int _rows() { return BlockRows; }
|
||||||
int _cols() const { return BlockCols; }
|
static int _cols() { return BlockCols; }
|
||||||
|
|
||||||
Scalar& _coeffRef(int row, int col)
|
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
|
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:
|
protected:
|
||||||
MatRef m_matrix;
|
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.
|
/** \returns a fixed-size expression of a block in *this.
|
||||||
*
|
*
|
||||||
* The template parameters \a blockRows and \a blockCols are the number of
|
* The template parameters \a BlockRows and \a BlockCols are the number of
|
||||||
* rows and columns in the block
|
* rows and columns in the block.
|
||||||
*
|
*
|
||||||
* \param startRow the first row in the block
|
* \param startRow the first row in the block
|
||||||
* \param startCol the first column in the block
|
* \param startCol the first column in the block
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_block.cpp
|
* Example: \include MatrixBase_fixedBlock_int_int.cpp
|
||||||
* Output: \verbinclude MatrixBase_block.out
|
* 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<typename Scalar, typename Derived>
|
||||||
template<int BlockRows, int BlockCols>
|
template<int BlockRows, int BlockCols>
|
||||||
@ -114,7 +117,7 @@ FixedBlock<Derived, BlockRows, BlockCols> MatrixBase<Scalar, Derived>
|
|||||||
return FixedBlock<Derived, BlockRows, BlockCols>(ref(), startRow, startCol);
|
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<typename Scalar, typename Derived>
|
||||||
template<int BlockRows, int BlockCols>
|
template<int BlockRows, int BlockCols>
|
||||||
const FixedBlock<Derived, BlockRows, BlockCols> MatrixBase<Scalar, Derived>
|
const FixedBlock<Derived, BlockRows, BlockCols> MatrixBase<Scalar, Derived>
|
||||||
|
@ -188,11 +188,23 @@ template<typename Scalar, typename Derived> class MatrixBase
|
|||||||
const Block<Derived>
|
const Block<Derived>
|
||||||
block(int startRow, int startCol, int blockRows, int blockCols) const;
|
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>
|
template<int BlockRows, int BlockCols>
|
||||||
FixedBlock<Derived, BlockRows, BlockCols> fixedBlock(int startRow, int startCol);
|
FixedBlock<Derived, BlockRows, BlockCols> fixedBlock(int startRow, int startCol);
|
||||||
template<int BlockRows, int BlockCols>
|
template<int BlockRows, int BlockCols>
|
||||||
const FixedBlock<Derived, BlockRows, BlockCols> fixedBlock(int startRow, int startCol) const;
|
const FixedBlock<Derived, BlockRows, BlockCols> fixedBlock(int startRow, int startCol) const;
|
||||||
|
|
||||||
Transpose<Derived> transpose();
|
Transpose<Derived> transpose();
|
||||||
const Transpose<Derived> transpose() const;
|
const Transpose<Derived> transpose() const;
|
||||||
|
|
||||||
|
@ -94,6 +94,8 @@ const int Dynamic = -10;
|
|||||||
const int ColumnMajor = 0;
|
const int ColumnMajor = 0;
|
||||||
const int RowMajor = 1;
|
const int RowMajor = 1;
|
||||||
|
|
||||||
|
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
|
||||||
|
|
||||||
//classes inheriting NoOperatorEquals don't generate a default operator=.
|
//classes inheriting NoOperatorEquals don't generate a default operator=.
|
||||||
class NoOperatorEquals
|
class NoOperatorEquals
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user