1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_LU_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_LU_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen {
142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename _MatrixType> struct traits<FullPivLU<_MatrixType> >
172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : traits<_MatrixType>
182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef MatrixXpr XprKind;
202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef SolverStorage StorageKind;
212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { Flags = 0 };
222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup LU_Module
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \class FullPivLU
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief LU decomposition of a matrix with complete pivoting, and related features
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \tparam _MatrixType the type of the matrix of which we are computing the LU decomposition
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * decomposed as \f$ A = P^{-1} L U Q^{-1} \f$ where L is unit-lower-triangular, U is
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * upper-triangular, and P and Q are permutation matrices. This is a rank-revealing LU
377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * decomposition. The eigenvalues (diagonal coefficients) of U are sorted in such a way that any
387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  * zeros are at the end.
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This decomposition provides the generic approach to solving systems of linear equations, computing
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * the rank, invertibility, inverse, kernel, and determinant.
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This LU decomposition is very stable and well tested with large matrices. However there are use cases where the SVD
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * decomposition is inherently more stable and/or flexible. For example, when computing the kernel of a matrix,
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * working with the SVD allows to select the smallest singular values of the matrix, something that
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * the LU decomposition doesn't see.
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * The data of the LU decomposition can be directly accessed through the methods matrixLU(),
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * permutationP(), permutationQ().
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * As an exemple, here is how the original matrix can be retrieved:
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \include class_FullPivLU.cpp
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Output: \verbinclude class_FullPivLU.out
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa MatrixBase::fullPivLu(), MatrixBase::determinant(), MatrixBase::inverse()
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType> class FullPivLU
602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  : public SolverBase<FullPivLU<_MatrixType> >
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef _MatrixType MatrixType;
642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef SolverBase<FullPivLU> Base;
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_GENERIC_PUBLIC_INTERFACE(FullPivLU)
672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // FIXME StorageIndex defined in EIGEN_GENERIC_PUBLIC_INTERFACE should be int
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename internal::plain_row_type<MatrixType, StorageIndex>::type IntRowVectorType;
732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename internal::plain_col_type<MatrixType, StorageIndex>::type IntColVectorType;
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationQType;
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationPType;
762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename MatrixType::PlainObject PlainObject;
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /**
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \brief Default Constructor.
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * The default constructor is useful in cases in which the user intends to
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * perform decompositions via LU::compute(const MatrixType&).
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    FullPivLU();
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \brief Default Constructor with memory preallocation
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Like the default constructor but with preallocation of the internal data
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * according to the specified problem \a size.
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa FullPivLU()
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    FullPivLU(Index rows, Index cols);
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Constructor.
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \param matrix the matrix of which to compute the LU decomposition.
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *               It is required to be nonzero.
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename InputType>
1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    explicit FullPivLU(const EigenBase<InputType>& matrix);
1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /** \brief Constructs a LU factorization from a given matrix
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      *
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      *
1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      * \sa FullPivLU(const EigenBase&)
1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      */
1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename InputType>
1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    explicit FullPivLU(EigenBase<InputType>& matrix);
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Computes the LU decomposition of the given matrix.
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \param matrix the matrix of which to compute the LU decomposition.
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *               It is required to be nonzero.
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \returns a reference to *this
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename InputType>
1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    FullPivLU& compute(const EigenBase<InputType>& matrix) {
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      m_lu = matrix.derived();
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      computeInPlace();
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return *this;
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the LU decomposition matrix: the upper-triangular part is U, the
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * unit-lower-triangular part is L (at least for square matrices; in the non-square
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * case, special care is needed, see the documentation of class FullPivLU).
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa matrixL(), matrixU()
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const MatrixType& matrixLU() const
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_lu;
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the number of nonzero pivots in the LU decomposition.
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Here nonzero is meant in the exact sense, not in a fuzzy sense.
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * So that notion isn't really intrinsically interesting, but it is
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * still useful when implementing algorithms.
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa rank()
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index nonzeroPivots() const
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_nonzero_pivots;
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the absolute value of the biggest pivot, i.e. the biggest
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          diagonal coefficient of U.
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar maxPivot() const { return m_maxpivot; }
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the permutation matrix P
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa permutationQ()
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC inline const PermutationPType& permutationP() const
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_p;
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the permutation matrix Q
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa permutationP()
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const PermutationQType& permutationQ() const
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_q;
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * will form a basis of the kernel.
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note If the kernel has dimension zero, then the returned matrix is a column-vector filled with zeros.
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Example: \include FullPivLU_kernel.cpp
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Output: \verbinclude FullPivLU_kernel.out
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa image()
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const internal::kernel_retval<FullPivLU> kernel() const
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return internal::kernel_retval<FullPivLU>(*this);
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the image of the matrix, also called its column-space. The columns of the returned matrix
1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      * will form a basis of the image (column-space).
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \param originalMatrix the original matrix, of which *this is the LU decomposition.
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *                       The reason why it is needed to pass it here, is that this allows
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *                       a large optimization, as otherwise this method would need to reconstruct it
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *                       from the LU decomposition.
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note If the image has dimension zero, then the returned matrix is a column-vector filled with zeros.
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Example: \include FullPivLU_image.cpp
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Output: \verbinclude FullPivLU_image.out
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa kernel()
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const internal::image_retval<FullPivLU>
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      image(const MatrixType& originalMatrix) const
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return internal::image_retval<FullPivLU>(*this, originalMatrix);
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \return a solution x to the equation Ax=b, where A is the matrix of which
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * *this is the LU decomposition.
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix,
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          the only requirement in order for the equation to make sense is that
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition.
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \returns a solution.
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note_about_checking_solutions
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note_about_arbitrary_choice_of_solution
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note_about_using_kernel_to_study_multiple_solutions
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Example: \include FullPivLU_solve.cpp
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Output: \verbinclude FullPivLU_solve.out
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa TriangularView::solve(), kernel(), inverse()
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // FIXME this is a copy-paste of the base-class member to add the isInitialized assertion.
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Rhs>
2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    inline const Solve<FullPivLU, Rhs>
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    solve(const MatrixBase<Rhs>& b) const
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return Solve<FullPivLU, Rhs>(*this, b.derived());
2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    }
2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /** \returns an estimate of the reciprocal condition number of the matrix of which \c *this is
2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        the LU decomposition.
2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      */
2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    inline RealScalar rcond() const
2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    {
2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return internal::rcond_estimate_helper(m_l1_norm, *this);
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the determinant of the matrix of which
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * *this is the LU decomposition. It has only linear complexity
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * (that is, O(n) where n is the dimension of the square matrix)
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * as the LU decomposition has already been computed.
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This is only for square matrices.
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       optimized paths.
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \warning a determinant can be very big or small, so for matrices
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * of large enough dimension, there is a risk of overflow/underflow.
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa MatrixBase::determinant()
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::traits<MatrixType>::Scalar determinant() const;
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * who need to determine when pivots are to be considered nonzero. This is not used for the
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * LU decomposition itself.
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * uses a formula to automatically determine a reasonable threshold.
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Once you have called the present method setThreshold(const RealScalar&),
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * your value is used instead.
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \param threshold The new value to use as the threshold.
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * A pivot will be considered nonzero if its absolute value is strictly greater than
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * where maxpivot is the biggest pivot.
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * If you want to come back to the default behavior, call setThreshold(Default_t)
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    FullPivLU& setThreshold(const RealScalar& threshold)
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_usePrescribedThreshold = true;
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_prescribedThreshold = threshold;
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *this;
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Allows to come back to the default behavior, letting Eigen use its default formula for
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * determining the threshold.
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * You should pass the special object Eigen::Default as parameter here.
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \code lu.setThreshold(Eigen::Default); \endcode
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * See the documentation of setThreshold(const RealScalar&).
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    FullPivLU& setThreshold(Default_t)
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_usePrescribedThreshold = false;
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *this;
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Returns the threshold that will be used by certain methods such as rank().
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * See the documentation of setThreshold(const RealScalar&).
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar threshold() const
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized || m_usePrescribedThreshold);
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_usePrescribedThreshold ? m_prescribedThreshold
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // this formula comes from experimenting (see "LU precision tuning" thread on the list)
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // and turns out to be identical to Higham's formula used already in LDLt.
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                      : NumTraits<Scalar>::epsilon() * m_lu.diagonalSize();
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the rank of the matrix of which *this is the LU decomposition.
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index rank() const
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
3347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      using std::abs;
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
3367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index result = 0;
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = 0; i < m_nonzero_pivots; ++i)
3397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold);
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return result;
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition.
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index dimensionOfKernel() const
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return cols() - rank();
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns true if the matrix of which *this is the LU decomposition represents an injective
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          linear map, i.e. has trivial kernel; false otherwise.
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline bool isInjective() const
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return rank() == cols();
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns true if the matrix of which *this is the LU decomposition represents a surjective
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *          linear map; false otherwise.
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline bool isSurjective() const
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return rank() == rows();
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns true if the matrix of which *this is the LU decomposition is invertible.
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note This method has to determine which pivots should be considered nonzero.
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       For that, it uses the threshold value that you can control by calling
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       setThreshold(const RealScalar&).
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline bool isInvertible() const
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return isInjective() && (m_lu.rows() == m_lu.cols());
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \returns the inverse of the matrix of which *this is the LU decomposition.
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \note If this matrix is not invertible, the returned matrix has undefined coefficients.
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *       Use isInvertible() to first determine whether this matrix is invertible.
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \sa MatrixBase::inverse()
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
4002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    inline const Inverse<FullPivLU> inverse() const
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_isInitialized && "LU is not initialized.");
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
4042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      return Inverse<FullPivLU>(*this);
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixType reconstructedMatrix() const;
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC inline Index rows() const { return m_lu.rows(); }
4102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC inline Index cols() const { return m_lu.cols(); }
4112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    #ifndef EIGEN_PARSED_BY_DOXYGEN
4132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename RhsType, typename DstType>
4142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
4152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    void _solve_impl(const RhsType &rhs, DstType &dst) const;
4162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<bool Conjugate, typename RhsType, typename DstType>
4182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
4192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
4202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    #endif
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
424a829215e078ace896f52702caa0c27608f40e3b0Miao Wang    static void check_template_parameters()
425a829215e078ace896f52702caa0c27608f40e3b0Miao Wang    {
426a829215e078ace896f52702caa0c27608f40e3b0Miao Wang      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
427a829215e078ace896f52702caa0c27608f40e3b0Miao Wang    }
4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    void computeInPlace();
4302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixType m_lu;
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    PermutationPType m_p;
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    PermutationQType m_q;
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IntColVectorType m_rowsTranspositions;
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IntRowVectorType m_colsTranspositions;
4362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Index m_nonzero_pivots;
4372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    RealScalar m_l1_norm;
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar m_maxpivot, m_prescribedThreshold;
4392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    signed char m_det_pq;
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool m_isInitialized, m_usePrescribedThreshold;
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathFullPivLU<MatrixType>::FullPivLU()
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : m_isInitialized(false), m_usePrescribedThreshold(false)
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathFullPivLU<MatrixType>::FullPivLU(Index rows, Index cols)
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : m_lu(rows, cols),
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_p(rows),
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_q(cols),
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_rowsTranspositions(rows),
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_colsTranspositions(cols),
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_isInitialized(false),
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_usePrescribedThreshold(false)
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
4622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename InputType>
4632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangFullPivLU<MatrixType>::FullPivLU(const EigenBase<InputType>& matrix)
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : m_lu(matrix.rows(), matrix.cols()),
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_p(matrix.rows()),
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_q(matrix.cols()),
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_rowsTranspositions(matrix.rows()),
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_colsTranspositions(matrix.cols()),
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_isInitialized(false),
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_usePrescribedThreshold(false)
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
4722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  compute(matrix.derived());
4732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
4742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename MatrixType>
4762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename InputType>
4772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangFullPivLU<MatrixType>::FullPivLU(EigenBase<InputType>& matrix)
4782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  : m_lu(matrix.derived()),
4792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_p(matrix.rows()),
4802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_q(matrix.cols()),
4812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_rowsTranspositions(matrix.rows()),
4822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_colsTranspositions(matrix.cols()),
4832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_isInitialized(false),
4842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_usePrescribedThreshold(false)
4852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  computeInPlace();
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
4902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid FullPivLU<MatrixType>::computeInPlace()
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
492a829215e078ace896f52702caa0c27608f40e3b0Miao Wang  check_template_parameters();
4932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  // the permutations are stored as int indices, so just to be sure:
4952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest());
4962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index size = m_lu.diagonalSize();
5002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index rows = m_lu.rows();
5012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index cols = m_lu.cols();
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // will store the transpositions, before we accumulate them at the end.
504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // can't accumulate on-the-fly because that will be done in reverse order for the rows.
5052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_rowsTranspositions.resize(m_lu.rows());
5062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_colsTranspositions.resize(m_lu.cols());
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m_maxpivot = RealScalar(0);
511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(Index k = 0; k < size; ++k)
513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // First, we need to find the pivot.
515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index row_of_biggest_in_corner, col_of_biggest_in_corner;
5182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef internal::scalar_score_coeff_op<Scalar> Scoring;
5192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Scoring::result_type Score;
5202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Score biggest_in_corner;
521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
5222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                        .unaryExpr(Scoring())
523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    col_of_biggest_in_corner += k; // need to add k to them.
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if(biggest_in_corner==Score(0))
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // before exiting, make sure to initialize the still uninitialized transpositions
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // in a sane state without destroying what we already have.
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_nonzero_pivots = k;
532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = k; i < size; ++i)
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_rowsTranspositions.coeffRef(i) = i;
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_colsTranspositions.coeffRef(i) = i;
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      break;
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
5402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
5412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // Now that we've found the pivot, we need to apply the row/col swaps to
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // bring it to the location (k,k).
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_rowsTranspositions.coeffRef(k) = row_of_biggest_in_corner;
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_colsTranspositions.coeffRef(k) = col_of_biggest_in_corner;
548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(k != row_of_biggest_in_corner) {
549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
550c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++number_of_transpositions;
551c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
552c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(k != col_of_biggest_in_corner) {
553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++number_of_transpositions;
555c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
556c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
557c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // Now that the pivot is at the right location, we update the remaining
558c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // bottom-right corner by Gaussian elimination.
559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(k<rows-1)
561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m_lu.col(k).tail(rows-k-1) /= m_lu.coeff(k,k);
562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(k<size-1)
563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      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);
564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
565c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // the main loop is over, we still have to accumulate the transpositions to find the
567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // permutations P and Q
568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m_p.setIdentity(rows);
570c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(Index k = size-1; k >= 0; --k)
571c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m_q.setIdentity(cols);
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(Index k = 0; k < size; ++k)
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
5782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_isInitialized = true;
580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtypename internal::traits<MatrixType>::Scalar FullPivLU<MatrixType>::determinant() const
584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(m_isInitialized && "LU is not initialized.");
586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!");
587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the matrix represented by the decomposition,
5917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * i.e., it returns the product: \f$ P^{-1} L U Q^{-1} \f$.
5927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * This function is provided for debug purposes. */
593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType>
594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathMatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(m_isInitialized && "LU is not initialized.");
597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols());
598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // LU
599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType res(m_lu.rows(),m_lu.cols());
600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // FIXME the .toDenseMatrix() should not be needed...
601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  res = m_lu.leftCols(smalldim)
602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            .template triangularView<UnitLower>().toDenseMatrix()
603c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * m_lu.topRows(smalldim)
604c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            .template triangularView<Upper>().toDenseMatrix();
605c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
606c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // P^{-1}(LU)
607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  res = m_p.inverse() * res;
608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // (P^{-1}LU)Q^{-1}
610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  res = res * m_q.inverse();
611c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
612c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return res;
613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/********* Implementation of kernel() **************************************************/
616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType>
619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct kernel_retval<FullPivLU<_MatrixType> >
620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : kernel_retval_base<FullPivLU<_MatrixType> >
621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>)
623c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
624c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
625c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            MatrixType::MaxColsAtCompileTime,
626c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            MatrixType::MaxRowsAtCompileTime)
627c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
628c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
629c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename Dest> void evalTo(Dest& dst) const
630c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
6317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
632c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
633c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(dimker == 0)
634c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
635c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
636c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // avoid crashing/asserting as that depends on floating point calculations. Let's
637c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // just return a single column vector filled with zeros.
638c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.setZero();
639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return;
640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
641c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /* Let us use the following lemma:
643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Lemma: If the matrix A has the LU decomposition PAQ = LU,
645c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * then Ker A = Q(Ker U).
646c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
647c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Proof: trivial: just keep in mind that P, Q, L are invertible.
648c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
649c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
650c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /* Thus, all we need to do is to compute Ker U, and then apply Q.
651c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      *
652c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
653c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * Thus, the diagonal of U ends with exactly
654c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * dimKer zero's. Let us use that to construct dimKer linearly
655c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * independent vectors in Ker U.
656c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
657c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
658c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
659c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
660c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index p = 0;
661c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < dec().nonzeroPivots(); ++i)
662c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
663c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        pivots.coeffRef(p++) = i;
664c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_internal_assert(p == rank());
665c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
666c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // we construct a temporaty trapezoid matrix m, by taking the U matrix and
667c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // permuting the rows and cols to bring the nonnegligible pivots to the top of
668c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // the main diagonal. We need that to be able to apply our triangular solvers.
669c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified
670c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Matrix<typename MatrixType::Scalar, Dynamic, Dynamic, MatrixType::Options,
671c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime>
672c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m(dec().matrixLU().block(0, 0, rank(), cols));
673c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < rank(); ++i)
674c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
675c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(i) m.row(i).head(i).setZero();
676c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m.row(i).tail(cols-i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols-i);
677c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
678c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m.block(0, 0, rank(), rank());
679c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero();
680c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < rank(); ++i)
681c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m.col(i).swap(m.col(pivots.coeff(i)));
682c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
683c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // ok, we have our trapezoid matrix, we can apply the triangular solver.
684c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // notice that the math behind this suggests that we should apply this to the
685c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // negative of the RHS, but for performance we just put the negative sign elsewhere, see below.
686c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    m.topLeftCorner(rank(), rank())
687c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath     .template triangularView<Upper>().solveInPlace(
688c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m.topRightCorner(rank(), dimker)
689c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      );
690c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
691c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // now we must undo the column permutation that we had applied!
692c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = rank()-1; i >= 0; --i)
693c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      m.col(i).swap(m.col(pivots.coeff(i)));
694c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
695c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // see the negative sign in the next line, that's what we were talking about above.
696c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker);
697c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
698c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
699c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
700c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
701c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
702c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***** Implementation of image() *****************************************************/
703c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
704c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType>
705c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct image_retval<FullPivLU<_MatrixType> >
706c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : image_retval_base<FullPivLU<_MatrixType> >
707c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
708c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>)
709c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
710c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
711c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            MatrixType::MaxColsAtCompileTime,
712c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            MatrixType::MaxRowsAtCompileTime)
713c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
714c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
715c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<typename Dest> void evalTo(Dest& dst) const
716c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
7177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    using std::abs;
718c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(rank() == 0)
719c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
720c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
721c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // avoid crashing/asserting as that depends on floating point calculations. Let's
722c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // just return a single column vector filled with zeros.
723c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.setZero();
724c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return;
725c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
726c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
727c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
728c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
729c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index p = 0;
730c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < dec().nonzeroPivots(); ++i)
731c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
732c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        pivots.coeffRef(p++) = i;
733c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_internal_assert(p == rank());
734c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
735c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < rank(); ++i)
736c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
737c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
738c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
739c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
740c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***** Implementation of solve() *****************************************************/
741c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal
7432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_PARSED_BY_DOXYGEN
7452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename _MatrixType>
7462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename RhsType, typename DstType>
7472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
748c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
7492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
7502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * So we proceed as follows:
7512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Step 1: compute c = P * rhs.
7522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible.
7532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Step 3: replace c by the solution x to Ux = c. May or may not exist.
7542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Step 4: result = Q * c;
7552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
756c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index rows = this->rows(),
7582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang              cols = this->cols(),
7592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang              nonzero_pivots = this->rank();
7602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  eigen_assert(rhs.rows() == rows);
7612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index smalldim = (std::min)(rows, cols);
7622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(nonzero_pivots == 0)
764c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
7652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.setZero();
7662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return;
7672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
7682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
7702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 1
7722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  c = permutationP() * rhs;
773c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 2
7752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_lu.topLeftCorner(smalldim,smalldim)
7762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      .template triangularView<UnitLower>()
7772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      .solveInPlace(c.topRows(smalldim));
7782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(rows>cols)
7792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    c.bottomRows(rows-cols) -= m_lu.bottomRows(rows-cols) * c.topRows(cols);
780c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 3
7822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
7832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      .template triangularView<Upper>()
7842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      .solveInPlace(c.topRows(nonzero_pivots));
785c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 4
7872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i = 0; i < nonzero_pivots; ++i)
7882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.row(permutationQ().indices().coeff(i)) = c.row(i);
7892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i = nonzero_pivots; i < m_lu.cols(); ++i)
7902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.row(permutationQ().indices().coeff(i)).setZero();
7912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
7922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename _MatrixType>
7942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<bool Conjugate, typename RhsType, typename DstType>
7952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangvoid FullPivLU<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
7962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1},
7982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * and since permutations are real and unitary, we can write this
7992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * as   A^T = Q U^T L^T P,
8002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * So we proceed as follows:
8012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * Step 1: compute c = Q^T rhs.
8022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * Step 2: replace c by the solution x to U^T x = c. May or may not exist.
8032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * Step 3: replace c by the solution x to L^T x = c.
8042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * Step 4: result = P^T c.
8052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   * If Conjugate is true, replace "^T" by "^*" above.
8062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   */
8072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index rows = this->rows(), cols = this->cols(),
8092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    nonzero_pivots = this->rank();
8102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   eigen_assert(rhs.rows() == cols);
8112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  const Index smalldim = (std::min)(rows, cols);
8122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(nonzero_pivots == 0)
8142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
8152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.setZero();
8162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    return;
8172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
8182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
8202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 1
8222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  c = permutationQ().inverse() * rhs;
8232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if (Conjugate) {
825c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // Step 2
8262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
8272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .template triangularView<Upper>()
8282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .adjoint()
8292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .solveInPlace(c.topRows(nonzero_pivots));
8302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // Step 3
8312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_lu.topLeftCorner(smalldim, smalldim)
832c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        .template triangularView<UnitLower>()
8332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .adjoint()
834c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        .solveInPlace(c.topRows(smalldim));
8352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  } else {
8362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // Step 2
8372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
838c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        .template triangularView<Upper>()
8392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .transpose()
840c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        .solveInPlace(c.topRows(nonzero_pivots));
8412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // Step 3
8422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    m_lu.topLeftCorner(smalldim, smalldim)
8432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .template triangularView<UnitLower>()
8442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .transpose()
8452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        .solveInPlace(c.topRows(smalldim));
8462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  }
8472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Step 4
8492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  PermutationPType invp = permutationP().inverse().eval();
8502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i = 0; i < smalldim; ++i)
8512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.row(invp.indices().coeff(i)) = c.row(i);
8522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  for(Index i = smalldim; i < rows; ++i)
8532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst.row(invp.indices().coeff(i)).setZero();
8542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
8552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
8572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
8592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
860c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
8612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/***** Implementation of inverse() *****************************************************/
8622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename DstXprType, typename MatrixType>
8632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename FullPivLU<MatrixType>::Scalar>, Dense2Dense>
8642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
8652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef FullPivLU<MatrixType> LuType;
8662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef Inverse<LuType> SrcXprType;
8672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename MatrixType::Scalar> &)
8682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
8692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
870c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
871c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
872c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
873c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
874c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/******* MatrixBase methods *****************************************************************/
875c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
876c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \lu_module
877c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
878c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \return the full-pivoting LU decomposition of \c *this.
879c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
880c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa class FullPivLU
881c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
882c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
883c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline const FullPivLU<typename MatrixBase<Derived>::PlainObject>
884c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathMatrixBase<Derived>::fullPivLu() const
885c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
886c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return FullPivLU<PlainObject>(eval());
887c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
888c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
889c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
890c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
891c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_LU_H
892