cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

FullPivLU.h (32383B)


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