18 template<
typename MatrixType_,
typename PermutationIndex_>
struct traits<FullPivLU<MatrixType_, PermutationIndex_> >
21 typedef MatrixXpr XprKind;
22 typedef SolverStorage StorageKind;
23 typedef PermutationIndex_ StorageIndex;
62 template<
typename MatrixType_,
typename PermutationIndex_>
class FullPivLU
63 :
public SolverBase<FullPivLU<MatrixType_, PermutationIndex_> >
76 typedef typename internal::plain_row_type<MatrixType, PermutationIndex>::type
IntRowVectorType;
77 typedef typename internal::plain_col_type<MatrixType, PermutationIndex>::type
IntColVectorType;
103 template<
typename InputType>
112 template<
typename InputType>
122 template<
typename InputType>
193 inline const internal::kernel_retval<FullPivLU>
kernel()
const
196 return internal::kernel_retval<FullPivLU>(*
this);
218 inline const internal::image_retval<FullPivLU>
222 return internal::image_retval<FullPivLU>(*
this, originalMatrix);
225 #ifdef EIGEN_PARSED_BY_DOXYGEN
245 template<
typename Rhs>
274 typename internal::traits<MatrixType>::Scalar
determinant()
const;
340 result += (
abs(
m_lu.coeff(
i,
i)) > premultiplied_threshold);
404 eigen_assert(
m_lu.rows() ==
m_lu.cols() &&
"You can't take the inverse of a non-square matrix!");
415 #ifndef EIGEN_PARSED_BY_DOXYGEN
416 template<
typename RhsType,
typename DstType>
417 void _solve_impl(
const RhsType &rhs, DstType &dst)
const;
419 template<
bool Conjugate,
typename RhsType,
typename DstType>
420 void _solve_impl_transposed(
const RhsType &rhs, DstType &dst)
const;
441 template<
typename MatrixType,
typename PermutationIndex>
443 : m_isInitialized(false), m_usePrescribedThreshold(false)
447 template<
typename MatrixType,
typename PermutationIndex>
452 m_rowsTranspositions(
rows),
453 m_colsTranspositions(
cols),
454 m_isInitialized(false),
455 m_usePrescribedThreshold(false)
459 template<
typename MatrixType,
typename PermutationIndex>
460 template<
typename InputType>
462 : m_lu(matrix.
rows(), matrix.
cols()),
465 m_rowsTranspositions(matrix.
rows()),
466 m_colsTranspositions(matrix.
cols()),
467 m_isInitialized(false),
468 m_usePrescribedThreshold(false)
473 template<
typename MatrixType,
typename PermutationIndex>
474 template<
typename InputType>
476 : m_lu(matrix.derived()),
479 m_rowsTranspositions(matrix.
rows()),
480 m_colsTranspositions(matrix.
cols()),
481 m_isInitialized(false),
482 m_usePrescribedThreshold(false)
487 template<
typename MatrixType,
typename PermutationIndex>
492 m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
500 m_rowsTranspositions.resize(m_lu.rows());
501 m_colsTranspositions.resize(m_lu.cols());
502 Index number_of_transpositions = 0;
504 m_nonzero_pivots =
size;
505 m_maxpivot = RealScalar(0);
512 Index row_of_biggest_in_corner, col_of_biggest_in_corner;
513 typedef internal::scalar_score_coeff_op<Scalar> Scoring;
514 typedef typename Scoring::result_type Score;
515 Score biggest_in_corner;
516 biggest_in_corner = m_lu.bottomRightCorner(
rows-k,
cols-k)
517 .unaryExpr(Scoring())
518 .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
519 row_of_biggest_in_corner += k;
520 col_of_biggest_in_corner += k;
526 m_nonzero_pivots = k;
529 m_rowsTranspositions.coeffRef(
i) = internal::convert_index<StorageIndex>(
i);
530 m_colsTranspositions.coeffRef(
i) = internal::convert_index<StorageIndex>(
i);
535 RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
536 if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
541 m_rowsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(row_of_biggest_in_corner);
542 m_colsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(col_of_biggest_in_corner);
543 if(k != row_of_biggest_in_corner) {
544 m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
545 ++number_of_transpositions;
547 if(k != col_of_biggest_in_corner) {
548 m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
549 ++number_of_transpositions;
556 m_lu.col(k).tail(
rows-k-1) /= m_lu.coeff(k,k);
558 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 m_p.setIdentity(
rows);
566 m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
568 m_q.setIdentity(
cols);
570 m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
572 m_det_pq = (number_of_transpositions%2) ? -1 : 1;
574 m_isInitialized =
true;
577 template<
typename MatrixType,
typename PermutationIndex>
580 eigen_assert(m_isInitialized &&
"LU is not initialized.");
581 eigen_assert(m_lu.rows() == m_lu.cols() &&
"You can't take the determinant of a non-square matrix!");
582 return Scalar(m_det_pq) *
Scalar(m_lu.diagonal().prod());
588 template<
typename MatrixType,
typename PermutationIndex>
591 eigen_assert(m_isInitialized &&
"LU is not initialized.");
596 res = m_lu.leftCols(smalldim)
597 .template triangularView<UnitLower>().toDenseMatrix()
598 * m_lu.topRows(smalldim)
599 .template triangularView<Upper>().toDenseMatrix();
602 res = m_p.inverse() *
res;
605 res =
res * m_q.inverse();
613 template<
typename MatrixType_,
typename PermutationIndex_>
614 struct kernel_retval<
FullPivLU<MatrixType_, PermutationIndex_> >
615 : kernel_retval_base<FullPivLU<MatrixType_, PermutationIndex_> >
621 MatrixType::MaxColsAtCompileTime,
622 MatrixType::MaxRowsAtCompileTime)
625 template<
typename Dest>
void evalTo(Dest& dst)
const
628 const Index cols = dec().matrixLU().cols(), dimker =
cols - rank();
654 Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
655 RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
657 for(
Index i = 0;
i < dec().nonzeroPivots(); ++
i)
658 if(
abs(dec().matrixLU().coeff(
i,
i)) > premultiplied_threshold)
659 pivots.coeffRef(
p++) =
i;
667 MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime>
668 m(dec().matrixLU().
block(0, 0, rank(),
cols));
671 if(
i)
m.row(
i).head(
i).setZero();
672 m.row(
i).tail(
cols-
i) = dec().matrixLU().row(pivots.coeff(
i)).tail(
cols-
i);
674 m.block(0, 0, rank(), rank());
675 m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero();
677 m.col(
i).swap(
m.col(pivots.coeff(
i)));
682 m.topLeftCorner(rank(), rank())
683 .
template triangularView<Upper>().solveInPlace(
684 m.topRightCorner(rank(), dimker)
688 for(
Index i = rank()-1;
i >= 0; --
i)
689 m.col(
i).swap(
m.col(pivots.coeff(
i)));
692 for(
Index i = 0;
i < rank(); ++
i) dst.row(dec().permutationQ().indices().coeff(
i)) = -
m.row(
i).tail(dimker);
693 for(
Index i = rank();
i <
cols; ++
i) dst.row(dec().permutationQ().indices().coeff(
i)).
setZero();
694 for(
Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
700 template<
typename MatrixType_,
typename PermutationIndex_>
701 struct image_retval<FullPivLU<MatrixType_, PermutationIndex_> >
702 : image_retval_base<FullPivLU<MatrixType_, PermutationIndex_> >
704 using DecompositionType = FullPivLU<MatrixType_, PermutationIndex_>;
708 MatrixType::MaxColsAtCompileTime,
709 MatrixType::MaxRowsAtCompileTime)
712 template<
typename Dest>
void evalTo(Dest& dst)
const
724 Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
725 RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
727 for(
Index i = 0;
i < dec().nonzeroPivots(); ++
i)
728 if(
abs(dec().matrixLU().coeff(
i,
i)) > premultiplied_threshold)
729 pivots.coeffRef(
p++) =
i;
733 dst.col(
i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(
i)));
741 #ifndef EIGEN_PARSED_BY_DOXYGEN
742 template<
typename MatrixType_,
typename PermutationIndex_>
743 template<
typename RhsType,
typename DstType>
744 void FullPivLU<MatrixType_, PermutationIndex_>::_solve_impl(
const RhsType &rhs, DstType &dst)
const
756 nonzero_pivots = this->rank();
759 if(nonzero_pivots == 0)
765 typename RhsType::PlainObject
c(rhs.rows(), rhs.cols());
768 c = permutationP() * rhs;
771 m_lu.topLeftCorner(smalldim,smalldim)
772 .template triangularView<UnitLower>()
773 .solveInPlace(
c.topRows(smalldim));
778 m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
779 .template triangularView<Upper>()
780 .solveInPlace(
c.topRows(nonzero_pivots));
783 for(
Index i = 0;
i < nonzero_pivots; ++
i)
784 dst.row(permutationQ().indices().coeff(
i)) =
c.row(
i);
785 for(
Index i = nonzero_pivots;
i < m_lu.cols(); ++
i)
786 dst.row(permutationQ().indices().coeff(
i)).
setZero();
789 template<
typename MatrixType_,
typename PermutationIndex_>
790 template<
bool Conjugate,
typename RhsType,
typename DstType>
791 void FullPivLU<MatrixType_, PermutationIndex_>::_solve_impl_transposed(
const RhsType &rhs, DstType &dst)
const
805 nonzero_pivots = this->rank();
808 if(nonzero_pivots == 0)
814 typename RhsType::PlainObject
c(rhs.rows(), rhs.cols());
817 c = permutationQ().inverse() * rhs;
820 m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
821 .template triangularView<Upper>()
823 .template conjugateIf<Conjugate>()
824 .solveInPlace(
c.topRows(nonzero_pivots));
827 m_lu.topLeftCorner(smalldim, smalldim)
828 .template triangularView<UnitLower>()
830 .template conjugateIf<Conjugate>()
831 .solveInPlace(
c.topRows(smalldim));
834 PermutationPType invp = permutationP().inverse().eval();
836 dst.row(invp.indices().coeff(
i)) =
c.row(
i);
838 dst.row(invp.indices().coeff(
i)).
setZero();
847 template<
typename DstXprType,
typename MatrixType,
typename PermutationIndex>
848 struct Assignment<DstXprType, Inverse<FullPivLU<
MatrixType, PermutationIndex> >,
internal::assign_op<typename DstXprType::Scalar,typename FullPivLU<MatrixType, PermutationIndex>::Scalar>, Dense2Dense>
850 typedef FullPivLU<MatrixType, PermutationIndex> LuType;
851 typedef Inverse<LuType> SrcXprType;
852 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::assign_op<typename DstXprType::Scalar,typename MatrixType::Scalar> &)
854 dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
867 template<
typename Derived>
868 template<
typename PermutationIndex>
const AbsReturnType abs() const
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL FixedBlockXpr<...,... >::Type block(Index startRow, Index startCol, NRowsType blockRows, NColsType blockCols)
#define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType)
#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType)
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived)
#define eigen_internal_assert(x)
#define EIGEN_DEVICE_FUNC
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Matrix< float, 1, Dynamic > MatrixType
TransposeReturnType transpose()
internal::traits< Derived >::Scalar Scalar
LU decomposition of a matrix with complete pivoting, and related features.
IntColVectorType m_rowsTranspositions
internal::plain_row_type< MatrixType, PermutationIndex >::type IntRowVectorType
FullPivLU & setThreshold(const RealScalar &threshold)
bool isInvertible() const
internal::traits< MatrixType >::Scalar determinant() const
internal::plain_col_type< MatrixType, PermutationIndex >::type IntColVectorType
IntRowVectorType m_colsTranspositions
Index nonzeroPivots() const
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
bool m_usePrescribedThreshold
MatrixType::PlainObject PlainObject
MatrixType reconstructedMatrix() const
const MatrixType & matrixLU() const
const Inverse< FullPivLU > inverse() const
const PermutationPType & permutationP() const
FullPivLU & compute(const EigenBase< InputType > &matrix)
RealScalar maxPivot() const
PermutationIndex_ PermutationIndex
FullPivLU & setThreshold(Default_t)
RealScalar m_prescribedThreshold
SolverBase< FullPivLU > Base
PermutationMatrix< ColsAtCompileTime, MaxColsAtCompileTime, PermutationIndex > PermutationQType
bool isSurjective() const
const internal::image_retval< FullPivLU > image(const MatrixType &originalMatrix) const
RealScalar threshold() const
const internal::kernel_retval< FullPivLU > kernel() const
PermutationMatrix< RowsAtCompileTime, MaxRowsAtCompileTime, PermutationIndex > PermutationPType
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
const PermutationQType & permutationQ() const
Index dimensionOfKernel() const
const Solve< FullPivLU, Rhs > solve(const MatrixBase< Rhs > &b) const
FullPivLU()
Default Constructor.
Expression of the inverse of another expression.
Base class for all dense matrices, vectors, and expressions.
const FullPivLU< PlainObject, PermutationIndex > fullPivLu() const
Base::PlainObject PlainObject
Derived & setZero(Index size)
Pseudo expression representing a solving operation.
A base class for matrix decomposition and solvers.
internal::traits< FullPivLU< MatrixType_, PermutationIndex_ > >::Scalar Scalar
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
constexpr int min_size_prefer_fixed(A a, B b)
Decomposition::RealScalar rcond_estimate_helper(typename Decomposition::RealScalar matrix_norm, const Decomposition &dec)
Reciprocal condition number estimator.
bool is_exactly_zero(const X &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
Eigen::Index Index
The interface type of indices.
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.