29 assert(
false &&
"Block structure was not analyzed yet.");
34 if ((nblocks == 0) || (n <= 1)) {
39 const isize rem = n - bs;
40 MatrixRef l00 =
mat.block(0, 0, bs, bs);
41 MatrixRef l11 =
mat.block(bs, bs, rem, rem);
42 const auto d0 = l00.diagonal();
43 const auto d0_inv = d0.asDiagonal().inverse();
45 MatrixRef work_tr =
mat.block(0, bs, bs, rem);
46 Eigen::Transpose<MatrixRef> work = work_tr.transpose();
60 for (
isize i = 1; i < nblocks; ++i) {
62 MatrixRef li0 =
mat.block(offset, 0, bsi, bs);
63 Eigen::Block<
decltype(work)> li0_copy =
64 work.block(offset - bs, 0, bsi, bs);
70 auto li0_u = li0.template triangularView<Eigen::Upper>();
74 l00.template triangularView<Eigen::UnitLower>().solveInPlace(
76 li0_copy.template triangularView<Eigen::Upper>() = li0_u;
83 l00.template triangularView<Eigen::UnitLower>().solveInPlace(
99 for (
isize k = 0; k < bs; k++) {
104 for (
isize i = 1; i < nblocks; ++i) {
106 MatrixRef li0 =
mat.block(offset, 0, bsi, bs);
107 Eigen::Block<
decltype(work)> li0_copy =
108 work.block(offset - bs, 0, bsi, bs);
114 auto li0_d = li0.diagonal();
115 li0_copy.diagonal() = li0_d;
116 li0_d = li0_d.cwiseQuotient(d0);
120 auto li0_u = li0.template triangularView<Eigen::Upper>();
121 li0_copy.template triangularView<Eigen::Upper>() = li0_u;
122 li0_u = li0 * d0_inv;
141 for (
isize i = 1; i < nblocks; ++i) {
143 Eigen::Block<MatrixRef> li0 =
mat.block(offset_i, 0, bsi, bs);
144 Eigen::Block<
decltype(work)> li0_prev =
145 work.block(offset_i - bs, 0, bsi, bs);
148 Eigen::Block<MatrixRef> target_ii =
149 mat.block(offset_i, offset_i, bsi, bsi);
156 isize offset_j = offset_i + bsi;
157 for (
isize j = i + 1; j < nblocks; ++j) {
161 Eigen::Block<MatrixRef> lj0 =
mat.block(offset_j, 0, bsj, bs);
162 Eigen::Block<MatrixRef> target_ji =
163 mat.block(offset_j, offset_i, bsj, bsi);
178 .ldlt_in_place_impl(sign);
202 using Traits = LDLT_Traits<MatrixXs, Eigen::Lower>;
204 Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic, isize>;
287 inline typename Traits::MatrixL
matrixL()
const {
291 inline typename Traits::MatrixU
matrixU()
const {
300 template <
typename Derived>
303 template <
typename Rhs>
304 typename Rhs::PlainObject
solve(
const Eigen::MatrixBase<Rhs> &rhs)
const {
305 typename Rhs::PlainObject out = rhs;
317 : Eigen::NumericalIssue;
323 assert(mat.rows() == mat.cols());
324 m_matrix.conservativeResizeLike(mat);
326 return i >= j ? mat(i, j) : mat(j, i);
331 for (
isize j = 0; j < n; ++j) {
332 auto pj = indices[j];
334 for (
isize i = j; i < n; ++i) {
335 m_matrix(i, j) = mat_coeff(indices[i], pj);
351#include "./block-ldlt.hxx"
353#ifdef PROXSUITE_NLP_ENABLE_TEMPLATE_INSTANTIATION
354#include "./block-ldlt.txx"
Routines for Cholesky factorization.
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
void gemmt(Eigen::MatrixBase< DstDerived > &dst, Eigen::MatrixBase< LhsDerived > const &lhs, Eigen::MatrixBase< RhsDerived > const &rhs, BlockKind lhs_kind, BlockKind rhs_kind, Scalar alpha)
bool dense_ldlt_in_place(Eigen::MatrixBase< Derived > &a, SignMatrix &sign)
void update_sign_matrix(SignMatrix &sign, const Scalar &akk)
std::make_unsigned< isize >::type usize
PROXSUITE_NLP_DLLAPI void print_sparsity_pattern(const SymbolicBlockMatrix &smat) noexcept
@ Dense
There is no known prior structure; assume a dense block.
@ Diag
The block is diagonal.
@ Zero
All entries in the block are zero.
@ TriL
The block is lower-triangular.
@ TriU
The block is upper-triangular.
Block sparsity-aware LDLT factorization algorithm.
Eigen::ComputationInfo m_info
BlockLDLT & compute(const ConstMatrixRef &mat) override
Eigen::PermutationMatrix< Eigen::Dynamic, Eigen::Dynamic, isize > PermutationType
typename Base::DView DView
Eigen::Matrix< isize, Eigen::Dynamic, 1 > PermIdxType
std::vector< isize > m_start_idx
BlockLDLT(BlockLDLT const &other)
Traits::MatrixL matrixL() const
void setBlockPermutation(isize const *new_perm=nullptr)
Calls updateBlockPermutationMatrix.
const PermutationType & permutationP() const
std::vector< isize > m_iwork
bool solveInPlace(Eigen::MatrixBase< Derived > &b) const
Solve for the right-hand side in-place.
BlockLDLT(isize size, SymbolicBlockMatrix const &structure)
The constructor copies the input matrix.
const SymbolicBlockMatrix & structure() const
BlockLDLT & findSparsifyingPermutation()
Find a sparsity-maximizing permutation of the blocks. This will also compute the symbolic factorizati...
Traits::MatrixU matrixU() const
BlockLDLT & updateBlockPermutationMatrix(SymbolicBlockMatrix const &in)
DView vectorD() const override
std::vector< isize > m_perm_inv
void print_sparsity() const
SymbolicBlockMatrix m_struct_tr
void computeStartIndices(const SymbolicBlockMatrix &in)
Compute indices indicating where blocks start.
auto blockPermIndices() -> std::vector< isize > &
SymbolicBlockMatrix m_structure
bool analyzePattern()
Analyze and factorize the block structure, if not done already.
Rhs::PlainObject solve(const Eigen::MatrixBase< Rhs > &rhs) const
MatrixXs reconstructedMatrix() const override
PermutationType m_permutation
LDLT_Traits< MatrixXs, Eigen::Lower > Traits
const MatrixXs & matrixLDLT() const override
std::vector< isize > m_perm
Symbolic representation of the sparsity structure of a (square) block matrix.
SymbolicBlockMatrix transpose() const
isize nsegments() const noexcept
SymbolicBlockMatrix submatrix(isize i, isize n) noexcept
Representation for triangular block matrices.
Implementation struct for the recursive block LDLT algorithm.
bool ldlt_in_place_impl(SignMatrix &sign)
SymbolicBlockMatrix sym_structure
Base interface for LDLT solvers.
Eigen::ComputationInfo m_info
Eigen::Map< const VectorXs, Eigen::Unaligned, Eigen::InnerStride< Eigen::Dynamic > > DView
static DView diag_view_impl(Mat &&mat)