369 else if (numext::real(mat.coeff(0, 0)) >
static_cast<RealScalar
>(0))
370 sign = PositiveSemiDef;
371 else if (numext::real(mat.coeff(0, 0)) <
static_cast<RealScalar
>(0))
372 sign = NegativeSemiDef;
378 for (Index k = 0; k < size; ++k) {
380 Index index_of_biggest_in_corner;
381 mat.diagonal().tail(size - k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
382 index_of_biggest_in_corner += k;
384 transpositions.coeffRef(k) = IndexType(index_of_biggest_in_corner);
385 if (k != index_of_biggest_in_corner) {
388 Index s = size - index_of_biggest_in_corner - 1;
389 mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k));
390 mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s));
391 std::swap(mat.coeffRef(k, k), mat.coeffRef(index_of_biggest_in_corner, index_of_biggest_in_corner));
392 for (Index i = k + 1; i < index_of_biggest_in_corner; ++i) {
393 Scalar tmp = mat.coeffRef(i, k);
394 mat.coeffRef(i, k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner, i));
395 mat.coeffRef(index_of_biggest_in_corner, i) = numext::conj(tmp);
397 EIGEN_IF_CONSTEXPR (NumTraits<Scalar>::IsComplex)
398 mat.coeffRef(index_of_biggest_in_corner, k) = numext::conj(mat.coeff(index_of_biggest_in_corner, k));
405 Index rs = size - k - 1;
406 Block<MatrixType, Dynamic, 1> A21(mat, k + 1, k, rs, 1);
407 Block<MatrixType, 1, Dynamic> A10(mat, k, 0, 1, k);
408 Block<MatrixType, Dynamic, Dynamic> A20(mat, k + 1, 0, rs, k);
411 temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint();
412 mat.coeffRef(k, k) -= (A10 * temp.head(k)).value();
413 if (rs > 0) A21.noalias() -= A20 * temp.head(k);
420 RealScalar realAkk = numext::real(mat.coeffRef(k, k));
421 bool pivot_is_valid = (abs(realAkk) > RealScalar(0));
423 if (k == 0 && !pivot_is_valid) {
427 for (Index j = 0; j < size; ++j) {
428 transpositions.coeffRef(j) = IndexType(j);
429 ret = ret && (mat.col(j).tail(size - j - 1).array() == Scalar(0)).all();
434 if ((rs > 0) && pivot_is_valid)
437 ret = ret && (A21.array() == Scalar(0)).all();
439 if (found_zero_pivot && pivot_is_valid)
441 else if (!pivot_is_valid)
442 found_zero_pivot =
true;
444 if (sign == PositiveSemiDef) {
445 if (realAkk <
static_cast<RealScalar
>(0)) sign = Indefinite;
446 }
else if (sign == NegativeSemiDef) {
447 if (realAkk >
static_cast<RealScalar
>(0)) sign = Indefinite;
448 }
else if (sign == ZeroSign) {
449 if (realAkk >
static_cast<RealScalar
>(0))
450 sign = PositiveSemiDef;
451 else if (realAkk <
static_cast<RealScalar
>(0))
452 sign = NegativeSemiDef;
466 template <
typename MatrixType,
typename WDerived>
467 static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w,
468 const typename MatrixType::RealScalar& sigma = 1) {
469 using numext::isfinite;
470 using Scalar =
typename MatrixType::Scalar;
471 using RealScalar =
typename MatrixType::RealScalar;
473 const Index size = mat.rows();
474 eigen_assert(mat.cols() == size && w.size() == size);
476 RealScalar alpha = 1;
479 for (Index j = 0; j < size; j++) {
481 if (!(isfinite)(alpha))
break;
484 RealScalar dj = numext::real(mat.coeff(j, j));
485 Scalar wj = w.coeff(j);
486 RealScalar swj2 = sigma * numext::abs2(wj);
487 RealScalar gamma = dj * alpha + swj2;
494 if (!numext::is_exactly_zero(swj2)) {
495 mat.coeffRef(j, j) += swj2 / alpha;
500 Index rs = size - j - 1;
501 w.tail(rs) -= wj * mat.col(j).tail(rs);
502 if (!numext::is_exactly_zero(gamma)) mat.col(j).tail(rs) += (sigma * numext::conj(wj) / gamma) * w.tail(rs);
507 template <
typename MatrixType,
typename TranspositionType,
typename Workspace,
typename WType>
508 static bool update(MatrixType& mat,
const TranspositionType& transpositions, Workspace& tmp,
const WType& w,
509 const typename MatrixType::RealScalar& sigma = 1) {
511 tmp = transpositions * w;
513 return ldlt_inplace<Lower>::updateInPlace(mat, tmp, sigma);
518struct ldlt_inplace<
Upper> {
519 template <
typename MatrixType,
typename TranspositionType,
typename Workspace>
520 static EIGEN_STRONG_INLINE
bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp,
522 Transpose<MatrixType> matt(mat);
523 return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
526 template <
typename MatrixType,
typename TranspositionType,
typename Workspace,
typename WType>
527 static EIGEN_STRONG_INLINE
bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w,
528 const typename MatrixType::RealScalar& sigma = 1) {
529 Transpose<MatrixType> matt(mat);
530 return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma);
534template <
typename MatrixType>
535struct LDLT_Traits<MatrixType,
Lower> {
536 using MatrixL =
const TriangularView<const MatrixType, UnitLower>;
537 using MatrixU =
const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper>;
538 static inline MatrixL getL(
const MatrixType& m) {
return MatrixL(m); }
539 static inline MatrixU getU(
const MatrixType& m) {
return MatrixU(m.adjoint()); }
542template <
typename MatrixType>
543struct LDLT_Traits<MatrixType,
Upper> {
544 using MatrixL =
const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower>;
545 using MatrixU =
const TriangularView<const MatrixType, UnitUpper>;
546 static inline MatrixL getL(
const MatrixType& m) {
return MatrixL(m.adjoint()); }
547 static inline MatrixU getU(
const MatrixType& m) {
return MatrixU(m); }
554template <
typename MatrixType,
int UpLo_>
555template <
typename InputType>
557 eigen_assert(a.rows() == a.cols());
558 const Index
size = a.rows();
560 m_matrix = a.derived();
563 m_l1_norm = m_matrix.template selfadjointView<UpLo_>().l1Norm();
565 m_transpositions.resize(
size);
566 m_isInitialized =
false;
567 m_temporary.resize(
size);
568 m_sign = internal::ZeroSign;
570 m_info = internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign) ?
Success
573 m_isInitialized =
true;
596template <
typename MatrixType,
int UpLo_>
597template <
typename Derived>
600 using IndexType =
typename TranspositionType::StorageIndex;
601 const Index
size = w.rows();
602 if (m_isInitialized) {
603 eigen_assert(m_matrix.rows() ==
size);
607 m_transpositions.resize(
size);
608 for (Index i = 0; i <
size; i++) m_transpositions.coeffRef(i) = IndexType(i);
609 m_temporary.resize(
size);
610 m_sign = sigma >= 0 ? internal::PositiveSemiDef : internal::NegativeSemiDef;
611 m_isInitialized =
true;
616 internal::ldlt_inplace<UpLo>::update(m_matrix, m_transpositions, m_temporary, w, sigma);
623template <
typename MatrixType_,
int UpLo_>
625 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
626 eigen_assert(m_info ==
Success &&
"LDLT failed because of a zero pivot.");
627 return Scalar(
vectorD().real().prod());
630template <
typename MatrixType_,
int UpLo_>
632 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
633 eigen_assert(m_info ==
Success &&
"LDLT failed because of a zero pivot.");
634 return numext::abs(
vectorD().real().prod());
637template <
typename MatrixType_,
int UpLo_>
639 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
640 eigen_assert(m_info ==
Success &&
"LDLT failed because of a zero pivot.");
641 return vectorD().real().cwiseAbs().array().log().sum();
644template <
typename MatrixType_,
int UpLo_>
646 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
647 eigen_assert(m_info ==
Success &&
"LDLT failed because of a zero pivot.");
648 return Scalar(
vectorD().real().array().sign().prod());
651#ifndef EIGEN_PARSED_BY_DOXYGEN
652template <
typename MatrixType_,
int UpLo_>
653template <
typename RhsType,
typename DstType>
655 _solve_impl_transposed<true>(rhs, dst);
658template <
typename MatrixType_,
int UpLo_>
659template <
bool Conjugate,
typename RhsType,
typename DstType>
660void LDLT<MatrixType_, UpLo_>::_solve_impl_transposed(
const RhsType& rhs, DstType& dst)
const {
662 dst = m_transpositions * rhs;
666 matrixL().template conjugateIf<!Conjugate>().solveInPlace(dst);
672 const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
679 RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
680 for (Index i = 0; i < vecD.size(); ++i) {
681 if (abs(vecD(i)) > tolerance)
682 dst.row(i) /= vecD(i);
684 dst.row(i).setZero();
689 matrixL().transpose().template conjugateIf<Conjugate>().solveInPlace(dst);
693 dst = m_transpositions.transpose() * dst;
710template <
typename MatrixType,
int UpLo_>
711template <
typename Derived>
713 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
714 eigen_assert(m_matrix.rows() == bAndX.rows());
716 bAndX = this->solve(bAndX);
724template <
typename MatrixType,
int UpLo_>
726 eigen_assert(m_isInitialized &&
"LDLT is not initialized.");
727 const Index
size = m_matrix.rows();
736 res =
vectorD().real().asDiagonal() * res;
749template <
typename MatrixType,
unsigned int UpLo>
759template <
typename Derived>