mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-31 01:03:38 +08:00
* 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
This commit is contained in:
parent
28dde19e40
commit
9962c59b56
@ -328,128 +328,456 @@ class Block<XprType,BlockRows,BlockCols,HasDirectAccess>
|
||||
* \sa class Block, block(int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename BlockReturnType<Derived>::Type DenseBase<Derived>
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::block(int startRow, int startCol, int blockRows, int blockCols)
|
||||
{
|
||||
return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
|
||||
return Block<Derived>(derived(), startRow, startCol, blockRows, blockCols);
|
||||
}
|
||||
|
||||
/** This is the const version of block(int,int,int,int). */
|
||||
template<typename Derived>
|
||||
inline const typename BlockReturnType<Derived>::Type DenseBase<Derived>
|
||||
inline const Block<Derived> DenseBase<Derived>
|
||||
::block(int startRow, int startCol, int blockRows, int blockCols) const
|
||||
{
|
||||
return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
|
||||
return Block<Derived>(derived(), startRow, startCol, blockRows, blockCols);
|
||||
}
|
||||
|
||||
/** \returns a dynamic-size expression of a corner of *this.
|
||||
|
||||
|
||||
|
||||
/** \returns a dynamic-size expression of a top-right corner of *this.
|
||||
*
|
||||
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
|
||||
* \a Eigen::BottomLeft, \a Eigen::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
|
||||
*
|
||||
* \note Even though the returned expression has dynamic size, in the case
|
||||
* when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
|
||||
* which means that evaluating it does not cause a dynamic memory allocation.
|
||||
* Example: \include MatrixBase_topRightCorner_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_topRightCorner_int_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename BlockReturnType<Derived>::Type DenseBase<Derived>
|
||||
::corner(CornerType type, int cRows, int cCols)
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::topRightCorner(int cRows, int cCols)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
|
||||
case TopRight:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
case BottomLeft:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
case BottomRight:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
return Block<Derived>(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
|
||||
/** This is the const version of corner(CornerType, int, int).*/
|
||||
/** This is the const version of topRightCorner(int, int).*/
|
||||
template<typename Derived>
|
||||
inline const typename BlockReturnType<Derived>::Type
|
||||
DenseBase<Derived>::corner(CornerType type, int cRows, int cCols) const
|
||||
inline const Block<Derived>
|
||||
DenseBase<Derived>::topRightCorner(int cRows, int cCols) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
|
||||
case TopRight:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
case BottomLeft:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
case BottomRight:
|
||||
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
return Block<Derived>(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
|
||||
/** \returns a fixed-size expression of a corner of *this.
|
||||
/** \returns an expression of a fixed-size top-right corner of *this.
|
||||
*
|
||||
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
|
||||
* \a Eigen::BottomLeft, \a Eigen::BottomRight.
|
||||
* The template parameters CRows and CCols are the number of rows and columns in the corner.
|
||||
*
|
||||
* The template parameters CRows and CCols arethe number of rows and columns in the corner.
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_int_corner_enum.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_corner_enum.out
|
||||
* Example: \include MatrixBase_template_int_int_topRightCorner.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_topRightCorner.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline typename BlockReturnType<Derived, CRows, CCols>::Type
|
||||
DenseBase<Derived>::corner(CornerType type)
|
||||
inline Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::topRightCorner()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
case TopRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
case BottomRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
}
|
||||
|
||||
/** This is the const version of corner<int, int>(CornerType).*/
|
||||
/** This is the const version of topRightCorner<int, int>().*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline const typename BlockReturnType<Derived, CRows, CCols>::Type
|
||||
DenseBase<Derived>::corner(CornerType type) const
|
||||
inline const Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::topRightCorner() const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
case TopRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
case BottomRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a dynamic-size expression of a top-left corner of *this.
|
||||
*
|
||||
* \param cRows the number of rows in the corner
|
||||
* \param cCols the number of columns in the corner
|
||||
*
|
||||
* Example: \include MatrixBase_topLeftCorner_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_topLeftCorner_int_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::topLeftCorner(int cRows, int cCols)
|
||||
{
|
||||
return Block<Derived>(derived(), 0, 0, cRows, cCols);
|
||||
}
|
||||
|
||||
/** This is the const version of topLeftCorner(int, int).*/
|
||||
template<typename Derived>
|
||||
inline const Block<Derived>
|
||||
DenseBase<Derived>::topLeftCorner(int cRows, int cCols) const
|
||||
{
|
||||
return Block<Derived>(derived(), 0, 0, cRows, cCols);
|
||||
}
|
||||
|
||||
/** \returns an expression of a fixed-size top-left corner of *this.
|
||||
*
|
||||
* The template parameters CRows and CCols are the number of rows and columns in the corner.
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_int_topLeftCorner.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_topLeftCorner.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::topLeftCorner()
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
}
|
||||
|
||||
/** This is the const version of topLeftCorner<int, int>().*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline const Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::topLeftCorner() const
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a dynamic-size expression of a bottom-right corner of *this.
|
||||
*
|
||||
* \param cRows the number of rows in the corner
|
||||
* \param cCols the number of columns in the corner
|
||||
*
|
||||
* Example: \include MatrixBase_bottomRightCorner_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_bottomRightCorner_int_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::bottomRightCorner(int cRows, int cCols)
|
||||
{
|
||||
return Block<Derived>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
|
||||
/** This is the const version of bottomRightCorner(int, int).*/
|
||||
template<typename Derived>
|
||||
inline const Block<Derived>
|
||||
DenseBase<Derived>::bottomRightCorner(int cRows, int cCols) const
|
||||
{
|
||||
return Block<Derived>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
|
||||
/** \returns an expression of a fixed-size bottom-right corner of *this.
|
||||
*
|
||||
* The template parameters CRows and CCols are the number of rows and columns in the corner.
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_int_bottomRightCorner.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::bottomRightCorner()
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
|
||||
/** This is the const version of bottomRightCorner<int, int>().*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline const Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::bottomRightCorner() const
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a dynamic-size expression of a bottom-left corner of *this.
|
||||
*
|
||||
* \param cRows the number of rows in the corner
|
||||
* \param cCols the number of columns in the corner
|
||||
*
|
||||
* Example: \include MatrixBase_bottomLeftCorner_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_bottomLeftCorner_int_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::bottomLeftCorner(int cRows, int cCols)
|
||||
{
|
||||
return Block<Derived>(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
}
|
||||
|
||||
/** This is the const version of bottomLeftCorner(int, int).*/
|
||||
template<typename Derived>
|
||||
inline const Block<Derived>
|
||||
DenseBase<Derived>::bottomLeftCorner(int cRows, int cCols) const
|
||||
{
|
||||
return Block<Derived>(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
}
|
||||
|
||||
/** \returns an expression of a fixed-size bottom-left corner of *this.
|
||||
*
|
||||
* The template parameters CRows and CCols are the number of rows and columns in the corner.
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_int_bottomLeftCorner.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::bottomLeftCorner()
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
}
|
||||
|
||||
/** This is the const version of bottomLeftCorner<int, int>().*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline const Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::bottomLeftCorner() const
|
||||
{
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** \returns a block consisting of the top rows of *this.
|
||||
*
|
||||
* \param n the number of rows in the block
|
||||
*
|
||||
* Example: \include MatrixBase_topRows_int.cpp
|
||||
* Output: \verbinclude MatrixBase_topRows_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename DenseBase<Derived>::RowsBlockXpr DenseBase<Derived>
|
||||
::topRows(int n)
|
||||
{
|
||||
return RowsBlockXpr(derived(), 0, 0, n, cols());
|
||||
}
|
||||
|
||||
/** This is the const version of topRows(int).*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::RowsBlockXpr
|
||||
DenseBase<Derived>::topRows(int n) const
|
||||
{
|
||||
return RowsBlockXpr(derived(), 0, 0, n, cols());
|
||||
}
|
||||
|
||||
/** \returns a block consisting of the top rows of *this.
|
||||
*
|
||||
* \param N the number of rows in the block
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_topRows.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_topRows.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::topRows()
|
||||
{
|
||||
return typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type(derived(), 0, 0, N, cols());
|
||||
}
|
||||
|
||||
/** This is the const version of topRows<int>().*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline const typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::topRows() const
|
||||
{
|
||||
return typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type(derived(), 0, 0, N, cols());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a block consisting of the bottom rows of *this.
|
||||
*
|
||||
* \param n the number of rows in the block
|
||||
*
|
||||
* Example: \include MatrixBase_bottomRows_int.cpp
|
||||
* Output: \verbinclude MatrixBase_bottomRows_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename DenseBase<Derived>::RowsBlockXpr DenseBase<Derived>
|
||||
::bottomRows(int n)
|
||||
{
|
||||
return RowsBlockXpr(derived(), rows() - n, 0, n, cols());
|
||||
}
|
||||
|
||||
/** This is the const version of bottomRows(int).*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::RowsBlockXpr
|
||||
DenseBase<Derived>::bottomRows(int n) const
|
||||
{
|
||||
return RowsBlockXpr(derived(), rows() - n, 0, n, cols());
|
||||
}
|
||||
|
||||
/** \returns a block consisting of the bottom rows of *this.
|
||||
*
|
||||
* \param N the number of rows in the block
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_bottomRows.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_bottomRows.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::bottomRows()
|
||||
{
|
||||
return typename NRowsBlockXpr<N>::Type(derived(), rows() - N, 0, N, cols());
|
||||
}
|
||||
|
||||
/** This is the const version of bottomRows<int>().*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline const typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::bottomRows() const
|
||||
{
|
||||
return typename NRowsBlockXpr<N>::Type(derived(), rows() - N, 0, N, cols());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a block consisting of the top columns of *this.
|
||||
*
|
||||
* \param n the number of columns in the block
|
||||
*
|
||||
* Example: \include MatrixBase_leftCols_int.cpp
|
||||
* Output: \verbinclude MatrixBase_leftCols_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename DenseBase<Derived>::ColsBlockXpr DenseBase<Derived>
|
||||
::leftCols(int n)
|
||||
{
|
||||
return ColsBlockXpr(derived(), 0, 0, rows(), n);
|
||||
}
|
||||
|
||||
/** This is the const version of leftCols(int).*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::ColsBlockXpr
|
||||
DenseBase<Derived>::leftCols(int n) const
|
||||
{
|
||||
return ColsBlockXpr(derived(), 0, 0, rows(), n);
|
||||
}
|
||||
|
||||
/** \returns a block consisting of the top columns of *this.
|
||||
*
|
||||
* \param N the number of columns in the block
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_leftCols.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_leftCols.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::leftCols()
|
||||
{
|
||||
return typename NColsBlockXpr<N>::Type(derived(), 0, 0, rows(), N);
|
||||
}
|
||||
|
||||
/** This is the const version of leftCols<int>().*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline const typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::leftCols() const
|
||||
{
|
||||
return typename NColsBlockXpr<N>::Type(derived(), 0, 0, rows(), N);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a block consisting of the top columns of *this.
|
||||
*
|
||||
* \param n the number of columns in the block
|
||||
*
|
||||
* Example: \include MatrixBase_rightCols_int.cpp
|
||||
* Output: \verbinclude MatrixBase_rightCols_int.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename DenseBase<Derived>::ColsBlockXpr DenseBase<Derived>
|
||||
::rightCols(int n)
|
||||
{
|
||||
return ColsBlockXpr(derived(), 0, cols() - n, rows(), n);
|
||||
}
|
||||
|
||||
/** This is the const version of rightCols(int).*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::ColsBlockXpr
|
||||
DenseBase<Derived>::rightCols(int n) const
|
||||
{
|
||||
return ColsBlockXpr(derived(), 0, cols() - n, rows(), n);
|
||||
}
|
||||
|
||||
/** \returns a block consisting of the top columns of *this.
|
||||
*
|
||||
* \param N the number of columns in the block
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_rightCols.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_rightCols.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::rightCols()
|
||||
{
|
||||
return typename DenseBase<Derived>::template NColsBlockXpr<N>::Type(derived(), 0, cols() - N, rows(), N);
|
||||
}
|
||||
|
||||
/** This is the const version of rightCols<int>().*/
|
||||
template<typename Derived>
|
||||
template<int N>
|
||||
inline const typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
|
||||
DenseBase<Derived>::rightCols() const
|
||||
{
|
||||
return typename DenseBase<Derived>::template NColsBlockXpr<N>::Type(derived(), 0, cols() - N, rows(), N);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** \returns a fixed-size expression of a block in *this.
|
||||
*
|
||||
* The template parameters \a BlockRows and \a BlockCols are the number of
|
||||
@ -468,7 +796,7 @@ DenseBase<Derived>::corner(CornerType type) const
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int BlockRows, int BlockCols>
|
||||
inline typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
|
||||
inline Block<Derived, BlockRows, BlockCols>
|
||||
DenseBase<Derived>::block(int startRow, int startCol)
|
||||
{
|
||||
return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
|
||||
@ -477,7 +805,7 @@ DenseBase<Derived>::block(int startRow, int startCol)
|
||||
/** This is the const version of block<>(int, int). */
|
||||
template<typename Derived>
|
||||
template<int BlockRows, int BlockCols>
|
||||
inline const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
|
||||
inline const Block<Derived, BlockRows, BlockCols>
|
||||
DenseBase<Derived>::block(int startRow, int startCol) const
|
||||
{
|
||||
return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
|
||||
@ -525,4 +853,116 @@ DenseBase<Derived>::row(int i) const
|
||||
return RowXpr(derived(), i);
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
|
||||
/** \returns a dynamic-size expression of a corner of *this.
|
||||
*
|
||||
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
|
||||
* \a Eigen::BottomLeft, \a Eigen::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
|
||||
*
|
||||
* \note Even though the returned expression has dynamic size, in the case
|
||||
* when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
|
||||
* which means that evaluating it does not cause a dynamic memory allocation.
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline Block<Derived> DenseBase<Derived>
|
||||
::corner(CornerType type, int cRows, int cCols)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived>(derived(), 0, 0, cRows, cCols);
|
||||
case TopRight:
|
||||
return Block<Derived>(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived>(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
case BottomRight:
|
||||
return Block<Derived>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
}
|
||||
|
||||
/** This is the const version of corner(CornerType, int, int).*/
|
||||
template<typename Derived>
|
||||
inline const Block<Derived>
|
||||
DenseBase<Derived>::corner(CornerType type, int cRows, int cCols) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived>(derived(), 0, 0, cRows, cCols);
|
||||
case TopRight:
|
||||
return Block<Derived>(derived(), 0, cols() - cCols, cRows, cCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived>(derived(), rows() - cRows, 0, cRows, cCols);
|
||||
case BottomRight:
|
||||
return Block<Derived>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
|
||||
}
|
||||
}
|
||||
|
||||
/** \returns a fixed-size expression of a corner of *this.
|
||||
*
|
||||
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
|
||||
* \a Eigen::BottomLeft, \a Eigen::BottomRight.
|
||||
*
|
||||
* The template parameters CRows and CCols arethe number of rows and columns in the corner.
|
||||
*
|
||||
* Example: \include MatrixBase_template_int_int_corner_enum.cpp
|
||||
* Output: \verbinclude MatrixBase_template_int_int_corner_enum.out
|
||||
*
|
||||
* \sa class Block, block(int,int,int,int)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::corner(CornerType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
case TopRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
case BottomRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
}
|
||||
|
||||
/** This is the const version of corner<int, int>(CornerType).*/
|
||||
template<typename Derived>
|
||||
template<int CRows, int CCols>
|
||||
inline const Block<Derived, CRows, CCols>
|
||||
DenseBase<Derived>::corner(CornerType type) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
ei_assert(false && "Bad corner type.");
|
||||
case TopLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, 0);
|
||||
case TopRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
|
||||
case BottomLeft:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
|
||||
case BottomRight:
|
||||
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EIGEN2_SUPPORT
|
||||
|
||||
#endif // EIGEN_BLOCK_H
|
||||
|
@ -220,8 +220,18 @@ template<typename Derived> class DenseBase
|
||||
typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||
/** \internal expression type of a column */
|
||||
typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
|
||||
/** \internal expression type of a column */
|
||||
/** \internal expression type of a row */
|
||||
typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
|
||||
/** \internal expression type of a block of whole columns */
|
||||
typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, Dynamic> ColsBlockXpr;
|
||||
/** \internal expression type of a block of whole rows */
|
||||
typedef Block<Derived, Dynamic, ei_traits<Derived>::ColsAtCompileTime> RowsBlockXpr;
|
||||
/** \internal expression type of a block of whole columns */
|
||||
template<int N> struct NColsBlockXpr { typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, N> Type; };
|
||||
/** \internal expression type of a block of whole rows */
|
||||
template<int N> struct NRowsBlockXpr { typedef Block<Derived, N, ei_traits<Derived>::ColsAtCompileTime> Type; };
|
||||
|
||||
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
const CoeffReturnType x() const;
|
||||
@ -334,9 +344,8 @@ template<typename Derived> class DenseBase
|
||||
ColXpr col(int i);
|
||||
const ColXpr col(int i) const;
|
||||
|
||||
typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
|
||||
const typename BlockReturnType<Derived>::Type
|
||||
block(int startRow, int startCol, int blockRows, int blockCols) const;
|
||||
Block<Derived> block(int startRow, int startCol, int blockRows, int blockCols);
|
||||
const Block<Derived> block(int startRow, int startCol, int blockRows, int blockCols) const;
|
||||
|
||||
VectorBlock<Derived> segment(int start, int size);
|
||||
const VectorBlock<Derived> segment(int start, int size) const;
|
||||
@ -347,18 +356,46 @@ template<typename Derived> class DenseBase
|
||||
VectorBlock<Derived> tail(int size);
|
||||
const VectorBlock<Derived> tail(int size) const;
|
||||
|
||||
typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
|
||||
const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
|
||||
Block<Derived> topLeftCorner(int cRows, int cCols);
|
||||
const Block<Derived> topLeftCorner(int cRows, int cCols) const;
|
||||
Block<Derived> topRightCorner(int cRows, int cCols);
|
||||
const Block<Derived> topRightCorner(int cRows, int cCols) const;
|
||||
Block<Derived> bottomLeftCorner(int cRows, int cCols);
|
||||
const Block<Derived> bottomLeftCorner(int cRows, int cCols) const;
|
||||
Block<Derived> bottomRightCorner(int cRows, int cCols);
|
||||
const Block<Derived> bottomRightCorner(int cRows, int cCols) const;
|
||||
|
||||
RowsBlockXpr topRows(int n);
|
||||
const RowsBlockXpr topRows(int n) const;
|
||||
RowsBlockXpr bottomRows(int n);
|
||||
const RowsBlockXpr bottomRows(int n) const;
|
||||
ColsBlockXpr leftCols(int n);
|
||||
const ColsBlockXpr leftCols(int n) const;
|
||||
ColsBlockXpr rightCols(int n);
|
||||
const ColsBlockXpr rightCols(int n) const;
|
||||
|
||||
template<int CRows, int CCols> Block<Derived, CRows, CCols> topLeftCorner();
|
||||
template<int CRows, int CCols> const Block<Derived, CRows, CCols> topLeftCorner() const;
|
||||
template<int CRows, int CCols> Block<Derived, CRows, CCols> topRightCorner();
|
||||
template<int CRows, int CCols> const Block<Derived, CRows, CCols> topRightCorner() const;
|
||||
template<int CRows, int CCols> Block<Derived, CRows, CCols> bottomLeftCorner();
|
||||
template<int CRows, int CCols> const Block<Derived, CRows, CCols> bottomLeftCorner() const;
|
||||
template<int CRows, int CCols> Block<Derived, CRows, CCols> bottomRightCorner();
|
||||
template<int CRows, int CCols> const Block<Derived, CRows, CCols> bottomRightCorner() const;
|
||||
|
||||
template<int NRows> typename NRowsBlockXpr<NRows>::Type topRows();
|
||||
template<int NRows> const typename NRowsBlockXpr<NRows>::Type topRows() const;
|
||||
template<int NRows> typename NRowsBlockXpr<NRows>::Type bottomRows();
|
||||
template<int NRows> const typename NRowsBlockXpr<NRows>::Type bottomRows() const;
|
||||
template<int NCols> typename NColsBlockXpr<NCols>::Type leftCols();
|
||||
template<int NCols> const typename NColsBlockXpr<NCols>::Type leftCols() const;
|
||||
template<int NCols> typename NColsBlockXpr<NCols>::Type rightCols();
|
||||
template<int NCols> const typename NColsBlockXpr<NCols>::Type rightCols() const;
|
||||
|
||||
template<int BlockRows, int BlockCols>
|
||||
typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
|
||||
Block<Derived, BlockRows, BlockCols> block(int startRow, int startCol);
|
||||
template<int BlockRows, int BlockCols>
|
||||
const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
|
||||
|
||||
template<int CRows, int CCols>
|
||||
typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
|
||||
template<int CRows, int CCols>
|
||||
const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
|
||||
const Block<Derived, BlockRows, BlockCols> block(int startRow, int startCol) const;
|
||||
|
||||
template<int Size> VectorBlock<Derived,Size> head(void);
|
||||
template<int Size> const VectorBlock<Derived,Size> head() const;
|
||||
@ -523,6 +560,17 @@ template<typename Derived> class DenseBase
|
||||
const Eigen::Reverse<Derived, BothDirections> reverse() const;
|
||||
void reverseInPlace();
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
|
||||
Block<Derived> corner(CornerType type, int cRows, int cCols);
|
||||
const Block<Derived> corner(CornerType type, int cRows, int cCols) const;
|
||||
template<int CRows, int CCols>
|
||||
Block<Derived, CRows, CCols> corner(CornerType type);
|
||||
template<int CRows, int CCols>
|
||||
const Block<Derived, CRows, CCols> corner(CornerType type) const;
|
||||
|
||||
#endif // EIGEN2_SUPPORT
|
||||
|
||||
#ifdef EIGEN_DENSEBASE_PLUGIN
|
||||
#include EIGEN_DENSEBASE_PLUGIN
|
||||
#endif
|
||||
|
@ -566,9 +566,9 @@ struct ei_conservative_resize_like_impl
|
||||
const int new_cols = other.cols() - _this.cols();
|
||||
_this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
|
||||
if (new_rows>0)
|
||||
_this.corner(BottomRight, new_rows, other.cols()) = other.corner(BottomRight, new_rows, other.cols());
|
||||
_this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
|
||||
else if (new_cols>0)
|
||||
_this.corner(BottomRight, other.rows(), new_cols) = other.corner(BottomRight, other.rows(), new_cols);
|
||||
_this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,7 +165,11 @@ enum {
|
||||
|
||||
enum { Unaligned=0, Aligned=1 };
|
||||
enum { ConditionalJumpCost = 5 };
|
||||
|
||||
// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox
|
||||
// TODO: find out what to do with that. Adapt the AlignedBox API ?
|
||||
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
|
||||
|
||||
enum DirectionType { Vertical, Horizontal, BothDirections };
|
||||
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
|
||||
|
||||
|
@ -329,13 +329,6 @@ struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public Eige
|
||||
{ return static_cast<const ei_special_scalar_op_base&>(matrix).operator*(scalar); }
|
||||
};
|
||||
|
||||
/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size
|
||||
* TODO: could be a good idea to define a big ReturnType struct ??
|
||||
*/
|
||||
template<typename ExpressionType, int RowsOrSize=Dynamic, int Cols=Dynamic> struct BlockReturnType {
|
||||
typedef Block<ExpressionType, RowsOrSize, Cols> Type;
|
||||
};
|
||||
|
||||
template<typename ExpressionType> struct HNormalizedReturnType {
|
||||
|
||||
enum {
|
||||
|
@ -272,11 +272,11 @@ void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVector
|
||||
// i.e., compute A = H A H'
|
||||
|
||||
// A = H A
|
||||
matA.corner(BottomRight, remainingSize, remainingSize)
|
||||
matA.bottomRightCorner(remainingSize, remainingSize)
|
||||
.applyHouseholderOnTheLeft(matA.col(i).tail(remainingSize-1), h, &temp.coeffRef(0));
|
||||
|
||||
// A = A H'
|
||||
matA.corner(BottomRight, n, remainingSize)
|
||||
matA.rightCols(remainingSize)
|
||||
.applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), ei_conj(h), &temp.coeffRef(0));
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,7 @@ HessenbergDecomposition<MatrixType>::matrixQ() const
|
||||
VectorType temp(n);
|
||||
for (int i = n-2; i>=0; i--)
|
||||
{
|
||||
matQ.corner(BottomRight,n-i-1,n-i-1)
|
||||
matQ.bottomRightCorner(n-i-1,n-i-1)
|
||||
.applyHouseholderOnTheLeft(m_matrix.col(i).tail(n-i-2), ei_conj(m_hCoeffs.coeff(i)), &temp.coeffRef(0,0));
|
||||
}
|
||||
return matQ;
|
||||
@ -307,7 +307,7 @@ HessenbergDecomposition<MatrixType>::matrixH() const
|
||||
int n = m_matrix.rows();
|
||||
MatrixType matH = m_matrix;
|
||||
if (n>2)
|
||||
matH.corner(BottomLeft,n-2, n-2).template triangularView<Lower>().setZero();
|
||||
matH.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
|
||||
return matH;
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
|
||||
const int size = m_matU.cols();
|
||||
// FIXME to be efficient the following would requires a triangular reduxion code
|
||||
// Scalar norm = m_matT.upper().cwiseAbs().sum()
|
||||
// + m_matT.corner(BottomLeft,size-1,size-1).diagonal().cwiseAbs().sum();
|
||||
// + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
|
||||
Scalar norm = 0.0;
|
||||
for (int j = 0; j < size; ++j)
|
||||
norm += m_matT.row(j).segment(std::max(j-1,0), size-std::max(j-1,0)).cwiseAbs().sum();
|
||||
|
@ -171,11 +171,11 @@ Tridiagonalization<MatrixType>::matrixT(void) const
|
||||
// and fill it ? (to avoid temporaries)
|
||||
int n = m_matrix.rows();
|
||||
MatrixType matT = m_matrix;
|
||||
matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().template cast<Scalar>().conjugate();
|
||||
matT.topRightCorner(n-1, n-1).diagonal() = subDiagonal().template cast<Scalar>().conjugate();
|
||||
if (n>2)
|
||||
{
|
||||
matT.corner(TopRight,n-2, n-2).template triangularView<Upper>().setZero();
|
||||
matT.corner(BottomLeft,n-2, n-2).template triangularView<Lower>().setZero();
|
||||
matT.topRightCorner(n-2, n-2).template triangularView<Upper>().setZero();
|
||||
matT.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
|
||||
}
|
||||
return matT;
|
||||
}
|
||||
@ -210,12 +210,12 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
|
||||
// i.e., A = H A H' where H = I - h v v' and v = matA.col(i).tail(n-i-1)
|
||||
matA.col(i).coeffRef(i+1) = 1;
|
||||
|
||||
hCoeffs.tail(n-i-1).noalias() = (matA.corner(BottomRight,remainingSize,remainingSize).template selfadjointView<Lower>()
|
||||
hCoeffs.tail(n-i-1).noalias() = (matA.bottomRightCorner(remainingSize,remainingSize).template selfadjointView<Lower>()
|
||||
* (ei_conj(h) * matA.col(i).tail(remainingSize)));
|
||||
|
||||
hCoeffs.tail(n-i-1) += (ei_conj(h)*Scalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1);
|
||||
|
||||
matA.corner(BottomRight, remainingSize, remainingSize).template selfadjointView<Lower>()
|
||||
matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>()
|
||||
.rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), -1);
|
||||
|
||||
matA.col(i).coeffRef(i+1) = beta;
|
||||
@ -243,7 +243,7 @@ void Tridiagonalization<MatrixType>::matrixQInPlace(MatrixBase<QDerived>* q) con
|
||||
RowVectorType aux(n);
|
||||
for (int i = n-2; i>=0; i--)
|
||||
{
|
||||
matQ.corner(BottomRight,n-i-1,n-i-1)
|
||||
matQ.bottomRightCorner(n-i-1,n-i-1)
|
||||
.applyHouseholderOnTheLeft(m_matrix.col(i).tail(n-i-2), ei_conj(m_hCoeffs.coeff(i)), &aux.coeffRef(0,0));
|
||||
}
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other)
|
||||
template<typename Scalar, int Dim, int Mode>
|
||||
inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(Scalar s)
|
||||
{
|
||||
m_matrix.template corner<Dim,HDim>(TopLeft) *= s;
|
||||
m_matrix.template topRows<Dim>() *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -940,18 +940,19 @@ Transform<Scalar,Dim,Mode>::inverse(TransformTraits hint) const
|
||||
{
|
||||
if (hint == Isometry)
|
||||
{
|
||||
res.matrix().template corner<Dim,Dim>(TopLeft) = linear().transpose();
|
||||
res.matrix().template topLeftCorner<Dim,Dim>() = linear().transpose();
|
||||
}
|
||||
else if(hint&Affine)
|
||||
{
|
||||
res.matrix().template corner<Dim,Dim>(TopLeft) = linear().inverse();
|
||||
res.matrix().template topLeftCorner<Dim,Dim>() = linear().inverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
ei_assert(false && "Invalid transform traits in Transform::Inverse");
|
||||
}
|
||||
// translation and remaining parts
|
||||
res.matrix().template corner<Dim,1>(TopRight) = - res.matrix().template corner<Dim,Dim>(TopLeft) * translation();
|
||||
res.matrix().template topRightCorner<Dim,1>()
|
||||
= - res.matrix().template topLeftCorner<Dim,Dim>() * translation();
|
||||
if(int(Mode)!=int(AffineCompact))
|
||||
{
|
||||
res.matrix().template block<1,Dim>(Dim,0).setZero();
|
||||
@ -1247,8 +1248,8 @@ struct ei_transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim>
|
||||
TransformType res;
|
||||
if(Mode!=AffineCompact)
|
||||
res.matrix().row(Dim) = tr.matrix().row(Dim);
|
||||
res.matrix().template corner<Dim,HDim>(TopLeft).noalias()
|
||||
= other * tr.matrix().template corner<Dim,HDim>(TopLeft);
|
||||
res.matrix().template topRows<Dim>().noalias()
|
||||
= other * tr.matrix().template topRows<Dim>();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ umeyama(const MatrixBase<Derived>& src, const MatrixBase<OtherDerived>& dst, boo
|
||||
// Note that we first assign dst_mean to the destination so that there no need
|
||||
// for a temporary.
|
||||
Rt.col(m).head(m) = dst_mean;
|
||||
Rt.col(m).head(m).noalias() -= c*Rt.corner(TopLeft,m,m)*src_mean;
|
||||
Rt.col(m).head(m).noalias() -= c*Rt.topLeftCorner(m,m)*src_mean;
|
||||
|
||||
if (with_scaling) Rt.block(0,0,m,m) *= c;
|
||||
|
||||
|
@ -161,10 +161,10 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
{
|
||||
int cornerSize = rows() - k - m_shift;
|
||||
if(m_trans)
|
||||
dst.corner(BottomRight, cornerSize, cornerSize)
|
||||
dst.bottomRightCorner(cornerSize, cornerSize)
|
||||
.applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
|
||||
else
|
||||
dst.corner(BottomRight, cornerSize, cornerSize)
|
||||
dst.bottomRightCorner(cornerSize, cornerSize)
|
||||
.applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0));
|
||||
}
|
||||
}
|
||||
@ -176,7 +176,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
for(int k = 0; k < m_actualVectors; ++k)
|
||||
{
|
||||
int actual_k = m_trans ? m_actualVectors-k-1 : k;
|
||||
dst.corner(BottomRight, dst.rows(), rows()-m_shift-actual_k)
|
||||
dst.rightCols(rows()-m_shift-actual_k)
|
||||
.applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0));
|
||||
}
|
||||
}
|
||||
@ -188,7 +188,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
for(int k = 0; k < m_actualVectors; ++k)
|
||||
{
|
||||
int actual_k = m_trans ? k : m_actualVectors-k-1;
|
||||
dst.corner(BottomRight, rows()-m_shift-actual_k, dst.cols())
|
||||
dst.bottomRows(rows()-m_shift-actual_k)
|
||||
.applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0));
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
// biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
|
||||
int row_of_biggest_in_corner, col_of_biggest_in_corner;
|
||||
RealScalar biggest_in_corner;
|
||||
biggest_in_corner = m_lu.corner(Eigen::BottomRight, rows-k, cols-k)
|
||||
biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
|
||||
.cwiseAbs()
|
||||
.maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
|
||||
row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
|
||||
@ -535,9 +535,9 @@ MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
|
||||
// LU
|
||||
MatrixType res(m_lu.rows(),m_lu.cols());
|
||||
// FIXME the .toDenseMatrix() should not be needed...
|
||||
res = m_lu.corner(TopLeft,m_lu.rows(),smalldim)
|
||||
res = m_lu.leftCols(smalldim)
|
||||
.template triangularView<UnitLower>().toDenseMatrix()
|
||||
* m_lu.corner(TopLeft,smalldim,m_lu.cols())
|
||||
* m_lu.topRows(smalldim)
|
||||
.template triangularView<Upper>().toDenseMatrix();
|
||||
|
||||
// P^{-1}(LU)
|
||||
@ -618,9 +618,9 @@ struct ei_kernel_retval<FullPivLU<_MatrixType> >
|
||||
// ok, we have our trapezoid matrix, we can apply the triangular solver.
|
||||
// notice that the math behind this suggests that we should apply this to the
|
||||
// negative of the RHS, but for performance we just put the negative sign elsewhere, see below.
|
||||
m.corner(TopLeft, rank(), rank())
|
||||
m.topLeftCorner(rank(), rank())
|
||||
.template triangularView<Upper>().solveInPlace(
|
||||
m.corner(TopRight, rank(), dimker)
|
||||
m.topRightCorner(rank(), dimker)
|
||||
);
|
||||
|
||||
// now we must undo the column permutation that we had applied!
|
||||
@ -707,21 +707,21 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
|
||||
|
||||
// Step 2
|
||||
dec().matrixLU()
|
||||
.corner(Eigen::TopLeft,smalldim,smalldim)
|
||||
.topLeftCorner(smalldim,smalldim)
|
||||
.template triangularView<UnitLower>()
|
||||
.solveInPlace(c.corner(Eigen::TopLeft, smalldim, c.cols()));
|
||||
.solveInPlace(c.topRows(smalldim));
|
||||
if(rows>cols)
|
||||
{
|
||||
c.corner(Eigen::BottomLeft, rows-cols, c.cols())
|
||||
-= dec().matrixLU().corner(Eigen::BottomLeft, rows-cols, cols)
|
||||
* c.corner(Eigen::TopLeft, cols, c.cols());
|
||||
c.bottomRows(rows-cols)
|
||||
-= dec().matrixLU().bottomRows(rows-cols)
|
||||
* c.topRows(cols);
|
||||
}
|
||||
|
||||
// Step 3
|
||||
dec().matrixLU()
|
||||
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
|
||||
.topLeftCorner(nonzero_pivots, nonzero_pivots)
|
||||
.template triangularView<Upper>()
|
||||
.solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
|
||||
.solveInPlace(c.topRows(nonzero_pivots));
|
||||
|
||||
// Step 4
|
||||
for(int i = 0; i < nonzero_pivots; ++i)
|
||||
|
@ -283,7 +283,7 @@ struct ei_partial_lu_impl
|
||||
int rrows = rows-k-1;
|
||||
int rsize = size-k-1;
|
||||
lu.col(k).tail(rrows) /= lu.coeff(k,k);
|
||||
lu.corner(BottomRight,rrows,rsize).noalias() -= lu.col(k).tail(rrows) * lu.row(k).tail(rsize);
|
||||
lu.bottomRightCorner(rrows,rsize).noalias() -= lu.col(k).tail(rrows) * lu.row(k).tail(rsize);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -411,7 +411,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
||||
{
|
||||
m_nonzero_pivots = k;
|
||||
m_hCoeffs.tail(size-k).setZero();
|
||||
m_qr.corner(BottomRight,rows-k,cols-k)
|
||||
m_qr.bottomRightCorner(rows-k,cols-k)
|
||||
.template triangularView<StrictlyLower>()
|
||||
.setZero();
|
||||
break;
|
||||
@ -436,7 +436,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
||||
if(ei_abs(beta) > m_maxpivot) m_maxpivot = ei_abs(beta);
|
||||
|
||||
// apply the householder transformation
|
||||
m_qr.corner(BottomRight, rows-k, cols-k-1)
|
||||
m_qr.bottomRightCorner(rows-k, cols-k-1)
|
||||
.applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
|
||||
|
||||
// update our table of squared norms of the columns
|
||||
@ -483,17 +483,17 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
|
||||
));
|
||||
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
|
||||
.topLeftCorner(nonzero_pivots, nonzero_pivots)
|
||||
.template triangularView<Upper>()
|
||||
.solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
|
||||
.solveInPlace(c.topRows(nonzero_pivots));
|
||||
|
||||
|
||||
typename Rhs::PlainObject d(c);
|
||||
d.corner(TopLeft, nonzero_pivots, c.cols())
|
||||
d.topRows(nonzero_pivots)
|
||||
= dec().matrixQR()
|
||||
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
|
||||
.topLeftCorner(nonzero_pivots, nonzero_pivots)
|
||||
.template triangularView<Upper>()
|
||||
* c.corner(TopLeft, nonzero_pivots, c.cols());
|
||||
* c.topRows(nonzero_pivots);
|
||||
|
||||
for(int i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
|
||||
for(int i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
|
||||
|
@ -314,7 +314,7 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
||||
int row_of_biggest_in_corner, col_of_biggest_in_corner;
|
||||
RealScalar biggest_in_corner;
|
||||
|
||||
biggest_in_corner = m_qr.corner(Eigen::BottomRight, rows-k, cols-k)
|
||||
biggest_in_corner = m_qr.bottomRightCorner(rows-k, cols-k)
|
||||
.cwiseAbs()
|
||||
.maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
|
||||
row_of_biggest_in_corner += k;
|
||||
@ -349,7 +349,7 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
||||
m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
|
||||
m_qr.coeffRef(k,k) = beta;
|
||||
|
||||
m_qr.corner(BottomRight, rows-k, cols-k-1)
|
||||
m_qr.bottomRightCorner(rows-k, cols-k-1)
|
||||
.applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
|
||||
}
|
||||
|
||||
@ -389,7 +389,7 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
|
||||
{
|
||||
int remainingSize = rows-k;
|
||||
c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k)));
|
||||
c.corner(BottomRight, remainingSize, rhs().cols())
|
||||
c.bottomRightCorner(remainingSize, rhs().cols())
|
||||
.applyHouseholderOnTheLeft(dec().matrixQR().col(k).tail(remainingSize-1),
|
||||
dec().hCoeffs().coeff(k), &temp.coeffRef(0));
|
||||
}
|
||||
@ -397,17 +397,17 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
|
||||
if(!dec().isSurjective())
|
||||
{
|
||||
// is c is in the image of R ?
|
||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff();
|
||||
RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff();
|
||||
RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff();
|
||||
// FIXME brain dead
|
||||
const RealScalar m_precision = NumTraits<Scalar>::epsilon() * std::min(rows,cols);
|
||||
if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
|
||||
return;
|
||||
}
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, dec().rank(), dec().rank())
|
||||
.topLeftCorner(dec().rank(), dec().rank())
|
||||
.template triangularView<Upper>()
|
||||
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
||||
.solveInPlace(c.topRows(dec().rank()));
|
||||
|
||||
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
|
||||
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
|
||||
|
@ -216,7 +216,7 @@ HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType&
|
||||
m_qr.coeffRef(k,k) = beta;
|
||||
|
||||
// apply H to remaining part of m_qr from the left
|
||||
m_qr.corner(BottomRight, remainingRows, remainingCols)
|
||||
m_qr.bottomRightCorner(remainingRows, remainingCols)
|
||||
.applyHouseholderOnTheLeft(m_qr.col(k).tail(remainingRows-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
|
||||
}
|
||||
m_isInitialized = true;
|
||||
@ -239,17 +239,17 @@ struct ei_solve_retval<HouseholderQR<_MatrixType>, Rhs>
|
||||
|
||||
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
|
||||
c.applyOnTheLeft(householderSequence(
|
||||
dec().matrixQR().corner(TopLeft,rows,rank),
|
||||
dec().matrixQR().leftCols(rank),
|
||||
dec().hCoeffs().head(rank)).transpose()
|
||||
);
|
||||
|
||||
dec().matrixQR()
|
||||
.corner(TopLeft, rank, rank)
|
||||
.topLeftCorner(rank, rank)
|
||||
.template triangularView<Upper>()
|
||||
.solveInPlace(c.corner(TopLeft, rank, c.cols()));
|
||||
.solveInPlace(c.topRows(rank));
|
||||
|
||||
dst.corner(TopLeft, rank, c.cols()) = c.corner(TopLeft, rank, c.cols());
|
||||
dst.corner(BottomLeft, cols-rank, c.cols()).setZero();
|
||||
dst.topRows(rank) = c.topRows(rank);
|
||||
dst.bottomRows(cols-rank).setZero();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -114,7 +114,7 @@ UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::comput
|
||||
.makeHouseholderInPlace(m_householder.coeffRef(k,k),
|
||||
m_bidiagonal.template diagonal<0>().coeffRef(k));
|
||||
// apply householder transform to remaining part of m_householder on the left
|
||||
m_householder.corner(BottomRight, remainingRows, remainingCols)
|
||||
m_householder.bottomRightCorner(remainingRows, remainingCols)
|
||||
.applyHouseholderOnTheLeft(m_householder.col(k).tail(remainingRows-1),
|
||||
m_householder.coeff(k,k),
|
||||
temp.data());
|
||||
@ -126,7 +126,7 @@ UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::comput
|
||||
.makeHouseholderInPlace(m_householder.coeffRef(k,k+1),
|
||||
m_bidiagonal.template diagonal<1>().coeffRef(k));
|
||||
// apply householder transform to remaining part of m_householder on the left
|
||||
m_householder.corner(BottomRight, remainingRows-1, remainingCols)
|
||||
m_householder.bottomRightCorner(remainingRows-1, remainingCols)
|
||||
.applyHouseholderOnTheRight(m_householder.row(k).tail(remainingCols-1).transpose(),
|
||||
m_householder.coeff(k,k+1),
|
||||
temp.data());
|
||||
|
@ -433,19 +433,11 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
||||
// typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size);
|
||||
// const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) const;
|
||||
//
|
||||
// typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
|
||||
// const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
|
||||
//
|
||||
// template<int BlockRows, int BlockCols>
|
||||
// typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
|
||||
// template<int BlockRows, int BlockCols>
|
||||
// const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
|
||||
|
||||
// template<int CRows, int CCols>
|
||||
// typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
|
||||
// template<int CRows, int CCols>
|
||||
// const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
|
||||
|
||||
// template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void);
|
||||
// template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
||||
|
121
doc/echelon.cpp
121
doc/echelon.cpp
@ -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;
|
||||
}
|
@ -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;
|
@ -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;
|
@ -105,6 +105,7 @@ ei_add_test(unalignedcount)
|
||||
ei_add_test(redux)
|
||||
ei_add_test(visitor)
|
||||
ei_add_test(block)
|
||||
ei_add_test(corners)
|
||||
ei_add_test(product_small)
|
||||
ei_add_test(product_large)
|
||||
ei_add_test(product_extra)
|
||||
|
99
test/corners.cpp
Normal file
99
test/corners.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define COMPARE_CORNER(A,B) \
|
||||
VERIFY_IS_EQUAL(matrix.A, matrix.B); \
|
||||
VERIFY_IS_EQUAL(const_matrix.A, const_matrix.B);
|
||||
|
||||
template<typename MatrixType> void corners(const MatrixType& m)
|
||||
{
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
int r = ei_random<int>(1,rows);
|
||||
int c = ei_random<int>(1,cols);
|
||||
|
||||
MatrixType matrix = MatrixType::Random(rows,cols);
|
||||
const MatrixType const_matrix = MatrixType::Random(rows,cols);
|
||||
|
||||
COMPARE_CORNER(topLeftCorner(r,c), block(0,0,r,c));
|
||||
COMPARE_CORNER(topRightCorner(r,c), block(0,cols-c,r,c));
|
||||
COMPARE_CORNER(bottomLeftCorner(r,c), block(rows-r,0,r,c));
|
||||
COMPARE_CORNER(bottomRightCorner(r,c), block(rows-r,cols-c,r,c));
|
||||
|
||||
COMPARE_CORNER(topRows(r), block(0,0,r,cols));
|
||||
COMPARE_CORNER(bottomRows(r), block(rows-r,0,r,cols));
|
||||
COMPARE_CORNER(leftCols(c), block(0,0,rows,c));
|
||||
COMPARE_CORNER(rightCols(c), block(0,cols-c,rows,c));
|
||||
}
|
||||
|
||||
template<typename MatrixType, int CRows, int CCols> void corners_fixedsize()
|
||||
{
|
||||
MatrixType matrix = MatrixType::Random();
|
||||
const MatrixType const_matrix = MatrixType::Random();
|
||||
|
||||
enum {
|
||||
rows = MatrixType::RowsAtCompileTime,
|
||||
cols = MatrixType::ColsAtCompileTime,
|
||||
r = CRows,
|
||||
c = CCols
|
||||
};
|
||||
|
||||
VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template block<r,c>(0,0)));
|
||||
VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template block<r,c>(0,cols-c)));
|
||||
VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template block<r,c>(rows-r,0)));
|
||||
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template block<r,c>(rows-r,cols-c)));
|
||||
|
||||
VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r,cols>(0,0)));
|
||||
VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r,cols>(rows-r,0)));
|
||||
VERIFY_IS_EQUAL((matrix.template leftCols<c>()), (matrix.template block<rows,c>(0,0)));
|
||||
VERIFY_IS_EQUAL((matrix.template rightCols<c>()), (matrix.template block<rows,c>(0,cols-c)));
|
||||
|
||||
VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template block<r,c>(0,0)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template block<r,c>(0,cols-c)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,0)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,cols-c)));
|
||||
|
||||
VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r,cols>(0,0)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r,cols>(rows-r,0)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template leftCols<c>()), (const_matrix.template block<rows,c>(0,0)));
|
||||
VERIFY_IS_EQUAL((const_matrix.template rightCols<c>()), (const_matrix.template block<rows,c>(0,cols-c)));
|
||||
}
|
||||
|
||||
void test_corners()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
CALL_SUBTEST_1( corners(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( corners(Matrix4d()) );
|
||||
CALL_SUBTEST_3( corners(Matrix<int,10,12>()) );
|
||||
CALL_SUBTEST_4( corners(MatrixXcf(5, 7)) );
|
||||
CALL_SUBTEST_5( corners(MatrixXf(21, 20)) );
|
||||
|
||||
CALL_SUBTEST_1(( corners_fixedsize<Matrix<float, 1, 1>, 1, 1>() ));
|
||||
CALL_SUBTEST_2(( corners_fixedsize<Matrix4d,2,2>() ));
|
||||
CALL_SUBTEST_3(( corners_fixedsize<Matrix<int,10,12>,4,7>() ));
|
||||
}
|
||||
}
|
@ -351,9 +351,10 @@ struct test_is_equal_impl
|
||||
{
|
||||
static bool run(const Derived1& a1, const Derived2& a2)
|
||||
{
|
||||
if(a1.size() == 0 && a2.size() == 0) return true;
|
||||
if(a1.size() != a2.size()) return false;
|
||||
// we evaluate a2 into a temporary of the shape of a1. this allows to let Assign.h handle the transposing if needed.
|
||||
typename Derived1::PlainObject a2_evaluated;
|
||||
typename Derived1::PlainObject a2_evaluated(a2.size());
|
||||
a2_evaluated(0,0) = a2(0,0); // shut up GCC 4.5.0 bogus warning about a2_evaluated's array being used uninitialized in the 1x1 case, see block_1 test
|
||||
a2_evaluated = a2;
|
||||
for(int i = 0; i < a1.size(); ++i)
|
||||
@ -367,6 +368,7 @@ struct test_is_equal_impl<Derived1, Derived2, false>
|
||||
{
|
||||
static bool run(const Derived1& a1, const Derived2& a2)
|
||||
{
|
||||
if(a1.size() == 0 && a2.size() == 0) return true;
|
||||
if(a1.rows() != a2.rows()) return false;
|
||||
if(a1.cols() != a2.cols()) return false;
|
||||
for(int j = 0; j < a1.cols(); ++j)
|
||||
|
@ -86,7 +86,8 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
|
||||
VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<Upper>() * (m2+m2), 1);
|
||||
VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * m2.adjoint(), 0);
|
||||
|
||||
VERIFY_EVALUATION_COUNT( rm3.col(c0).noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * (s2*m2.row(c0)).adjoint(), 0);
|
||||
// NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products
|
||||
VERIFY_EVALUATION_COUNT( rm3.col(c0).noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * (s2*m2.row(c0)).adjoint(), 1);
|
||||
|
||||
VERIFY_EVALUATION_COUNT( m1.template triangularView<Lower>().solveInPlace(m3), 0);
|
||||
VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<Lower>().solveInPlace(m3.transpose()), 0);
|
||||
@ -95,8 +96,9 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m)
|
||||
VERIFY_EVALUATION_COUNT( m3.noalias() = s2 * m2.adjoint() * (s1 * m1.adjoint()).template selfadjointView<Upper>(), 0);
|
||||
VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template selfadjointView<Lower>() * m2.adjoint(), 0);
|
||||
|
||||
VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() = (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2.row(c0)*s3).adjoint(), 0);
|
||||
VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() -= (s1 * m1).adjoint().template selfadjointView<Upper>() * (-m2.row(c0)*s3).adjoint(), 0);
|
||||
// NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products
|
||||
VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() = (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2.row(c0)*s3).adjoint(), 1);
|
||||
VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() -= (s1 * m1).adjoint().template selfadjointView<Upper>() * (-m2.row(c0)*s3).adjoint(), 1);
|
||||
|
||||
VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() += m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * (s1*m2.block(r0,c0,r1,c1)), 0);
|
||||
VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * m2.block(r0,c0,r1,c1), 0);
|
||||
|
@ -88,7 +88,7 @@ namespace Eigen {
|
||||
* (c)minpack performs VERY well compared to those, both in accuracy and speed.
|
||||
*
|
||||
* The documentation for running the tests is on the wiki
|
||||
* http://eigen.tuxfamily.org/index.php?title=Developer%27s_Corner#Running_the_unit_tests
|
||||
* http://eigen.tuxfamily.org/index.php?title=Tests
|
||||
*
|
||||
* \section API API : overview of methods
|
||||
*
|
||||
|
@ -159,7 +159,7 @@ class MatrixFunction<MatrixType, 1>
|
||||
void permuteSchur();
|
||||
void swapEntriesInSchur(int index);
|
||||
void computeBlockAtomic();
|
||||
typename BlockReturnType<MatrixType>::Type block(const MatrixType& A, int i, int j);
|
||||
Block<MatrixType> block(const MatrixType& A, int i, int j);
|
||||
void computeOffDiagonal();
|
||||
DynMatrixType solveTriangularSylvester(const DynMatrixType& A, const DynMatrixType& B, const DynMatrixType& C);
|
||||
|
||||
@ -379,7 +379,7 @@ void MatrixFunction<MatrixType,1>::computeBlockAtomic()
|
||||
|
||||
/** \brief Return block of matrix according to blocking given by #m_blockStart */
|
||||
template <typename MatrixType>
|
||||
typename BlockReturnType<MatrixType>::Type MatrixFunction<MatrixType,1>::block(const MatrixType& A, int i, int j)
|
||||
Block<MatrixType> MatrixFunction<MatrixType,1>::block(const MatrixType& A, int i, int j)
|
||||
{
|
||||
return A.block(m_blockStart(i), m_blockStart(j), m_clusterSize(i), m_clusterSize(j));
|
||||
}
|
||||
|
@ -543,7 +543,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(FVectorTyp
|
||||
|
||||
/* compute the scaled predicted reduction and */
|
||||
/* the scaled directional derivative. */
|
||||
wa3 = fjac.corner(TopLeft,n,n).template triangularView<Upper>() * (permutation.inverse() * wa1);
|
||||
wa3 = fjac.topLeftCorner(n,n).template triangularView<Upper>() * (permutation.inverse() * wa1);
|
||||
temp1 = ei_abs2(wa3.stableNorm() / fnorm);
|
||||
temp2 = ei_abs2(ei_sqrt(par) * pnorm / fnorm);
|
||||
prered = temp1 + temp2 / Scalar(.5);
|
||||
|
@ -55,7 +55,7 @@ void ei_covar(
|
||||
}
|
||||
|
||||
/* symmetrize the covariance matrix in r. */
|
||||
r.corner(TopLeft,n,n).template triangularView<StrictlyUpper>() = r.corner(TopLeft,n,n).transpose();
|
||||
r.topLeftCorner(n,n).template triangularView<StrictlyUpper>() = r.topLeftCorner(n,n).transpose();
|
||||
r.diagonal() = wa;
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ void ei_lmpar2(
|
||||
const int rank = qr.rank(); // use a threshold
|
||||
wa1 = qtb;
|
||||
wa1.tail(n-rank).setZero();
|
||||
qr.matrixQR().corner(TopLeft, rank, rank).template triangularView<Upper>().solveInPlace(wa1.head(rank));
|
||||
qr.matrixQR().topLeftCorner(rank, rank).template triangularView<Upper>().solveInPlace(wa1.head(rank));
|
||||
|
||||
x = qr.colsPermutation()*wa1;
|
||||
|
||||
@ -210,7 +210,7 @@ void ei_lmpar2(
|
||||
parl = 0.;
|
||||
if (rank==n) {
|
||||
wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2)/dxnorm;
|
||||
qr.matrixQR().corner(TopLeft, n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
|
||||
qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
|
||||
temp = wa1.blueNorm();
|
||||
parl = fp / delta / temp / temp;
|
||||
}
|
||||
@ -258,7 +258,7 @@ void ei_lmpar2(
|
||||
/* compute the newton correction. */
|
||||
wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2/dxnorm);
|
||||
// we could almost use this here, but the diagonal is outside qr, in sdiag[]
|
||||
// qr.matrixQR().corner(TopLeft, n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
|
||||
// qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);
|
||||
for (j = 0; j < n; ++j) {
|
||||
wa1[j] /= sdiag[j];
|
||||
temp = wa1[j];
|
||||
|
@ -27,7 +27,7 @@ void ei_qrsolv(
|
||||
x = s.diagonal();
|
||||
wa = qtb;
|
||||
|
||||
s.corner(TopLeft,n,n).template triangularView<StrictlyLower>() = s.corner(TopLeft,n,n).transpose();
|
||||
s.topLeftCorner(n,n).template triangularView<StrictlyLower>() = s.topLeftCorner(n,n).transpose();
|
||||
|
||||
/* eliminate the diagonal matrix d using a givens rotation. */
|
||||
for (j = 0; j < n; ++j) {
|
||||
@ -71,7 +71,7 @@ void ei_qrsolv(
|
||||
for (nsing=0; nsing<n && sdiag[nsing]!=0; nsing++);
|
||||
|
||||
wa.tail(n-nsing).setZero();
|
||||
s.corner(TopLeft, nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));
|
||||
s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));
|
||||
|
||||
// restore
|
||||
sdiag = s.diagonal();
|
||||
|
@ -227,10 +227,10 @@ void testLmder()
|
||||
// std::cout << fjac*covfac << std::endl;
|
||||
|
||||
MatrixXd cov;
|
||||
cov = covfac*lm.fjac.corner<n,n>(TopLeft);
|
||||
cov = covfac*lm.fjac.topLeftCorner<n,n>();
|
||||
VERIFY_IS_APPROX( cov, cov_ref);
|
||||
// TODO: why isn't this allowed ? :
|
||||
// VERIFY_IS_APPROX( covfac*fjac.corner<n,n>(TopLeft) , cov_ref);
|
||||
// VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
|
||||
}
|
||||
|
||||
struct hybrj_functor : Functor<double>
|
||||
@ -618,10 +618,10 @@ void testLmdif()
|
||||
// std::cout << fjac*covfac << std::endl;
|
||||
|
||||
MatrixXd cov;
|
||||
cov = covfac*lm.fjac.corner<n,n>(TopLeft);
|
||||
cov = covfac*lm.fjac.topLeftCorner<n,n>();
|
||||
VERIFY_IS_APPROX( cov, cov_ref);
|
||||
// TODO: why isn't this allowed ? :
|
||||
// VERIFY_IS_APPROX( covfac*fjac.corner<n,n>(TopLeft) , cov_ref);
|
||||
// VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);
|
||||
}
|
||||
|
||||
struct chwirut2_functor : Functor<double>
|
||||
|
Loading…
x
Reference in New Issue
Block a user