38 isize first_initial_len,
48 if (second.len() == 0) {
50 proxsuite::linalg::veg::tuplify,
51 { unsafe, from_raw_parts, first_values, first_initial_len },
52 { unsafe, from_raw_parts, first_ptr, first_initial_len },
53 { unsafe, from_raw_parts, difference, 0 },
57 I
const* second_ptr = second.ptr();
60 usize index_second = 0;
62 for (; index_second < second_len; ++index_second) {
63 if (second_ptr[index_second] > ignore_threshold_inclusive) {
67 auto ufirst_initial_len =
usize(first_initial_len);
69 second_ptr += index_second;
70 second_len -= index_second;
73 proxsuite::linalg::veg::Tag<I> tag{};
75 auto _ins_pos = stack.make_new_for_overwrite(tag,
isize(second_len));
77 I* insert_pos_ptr = _ins_pos.ptr_mut();
78 usize insert_count = 0;
80 for (
usize index_first = 0; index_first < ufirst_initial_len; ++index_first) {
81 I current_first = first_ptr[index_first];
83 if (!(index_second < second_len)) {
87 I current_second = second_ptr[index_second];
88 if (!(current_second < current_first)) {
92 insert_pos_ptr[insert_count] = I(index_first);
93 difference[insert_count] = current_second;
98 if (index_second == second_len) {
101 if (second_ptr[index_second] == current_first) {
106 usize remaining_insert_count = insert_count;
107 usize first_new_len =
108 ufirst_initial_len + insert_count + (second_len - index_second);
111 usize append_count = second_len - index_second;
113 difference + insert_count,
114 second_ptr + index_second,
115 append_count *
sizeof(I));
117 first_ptr + (ufirst_initial_len + insert_count),
118 second_ptr + index_second,
119 append_count *
sizeof(I));
121 for (
usize i = 0; i < append_count; ++i) {
122 first_values[i + ufirst_initial_len + insert_count] = 0;
126 while (remaining_insert_count != 0) {
128 usize old_insert_pos =
usize(insert_pos_ptr[remaining_insert_count - 1]);
130 (remaining_insert_count == insert_count)
131 ? ufirst_initial_len - old_insert_pos
132 :
usize(insert_pos_ptr[remaining_insert_count]) - old_insert_pos;
134 usize old_pos = old_insert_pos;
135 usize new_pos = old_pos + remaining_insert_count;
140 range_size *
sizeof(I));
143 first_values + new_pos,
144 first_values + old_pos,
145 range_size *
sizeof(T));
146 first_values[new_pos - 1] = 0;
149 first_ptr[new_pos - 1] = difference[remaining_insert_count - 1];
150 --remaining_insert_count;
154 proxsuite::linalg::veg::tuplify,
155 { unsafe, from_raw_parts, first_values,
isize(first_new_len) },
156 { unsafe, from_raw_parts, first_ptr,
isize(first_new_len) },
157 { unsafe, from_raw_parts, difference,
isize(insert_count + append_count) },
220 proxsuite::linalg::veg::Tag<I> tag;
222 bool id_perm = perm_inv ==
nullptr;
224 auto _w_permuted_indices =
225 stack.make_new_for_overwrite(tag, id_perm ?
isize(0) : w.nnz());
227 auto w_permuted_indices =
228 id_perm ? w.row_indices() : _w_permuted_indices.ptr();
230 I* pw_permuted_indices = _w_permuted_indices.ptr_mut();
232 usize i = util::zero_extend(w.row_indices()[k]);
233 pw_permuted_indices[k] = perm_inv[i];
235 std::sort(pw_permuted_indices, pw_permuted_indices + w.nnz());
238 auto sx = util::sign_extend;
239 auto zx = util::zero_extend;
242 usize current_col = zx(w_permuted_indices[0]);
245 stack.make_new_for_overwrite(tag,
isize(n - current_col));
246 auto _difference_backup =
247 stack.make_new_for_overwrite(tag,
isize(n - current_col));
249 auto merge_col = w_permuted_indices;
250 isize merge_col_len = w.nnz();
251 I* difference = _difference.ptr_mut();
256 usize current_ptr_idx = zx(ld.col_ptrs()[
isize(current_col)]);
257 usize next_ptr_idx = zx(ld.col_ptrs()[
isize(current_col) + 1]);
260 (_, new_current_col, computed_difference),
263 ld.values_mut() + (current_ptr_idx + 1),
264 ld.row_indices_mut() + (current_ptr_idx + 1),
265 isize(next_ptr_idx - current_ptr_idx),
266 isize(zx(ld.nnz_per_col()[
isize(current_col)])) - 1,
268 unsafe, from_raw_parts, merge_col, merge_col_len },
274 ld._set_nnz(ld.nnz() + new_current_col.len() + 1 -
276 ld.nnz_per_col_mut()[
isize(current_col)] = I(new_current_col.len() + 1);
279 (new_current_col.len() == 0) ?
usize(-1) : sx(new_current_col[0]);
281 if (new_parent ==
usize(-1)) {
285 if (new_parent == old_parent) {
286 merge_col = computed_difference.ptr();
287 merge_col_len = computed_difference.len();
288 difference = _difference_backup.ptr_mut();
290 merge_col = new_current_col.ptr();
291 merge_col_len = new_current_col.len();
292 difference = _difference.ptr_mut();
296 current_col = new_parent;
302 usize first_col = zx(w_permuted_indices[0]);
304 stack.make_new_for_overwrite(proxsuite::linalg::veg::Tag<T>{},
isize(n));
305 T* pwork = _work.ptr_mut();
311 pwork[id_perm ? zx(w.row_indices()[
isize(p)])
312 : zx(perm_inv[w.row_indices()[
isize(p)]])] =
313 w.values()[
isize(p)];
316 I
const* pldi = ld.row_indices();
317 T* pldx = ld.values_mut();
320 auto col_start = ld.col_start(col);
321 auto col_end = ld.col_end(col);
324 T old_d = pldx[col_start];
325 T new_d = old_d + alpha * w0 * w0;
326 T beta = alpha * w0 / new_d;
327 alpha = alpha - new_d * beta * beta;
329 pldx[col_start] = new_d;
332 for (
usize p = col_start + 1; p < col_end; ++p) {
333 usize i = util::zero_extend(pldi[p]);
336 pwork[i] = pwork[i] - w0 * tmp;
337 pldx[p] = tmp + beta * pwork[i];
auto merge_second_col_into_first(I *difference, T *first_values, I *first_ptr, PROXSUITE_MAYBE_UNUSED isize first_full_len, isize first_initial_len, Slice< I > second, proxsuite::linalg::veg::DoNotDeduce< I > ignore_threshold_inclusive, bool move_values, DynStackMut stack) noexcept(false) -> proxsuite::linalg::veg::Tuple< SliceMut< T >, SliceMut< I >, SliceMut< I > >