28 if (!sym_structure.performed_llt) {
29 assert(
false &&
"Block structure was not analyzed yet.");
32 const isize nblocks = sym_structure.nsegments();
33 const isize n = mat.rows();
34 if ((nblocks == 0) || (n <= 1)) {
38 const isize bs = sym_structure.segment_lens[0];
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();
48 switch (sym_structure(0, 0)) {
60 for (isize i = 1; i < nblocks; ++i) {
61 const isize bsi = sym_structure.segment_lens[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);
66 switch (sym_structure(i, 0)) {
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++) {
100 update_sign_matrix(sign, l00(k, k));
104 for (isize i = 1; i < nblocks; ++i) {
105 const isize bsi = sym_structure.segment_lens[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);
110 switch (sym_structure(i, 0)) {
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) {
142 const isize bsi = sym_structure.segment_lens[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);
153 backend::gemmt(target_ii, li0, li0_prev, sym_structure(i, 0),
154 sym_structure(i, 0), Scalar(-1));
156 isize offset_j = offset_i + bsi;
157 for (isize j = i + 1; j < nblocks; ++j) {
160 const isize bsj = sym_structure.segment_lens[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);
165 backend::gemmt(target_ji, lj0, li0_prev, sym_structure(j, 0),
166 sym_structure(i, 0), Scalar(-1));
176 sym_structure.submatrix(1, nblocks - 1),