20#ifndef EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
21#define EIGEN_SIMPLICIAL_CHOLESKY_IMPL_H
24#include "./InternalHeaderCheck.h"
28template <
typename Derived>
29void SimplicialCholeskyBase<Derived>::analyzePattern_preordered(
const CholMatrixType& ap,
bool doLDLT) {
30 const StorageIndex size = StorageIndex(ap.rows());
31 m_matrix.resize(size, size);
32 m_parent.resize(size);
33 m_nonZerosPerCol.resize(size);
35 ei_declare_aligned_stack_constructed_variable(StorageIndex, tags, size, 0);
37 for (StorageIndex k = 0; k < size; ++k) {
41 m_nonZerosPerCol[k] = 0;
42 for (
typename CholMatrixType::InnerIterator it(ap, k); it; ++it) {
43 StorageIndex i = it.index();
46 for (; tags[i] != k; i = m_parent[i]) {
48 if (m_parent[i] == -1) m_parent[i] = k;
49 m_nonZerosPerCol[i]++;
57 StorageIndex* Lp = m_matrix.outerIndexPtr();
59 for (StorageIndex k = 0; k < size; ++k) Lp[k + 1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1);
61 m_matrix.resizeNonZeros(Lp[size]);
63 m_isInitialized =
true;
65 m_analysisIsOk =
true;
66 m_factorizationIsOk =
false;
69template <
typename Derived>
70template <
bool DoLDLT,
bool NonHermitian>
71void SimplicialCholeskyBase<Derived>::factorize_preordered(
const CholMatrixType& ap) {
74 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
75 eigen_assert(ap.rows() == ap.cols());
76 eigen_assert(m_parent.size() == ap.rows());
77 eigen_assert(m_nonZerosPerCol.size() == ap.rows());
79 const StorageIndex size = StorageIndex(ap.rows());
80 const StorageIndex* Lp = m_matrix.outerIndexPtr();
81 StorageIndex* Li = m_matrix.innerIndexPtr();
82 Scalar* Lx = m_matrix.valuePtr();
84 ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0);
85 ei_declare_aligned_stack_constructed_variable(StorageIndex, pattern, size, 0);
86 ei_declare_aligned_stack_constructed_variable(StorageIndex, tags, size, 0);
89 m_diag.resize(DoLDLT ? size : 0);
91 for (StorageIndex k = 0; k < size; ++k) {
94 StorageIndex top = size;
96 m_nonZerosPerCol[k] = 0;
97 for (
typename CholMatrixType::InnerIterator it(ap, k); it; ++it) {
98 StorageIndex i = it.index();
100 y[i] += getSymm(it.value());
102 for (len = 0; tags[i] != k; i = m_parent[i]) {
106 while (len > 0) pattern[--top] = pattern[--len];
113 getDiag(y[k]) * m_shiftScale + m_shiftOffset;
115 for (; top < size; ++top) {
116 Index i = pattern[top];
123 l_ki = yi / getDiag(m_diag[i]);
125 yi = l_ki = yi / Lx[Lp[i]];
127 Index p2 = Lp[i] + m_nonZerosPerCol[i];
129 for (p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p) y[Li[p]] -= getSymm(Lx[p]) * yi;
130 d -= getDiag(l_ki * getSymm(yi));
133 ++m_nonZerosPerCol[i];
137 if (d == RealScalar(0)) {
142 Index p = Lp[k] + m_nonZerosPerCol[k]++;
144 if (NonHermitian ? d == RealScalar(0) : numext::
real(d) <= RealScalar(0)) {
153 m_factorizationIsOk =
true;
@ NumericalIssue
Definition Constants.h:442
@ Success
Definition Constants.h:440
Namespace containing all symbols from the Eigen library.
Definition Core:137
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)