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