1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li // for linear algebra. 3*bf2c3715SXin Li // 4*bf2c3715SXin Li // Copyright (C) 2006-2009 Benoit Jacob <[email protected]> 5*bf2c3715SXin Li // 6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla 7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed 8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9*bf2c3715SXin Li 10*bf2c3715SXin Li #ifndef EIGEN_LU_H 11*bf2c3715SXin Li #define EIGEN_LU_H 12*bf2c3715SXin Li 13*bf2c3715SXin Li namespace Eigen { 14*bf2c3715SXin Li 15*bf2c3715SXin Li namespace internal { 16*bf2c3715SXin Li template<typename _MatrixType> struct traits<FullPivLU<_MatrixType> > 17*bf2c3715SXin Li : traits<_MatrixType> 18*bf2c3715SXin Li { 19*bf2c3715SXin Li typedef MatrixXpr XprKind; 20*bf2c3715SXin Li typedef SolverStorage StorageKind; 21*bf2c3715SXin Li typedef int StorageIndex; 22*bf2c3715SXin Li enum { Flags = 0 }; 23*bf2c3715SXin Li }; 24*bf2c3715SXin Li 25*bf2c3715SXin Li } // end namespace internal 26*bf2c3715SXin Li 27*bf2c3715SXin Li /** \ingroup LU_Module 28*bf2c3715SXin Li * 29*bf2c3715SXin Li * \class FullPivLU 30*bf2c3715SXin Li * 31*bf2c3715SXin Li * \brief LU decomposition of a matrix with complete pivoting, and related features 32*bf2c3715SXin Li * 33*bf2c3715SXin Li * \tparam _MatrixType the type of the matrix of which we are computing the LU decomposition 34*bf2c3715SXin Li * 35*bf2c3715SXin Li * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is 36*bf2c3715SXin Li * decomposed as \f$ A = P^{-1} L U Q^{-1} \f$ where L is unit-lower-triangular, U is 37*bf2c3715SXin Li * upper-triangular, and P and Q are permutation matrices. This is a rank-revealing LU 38*bf2c3715SXin Li * decomposition. The eigenvalues (diagonal coefficients) of U are sorted in such a way that any 39*bf2c3715SXin Li * zeros are at the end. 40*bf2c3715SXin Li * 41*bf2c3715SXin Li * This decomposition provides the generic approach to solving systems of linear equations, computing 42*bf2c3715SXin Li * the rank, invertibility, inverse, kernel, and determinant. 43*bf2c3715SXin Li * 44*bf2c3715SXin Li * This LU decomposition is very stable and well tested with large matrices. However there are use cases where the SVD 45*bf2c3715SXin Li * decomposition is inherently more stable and/or flexible. For example, when computing the kernel of a matrix, 46*bf2c3715SXin Li * working with the SVD allows to select the smallest singular values of the matrix, something that 47*bf2c3715SXin Li * the LU decomposition doesn't see. 48*bf2c3715SXin Li * 49*bf2c3715SXin Li * The data of the LU decomposition can be directly accessed through the methods matrixLU(), 50*bf2c3715SXin Li * permutationP(), permutationQ(). 51*bf2c3715SXin Li * 52*bf2c3715SXin Li * As an example, here is how the original matrix can be retrieved: 53*bf2c3715SXin Li * \include class_FullPivLU.cpp 54*bf2c3715SXin Li * Output: \verbinclude class_FullPivLU.out 55*bf2c3715SXin Li * 56*bf2c3715SXin Li * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism. 57*bf2c3715SXin Li * 58*bf2c3715SXin Li * \sa MatrixBase::fullPivLu(), MatrixBase::determinant(), MatrixBase::inverse() 59*bf2c3715SXin Li */ 60*bf2c3715SXin Li template<typename _MatrixType> class FullPivLU 61*bf2c3715SXin Li : public SolverBase<FullPivLU<_MatrixType> > 62*bf2c3715SXin Li { 63*bf2c3715SXin Li public: 64*bf2c3715SXin Li typedef _MatrixType MatrixType; 65*bf2c3715SXin Li typedef SolverBase<FullPivLU> Base; 66*bf2c3715SXin Li friend class SolverBase<FullPivLU>; 67*bf2c3715SXin Li 68*bf2c3715SXin Li EIGEN_GENERIC_PUBLIC_INTERFACE(FullPivLU) 69*bf2c3715SXin Li enum { 70*bf2c3715SXin Li MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 71*bf2c3715SXin Li MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime 72*bf2c3715SXin Li }; 73*bf2c3715SXin Li typedef typename internal::plain_row_type<MatrixType, StorageIndex>::type IntRowVectorType; 74*bf2c3715SXin Li typedef typename internal::plain_col_type<MatrixType, StorageIndex>::type IntColVectorType; 75*bf2c3715SXin Li typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationQType; 76*bf2c3715SXin Li typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationPType; 77*bf2c3715SXin Li typedef typename MatrixType::PlainObject PlainObject; 78*bf2c3715SXin Li 79*bf2c3715SXin Li /** 80*bf2c3715SXin Li * \brief Default Constructor. 81*bf2c3715SXin Li * 82*bf2c3715SXin Li * The default constructor is useful in cases in which the user intends to 83*bf2c3715SXin Li * perform decompositions via LU::compute(const MatrixType&). 84*bf2c3715SXin Li */ 85*bf2c3715SXin Li FullPivLU(); 86*bf2c3715SXin Li 87*bf2c3715SXin Li /** \brief Default Constructor with memory preallocation 88*bf2c3715SXin Li * 89*bf2c3715SXin Li * Like the default constructor but with preallocation of the internal data 90*bf2c3715SXin Li * according to the specified problem \a size. 91*bf2c3715SXin Li * \sa FullPivLU() 92*bf2c3715SXin Li */ 93*bf2c3715SXin Li FullPivLU(Index rows, Index cols); 94*bf2c3715SXin Li 95*bf2c3715SXin Li /** Constructor. 96*bf2c3715SXin Li * 97*bf2c3715SXin Li * \param matrix the matrix of which to compute the LU decomposition. 98*bf2c3715SXin Li * It is required to be nonzero. 99*bf2c3715SXin Li */ 100*bf2c3715SXin Li template<typename InputType> 101*bf2c3715SXin Li explicit FullPivLU(const EigenBase<InputType>& matrix); 102*bf2c3715SXin Li 103*bf2c3715SXin Li /** \brief Constructs a LU factorization from a given matrix 104*bf2c3715SXin Li * 105*bf2c3715SXin Li * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref. 106*bf2c3715SXin Li * 107*bf2c3715SXin Li * \sa FullPivLU(const EigenBase&) 108*bf2c3715SXin Li */ 109*bf2c3715SXin Li template<typename InputType> 110*bf2c3715SXin Li explicit FullPivLU(EigenBase<InputType>& matrix); 111*bf2c3715SXin Li 112*bf2c3715SXin Li /** Computes the LU decomposition of the given matrix. 113*bf2c3715SXin Li * 114*bf2c3715SXin Li * \param matrix the matrix of which to compute the LU decomposition. 115*bf2c3715SXin Li * It is required to be nonzero. 116*bf2c3715SXin Li * 117*bf2c3715SXin Li * \returns a reference to *this 118*bf2c3715SXin Li */ 119*bf2c3715SXin Li template<typename InputType> 120*bf2c3715SXin Li FullPivLU& compute(const EigenBase<InputType>& matrix) { 121*bf2c3715SXin Li m_lu = matrix.derived(); 122*bf2c3715SXin Li computeInPlace(); 123*bf2c3715SXin Li return *this; 124*bf2c3715SXin Li } 125*bf2c3715SXin Li 126*bf2c3715SXin Li /** \returns the LU decomposition matrix: the upper-triangular part is U, the 127*bf2c3715SXin Li * unit-lower-triangular part is L (at least for square matrices; in the non-square 128*bf2c3715SXin Li * case, special care is needed, see the documentation of class FullPivLU). 129*bf2c3715SXin Li * 130*bf2c3715SXin Li * \sa matrixL(), matrixU() 131*bf2c3715SXin Li */ 132*bf2c3715SXin Li inline const MatrixType& matrixLU() const 133*bf2c3715SXin Li { 134*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 135*bf2c3715SXin Li return m_lu; 136*bf2c3715SXin Li } 137*bf2c3715SXin Li 138*bf2c3715SXin Li /** \returns the number of nonzero pivots in the LU decomposition. 139*bf2c3715SXin Li * Here nonzero is meant in the exact sense, not in a fuzzy sense. 140*bf2c3715SXin Li * So that notion isn't really intrinsically interesting, but it is 141*bf2c3715SXin Li * still useful when implementing algorithms. 142*bf2c3715SXin Li * 143*bf2c3715SXin Li * \sa rank() 144*bf2c3715SXin Li */ 145*bf2c3715SXin Li inline Index nonzeroPivots() const 146*bf2c3715SXin Li { 147*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 148*bf2c3715SXin Li return m_nonzero_pivots; 149*bf2c3715SXin Li } 150*bf2c3715SXin Li 151*bf2c3715SXin Li /** \returns the absolute value of the biggest pivot, i.e. the biggest 152*bf2c3715SXin Li * diagonal coefficient of U. 153*bf2c3715SXin Li */ 154*bf2c3715SXin Li RealScalar maxPivot() const { return m_maxpivot; } 155*bf2c3715SXin Li 156*bf2c3715SXin Li /** \returns the permutation matrix P 157*bf2c3715SXin Li * 158*bf2c3715SXin Li * \sa permutationQ() 159*bf2c3715SXin Li */ 160*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline const PermutationPType& permutationP() const 161*bf2c3715SXin Li { 162*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 163*bf2c3715SXin Li return m_p; 164*bf2c3715SXin Li } 165*bf2c3715SXin Li 166*bf2c3715SXin Li /** \returns the permutation matrix Q 167*bf2c3715SXin Li * 168*bf2c3715SXin Li * \sa permutationP() 169*bf2c3715SXin Li */ 170*bf2c3715SXin Li inline const PermutationQType& permutationQ() const 171*bf2c3715SXin Li { 172*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 173*bf2c3715SXin Li return m_q; 174*bf2c3715SXin Li } 175*bf2c3715SXin Li 176*bf2c3715SXin Li /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix 177*bf2c3715SXin Li * will form a basis of the kernel. 178*bf2c3715SXin Li * 179*bf2c3715SXin Li * \note If the kernel has dimension zero, then the returned matrix is a column-vector filled with zeros. 180*bf2c3715SXin Li * 181*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 182*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 183*bf2c3715SXin Li * setThreshold(const RealScalar&). 184*bf2c3715SXin Li * 185*bf2c3715SXin Li * Example: \include FullPivLU_kernel.cpp 186*bf2c3715SXin Li * Output: \verbinclude FullPivLU_kernel.out 187*bf2c3715SXin Li * 188*bf2c3715SXin Li * \sa image() 189*bf2c3715SXin Li */ 190*bf2c3715SXin Li inline const internal::kernel_retval<FullPivLU> kernel() const 191*bf2c3715SXin Li { 192*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 193*bf2c3715SXin Li return internal::kernel_retval<FullPivLU>(*this); 194*bf2c3715SXin Li } 195*bf2c3715SXin Li 196*bf2c3715SXin Li /** \returns the image of the matrix, also called its column-space. The columns of the returned matrix 197*bf2c3715SXin Li * will form a basis of the image (column-space). 198*bf2c3715SXin Li * 199*bf2c3715SXin Li * \param originalMatrix the original matrix, of which *this is the LU decomposition. 200*bf2c3715SXin Li * The reason why it is needed to pass it here, is that this allows 201*bf2c3715SXin Li * a large optimization, as otherwise this method would need to reconstruct it 202*bf2c3715SXin Li * from the LU decomposition. 203*bf2c3715SXin Li * 204*bf2c3715SXin Li * \note If the image has dimension zero, then the returned matrix is a column-vector filled with zeros. 205*bf2c3715SXin Li * 206*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 207*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 208*bf2c3715SXin Li * setThreshold(const RealScalar&). 209*bf2c3715SXin Li * 210*bf2c3715SXin Li * Example: \include FullPivLU_image.cpp 211*bf2c3715SXin Li * Output: \verbinclude FullPivLU_image.out 212*bf2c3715SXin Li * 213*bf2c3715SXin Li * \sa kernel() 214*bf2c3715SXin Li */ 215*bf2c3715SXin Li inline const internal::image_retval<FullPivLU> 216*bf2c3715SXin Li image(const MatrixType& originalMatrix) const 217*bf2c3715SXin Li { 218*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 219*bf2c3715SXin Li return internal::image_retval<FullPivLU>(*this, originalMatrix); 220*bf2c3715SXin Li } 221*bf2c3715SXin Li 222*bf2c3715SXin Li #ifdef EIGEN_PARSED_BY_DOXYGEN 223*bf2c3715SXin Li /** \return a solution x to the equation Ax=b, where A is the matrix of which 224*bf2c3715SXin Li * *this is the LU decomposition. 225*bf2c3715SXin Li * 226*bf2c3715SXin Li * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix, 227*bf2c3715SXin Li * the only requirement in order for the equation to make sense is that 228*bf2c3715SXin Li * b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition. 229*bf2c3715SXin Li * 230*bf2c3715SXin Li * \returns a solution. 231*bf2c3715SXin Li * 232*bf2c3715SXin Li * \note_about_checking_solutions 233*bf2c3715SXin Li * 234*bf2c3715SXin Li * \note_about_arbitrary_choice_of_solution 235*bf2c3715SXin Li * \note_about_using_kernel_to_study_multiple_solutions 236*bf2c3715SXin Li * 237*bf2c3715SXin Li * Example: \include FullPivLU_solve.cpp 238*bf2c3715SXin Li * Output: \verbinclude FullPivLU_solve.out 239*bf2c3715SXin Li * 240*bf2c3715SXin Li * \sa TriangularView::solve(), kernel(), inverse() 241*bf2c3715SXin Li */ 242*bf2c3715SXin Li template<typename Rhs> 243*bf2c3715SXin Li inline const Solve<FullPivLU, Rhs> 244*bf2c3715SXin Li solve(const MatrixBase<Rhs>& b) const; 245*bf2c3715SXin Li #endif 246*bf2c3715SXin Li 247*bf2c3715SXin Li /** \returns an estimate of the reciprocal condition number of the matrix of which \c *this is 248*bf2c3715SXin Li the LU decomposition. 249*bf2c3715SXin Li */ 250*bf2c3715SXin Li inline RealScalar rcond() const 251*bf2c3715SXin Li { 252*bf2c3715SXin Li eigen_assert(m_isInitialized && "PartialPivLU is not initialized."); 253*bf2c3715SXin Li return internal::rcond_estimate_helper(m_l1_norm, *this); 254*bf2c3715SXin Li } 255*bf2c3715SXin Li 256*bf2c3715SXin Li /** \returns the determinant of the matrix of which 257*bf2c3715SXin Li * *this is the LU decomposition. It has only linear complexity 258*bf2c3715SXin Li * (that is, O(n) where n is the dimension of the square matrix) 259*bf2c3715SXin Li * as the LU decomposition has already been computed. 260*bf2c3715SXin Li * 261*bf2c3715SXin Li * \note This is only for square matrices. 262*bf2c3715SXin Li * 263*bf2c3715SXin Li * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers 264*bf2c3715SXin Li * optimized paths. 265*bf2c3715SXin Li * 266*bf2c3715SXin Li * \warning a determinant can be very big or small, so for matrices 267*bf2c3715SXin Li * of large enough dimension, there is a risk of overflow/underflow. 268*bf2c3715SXin Li * 269*bf2c3715SXin Li * \sa MatrixBase::determinant() 270*bf2c3715SXin Li */ 271*bf2c3715SXin Li typename internal::traits<MatrixType>::Scalar determinant() const; 272*bf2c3715SXin Li 273*bf2c3715SXin Li /** Allows to prescribe a threshold to be used by certain methods, such as rank(), 274*bf2c3715SXin Li * who need to determine when pivots are to be considered nonzero. This is not used for the 275*bf2c3715SXin Li * LU decomposition itself. 276*bf2c3715SXin Li * 277*bf2c3715SXin Li * When it needs to get the threshold value, Eigen calls threshold(). By default, this 278*bf2c3715SXin Li * uses a formula to automatically determine a reasonable threshold. 279*bf2c3715SXin Li * Once you have called the present method setThreshold(const RealScalar&), 280*bf2c3715SXin Li * your value is used instead. 281*bf2c3715SXin Li * 282*bf2c3715SXin Li * \param threshold The new value to use as the threshold. 283*bf2c3715SXin Li * 284*bf2c3715SXin Li * A pivot will be considered nonzero if its absolute value is strictly greater than 285*bf2c3715SXin Li * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$ 286*bf2c3715SXin Li * where maxpivot is the biggest pivot. 287*bf2c3715SXin Li * 288*bf2c3715SXin Li * If you want to come back to the default behavior, call setThreshold(Default_t) 289*bf2c3715SXin Li */ 290*bf2c3715SXin Li FullPivLU& setThreshold(const RealScalar& threshold) 291*bf2c3715SXin Li { 292*bf2c3715SXin Li m_usePrescribedThreshold = true; 293*bf2c3715SXin Li m_prescribedThreshold = threshold; 294*bf2c3715SXin Li return *this; 295*bf2c3715SXin Li } 296*bf2c3715SXin Li 297*bf2c3715SXin Li /** Allows to come back to the default behavior, letting Eigen use its default formula for 298*bf2c3715SXin Li * determining the threshold. 299*bf2c3715SXin Li * 300*bf2c3715SXin Li * You should pass the special object Eigen::Default as parameter here. 301*bf2c3715SXin Li * \code lu.setThreshold(Eigen::Default); \endcode 302*bf2c3715SXin Li * 303*bf2c3715SXin Li * See the documentation of setThreshold(const RealScalar&). 304*bf2c3715SXin Li */ 305*bf2c3715SXin Li FullPivLU& setThreshold(Default_t) 306*bf2c3715SXin Li { 307*bf2c3715SXin Li m_usePrescribedThreshold = false; 308*bf2c3715SXin Li return *this; 309*bf2c3715SXin Li } 310*bf2c3715SXin Li 311*bf2c3715SXin Li /** Returns the threshold that will be used by certain methods such as rank(). 312*bf2c3715SXin Li * 313*bf2c3715SXin Li * See the documentation of setThreshold(const RealScalar&). 314*bf2c3715SXin Li */ 315*bf2c3715SXin Li RealScalar threshold() const 316*bf2c3715SXin Li { 317*bf2c3715SXin Li eigen_assert(m_isInitialized || m_usePrescribedThreshold); 318*bf2c3715SXin Li return m_usePrescribedThreshold ? m_prescribedThreshold 319*bf2c3715SXin Li // this formula comes from experimenting (see "LU precision tuning" thread on the list) 320*bf2c3715SXin Li // and turns out to be identical to Higham's formula used already in LDLt. 321*bf2c3715SXin Li : NumTraits<Scalar>::epsilon() * RealScalar(m_lu.diagonalSize()); 322*bf2c3715SXin Li } 323*bf2c3715SXin Li 324*bf2c3715SXin Li /** \returns the rank of the matrix of which *this is the LU decomposition. 325*bf2c3715SXin Li * 326*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 327*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 328*bf2c3715SXin Li * setThreshold(const RealScalar&). 329*bf2c3715SXin Li */ 330*bf2c3715SXin Li inline Index rank() const 331*bf2c3715SXin Li { 332*bf2c3715SXin Li using std::abs; 333*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 334*bf2c3715SXin Li RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); 335*bf2c3715SXin Li Index result = 0; 336*bf2c3715SXin Li for(Index i = 0; i < m_nonzero_pivots; ++i) 337*bf2c3715SXin Li result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold); 338*bf2c3715SXin Li return result; 339*bf2c3715SXin Li } 340*bf2c3715SXin Li 341*bf2c3715SXin Li /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition. 342*bf2c3715SXin Li * 343*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 344*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 345*bf2c3715SXin Li * setThreshold(const RealScalar&). 346*bf2c3715SXin Li */ 347*bf2c3715SXin Li inline Index dimensionOfKernel() const 348*bf2c3715SXin Li { 349*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 350*bf2c3715SXin Li return cols() - rank(); 351*bf2c3715SXin Li } 352*bf2c3715SXin Li 353*bf2c3715SXin Li /** \returns true if the matrix of which *this is the LU decomposition represents an injective 354*bf2c3715SXin Li * linear map, i.e. has trivial kernel; false otherwise. 355*bf2c3715SXin Li * 356*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 357*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 358*bf2c3715SXin Li * setThreshold(const RealScalar&). 359*bf2c3715SXin Li */ 360*bf2c3715SXin Li inline bool isInjective() const 361*bf2c3715SXin Li { 362*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 363*bf2c3715SXin Li return rank() == cols(); 364*bf2c3715SXin Li } 365*bf2c3715SXin Li 366*bf2c3715SXin Li /** \returns true if the matrix of which *this is the LU decomposition represents a surjective 367*bf2c3715SXin Li * linear map; false otherwise. 368*bf2c3715SXin Li * 369*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 370*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 371*bf2c3715SXin Li * setThreshold(const RealScalar&). 372*bf2c3715SXin Li */ 373*bf2c3715SXin Li inline bool isSurjective() const 374*bf2c3715SXin Li { 375*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 376*bf2c3715SXin Li return rank() == rows(); 377*bf2c3715SXin Li } 378*bf2c3715SXin Li 379*bf2c3715SXin Li /** \returns true if the matrix of which *this is the LU decomposition is invertible. 380*bf2c3715SXin Li * 381*bf2c3715SXin Li * \note This method has to determine which pivots should be considered nonzero. 382*bf2c3715SXin Li * For that, it uses the threshold value that you can control by calling 383*bf2c3715SXin Li * setThreshold(const RealScalar&). 384*bf2c3715SXin Li */ 385*bf2c3715SXin Li inline bool isInvertible() const 386*bf2c3715SXin Li { 387*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 388*bf2c3715SXin Li return isInjective() && (m_lu.rows() == m_lu.cols()); 389*bf2c3715SXin Li } 390*bf2c3715SXin Li 391*bf2c3715SXin Li /** \returns the inverse of the matrix of which *this is the LU decomposition. 392*bf2c3715SXin Li * 393*bf2c3715SXin Li * \note If this matrix is not invertible, the returned matrix has undefined coefficients. 394*bf2c3715SXin Li * Use isInvertible() to first determine whether this matrix is invertible. 395*bf2c3715SXin Li * 396*bf2c3715SXin Li * \sa MatrixBase::inverse() 397*bf2c3715SXin Li */ 398*bf2c3715SXin Li inline const Inverse<FullPivLU> inverse() const 399*bf2c3715SXin Li { 400*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 401*bf2c3715SXin Li eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!"); 402*bf2c3715SXin Li return Inverse<FullPivLU>(*this); 403*bf2c3715SXin Li } 404*bf2c3715SXin Li 405*bf2c3715SXin Li MatrixType reconstructedMatrix() const; 406*bf2c3715SXin Li 407*bf2c3715SXin Li EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 408*bf2c3715SXin Li inline Index rows() const EIGEN_NOEXCEPT { return m_lu.rows(); } 409*bf2c3715SXin Li EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 410*bf2c3715SXin Li inline Index cols() const EIGEN_NOEXCEPT { return m_lu.cols(); } 411*bf2c3715SXin Li 412*bf2c3715SXin Li #ifndef EIGEN_PARSED_BY_DOXYGEN 413*bf2c3715SXin Li template<typename RhsType, typename DstType> 414*bf2c3715SXin Li void _solve_impl(const RhsType &rhs, DstType &dst) const; 415*bf2c3715SXin Li 416*bf2c3715SXin Li template<bool Conjugate, typename RhsType, typename DstType> 417*bf2c3715SXin Li void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const; 418*bf2c3715SXin Li #endif 419*bf2c3715SXin Li 420*bf2c3715SXin Li protected: 421*bf2c3715SXin Li 422*bf2c3715SXin Li static void check_template_parameters() 423*bf2c3715SXin Li { 424*bf2c3715SXin Li EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); 425*bf2c3715SXin Li } 426*bf2c3715SXin Li 427*bf2c3715SXin Li void computeInPlace(); 428*bf2c3715SXin Li 429*bf2c3715SXin Li MatrixType m_lu; 430*bf2c3715SXin Li PermutationPType m_p; 431*bf2c3715SXin Li PermutationQType m_q; 432*bf2c3715SXin Li IntColVectorType m_rowsTranspositions; 433*bf2c3715SXin Li IntRowVectorType m_colsTranspositions; 434*bf2c3715SXin Li Index m_nonzero_pivots; 435*bf2c3715SXin Li RealScalar m_l1_norm; 436*bf2c3715SXin Li RealScalar m_maxpivot, m_prescribedThreshold; 437*bf2c3715SXin Li signed char m_det_pq; 438*bf2c3715SXin Li bool m_isInitialized, m_usePrescribedThreshold; 439*bf2c3715SXin Li }; 440*bf2c3715SXin Li 441*bf2c3715SXin Li template<typename MatrixType> 442*bf2c3715SXin Li FullPivLU<MatrixType>::FullPivLU() 443*bf2c3715SXin Li : m_isInitialized(false), m_usePrescribedThreshold(false) 444*bf2c3715SXin Li { 445*bf2c3715SXin Li } 446*bf2c3715SXin Li 447*bf2c3715SXin Li template<typename MatrixType> 448*bf2c3715SXin Li FullPivLU<MatrixType>::FullPivLU(Index rows, Index cols) 449*bf2c3715SXin Li : m_lu(rows, cols), 450*bf2c3715SXin Li m_p(rows), 451*bf2c3715SXin Li m_q(cols), 452*bf2c3715SXin Li m_rowsTranspositions(rows), 453*bf2c3715SXin Li m_colsTranspositions(cols), 454*bf2c3715SXin Li m_isInitialized(false), 455*bf2c3715SXin Li m_usePrescribedThreshold(false) 456*bf2c3715SXin Li { 457*bf2c3715SXin Li } 458*bf2c3715SXin Li 459*bf2c3715SXin Li template<typename MatrixType> 460*bf2c3715SXin Li template<typename InputType> 461*bf2c3715SXin Li FullPivLU<MatrixType>::FullPivLU(const EigenBase<InputType>& matrix) 462*bf2c3715SXin Li : m_lu(matrix.rows(), matrix.cols()), 463*bf2c3715SXin Li m_p(matrix.rows()), 464*bf2c3715SXin Li m_q(matrix.cols()), 465*bf2c3715SXin Li m_rowsTranspositions(matrix.rows()), 466*bf2c3715SXin Li m_colsTranspositions(matrix.cols()), 467*bf2c3715SXin Li m_isInitialized(false), 468*bf2c3715SXin Li m_usePrescribedThreshold(false) 469*bf2c3715SXin Li { 470*bf2c3715SXin Li compute(matrix.derived()); 471*bf2c3715SXin Li } 472*bf2c3715SXin Li 473*bf2c3715SXin Li template<typename MatrixType> 474*bf2c3715SXin Li template<typename InputType> 475*bf2c3715SXin Li FullPivLU<MatrixType>::FullPivLU(EigenBase<InputType>& matrix) 476*bf2c3715SXin Li : m_lu(matrix.derived()), 477*bf2c3715SXin Li m_p(matrix.rows()), 478*bf2c3715SXin Li m_q(matrix.cols()), 479*bf2c3715SXin Li m_rowsTranspositions(matrix.rows()), 480*bf2c3715SXin Li m_colsTranspositions(matrix.cols()), 481*bf2c3715SXin Li m_isInitialized(false), 482*bf2c3715SXin Li m_usePrescribedThreshold(false) 483*bf2c3715SXin Li { 484*bf2c3715SXin Li computeInPlace(); 485*bf2c3715SXin Li } 486*bf2c3715SXin Li 487*bf2c3715SXin Li template<typename MatrixType> 488*bf2c3715SXin Li void FullPivLU<MatrixType>::computeInPlace() 489*bf2c3715SXin Li { 490*bf2c3715SXin Li check_template_parameters(); 491*bf2c3715SXin Li 492*bf2c3715SXin Li // the permutations are stored as int indices, so just to be sure: 493*bf2c3715SXin Li eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest()); 494*bf2c3715SXin Li 495*bf2c3715SXin Li m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff(); 496*bf2c3715SXin Li 497*bf2c3715SXin Li const Index size = m_lu.diagonalSize(); 498*bf2c3715SXin Li const Index rows = m_lu.rows(); 499*bf2c3715SXin Li const Index cols = m_lu.cols(); 500*bf2c3715SXin Li 501*bf2c3715SXin Li // will store the transpositions, before we accumulate them at the end. 502*bf2c3715SXin Li // can't accumulate on-the-fly because that will be done in reverse order for the rows. 503*bf2c3715SXin Li m_rowsTranspositions.resize(m_lu.rows()); 504*bf2c3715SXin Li m_colsTranspositions.resize(m_lu.cols()); 505*bf2c3715SXin Li Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i 506*bf2c3715SXin Li 507*bf2c3715SXin Li m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) 508*bf2c3715SXin Li m_maxpivot = RealScalar(0); 509*bf2c3715SXin Li 510*bf2c3715SXin Li for(Index k = 0; k < size; ++k) 511*bf2c3715SXin Li { 512*bf2c3715SXin Li // First, we need to find the pivot. 513*bf2c3715SXin Li 514*bf2c3715SXin Li // biggest coefficient in the remaining bottom-right corner (starting at row k, col k) 515*bf2c3715SXin Li Index row_of_biggest_in_corner, col_of_biggest_in_corner; 516*bf2c3715SXin Li typedef internal::scalar_score_coeff_op<Scalar> Scoring; 517*bf2c3715SXin Li typedef typename Scoring::result_type Score; 518*bf2c3715SXin Li Score biggest_in_corner; 519*bf2c3715SXin Li biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k) 520*bf2c3715SXin Li .unaryExpr(Scoring()) 521*bf2c3715SXin Li .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); 522*bf2c3715SXin Li row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner, 523*bf2c3715SXin Li col_of_biggest_in_corner += k; // need to add k to them. 524*bf2c3715SXin Li 525*bf2c3715SXin Li if(biggest_in_corner==Score(0)) 526*bf2c3715SXin Li { 527*bf2c3715SXin Li // before exiting, make sure to initialize the still uninitialized transpositions 528*bf2c3715SXin Li // in a sane state without destroying what we already have. 529*bf2c3715SXin Li m_nonzero_pivots = k; 530*bf2c3715SXin Li for(Index i = k; i < size; ++i) 531*bf2c3715SXin Li { 532*bf2c3715SXin Li m_rowsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i); 533*bf2c3715SXin Li m_colsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i); 534*bf2c3715SXin Li } 535*bf2c3715SXin Li break; 536*bf2c3715SXin Li } 537*bf2c3715SXin Li 538*bf2c3715SXin Li RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner); 539*bf2c3715SXin Li if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot; 540*bf2c3715SXin Li 541*bf2c3715SXin Li // Now that we've found the pivot, we need to apply the row/col swaps to 542*bf2c3715SXin Li // bring it to the location (k,k). 543*bf2c3715SXin Li 544*bf2c3715SXin Li m_rowsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(row_of_biggest_in_corner); 545*bf2c3715SXin Li m_colsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(col_of_biggest_in_corner); 546*bf2c3715SXin Li if(k != row_of_biggest_in_corner) { 547*bf2c3715SXin Li m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner)); 548*bf2c3715SXin Li ++number_of_transpositions; 549*bf2c3715SXin Li } 550*bf2c3715SXin Li if(k != col_of_biggest_in_corner) { 551*bf2c3715SXin Li m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner)); 552*bf2c3715SXin Li ++number_of_transpositions; 553*bf2c3715SXin Li } 554*bf2c3715SXin Li 555*bf2c3715SXin Li // Now that the pivot is at the right location, we update the remaining 556*bf2c3715SXin Li // bottom-right corner by Gaussian elimination. 557*bf2c3715SXin Li 558*bf2c3715SXin Li if(k<rows-1) 559*bf2c3715SXin Li m_lu.col(k).tail(rows-k-1) /= m_lu.coeff(k,k); 560*bf2c3715SXin Li if(k<size-1) 561*bf2c3715SXin Li m_lu.block(k+1,k+1,rows-k-1,cols-k-1).noalias() -= m_lu.col(k).tail(rows-k-1) * m_lu.row(k).tail(cols-k-1); 562*bf2c3715SXin Li } 563*bf2c3715SXin Li 564*bf2c3715SXin Li // the main loop is over, we still have to accumulate the transpositions to find the 565*bf2c3715SXin Li // permutations P and Q 566*bf2c3715SXin Li 567*bf2c3715SXin Li m_p.setIdentity(rows); 568*bf2c3715SXin Li for(Index k = size-1; k >= 0; --k) 569*bf2c3715SXin Li m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k)); 570*bf2c3715SXin Li 571*bf2c3715SXin Li m_q.setIdentity(cols); 572*bf2c3715SXin Li for(Index k = 0; k < size; ++k) 573*bf2c3715SXin Li m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k)); 574*bf2c3715SXin Li 575*bf2c3715SXin Li m_det_pq = (number_of_transpositions%2) ? -1 : 1; 576*bf2c3715SXin Li 577*bf2c3715SXin Li m_isInitialized = true; 578*bf2c3715SXin Li } 579*bf2c3715SXin Li 580*bf2c3715SXin Li template<typename MatrixType> 581*bf2c3715SXin Li typename internal::traits<MatrixType>::Scalar FullPivLU<MatrixType>::determinant() const 582*bf2c3715SXin Li { 583*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 584*bf2c3715SXin Li eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!"); 585*bf2c3715SXin Li return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod()); 586*bf2c3715SXin Li } 587*bf2c3715SXin Li 588*bf2c3715SXin Li /** \returns the matrix represented by the decomposition, 589*bf2c3715SXin Li * i.e., it returns the product: \f$ P^{-1} L U Q^{-1} \f$. 590*bf2c3715SXin Li * This function is provided for debug purposes. */ 591*bf2c3715SXin Li template<typename MatrixType> 592*bf2c3715SXin Li MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const 593*bf2c3715SXin Li { 594*bf2c3715SXin Li eigen_assert(m_isInitialized && "LU is not initialized."); 595*bf2c3715SXin Li const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols()); 596*bf2c3715SXin Li // LU 597*bf2c3715SXin Li MatrixType res(m_lu.rows(),m_lu.cols()); 598*bf2c3715SXin Li // FIXME the .toDenseMatrix() should not be needed... 599*bf2c3715SXin Li res = m_lu.leftCols(smalldim) 600*bf2c3715SXin Li .template triangularView<UnitLower>().toDenseMatrix() 601*bf2c3715SXin Li * m_lu.topRows(smalldim) 602*bf2c3715SXin Li .template triangularView<Upper>().toDenseMatrix(); 603*bf2c3715SXin Li 604*bf2c3715SXin Li // P^{-1}(LU) 605*bf2c3715SXin Li res = m_p.inverse() * res; 606*bf2c3715SXin Li 607*bf2c3715SXin Li // (P^{-1}LU)Q^{-1} 608*bf2c3715SXin Li res = res * m_q.inverse(); 609*bf2c3715SXin Li 610*bf2c3715SXin Li return res; 611*bf2c3715SXin Li } 612*bf2c3715SXin Li 613*bf2c3715SXin Li /********* Implementation of kernel() **************************************************/ 614*bf2c3715SXin Li 615*bf2c3715SXin Li namespace internal { 616*bf2c3715SXin Li template<typename _MatrixType> 617*bf2c3715SXin Li struct kernel_retval<FullPivLU<_MatrixType> > 618*bf2c3715SXin Li : kernel_retval_base<FullPivLU<_MatrixType> > 619*bf2c3715SXin Li { 620*bf2c3715SXin Li EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>) 621*bf2c3715SXin Li 622*bf2c3715SXin Li enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED( 623*bf2c3715SXin Li MatrixType::MaxColsAtCompileTime, 624*bf2c3715SXin Li MatrixType::MaxRowsAtCompileTime) 625*bf2c3715SXin Li }; 626*bf2c3715SXin Li 627*bf2c3715SXin Li template<typename Dest> void evalTo(Dest& dst) const 628*bf2c3715SXin Li { 629*bf2c3715SXin Li using std::abs; 630*bf2c3715SXin Li const Index cols = dec().matrixLU().cols(), dimker = cols - rank(); 631*bf2c3715SXin Li if(dimker == 0) 632*bf2c3715SXin Li { 633*bf2c3715SXin Li // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's 634*bf2c3715SXin Li // avoid crashing/asserting as that depends on floating point calculations. Let's 635*bf2c3715SXin Li // just return a single column vector filled with zeros. 636*bf2c3715SXin Li dst.setZero(); 637*bf2c3715SXin Li return; 638*bf2c3715SXin Li } 639*bf2c3715SXin Li 640*bf2c3715SXin Li /* Let us use the following lemma: 641*bf2c3715SXin Li * 642*bf2c3715SXin Li * Lemma: If the matrix A has the LU decomposition PAQ = LU, 643*bf2c3715SXin Li * then Ker A = Q(Ker U). 644*bf2c3715SXin Li * 645*bf2c3715SXin Li * Proof: trivial: just keep in mind that P, Q, L are invertible. 646*bf2c3715SXin Li */ 647*bf2c3715SXin Li 648*bf2c3715SXin Li /* Thus, all we need to do is to compute Ker U, and then apply Q. 649*bf2c3715SXin Li * 650*bf2c3715SXin Li * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end. 651*bf2c3715SXin Li * Thus, the diagonal of U ends with exactly 652*bf2c3715SXin Li * dimKer zero's. Let us use that to construct dimKer linearly 653*bf2c3715SXin Li * independent vectors in Ker U. 654*bf2c3715SXin Li */ 655*bf2c3715SXin Li 656*bf2c3715SXin Li Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank()); 657*bf2c3715SXin Li RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold(); 658*bf2c3715SXin Li Index p = 0; 659*bf2c3715SXin Li for(Index i = 0; i < dec().nonzeroPivots(); ++i) 660*bf2c3715SXin Li if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold) 661*bf2c3715SXin Li pivots.coeffRef(p++) = i; 662*bf2c3715SXin Li eigen_internal_assert(p == rank()); 663*bf2c3715SXin Li 664*bf2c3715SXin Li // we construct a temporaty trapezoid matrix m, by taking the U matrix and 665*bf2c3715SXin Li // permuting the rows and cols to bring the nonnegligible pivots to the top of 666*bf2c3715SXin Li // the main diagonal. We need that to be able to apply our triangular solvers. 667*bf2c3715SXin Li // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified 668*bf2c3715SXin Li Matrix<typename MatrixType::Scalar, Dynamic, Dynamic, MatrixType::Options, 669*bf2c3715SXin Li MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime> 670*bf2c3715SXin Li m(dec().matrixLU().block(0, 0, rank(), cols)); 671*bf2c3715SXin Li for(Index i = 0; i < rank(); ++i) 672*bf2c3715SXin Li { 673*bf2c3715SXin Li if(i) m.row(i).head(i).setZero(); 674*bf2c3715SXin Li m.row(i).tail(cols-i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols-i); 675*bf2c3715SXin Li } 676*bf2c3715SXin Li m.block(0, 0, rank(), rank()); 677*bf2c3715SXin Li m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero(); 678*bf2c3715SXin Li for(Index i = 0; i < rank(); ++i) 679*bf2c3715SXin Li m.col(i).swap(m.col(pivots.coeff(i))); 680*bf2c3715SXin Li 681*bf2c3715SXin Li // ok, we have our trapezoid matrix, we can apply the triangular solver. 682*bf2c3715SXin Li // notice that the math behind this suggests that we should apply this to the 683*bf2c3715SXin Li // negative of the RHS, but for performance we just put the negative sign elsewhere, see below. 684*bf2c3715SXin Li m.topLeftCorner(rank(), rank()) 685*bf2c3715SXin Li .template triangularView<Upper>().solveInPlace( 686*bf2c3715SXin Li m.topRightCorner(rank(), dimker) 687*bf2c3715SXin Li ); 688*bf2c3715SXin Li 689*bf2c3715SXin Li // now we must undo the column permutation that we had applied! 690*bf2c3715SXin Li for(Index i = rank()-1; i >= 0; --i) 691*bf2c3715SXin Li m.col(i).swap(m.col(pivots.coeff(i))); 692*bf2c3715SXin Li 693*bf2c3715SXin Li // see the negative sign in the next line, that's what we were talking about above. 694*bf2c3715SXin Li for(Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker); 695*bf2c3715SXin Li for(Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); 696*bf2c3715SXin Li for(Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1); 697*bf2c3715SXin Li } 698*bf2c3715SXin Li }; 699*bf2c3715SXin Li 700*bf2c3715SXin Li /***** Implementation of image() *****************************************************/ 701*bf2c3715SXin Li 702*bf2c3715SXin Li template<typename _MatrixType> 703*bf2c3715SXin Li struct image_retval<FullPivLU<_MatrixType> > 704*bf2c3715SXin Li : image_retval_base<FullPivLU<_MatrixType> > 705*bf2c3715SXin Li { 706*bf2c3715SXin Li EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>) 707*bf2c3715SXin Li 708*bf2c3715SXin Li enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED( 709*bf2c3715SXin Li MatrixType::MaxColsAtCompileTime, 710*bf2c3715SXin Li MatrixType::MaxRowsAtCompileTime) 711*bf2c3715SXin Li }; 712*bf2c3715SXin Li 713*bf2c3715SXin Li template<typename Dest> void evalTo(Dest& dst) const 714*bf2c3715SXin Li { 715*bf2c3715SXin Li using std::abs; 716*bf2c3715SXin Li if(rank() == 0) 717*bf2c3715SXin Li { 718*bf2c3715SXin Li // The Image is just {0}, so it doesn't have a basis properly speaking, but let's 719*bf2c3715SXin Li // avoid crashing/asserting as that depends on floating point calculations. Let's 720*bf2c3715SXin Li // just return a single column vector filled with zeros. 721*bf2c3715SXin Li dst.setZero(); 722*bf2c3715SXin Li return; 723*bf2c3715SXin Li } 724*bf2c3715SXin Li 725*bf2c3715SXin Li Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank()); 726*bf2c3715SXin Li RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold(); 727*bf2c3715SXin Li Index p = 0; 728*bf2c3715SXin Li for(Index i = 0; i < dec().nonzeroPivots(); ++i) 729*bf2c3715SXin Li if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold) 730*bf2c3715SXin Li pivots.coeffRef(p++) = i; 731*bf2c3715SXin Li eigen_internal_assert(p == rank()); 732*bf2c3715SXin Li 733*bf2c3715SXin Li for(Index i = 0; i < rank(); ++i) 734*bf2c3715SXin Li dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i))); 735*bf2c3715SXin Li } 736*bf2c3715SXin Li }; 737*bf2c3715SXin Li 738*bf2c3715SXin Li /***** Implementation of solve() *****************************************************/ 739*bf2c3715SXin Li 740*bf2c3715SXin Li } // end namespace internal 741*bf2c3715SXin Li 742*bf2c3715SXin Li #ifndef EIGEN_PARSED_BY_DOXYGEN 743*bf2c3715SXin Li template<typename _MatrixType> 744*bf2c3715SXin Li template<typename RhsType, typename DstType> 745*bf2c3715SXin Li void FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const 746*bf2c3715SXin Li { 747*bf2c3715SXin Li /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}. 748*bf2c3715SXin Li * So we proceed as follows: 749*bf2c3715SXin Li * Step 1: compute c = P * rhs. 750*bf2c3715SXin Li * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible. 751*bf2c3715SXin Li * Step 3: replace c by the solution x to Ux = c. May or may not exist. 752*bf2c3715SXin Li * Step 4: result = Q * c; 753*bf2c3715SXin Li */ 754*bf2c3715SXin Li 755*bf2c3715SXin Li const Index rows = this->rows(), 756*bf2c3715SXin Li cols = this->cols(), 757*bf2c3715SXin Li nonzero_pivots = this->rank(); 758*bf2c3715SXin Li const Index smalldim = (std::min)(rows, cols); 759*bf2c3715SXin Li 760*bf2c3715SXin Li if(nonzero_pivots == 0) 761*bf2c3715SXin Li { 762*bf2c3715SXin Li dst.setZero(); 763*bf2c3715SXin Li return; 764*bf2c3715SXin Li } 765*bf2c3715SXin Li 766*bf2c3715SXin Li typename RhsType::PlainObject c(rhs.rows(), rhs.cols()); 767*bf2c3715SXin Li 768*bf2c3715SXin Li // Step 1 769*bf2c3715SXin Li c = permutationP() * rhs; 770*bf2c3715SXin Li 771*bf2c3715SXin Li // Step 2 772*bf2c3715SXin Li m_lu.topLeftCorner(smalldim,smalldim) 773*bf2c3715SXin Li .template triangularView<UnitLower>() 774*bf2c3715SXin Li .solveInPlace(c.topRows(smalldim)); 775*bf2c3715SXin Li if(rows>cols) 776*bf2c3715SXin Li c.bottomRows(rows-cols) -= m_lu.bottomRows(rows-cols) * c.topRows(cols); 777*bf2c3715SXin Li 778*bf2c3715SXin Li // Step 3 779*bf2c3715SXin Li m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots) 780*bf2c3715SXin Li .template triangularView<Upper>() 781*bf2c3715SXin Li .solveInPlace(c.topRows(nonzero_pivots)); 782*bf2c3715SXin Li 783*bf2c3715SXin Li // Step 4 784*bf2c3715SXin Li for(Index i = 0; i < nonzero_pivots; ++i) 785*bf2c3715SXin Li dst.row(permutationQ().indices().coeff(i)) = c.row(i); 786*bf2c3715SXin Li for(Index i = nonzero_pivots; i < m_lu.cols(); ++i) 787*bf2c3715SXin Li dst.row(permutationQ().indices().coeff(i)).setZero(); 788*bf2c3715SXin Li } 789*bf2c3715SXin Li 790*bf2c3715SXin Li template<typename _MatrixType> 791*bf2c3715SXin Li template<bool Conjugate, typename RhsType, typename DstType> 792*bf2c3715SXin Li void FullPivLU<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const 793*bf2c3715SXin Li { 794*bf2c3715SXin Li /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}, 795*bf2c3715SXin Li * and since permutations are real and unitary, we can write this 796*bf2c3715SXin Li * as A^T = Q U^T L^T P, 797*bf2c3715SXin Li * So we proceed as follows: 798*bf2c3715SXin Li * Step 1: compute c = Q^T rhs. 799*bf2c3715SXin Li * Step 2: replace c by the solution x to U^T x = c. May or may not exist. 800*bf2c3715SXin Li * Step 3: replace c by the solution x to L^T x = c. 801*bf2c3715SXin Li * Step 4: result = P^T c. 802*bf2c3715SXin Li * If Conjugate is true, replace "^T" by "^*" above. 803*bf2c3715SXin Li */ 804*bf2c3715SXin Li 805*bf2c3715SXin Li const Index rows = this->rows(), cols = this->cols(), 806*bf2c3715SXin Li nonzero_pivots = this->rank(); 807*bf2c3715SXin Li const Index smalldim = (std::min)(rows, cols); 808*bf2c3715SXin Li 809*bf2c3715SXin Li if(nonzero_pivots == 0) 810*bf2c3715SXin Li { 811*bf2c3715SXin Li dst.setZero(); 812*bf2c3715SXin Li return; 813*bf2c3715SXin Li } 814*bf2c3715SXin Li 815*bf2c3715SXin Li typename RhsType::PlainObject c(rhs.rows(), rhs.cols()); 816*bf2c3715SXin Li 817*bf2c3715SXin Li // Step 1 818*bf2c3715SXin Li c = permutationQ().inverse() * rhs; 819*bf2c3715SXin Li 820*bf2c3715SXin Li // Step 2 821*bf2c3715SXin Li m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots) 822*bf2c3715SXin Li .template triangularView<Upper>() 823*bf2c3715SXin Li .transpose() 824*bf2c3715SXin Li .template conjugateIf<Conjugate>() 825*bf2c3715SXin Li .solveInPlace(c.topRows(nonzero_pivots)); 826*bf2c3715SXin Li 827*bf2c3715SXin Li // Step 3 828*bf2c3715SXin Li m_lu.topLeftCorner(smalldim, smalldim) 829*bf2c3715SXin Li .template triangularView<UnitLower>() 830*bf2c3715SXin Li .transpose() 831*bf2c3715SXin Li .template conjugateIf<Conjugate>() 832*bf2c3715SXin Li .solveInPlace(c.topRows(smalldim)); 833*bf2c3715SXin Li 834*bf2c3715SXin Li // Step 4 835*bf2c3715SXin Li PermutationPType invp = permutationP().inverse().eval(); 836*bf2c3715SXin Li for(Index i = 0; i < smalldim; ++i) 837*bf2c3715SXin Li dst.row(invp.indices().coeff(i)) = c.row(i); 838*bf2c3715SXin Li for(Index i = smalldim; i < rows; ++i) 839*bf2c3715SXin Li dst.row(invp.indices().coeff(i)).setZero(); 840*bf2c3715SXin Li } 841*bf2c3715SXin Li 842*bf2c3715SXin Li #endif 843*bf2c3715SXin Li 844*bf2c3715SXin Li namespace internal { 845*bf2c3715SXin Li 846*bf2c3715SXin Li 847*bf2c3715SXin Li /***** Implementation of inverse() *****************************************************/ 848*bf2c3715SXin Li template<typename DstXprType, typename MatrixType> 849*bf2c3715SXin Li struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename FullPivLU<MatrixType>::Scalar>, Dense2Dense> 850*bf2c3715SXin Li { 851*bf2c3715SXin Li typedef FullPivLU<MatrixType> LuType; 852*bf2c3715SXin Li typedef Inverse<LuType> SrcXprType; 853*bf2c3715SXin Li static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename MatrixType::Scalar> &) 854*bf2c3715SXin Li { 855*bf2c3715SXin Li dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols())); 856*bf2c3715SXin Li } 857*bf2c3715SXin Li }; 858*bf2c3715SXin Li } // end namespace internal 859*bf2c3715SXin Li 860*bf2c3715SXin Li /******* MatrixBase methods *****************************************************************/ 861*bf2c3715SXin Li 862*bf2c3715SXin Li /** \lu_module 863*bf2c3715SXin Li * 864*bf2c3715SXin Li * \return the full-pivoting LU decomposition of \c *this. 865*bf2c3715SXin Li * 866*bf2c3715SXin Li * \sa class FullPivLU 867*bf2c3715SXin Li */ 868*bf2c3715SXin Li template<typename Derived> 869*bf2c3715SXin Li inline const FullPivLU<typename MatrixBase<Derived>::PlainObject> 870*bf2c3715SXin Li MatrixBase<Derived>::fullPivLu() const 871*bf2c3715SXin Li { 872*bf2c3715SXin Li return FullPivLU<PlainObject>(eval()); 873*bf2c3715SXin Li } 874*bf2c3715SXin Li 875*bf2c3715SXin Li } // end namespace Eigen 876*bf2c3715SXin Li 877*bf2c3715SXin Li #endif // EIGEN_LU_H 878