aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/QR/ColPivHouseholderQR.h
diff options
context:
space:
mode:
Diffstat (limited to 'Eigen/src/QR/ColPivHouseholderQR.h')
-rw-r--r--Eigen/src/QR/ColPivHouseholderQR.h110
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