64 perm_inv ==
nullptr ?
usize(pos) : util::zero_extend(perm_inv[pos]);
67 I* pldi = ld.row_indices_mut();
68 T* pldx = ld.values_mut();
69 I* pldnz = ld.nnz_per_col_mut();
71 for (
usize j = 0; j < permuted_pos; ++j) {
72 auto col_start = ld.col_start(j) + 1;
73 auto col_end = ld.col_end(j);
76 std::lower_bound(pldi + col_start, pldi + col_end, I(permuted_pos));
79 if ((it != (pldi + col_end)) && *it == I(permuted_pos)) {
81 usize count = (col_end - col_start - it_pos);
84 std::memmove(it, it + 1, count *
sizeof(I));
85 T* itx = pldx + col_start + it_pos;
89 std::memmove(itx, itx + 1, count *
sizeof(T));
93 ld._set_nnz(ld.nnz() - 1);
96 if (petree[j] == I(permuted_pos)) {
108 T d_old = ld.values()[ld.col_start(permuted_pos)];
109 ld.values_mut()[ld.col_start(permuted_pos)] = 1;
112 isize len =
isize(util::zero_extend(ld.nnz_per_col()[permuted_pos])) - 1;
116 static_cast<I const*
>(
nullptr),
121 pldi + ld.col_start(permuted_pos) + 1,
122 pldx + ld.col_start(permuted_pos) + 1,
127 ld.nnz_per_col_mut()[permuted_pos] = 1;
128 petree[permuted_pos] = I(-1);
199 bool id_perm = perm_inv ==
nullptr;
200 auto zx = util::zero_extend;
202 I* pldp = ld.col_ptrs_mut();
203 I* pldnz = ld.nnz_per_col_mut();
204 I* pldi = ld.row_indices_mut();
205 T* pldx = ld.values_mut();
209 usize permuted_pos = id_perm ?
usize(pos) : zx(perm_inv[pos]);
215 auto _lx2_storage = stack.make_new_for_overwrite(
216 proxsuite::linalg::veg::Tag<T>{}, ld.nrows());
217 auto plx2_storage = _lx2_storage.ptr_mut();
221 auto _new_col_permuted_indices = stack.make_new_for_overwrite(
222 proxsuite::linalg::veg::Tag<I>{}, id_perm ?
isize(0) : new_col.nnz());
224 auto new_col_permuted_indices =
225 id_perm ? new_col.row_indices() : _new_col_permuted_indices.ptr();
229 I* pnew_col_permuted_indices = _new_col_permuted_indices.ptr_mut();
230 for (
usize k = 0; k <
usize(new_col.nnz()); ++k) {
231 usize i = zx(new_col.row_indices()[k]);
232 pnew_col_permuted_indices[k] = perm_inv[i];
234 std::sort(pnew_col_permuted_indices,
235 pnew_col_permuted_indices + new_col.nnz());
239 auto _l12_nnz_pattern = stack.make_new_for_overwrite(
240 proxsuite::linalg::veg::Tag<I>{},
isize(permuted_pos));
241 auto _difference = stack.make_new_for_overwrite(
242 proxsuite::linalg::veg::Tag<I>{}, ld.nrows() -
isize(permuted_pos));
243 auto pdifference = _difference.ptr_mut();
245 auto pl12_nnz_pattern = _l12_nnz_pattern.ptr_mut();
246 usize l12_nnz_pattern_count = 0;
255 auto _visited = stack.make_new(proxsuite::linalg::veg::Tag<bool>{},
256 isize(permuted_pos));
257 bool* visited = _visited.ptr_mut();
258 for (
usize p = 0; p <
usize(new_col.nnz()); ++p) {
259 auto j = zx(new_col_permuted_indices[p]);
260 if (j >= permuted_pos) {
272 pl12_nnz_pattern[l12_nnz_pattern_count] = I(j);
273 ++l12_nnz_pattern_count;
275 j = util::sign_extend(
etree[j]);
276 if (j ==
usize(-1) || j >= permuted_pos || visited[j]) {
282 std::sort(pl12_nnz_pattern, pl12_nnz_pattern + l12_nnz_pattern_count);
285 for (
usize p = 0; p < l12_nnz_pattern_count; ++p) {
286 plx2_storage[zx(pl12_nnz_pattern[p])] = 0;
292 for (
usize p = 0; p <
usize(new_col.nnz()); ++p) {
293 auto j = zx(new_col.row_indices()[p]);
294 auto permuted_j = id_perm ? j : zx(perm_inv[j]);
295 plx2_storage[permuted_j] = new_col.values()[p];
299 if (permuted_j > permuted_pos) {
300 usize nz = zx(pldnz[permuted_pos]);
301 VEG_ASSERT(nz < (zx(pldp[permuted_pos + 1]) - zx(pldp[permuted_pos])));
302 pldi[zx(pldp[permuted_pos]) + nz] = I(permuted_j);
303 ++pldnz[permuted_pos];
304 ld._set_nnz(ld.nnz() + 1);
308 std::sort(pldi + zx(pldp[permuted_pos]) + 1,
309 pldi + zx(pldp[permuted_pos]) + zx(pldnz[permuted_pos]));
313 for (
usize p = 0; p < l12_nnz_pattern_count; ++p) {
314 usize j = zx(pl12_nnz_pattern[p]);
315 auto col_start = ld.col_start(j);
316 auto col_end = ld.col_end(j);
322 (_, new_current_col, computed_difference),
325 static_cast<T*
>(
nullptr),
326 pldi + (zx(pldp[permuted_pos]) + 1),
327 isize(zx(pldp[permuted_pos + 1]) - zx(pldp[permuted_pos])) - 1,
328 pldnz[permuted_pos] - 1,
332 pldi + (zx(pldp[j]) + 1),
333 isize(zx(pldnz[j])) - 1,
339 (void)new_current_col;
342 pldnz[permuted_pos] += I(computed_difference.len());
343 ld._set_nnz(ld.nnz() + computed_difference.len());
345 for (
usize q = 0; q <
usize(computed_difference.len()); ++q) {
346 plx2_storage[zx(computed_difference.ptr()[q])] = 0;
350 auto const xj = plx2_storage[j];
351 for (
usize q = col_start + 1; q < col_end; ++q) {
352 auto i = zx(pldi[q]);
353 plx2_storage[i] -= pldx[q] * xj;
358 for (
usize p = 0; p < l12_nnz_pattern_count; ++p) {
361 usize j = zx(pl12_nnz_pattern[p]);
362 auto col_start = ld.col_start(j);
363 auto col_end = ld.col_end(j);
364 T d = pldx[col_start];
365 T l12_elem = plx2_storage[j];
366 diag_element -= l12_elem * l12_elem / d;
369 VEG_ASSERT(zx(pldnz[j]) < (zx(pldp[j + 1]) - zx(pldp[j])));
373 std::lower_bound(pldi + col_start, pldi + col_end, I(permuted_pos));
377 if (it == (pldi + col_start + 1)) {
378 etree[j] = I(permuted_pos);
386 usize((pldi + col_end) - it) *
sizeof(I));
393 pldx + (it - pldi) + 1,
395 usize((pldi + col_end) - it) *
sizeof(T));
398 *it = I(permuted_pos);
400 *(pldx + (it - pldi)) = l12_elem / d;
403 ld._set_nnz(ld.nnz() + 1);
408 usize col_start = ld.col_start(permuted_pos);
409 usize col_end = ld.col_end(permuted_pos);
410 pldx[col_start] = diag_element;
411 for (
usize p = col_start + 1; p < col_end; ++p) {
412 pldx[p] = plx2_storage[zx(pldi[p])] / diag_element;
418 if (pldnz[permuted_pos] > 1) {
419 etree[permuted_pos] = pldi[ld.col_start(permuted_pos) + 1];
422 isize len =
isize(util::zero_extend(ld.nnz_per_col()[permuted_pos])) - 1;
426 static_cast<I const*
>(
nullptr),
431 pldi + ld.col_start(permuted_pos) + 1,
432 pldx + ld.col_start(permuted_pos) + 1,