From 5c5789cf0f28b375e3bfebe3e61756fc0b00fe0c Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Fri, 22 May 2009 14:27:58 +0200 Subject: QR and SVD decomposition interface unification. Added default ctor and public compute method as well as safe-guards against uninitialized usage. Added unit tests for the safe-guards. --- Eigen/src/QR/QR.h | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'Eigen/src/QR') diff --git a/Eigen/src/QR/QR.h b/Eigen/src/QR/QR.h index 19002e0eb..63fd2d48b 100644 --- a/Eigen/src/QR/QR.h +++ b/Eigen/src/QR/QR.h @@ -49,11 +49,20 @@ template class QR typedef Matrix MatrixTypeR; typedef Matrix VectorType; + /** + * \brief Default Constructor. + * + * The default constructor is useful in cases in which the user intends to + * perform decompositions via QR::compute(const MatrixType&). + */ + QR() : m_qr(), m_hCoeffs(), m_isInitialized(false) {} + QR(const MatrixType& matrix) : m_qr(matrix.rows(), matrix.cols()), - m_hCoeffs(matrix.cols()) + m_hCoeffs(matrix.cols()), + m_isInitialized(false) { - _compute(matrix); + compute(matrix); } /** \deprecated use isInjective() @@ -62,7 +71,11 @@ template class QR * \note Since the rank is computed only once, i.e. the first time it is needed, this * method almost does not perform any further computation. */ - EIGEN_DEPRECATED bool isFullRank() const { return rank() == m_qr.cols(); } + EIGEN_DEPRECATED bool isFullRank() const + { + ei_assert(m_isInitialized && "QR is not initialized."); + return rank() == m_qr.cols(); + } /** \returns the rank of the matrix of which *this is the QR decomposition. * @@ -78,6 +91,7 @@ template class QR */ inline int dimensionOfKernel() const { + ei_assert(m_isInitialized && "QR is not initialized."); return m_qr.cols() - rank(); } @@ -89,6 +103,7 @@ template class QR */ inline bool isInjective() const { + ei_assert(m_isInitialized && "QR is not initialized."); return rank() == m_qr.cols(); } @@ -100,6 +115,7 @@ template class QR */ inline bool isSurjective() const { + ei_assert(m_isInitialized && "QR is not initialized."); return rank() == m_qr.rows(); } @@ -110,6 +126,7 @@ template class QR */ inline bool isInvertible() const { + ei_assert(m_isInitialized && "QR is not initialized."); return isInjective() && isSurjective(); } @@ -117,6 +134,7 @@ template class QR const Part, UpperTriangular> matrixR(void) const { + ei_assert(m_isInitialized && "QR is not initialized."); int cols = m_qr.cols(); return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part(); } @@ -149,21 +167,21 @@ template class QR MatrixType matrixQ(void) const; - private: - - void _compute(const MatrixType& matrix); + void compute(const MatrixType& matrix); protected: MatrixType m_qr; VectorType m_hCoeffs; mutable int m_rank; mutable bool m_rankIsUptodate; + bool m_isInitialized; }; /** \returns the rank of the matrix of which *this is the QR decomposition. */ template int QR::rank() const { + ei_assert(m_isInitialized && "QR is not initialized."); if (!m_rankIsUptodate) { RealScalar maxCoeff = m_qr.diagonal().cwise().abs().maxCoeff(); @@ -179,10 +197,12 @@ int QR::rank() const #ifndef EIGEN_HIDE_HEAVY_CODE template -void QR::_compute(const MatrixType& matrix) -{ +void QR::compute(const MatrixType& matrix) +{ m_rankIsUptodate = false; m_qr = matrix; + m_hCoeffs.resize(matrix.cols()); + int rows = matrix.rows(); int cols = matrix.cols(); RealScalar eps2 = precision()*precision(); @@ -237,6 +257,7 @@ void QR::_compute(const MatrixType& matrix) m_hCoeffs.coeffRef(k) = 0; } } + m_isInitialized = true; } template @@ -246,6 +267,7 @@ bool QR::solve( ResultType *result ) const { + ei_assert(m_isInitialized && "QR is not initialized."); const int rows = m_qr.rows(); ei_assert(b.rows() == rows); result->resize(rows, b.cols()); @@ -274,6 +296,7 @@ bool QR::solve( template MatrixType QR::matrixQ() const { + ei_assert(m_isInitialized && "QR is not initialized."); // compute the product Q_0 Q_1 ... Q_n-1, // where Q_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), ...] -- cgit v1.2.3