big huge changes, so i dont remember everything.

* renaming, e.g. LU ---> FullPivLU
* split tests framework: more robust, e.g. dont generate empty tests if a number is skipped
* make all remaining tests use that splitting, as needed.
* Fix 4x4 inversion (see stable branch)
* Transform::inverse() and geo_transform test : adapt to new inverse() API, it was also trying to instantiate inverse() for 3x4 matrices.
* CMakeLists: more robust regexp to parse the version number
* misc fixes in unit tests
This commit is contained in:
Benoit Jacob
2009-10-28 18:19:29 -04:00
parent 1f1c04cac1
commit 2840ac7e94
99 changed files with 816 additions and 710 deletions

View File

@@ -29,7 +29,7 @@
/** \ingroup QR_Module
* \nonstableyet
*
* \class ColPivotingHouseholderQR
* \class ColPivHouseholderQR
*
* \brief Householder rank-revealing QR decomposition of a matrix with column-pivoting
*
@@ -38,11 +38,11 @@
* This class performs a rank-revealing QR decomposition using Householder transformations.
*
* This decomposition performs column pivoting in order to be rank-revealing and improve
* numerical stability. It is slower than HouseholderQR, and faster than FullPivotingHouseholderQR.
* numerical stability. It is slower than HouseholderQR, and faster than FullPivHouseholderQR.
*
* \sa MatrixBase::colPivotingHouseholderQr()
* \sa MatrixBase::colPivHouseholderQr()
*/
template<typename MatrixType> class ColPivotingHouseholderQR
template<typename MatrixType> class ColPivHouseholderQR
{
public:
@@ -68,11 +68,11 @@ template<typename MatrixType> class ColPivotingHouseholderQR
* \brief Default Constructor.
*
* The default constructor is useful in cases in which the user intends to
* perform decompositions via ColPivotingHouseholderQR::compute(const MatrixType&).
* perform decompositions via ColPivHouseholderQR::compute(const MatrixType&).
*/
ColPivotingHouseholderQR() : m_qr(), m_hCoeffs(), m_isInitialized(false) {}
ColPivHouseholderQR() : m_qr(), m_hCoeffs(), m_isInitialized(false) {}
ColPivotingHouseholderQR(const MatrixType& matrix)
ColPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs(std::min(matrix.rows(),matrix.cols())),
m_isInitialized(false)
@@ -94,8 +94,8 @@ template<typename MatrixType> class ColPivotingHouseholderQR
* \note The case where b is a matrix is not yet implemented. Also, this
* code is space inefficient.
*
* Example: \include ColPivotingHouseholderQR_solve.cpp
* Output: \verbinclude ColPivotingHouseholderQR_solve.out
* Example: \include ColPivHouseholderQR_solve.cpp
* Output: \verbinclude ColPivHouseholderQR_solve.out
*/
template<typename OtherDerived, typename ResultType>
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const;
@@ -106,15 +106,15 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
const MatrixType& matrixQR() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_qr;
}
ColPivotingHouseholderQR& compute(const MatrixType& matrix);
ColPivHouseholderQR& compute(const MatrixType& matrix);
const IntRowVectorType& colsPermutation() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_cols_permutation;
}
@@ -154,7 +154,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline int rank() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_rank;
}
@@ -165,7 +165,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline int dimensionOfKernel() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_qr.cols() - m_rank;
}
@@ -177,7 +177,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline bool isInjective() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_rank == m_qr.cols();
}
@@ -189,7 +189,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline bool isSurjective() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_rank == m_qr.rows();
}
@@ -200,7 +200,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline bool isInvertible() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return isInjective() && isSurjective();
}
@@ -215,7 +215,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
*/
inline void computeInverse(MatrixType *result) const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the inverse of a non-square matrix!");
solve(MatrixType::Identity(m_qr.rows(), m_qr.cols()), result);
}
@@ -247,23 +247,23 @@ template<typename MatrixType> class ColPivotingHouseholderQR
#ifndef EIGEN_HIDE_HEAVY_CODE
template<typename MatrixType>
typename MatrixType::RealScalar ColPivotingHouseholderQR<MatrixType>::absDeterminant() const
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
return ei_abs(m_qr.diagonal().prod());
}
template<typename MatrixType>
typename MatrixType::RealScalar ColPivotingHouseholderQR<MatrixType>::logAbsDeterminant() const
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDeterminant() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
return m_qr.diagonal().cwise().abs().cwise().log().sum();
}
template<typename MatrixType>
ColPivotingHouseholderQR<MatrixType>& ColPivotingHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
int rows = matrix.rows();
int cols = matrix.cols();
@@ -333,12 +333,12 @@ ColPivotingHouseholderQR<MatrixType>& ColPivotingHouseholderQR<MatrixType>::comp
template<typename MatrixType>
template<typename OtherDerived, typename ResultType>
bool ColPivotingHouseholderQR<MatrixType>::solve(
bool ColPivHouseholderQR<MatrixType>::solve(
const MatrixBase<OtherDerived>& b,
ResultType *result
) const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
result->resize(m_qr.cols(), b.cols());
if(m_rank==0)
{
@@ -378,9 +378,9 @@ bool ColPivotingHouseholderQR<MatrixType>::solve(
/** \returns the matrix Q as a sequence of householder transformations */
template<typename MatrixType>
typename ColPivotingHouseholderQR<MatrixType>::HouseholderSequenceType ColPivotingHouseholderQR<MatrixType>::matrixQ() const
typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>::matrixQ() const
{
ei_assert(m_isInitialized && "ColPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
}
@@ -388,13 +388,13 @@ typename ColPivotingHouseholderQR<MatrixType>::HouseholderSequenceType ColPivoti
/** \return the column-pivoting Householder QR decomposition of \c *this.
*
* \sa class ColPivotingHouseholderQR
* \sa class ColPivHouseholderQR
*/
template<typename Derived>
const ColPivotingHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::colPivotingHouseholderQr() const
const ColPivHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::colPivHouseholderQr() const
{
return ColPivotingHouseholderQR<PlainMatrixType>(eval());
return ColPivHouseholderQR<PlainMatrixType>(eval());
}

View File

@@ -29,7 +29,7 @@
/** \ingroup QR_Module
* \nonstableyet
*
* \class FullPivotingHouseholderQR
* \class FullPivHouseholderQR
*
* \brief Householder rank-revealing QR decomposition of a matrix with full pivoting
*
@@ -38,11 +38,11 @@
* This class performs a rank-revealing QR decomposition using Householder transformations.
*
* This decomposition performs a very prudent full pivoting in order to be rank-revealing and achieve optimal
* numerical stability. The trade-off is that it is slower than HouseholderQR and ColPivotingHouseholderQR.
* numerical stability. The trade-off is that it is slower than HouseholderQR and ColPivHouseholderQR.
*
* \sa MatrixBase::fullPivotingHouseholderQr()
* \sa MatrixBase::fullPivHouseholderQr()
*/
template<typename MatrixType> class FullPivotingHouseholderQR
template<typename MatrixType> class FullPivHouseholderQR
{
public:
@@ -65,11 +65,11 @@ template<typename MatrixType> class FullPivotingHouseholderQR
/** \brief Default Constructor.
*
* The default constructor is useful in cases in which the user intends to
* perform decompositions via FullPivotingHouseholderQR::compute(const MatrixType&).
* perform decompositions via FullPivHouseholderQR::compute(const MatrixType&).
*/
FullPivotingHouseholderQR() : m_isInitialized(false) {}
FullPivHouseholderQR() : m_isInitialized(false) {}
FullPivotingHouseholderQR(const MatrixType& matrix)
FullPivHouseholderQR(const MatrixType& matrix)
: m_isInitialized(false)
{
compute(matrix);
@@ -89,8 +89,8 @@ template<typename MatrixType> class FullPivotingHouseholderQR
* \note The case where b is a matrix is not yet implemented. Also, this
* code is space inefficient.
*
* Example: \include FullPivotingHouseholderQR_solve.cpp
* Output: \verbinclude FullPivotingHouseholderQR_solve.out
* Example: \include FullPivHouseholderQR_solve.cpp
* Output: \verbinclude FullPivHouseholderQR_solve.out
*/
template<typename OtherDerived, typename ResultType>
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const;
@@ -101,21 +101,21 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
const MatrixType& matrixQR() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_qr;
}
FullPivotingHouseholderQR& compute(const MatrixType& matrix);
FullPivHouseholderQR& compute(const MatrixType& matrix);
const IntRowVectorType& colsPermutation() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_cols_permutation;
}
const IntColVectorType& rowsTranspositions() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rows_transpositions;
}
@@ -155,7 +155,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline int rank() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rank;
}
@@ -166,7 +166,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline int dimensionOfKernel() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_qr.cols() - m_rank;
}
@@ -178,7 +178,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline bool isInjective() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rank == m_qr.cols();
}
@@ -190,7 +190,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline bool isSurjective() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_rank == m_qr.rows();
}
@@ -201,7 +201,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline bool isInvertible() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return isInjective() && isSurjective();
}
@@ -216,7 +216,7 @@ template<typename MatrixType> class FullPivotingHouseholderQR
*/
inline void computeInverse(MatrixType *result) const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the inverse of a non-square matrix!");
solve(MatrixType::Identity(m_qr.rows(), m_qr.cols()), result);
}
@@ -249,23 +249,23 @@ template<typename MatrixType> class FullPivotingHouseholderQR
#ifndef EIGEN_HIDE_HEAVY_CODE
template<typename MatrixType>
typename MatrixType::RealScalar FullPivotingHouseholderQR<MatrixType>::absDeterminant() const
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
return ei_abs(m_qr.diagonal().prod());
}
template<typename MatrixType>
typename MatrixType::RealScalar FullPivotingHouseholderQR<MatrixType>::logAbsDeterminant() const
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDeterminant() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
return m_qr.diagonal().cwise().abs().cwise().log().sum();
}
template<typename MatrixType>
FullPivotingHouseholderQR<MatrixType>& FullPivotingHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
int rows = matrix.rows();
int cols = matrix.cols();
@@ -342,12 +342,12 @@ FullPivotingHouseholderQR<MatrixType>& FullPivotingHouseholderQR<MatrixType>::co
template<typename MatrixType>
template<typename OtherDerived, typename ResultType>
bool FullPivotingHouseholderQR<MatrixType>::solve(
bool FullPivHouseholderQR<MatrixType>::solve(
const MatrixBase<OtherDerived>& b,
ResultType *result
) const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
result->resize(m_qr.cols(), b.cols());
if(m_rank==0)
{
@@ -393,9 +393,9 @@ bool FullPivotingHouseholderQR<MatrixType>::solve(
/** \returns the matrix Q */
template<typename MatrixType>
typename FullPivotingHouseholderQR<MatrixType>::MatrixQType FullPivotingHouseholderQR<MatrixType>::matrixQ() const
typename FullPivHouseholderQR<MatrixType>::MatrixQType FullPivHouseholderQR<MatrixType>::matrixQ() const
{
ei_assert(m_isInitialized && "FullPivotingHouseholderQR is not initialized.");
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
// compute the product H'_0 H'_1 ... H'_n-1,
// where H_k is the k-th Householder transformation I - h_k v_k v_k'
// and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...]
@@ -417,13 +417,13 @@ typename FullPivotingHouseholderQR<MatrixType>::MatrixQType FullPivotingHousehol
/** \return the full-pivoting Householder QR decomposition of \c *this.
*
* \sa class FullPivotingHouseholderQR
* \sa class FullPivHouseholderQR
*/
template<typename Derived>
const FullPivotingHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::fullPivotingHouseholderQr() const
const FullPivHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::fullPivHouseholderQr() const
{
return FullPivotingHouseholderQR<PlainMatrixType>(eval());
return FullPivHouseholderQR<PlainMatrixType>(eval());
}
#endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H

View File

@@ -39,10 +39,10 @@
* stored in a compact way compatible with LAPACK.
*
* Note that no pivoting is performed. This is \b not a rank-revealing decomposition.
* If you want that feature, use FullPivotingHouseholderQR or ColPivotingHouseholderQR instead.
* If you want that feature, use FullPivHouseholderQR or ColPivHouseholderQR instead.
*
* This Householder QR decomposition is faster, but less numerically stable and less feature-full than
* FullPivotingHouseholderQR or ColPivotingHouseholderQR.
* FullPivHouseholderQR or ColPivHouseholderQR.
*
* \sa MatrixBase::householderQr()
*/