diff options
Diffstat (limited to 'Eigen/src/QR/ColPivHouseholderQR.h')
-rw-r--r-- | Eigen/src/QR/ColPivHouseholderQR.h | 110 |
1 files changed, 83 insertions, 27 deletions
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index 4824880f5..96904c65f 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -13,6 +13,15 @@ namespace Eigen { +namespace internal { +template<typename _MatrixType> struct traits<ColPivHouseholderQR<_MatrixType> > + : traits<_MatrixType> +{ + enum { Flags = 0 }; +}; + +} // end namespace internal + /** \ingroup QR_Module * * \class ColPivHouseholderQR @@ -56,6 +65,7 @@ template<typename _MatrixType> class ColPivHouseholderQR typedef typename internal::plain_row_type<MatrixType>::type RowVectorType; typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType; typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType; + typedef typename MatrixType::PlainObject PlainObject; private: @@ -137,6 +147,15 @@ template<typename _MatrixType> class ColPivHouseholderQR * Example: \include ColPivHouseholderQR_solve.cpp * Output: \verbinclude ColPivHouseholderQR_solve.out */ +#ifdef EIGEN_TEST_EVALUATORS + template<typename Rhs> + inline const Solve<ColPivHouseholderQR, Rhs> + solve(const MatrixBase<Rhs>& b) const + { + eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); + return Solve<ColPivHouseholderQR, Rhs>(*this, b.derived()); + } +#else template<typename Rhs> inline const internal::solve_retval<ColPivHouseholderQR, Rhs> solve(const MatrixBase<Rhs>& b) const @@ -144,9 +163,10 @@ template<typename _MatrixType> class ColPivHouseholderQR eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); return internal::solve_retval<ColPivHouseholderQR, Rhs>(*this, b.derived()); } +#endif - HouseholderSequenceType householderQ(void) const; - HouseholderSequenceType matrixQ(void) const + HouseholderSequenceType householderQ() const; + HouseholderSequenceType matrixQ() const { return householderQ(); } @@ -284,6 +304,13 @@ template<typename _MatrixType> class ColPivHouseholderQR * \note If this matrix is not invertible, the returned matrix has undefined coefficients. * Use isInvertible() to first determine whether this matrix is invertible. */ +#ifdef EIGEN_TEST_EVALUATORS + inline const Inverse<ColPivHouseholderQR> inverse() const + { + eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); + return Inverse<ColPivHouseholderQR>(*this); + } +#else inline const internal::solve_retval<ColPivHouseholderQR, typename MatrixType::IdentityReturnType> inverse() const @@ -292,6 +319,7 @@ template<typename _MatrixType> class ColPivHouseholderQR return internal::solve_retval<ColPivHouseholderQR,typename MatrixType::IdentityReturnType> (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); } +#endif inline Index rows() const { return m_qr.rows(); } inline Index cols() const { return m_qr.cols(); } @@ -382,6 +410,12 @@ template<typename _MatrixType> class ColPivHouseholderQR eigen_assert(m_isInitialized && "Decomposition is not initialized."); return Success; } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template<typename RhsType, typename DstType> + EIGEN_DEVICE_FUNC + void _solve_impl(const RhsType &rhs, DstType &dst) const; + #endif protected: MatrixType m_qr; @@ -514,8 +548,41 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const return *this; } +#ifndef EIGEN_PARSED_BY_DOXYGEN +template<typename _MatrixType> +template<typename RhsType, typename DstType> +void ColPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const +{ + eigen_assert(rhs.rows() == rows()); + + const Index nonzero_pivots = nonzeroPivots(); + + if(nonzero_pivots == 0) + { + dst.setZero(); + return; + } + + typename RhsType::PlainObject c(rhs); + + // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T + c.applyOnTheLeft(householderSequence(m_qr, m_hCoeffs) + .setLength(nonzero_pivots) + .transpose() + ); + + m_qr.topLeftCorner(nonzero_pivots, nonzero_pivots) + .template triangularView<Upper>() + .solveInPlace(c.topRows(nonzero_pivots)); + + for(Index i = 0; i < nonzero_pivots; ++i) dst.row(m_colsPermutation.indices().coeff(i)) = c.row(i); + for(Index i = nonzero_pivots; i < cols(); ++i) dst.row(m_colsPermutation.indices().coeff(i)).setZero(); +} +#endif + namespace internal { +#ifndef EIGEN_TEST_EVALUATORS template<typename _MatrixType, typename Rhs> struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs> : solve_retval_base<ColPivHouseholderQR<_MatrixType>, Rhs> @@ -524,34 +591,23 @@ struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs> template<typename Dest> void evalTo(Dest& dst) const { - eigen_assert(rhs().rows() == dec().rows()); - - const Index cols = dec().cols(), - nonzero_pivots = dec().nonzeroPivots(); - - if(nonzero_pivots == 0) - { - dst.setZero(); - return; - } - - typename Rhs::PlainObject c(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(), dec().hCoeffs()) - .setLength(dec().nonzeroPivots()) - .transpose() - ); - - dec().matrixR() - .topLeftCorner(nonzero_pivots, nonzero_pivots) - .template triangularView<Upper>() - .solveInPlace(c.topRows(nonzero_pivots)); + dec()._solve_impl(rhs(), dst); + } +}; +#endif - for(Index i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); - for(Index i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); +#ifdef EIGEN_TEST_EVALUATORS +template<typename DstXprType, typename MatrixType, typename Scalar> +struct Assignment<DstXprType, Inverse<ColPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar> +{ + typedef ColPivHouseholderQR<MatrixType> QrType; + typedef Inverse<QrType> SrcXprType; + static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) + { + dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols())); } }; +#endif } // end namespace internal |