diff options
author | Rasmus Munk Larsen <rmlarsen@google.com> | 2015-11-30 13:39:24 -0800 |
---|---|---|
committer | Rasmus Munk Larsen <rmlarsen@google.com> | 2015-11-30 13:39:24 -0800 |
commit | 1663d15da7daf6cea77b6d0072849e77428db7a4 (patch) | |
tree | d939beabe37b3b67afb39053448a090f4c25016d /Eigen/src/LU/PartialPivLU.h | |
parent | 274b2272b77fd89bc4151f3ac5e7ccc5f0fad859 (diff) |
Add internal method _solve_impl_transposed() to LU decomposition classes that solves A^T x = b or A^* x = b.
Diffstat (limited to 'Eigen/src/LU/PartialPivLU.h')
-rw-r--r-- | Eigen/src/LU/PartialPivLU.h | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 2c28818a3..91abbc341 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -11,7 +11,7 @@ #ifndef EIGEN_PARTIALLU_H #define EIGEN_PARTIALLU_H -namespace Eigen { +namespace Eigen { namespace internal { template<typename _MatrixType> struct traits<PartialPivLU<_MatrixType> > @@ -185,7 +185,7 @@ template<typename _MatrixType> class PartialPivLU inline Index rows() const { return m_lu.rows(); } inline Index cols() const { return m_lu.cols(); } - + #ifndef EIGEN_PARSED_BY_DOXYGEN template<typename RhsType, typename DstType> EIGEN_DEVICE_FUNC @@ -206,17 +206,44 @@ template<typename _MatrixType> class PartialPivLU m_lu.template triangularView<UnitLower>().solveInPlace(dst); // Step 3 - m_lu.template triangularView<Upper>().solveInPlace(dst); + m_lu.template triangularView<Upper>().solveInPlace(dst); + } + + template<bool Conjugate, typename RhsType, typename DstType> + EIGEN_DEVICE_FUNC + void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const { + /* The decomposition PA = LU can be rewritten as A = P^{-1} L U. + * So we proceed as follows: + * Step 1: compute c = Pb. + * Step 2: replace c by the solution x to Lx = c. + * Step 3: replace c by the solution x to Ux = c. + */ + + eigen_assert(rhs.rows() == m_lu.cols()); + + if (Conjugate) { + // Step 1 + dst = m_lu.template triangularView<Upper>().adjoint().solve(rhs); + // Step 2 + m_lu.template triangularView<UnitLower>().adjoint().solveInPlace(dst); + } else { + // Step 1 + dst = m_lu.template triangularView<Upper>().transpose().solve(rhs); + // Step 2 + m_lu.template triangularView<UnitLower>().transpose().solveInPlace(dst); + } + // Step 3 + dst = permutationP().transpose() * dst; } #endif protected: - + static void check_template_parameters() { EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); } - + MatrixType m_lu; PermutationType m_p; TranspositionType m_rowsTranspositions; @@ -295,7 +322,7 @@ struct partial_lu_impl { Index rrows = rows-k-1; Index rcols = cols-k-1; - + Index row_of_biggest_in_col; Score biggest_in_corner = lu.col(k).tail(rows-k).unaryExpr(Scoring()).maxCoeff(&row_of_biggest_in_col); @@ -436,10 +463,10 @@ template<typename InputType> PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const EigenBase<InputType>& matrix) { check_template_parameters(); - + // the row permutation is stored as int indices, so just to be sure: eigen_assert(matrix.rows()<NumTraits<int>::highest()); - + m_lu = matrix.derived(); eigen_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices"); @@ -492,7 +519,7 @@ struct Assignment<DstXprType, Inverse<PartialPivLU<MatrixType> >, internal::assi typedef PartialPivLU<MatrixType> LuType; typedef Inverse<LuType> SrcXprType; static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) - { + { dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols())); } }; |