aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/QR/FullPivHouseholderQR.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-03-11 11:47:32 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-03-11 11:47:32 +0100
commit9be72cda2ab25650ce97eacd6dc2e994c988741b (patch)
treeef087b1fa46a3142d976b9a486bd6d80bb6ad2cc /Eigen/src/QR/FullPivHouseholderQR.h
parentae405839652dc72935821bdaed163e7be04b3082 (diff)
Port QR module to Solve/Inverse
Diffstat (limited to 'Eigen/src/QR/FullPivHouseholderQR.h')
-rw-r--r--Eigen/src/QR/FullPivHouseholderQR.h133
1 files changed, 98 insertions, 35 deletions
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index 44eaa1b1a..8cdf14e4b 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -15,6 +15,12 @@ namespace Eigen {
namespace internal {
+template<typename _MatrixType> struct traits<FullPivHouseholderQR<_MatrixType> >
+ : traits<_MatrixType>
+{
+ enum { Flags = 0 };
+};
+
template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType;
template<typename MatrixType>
@@ -23,7 +29,7 @@ struct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
typedef typename MatrixType::PlainObject ReturnType;
};
-}
+} // end namespace internal
/** \ingroup QR_Module
*
@@ -69,6 +75,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_col_type<MatrixType>::type ColVectorType;
+ typedef typename MatrixType::PlainObject PlainObject;
/** \brief Default Constructor.
*
@@ -144,6 +151,15 @@ template<typename _MatrixType> class FullPivHouseholderQR
* Example: \include FullPivHouseholderQR_solve.cpp
* Output: \verbinclude FullPivHouseholderQR_solve.out
*/
+#ifdef EIGEN_TEST_EVALUATORS
+ template<typename Rhs>
+ inline const Solve<FullPivHouseholderQR, Rhs>
+ solve(const MatrixBase<Rhs>& b) const
+ {
+ eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
+ return Solve<FullPivHouseholderQR, Rhs>(*this, b.derived());
+ }
+#else
template<typename Rhs>
inline const internal::solve_retval<FullPivHouseholderQR, Rhs>
solve(const MatrixBase<Rhs>& b) const
@@ -151,6 +167,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return internal::solve_retval<FullPivHouseholderQR, Rhs>(*this, b.derived());
}
+#endif
/** \returns Expression object representing the matrix Q
*/
@@ -280,7 +297,15 @@ template<typename _MatrixType> class FullPivHouseholderQR
*
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
* Use isInvertible() to first determine whether this matrix is invertible.
- */ inline const
+ */
+#ifdef EIGEN_TEST_EVALUATORS
+ inline const Inverse<FullPivHouseholderQR> inverse() const
+ {
+ eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
+ return Inverse<FullPivHouseholderQR>(*this);
+ }
+#else
+ inline const
internal::solve_retval<FullPivHouseholderQR, typename MatrixType::IdentityReturnType>
inverse() const
{
@@ -288,6 +313,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
return internal::solve_retval<FullPivHouseholderQR,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(); }
@@ -366,6 +392,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
* diagonal coefficient of U.
*/
RealScalar maxPivot() const { return m_maxpivot; }
+
+ #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;
@@ -485,8 +517,46 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
return *this;
}
-namespace internal {
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+template<typename _MatrixType>
+template<typename RhsType, typename DstType>
+void FullPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
+{
+ eigen_assert(rhs.rows() == rows());
+ const Index l_rank = rank();
+
+ // FIXME introduce nonzeroPivots() and use it here. and more generally,
+ // make the same improvements in this dec as in FullPivLU.
+ if(l_rank==0)
+ {
+ dst.setZero();
+ return;
+ }
+ typename RhsType::PlainObject c(rhs);
+
+ Matrix<Scalar,1,RhsType::ColsAtCompileTime> temp(rhs.cols());
+ for (Index k = 0; k < l_rank; ++k)
+ {
+ Index remainingSize = rows()-k;
+ c.row(k).swap(c.row(m_rows_transpositions.coeff(k)));
+ c.bottomRightCorner(remainingSize, rhs.cols())
+ .applyHouseholderOnTheLeft(m_qr.col(k).tail(remainingSize-1),
+ m_hCoeffs.coeff(k), &temp.coeffRef(0));
+ }
+
+ m_qr.topLeftCorner(l_rank, l_rank)
+ .template triangularView<Upper>()
+ .solveInPlace(c.topRows(l_rank));
+
+ for(Index i = 0; i < l_rank; ++i) dst.row(m_cols_permutation.indices().coeff(i)) = c.row(i);
+ for(Index i = l_rank; i < cols(); ++i) dst.row(m_cols_permutation.indices().coeff(i)).setZero();
+}
+#endif
+
+namespace internal {
+
+#ifndef EIGEN_TEST_EVALUATORS
template<typename _MatrixType, typename Rhs>
struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
: solve_retval_base<FullPivHouseholderQR<_MatrixType>, Rhs>
@@ -495,38 +565,23 @@ struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- const Index rows = dec().rows(), cols = dec().cols();
- eigen_assert(rhs().rows() == rows);
-
- // FIXME introduce nonzeroPivots() and use it here. and more generally,
- // make the same improvements in this dec as in FullPivLU.
- if(dec().rank()==0)
- {
- dst.setZero();
- return;
- }
-
- typename Rhs::PlainObject c(rhs());
-
- Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs().cols());
- for (Index k = 0; k < dec().rank(); ++k)
- {
- Index remainingSize = rows-k;
- c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k)));
- c.bottomRightCorner(remainingSize, rhs().cols())
- .applyHouseholderOnTheLeft(dec().matrixQR().col(k).tail(remainingSize-1),
- dec().hCoeffs().coeff(k), &temp.coeffRef(0));
- }
-
- dec().matrixQR()
- .topLeftCorner(dec().rank(), dec().rank())
- .template triangularView<Upper>()
- .solveInPlace(c.topRows(dec().rank()));
+ dec()._solve_impl(rhs(), dst);
+ }
+};
+#endif // EIGEN_TEST_EVALUATORS
- for(Index i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
- for(Index i = dec().rank(); 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<FullPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
+{
+ typedef FullPivHouseholderQR<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
/** \ingroup QR_Module
*
@@ -534,6 +589,7 @@ struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
*
* \tparam MatrixType type of underlying dense matrix
*/
+// #ifndef EIGEN_TEST_EVALUATORS
template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
: public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
{
@@ -550,7 +606,7 @@ public:
: m_qr(qr),
m_hCoeffs(hCoeffs),
m_rowsTranspositions(rowsTranspositions)
- {}
+ {}
template <typename ResultType>
void evalTo(ResultType& result) const
@@ -580,8 +636,8 @@ public:
}
}
- Index rows() const { return m_qr.rows(); }
- Index cols() const { return m_qr.rows(); }
+ Index rows() const { return m_qr.rows(); }
+ Index cols() const { return m_qr.rows(); }
protected:
typename MatrixType::Nested m_qr;
@@ -589,6 +645,13 @@ protected:
typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
};
+// #ifdef EIGEN_TEST_EVALUATORS
+// template<typename MatrixType>
+// struct evaluator<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
+// : public evaluator<ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > >
+// {};
+// #endif
+
} // end namespace internal
template<typename MatrixType>