61 typedef _MatrixType MatrixType;
67 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
68 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
74 typedef typename MatrixType::PlainObject PlainObject;
97 template<
typename InputType>
107 template<
typename InputType>
118 eigen_assert(m_isInitialized &&
"LU is not initialized.");
131 eigen_assert(m_isInitialized &&
"LU is not initialized.");
132 return m_nonzero_pivots;
146 eigen_assert(m_isInitialized &&
"LU is not initialized.");
156 eigen_assert(m_isInitialized &&
"LU is not initialized.");
176 eigen_assert(m_isInitialized &&
"LU is not initialized.");
200 image(
const MatrixType& originalMatrix)
const
202 eigen_assert(m_isInitialized &&
"LU is not initialized.");
226 template<
typename Rhs>
230 eigen_assert(m_isInitialized &&
"LU is not initialized.");
270 m_usePrescribedThreshold =
true;
285 m_usePrescribedThreshold =
false;
295 eigen_assert(m_isInitialized || m_usePrescribedThreshold);
296 return m_usePrescribedThreshold ? m_prescribedThreshold
311 eigen_assert(m_isInitialized &&
"LU is not initialized.");
314 for(
Index i = 0; i < m_nonzero_pivots; ++i)
327 eigen_assert(m_isInitialized &&
"LU is not initialized.");
328 return cols() -
rank();
340 eigen_assert(m_isInitialized &&
"LU is not initialized.");
341 return rank() == cols();
353 eigen_assert(m_isInitialized &&
"LU is not initialized.");
354 return rank() == rows();
365 eigen_assert(m_isInitialized &&
"LU is not initialized.");
366 return isInjective() && (m_lu.rows() == m_lu.cols());
378 eigen_assert(m_isInitialized &&
"LU is not initialized.");
379 eigen_assert(m_lu.rows() == m_lu.cols() &&
"You can't take the inverse of a non-square matrix!");
385 inline Index rows()
const {
return m_lu.rows(); }
386 inline Index cols()
const {
return m_lu.cols(); }
388 #ifndef EIGEN_PARSED_BY_DOXYGEN
389 template<
typename RhsType,
typename DstType>
391 void _solve_impl(
const RhsType &rhs, DstType &dst)
const;
393 template<
bool Conjugate,
typename RhsType,
typename DstType>
395 void _solve_impl_transposed(
const RhsType &rhs, DstType &dst)
const;
400 static void check_template_parameters()
402 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
405 void computeInPlace();
408 PermutationPType m_p;
409 PermutationQType m_q;
410 IntColVectorType m_rowsTranspositions;
411 IntRowVectorType m_colsTranspositions;
412 Index m_det_pq, m_nonzero_pivots;
413 RealScalar m_maxpivot, m_prescribedThreshold;
414 bool m_isInitialized, m_usePrescribedThreshold;
417template<
typename MatrixType>
419 : m_isInitialized(
false), m_usePrescribedThreshold(
false)
423template<
typename MatrixType>
428 m_rowsTranspositions(rows),
429 m_colsTranspositions(cols),
430 m_isInitialized(
false),
431 m_usePrescribedThreshold(
false)
435template<
typename MatrixType>
436template<
typename InputType>
438 : m_lu(matrix.rows(), matrix.cols()),
441 m_rowsTranspositions(matrix.rows()),
442 m_colsTranspositions(matrix.cols()),
443 m_isInitialized(
false),
444 m_usePrescribedThreshold(
false)
449template<
typename MatrixType>
450template<
typename InputType>
453 check_template_parameters();
458 m_isInitialized =
true;
459 m_lu = matrix.derived();
466template<
typename MatrixType>
467void FullPivLU<MatrixType>::computeInPlace()
469 const Index size = m_lu.diagonalSize();
470 const Index rows = m_lu.rows();
471 const Index cols = m_lu.cols();
475 m_rowsTranspositions.resize(m_lu.rows());
476 m_colsTranspositions.resize(m_lu.cols());
477 Index number_of_transpositions = 0;
479 m_nonzero_pivots = size;
480 m_maxpivot = RealScalar(0);
482 for(Index k = 0; k < size; ++k)
487 Index row_of_biggest_in_corner, col_of_biggest_in_corner;
488 typedef internal::scalar_score_coeff_op<Scalar> Scoring;
489 typedef typename Scoring::result_type Score;
490 Score biggest_in_corner;
491 biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
492 .unaryExpr(Scoring())
493 .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
494 row_of_biggest_in_corner += k;
495 col_of_biggest_in_corner += k;
497 if(biggest_in_corner==Score(0))
501 m_nonzero_pivots = k;
502 for(Index i = k; i < size; ++i)
504 m_rowsTranspositions.coeffRef(i) = i;
505 m_colsTranspositions.coeffRef(i) = i;
510 RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
511 if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
516 m_rowsTranspositions.coeffRef(k) = row_of_biggest_in_corner;
517 m_colsTranspositions.coeffRef(k) = col_of_biggest_in_corner;
518 if(k != row_of_biggest_in_corner) {
519 m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
520 ++number_of_transpositions;
522 if(k != col_of_biggest_in_corner) {
523 m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
524 ++number_of_transpositions;
531 m_lu.col(k).tail(rows-k-1) /= m_lu.coeff(k,k);
533 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);
539 m_p.setIdentity(rows);
540 for(Index k = size-1; k >= 0; --k)
541 m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
543 m_q.setIdentity(cols);
544 for(Index k = 0; k < size; ++k)
545 m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
547 m_det_pq = (number_of_transpositions%2) ? -1 : 1;
550template<
typename MatrixType>
553 eigen_assert(m_isInitialized &&
"LU is not initialized.");
554 eigen_assert(m_lu.rows() == m_lu.cols() &&
"You can't take the determinant of a non-square matrix!");
555 return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
561template<
typename MatrixType>
564 eigen_assert(m_isInitialized &&
"LU is not initialized.");
567 MatrixType res(m_lu.rows(),m_lu.cols());
575 res = m_p.inverse() * res;
578 res = res * m_q.inverse();
586template<
typename _MatrixType>
592 enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
593 MatrixType::MaxColsAtCompileTime,
594 MatrixType::MaxRowsAtCompileTime)
597 template<
typename Dest>
void evalTo(
Dest&
dst)
const
600 const Index cols = dec().matrixLU().cols(),
dimker = cols - rank();
629 for(Index i = 0; i < dec().nonzeroPivots(); ++i)
632 eigen_internal_assert(p == rank());
638 Matrix<
typename MatrixType::Scalar, Dynamic, Dynamic, MatrixType::Options,
639 MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime>
640 m(dec().matrixLU().block(0, 0, rank(), cols));
641 for(Index i = 0; i < rank(); ++i)
643 if(i) m.row(i).head(i).setZero();
644 m.row(i).tail(cols-i) = dec().matrixLU().row(
pivots.coeff(i)).tail(cols-i);
646 m.block(0, 0, rank(), rank());
648 for(Index i = 0; i < rank(); ++i)
649 m.col(i).swap(m.col(
pivots.coeff(i)));
654 m.topLeftCorner(rank(), rank())
656 m.topRightCorner(rank(),
dimker)
660 for(Index i = rank()-1; i >= 0; --i)
661 m.col(i).swap(m.col(
pivots.coeff(i)));
664 for(Index i = 0; i < rank(); ++i)
dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(
dimker);
665 for(Index i = rank(); i < cols; ++i)
dst.row(dec().permutationQ().indices().coeff(i)).setZero();
666 for(Index k = 0; k <
dimker; ++k)
dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
672template<
typename _MatrixType>
678 enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
679 MatrixType::MaxColsAtCompileTime,
680 MatrixType::MaxRowsAtCompileTime)
683 template<
typename Dest>
void evalTo(
Dest&
dst)
const
698 for(Index i = 0; i < dec().nonzeroPivots(); ++i)
701 eigen_internal_assert(p == rank());
703 for(Index i = 0; i < rank(); ++i)
704 dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(
pivots.coeff(i)));
712#ifndef EIGEN_PARSED_BY_DOXYGEN
713template<
typename _MatrixType>
714template<
typename RhsType,
typename DstType>
725 const Index rows = this->rows(),
728 eigen_assert(rhs.rows() == rows);
729 const Index
smalldim = (std::min)(rows, cols);
737 typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
740 c = permutationP() * rhs;
743 m_lu.topLeftCorner(smalldim,smalldim)
744 .template triangularView<UnitLower>()
745 .solveInPlace(c.topRows(smalldim));
747 c.bottomRows(rows-cols) -= m_lu.bottomRows(rows-cols) * c.topRows(cols);
750 m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
751 .template triangularView<Upper>()
752 .solveInPlace(c.topRows(nonzero_pivots));
755 for(Index i = 0; i < nonzero_pivots; ++i)
756 dst.row(permutationQ().indices().coeff(i)) = c.row(i);
757 for(Index i = nonzero_pivots; i < m_lu.cols(); ++i)
758 dst.row(permutationQ().indices().coeff(i)).setZero();
761template<
typename _MatrixType>
762template<
bool Conjugate,
typename RhsType,
typename DstType>
763void FullPivLU<_MatrixType>::_solve_impl_transposed(
const RhsType &rhs, DstType &dst)
const
776 const Index rows = this->rows(), cols = this->cols(),
777 nonzero_pivots = this->rank();
778 eigen_assert(rhs.rows() == cols);
779 const Index smalldim = (std::min)(rows, cols);
781 if(nonzero_pivots == 0)
787 typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
790 c = permutationQ().inverse() * rhs;
794 m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
795 .template triangularView<Upper>()
797 .solveInPlace(c.topRows(nonzero_pivots));
799 m_lu.topLeftCorner(smalldim, smalldim)
800 .template triangularView<UnitLower>()
802 .solveInPlace(c.topRows(smalldim));
805 m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
806 .template triangularView<Upper>()
808 .solveInPlace(c.topRows(nonzero_pivots));
810 m_lu.topLeftCorner(smalldim, smalldim)
811 .template triangularView<UnitLower>()
813 .solveInPlace(c.topRows(smalldim));
817 PermutationPType invp = permutationP().inverse().eval();
818 for(Index i = 0; i < smalldim; ++i)
819 dst.row(invp.indices().coeff(i)) = c.row(i);
820 for(Index i = smalldim; i < rows; ++i)
821 dst.row(invp.indices().coeff(i)).setZero();
830template<
typename DstXprType,
typename MatrixType,
typename Scalar>
837 dst =
src.nestedExpression().solve(MatrixType::Identity(
src.rows(),
src.cols()));
851template<
typename Derived>
LU decomposition of a matrix with complete pivoting, and related features.
Definition FullPivLU.h:59
MatrixType reconstructedMatrix() const
Definition FullPivLU.h:562
bool isSurjective() const
Definition FullPivLU.h:351
FullPivLU & setThreshold(Default_t)
Allows to come back to the default behavior, letting Eigen use its default formula for determining th...
Definition FullPivLU.h:283
const internal::kernel_retval< FullPivLU > kernel() const
Definition FullPivLU.h:174
Index dimensionOfKernel() const
Definition FullPivLU.h:325
Index rank() const
Definition FullPivLU.h:308
internal::traits< MatrixType >::Scalar determinant() const
Definition FullPivLU.h:551
const Solve< FullPivLU, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition FullPivLU.h:228
const PermutationPType & permutationP() const
Definition FullPivLU.h:144
Index nonzeroPivots() const
Definition FullPivLU.h:129
bool isInjective() const
Definition FullPivLU.h:338
FullPivLU & setThreshold(const RealScalar &threshold)
Allows to prescribe a threshold to be used by certain methods, such as rank(), who need to determine ...
Definition FullPivLU.h:268
RealScalar maxPivot() const
Definition FullPivLU.h:138
const Inverse< FullPivLU > inverse() const
Definition FullPivLU.h:376
const MatrixType & matrixLU() const
Definition FullPivLU.h:116
RealScalar threshold() const
Returns the threshold that will be used by certain methods such as rank().
Definition FullPivLU.h:293
const PermutationQType & permutationQ() const
Definition FullPivLU.h:154
FullPivLU & compute(const EigenBase< InputType > &matrix)
Computes the LU decomposition of the given matrix.
const internal::image_retval< FullPivLU > image(const MatrixType &originalMatrix) const
Definition FullPivLU.h:200
FullPivLU()
Default Constructor.
Definition FullPivLU.h:418
bool isInvertible() const
Definition FullPivLU.h:363
Expression of the inverse of another expression.
Definition Inverse.h:44
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
Pseudo expression representing a solving operation.
Definition Solve.h:63
A base class for matrix decomposition and solvers.
Definition SolverBase.h:42
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:37
The type used to identify a matrix expression.
Definition Constants.h:505
Holds information about the various numeric (i.e.
Definition NumTraits.h:108
The type used to identify a general solver (foctored) storage.
Definition Constants.h:496
Definition AssignEvaluator.h:684
Definition AssignEvaluator.h:674
Definition AssignmentFunctors.h:21
Definition ForwardDeclarations.h:142
Definition ForwardDeclarations.h:140
Definition ForwardDeclarations.h:17