proxsuite 0.6.7
The Advanced Proximal Optimization Toolbox
Loading...
Searching...
No Matches
modify.hpp
Go to the documentation of this file.
1
2//
3// Copyright (c) 2022 INRIA
4//
5#ifndef PROXSUITE_LINALG_DENSE_LDLT_MODIFY_HPP
6#define PROXSUITE_LINALG_DENSE_LDLT_MODIFY_HPP
7
11#include <algorithm>
13
14namespace proxsuite {
15namespace linalg {
16namespace dense {
17namespace _detail {
18
19template<typename Mat>
20void
21delete_rows_and_cols_triangular_impl(Mat mat, isize const* indices, isize r)
22{
23 isize n = mat.rows();
24
25 for (isize chunk_j = 0; chunk_j < r + 1; ++chunk_j) {
26 isize j_start = chunk_j == 0 ? 0 : indices[chunk_j - 1] + 1;
27 isize j_finish = chunk_j == r ? n : indices[chunk_j];
28
29 for (isize j = j_start; j < j_finish; ++j) {
30 for (isize chunk_i = chunk_j; chunk_i < r + 1; ++chunk_i) {
31 isize i_start = chunk_i == chunk_j ? j : indices[chunk_i - 1] + 1;
32 isize i_finish = chunk_i == r ? n : indices[chunk_i];
33
34 if (chunk_i != 0 || chunk_j != 0) {
35 std::move( //
36 util::matrix_elem_addr(mat, i_start, j),
37 util::matrix_elem_addr(mat, i_finish, j),
39 mat,
40 (i_start - chunk_i),
41 (j - chunk_j)));
42 }
43 }
44 }
45 }
46}
47// indices: rows and columns to delete, in strictly increasing order
48// must have at least one element (excluding the end)
49// r: count of rows to delete
50template<typename Mat>
51void
52delete_rows_and_cols_triangular(Mat&& mat, isize const* indices, isize r)
53{
55 util::to_view_dyn(mat), indices, r);
56}
57
59{
61 isize current_r;
62 isize r;
63 isize const* indices;
64 VEG_INLINE auto operator()() noexcept -> isize
65 {
66 if (current_r == r) {
67 return current_r;
68 }
69
71 ++current_r;
72 if (current_r == r) {
73 return current_r;
74 }
75 }
77 return current_r;
78 }
79};
80template<typename Mat>
81void
83 Mat ld,
84 isize* indices,
85 isize r,
87{
88 std::sort(indices, indices + r);
89
90 using T = typename Mat::Scalar;
91
92 isize n = ld.rows();
93 isize first = indices[0];
94
95 auto w_stride = _detail::adjusted_stride<T>(n - first - r);
96
98
99 auto _w = stack.make_new(tag, r * w_stride, _detail::align<T>());
100 auto _alpha = stack.make_new_for_overwrite(tag, r);
101
102 auto pw = _w.ptr_mut();
103 auto palpha = _alpha.ptr_mut();
104
105 for (isize k = 0; k < r; ++k) {
106 isize j = indices[k];
107 palpha[k] = ld(j, j);
108 auto pwk = pw + k * w_stride;
109
110 for (isize chunk_i = k + 1; chunk_i < r + 1; ++chunk_i) {
111 isize i_start = indices[chunk_i - 1] + 1;
112 isize i_finish = chunk_i == r ? n : indices[chunk_i];
113
114 std::move(util::matrix_elem_addr(ld, i_start, j),
115 util::matrix_elem_addr(ld, i_finish, j),
116 pwk + i_start - chunk_i - first);
117 }
118 }
120
122 util::submatrix(ld, first, first, n - first - r, n - first - r),
123 pw,
124 w_stride,
125 palpha,
126 IndicesR{ first, 0, r, indices });
127}
128
129template<typename Mat, typename A_1>
130void
132 Mat ld,
133 isize pos,
134 A_1 a_1,
136{
137 using T = typename Mat::Scalar;
138
140
141 isize const new_n = ld.rows();
142 isize const r = a_1.cols();
143 isize const old_n = new_n - r;
144
145 isize current_col = old_n;
146 while (true) {
147 if (current_col == pos) {
148 break;
149 }
150 --current_col;
151
152 T* src_col_ptr = util::matrix_elem_addr(ld, 0, current_col);
153 T* dest_col_ptr = util::matrix_elem_addr(ld, 0, current_col + r);
154
155 std::move_backward( //
156 src_col_ptr + pos,
157 src_col_ptr + old_n,
158 dest_col_ptr + new_n);
159
160 std::move_backward( //
161 src_col_ptr,
162 src_col_ptr + pos,
163 dest_col_ptr + pos);
164 }
165
166 while (true) {
167 if (current_col == 0) {
168 break;
169 }
170 --current_col;
171
172 T* src_col_ptr = util::matrix_elem_addr(ld, 0, current_col);
173 T* dest_col_ptr = src_col_ptr;
174
175 std::move_backward( //
176 src_col_ptr + pos,
177 src_col_ptr + old_n,
178 dest_col_ptr + new_n);
179 }
180
181 auto rem = new_n - pos - r;
182
183 auto ld00 = util::submatrix(ld, 0, 0, pos, pos);
184 auto l10 = util::submatrix(ld, pos, 0, r, pos);
185 auto l20 = util::submatrix(ld, pos + r, 0, rem, pos);
186
187 auto ld11 = util::submatrix(ld, pos, pos, r, r);
188 auto l21 = util::submatrix(ld, pos + r, pos, rem, r);
189
190 auto ld22 = util::submatrix(ld, pos + r, pos + r, rem, rem);
191
192 auto d0 = util::diagonal(ld00).asDiagonal();
193
194 auto a01 = util::subrows(a_1, 0, pos);
195 auto a11 = util::subrows(a_1, pos, r);
196 auto a21 = util::subrows(a_1, pos + r, rem);
197
198 if (l10.cols() > 0) {
199 l10 = util::trans(a01);
200 util::trans(ld00) //
201 .template triangularView<Eigen::UnitUpper>()
202 .template solveInPlace<Eigen::OnTheRight>(l10);
203
204 l10 = l10 * d0.inverse();
205 }
206
207 {
208 isize tmp_stride = _detail::adjusted_stride<T>(pos);
209 auto _tmp = stack.make_new_for_overwrite( //
210 tag,
211 tmp_stride,
212 _detail::align<T>());
213 auto d0xl10T = Eigen::Map<Eigen::Matrix< //
214 T,
215 Eigen::Dynamic,
216 A_1::ColsAtCompileTime>,
217 Eigen::Unaligned,
218 Eigen::OuterStride<Eigen::Dynamic>>{
219 _tmp.ptr_mut(),
220 pos,
221 r,
222 tmp_stride,
223 };
224
225 ld11.template triangularView<Eigen::Lower>() =
226 a11.template triangularView<Eigen::Lower>();
227
228 if (l10.cols() > 0) {
229 d0xl10T = d0 * util::trans(l10);
230 ld11.template triangularView<Eigen::Lower>() -= l10 * d0xl10T;
231 }
232
233 l21 = a21;
234 util::noalias_mul_add(l21, l20, d0xl10T, T(-1));
235 }
236
238 util::trans(ld11) //
239 .template triangularView<Eigen::UnitUpper>()
240 .template solveInPlace<Eigen::OnTheRight>(l21);
241
242 auto d1 = util::diagonal(ld11).asDiagonal();
243 l21 = l21 * d1.inverse();
244
245 auto w_stride = _detail::adjusted_stride<T>(rem);
246 auto _w = stack.make_new(tag, r * w_stride, _detail::align<T>());
247 auto _alpha = stack.make_new_for_overwrite(tag, r);
248
249 auto pw = _w.ptr_mut();
250 auto palpha = _alpha.ptr_mut();
251
252 for (isize k = 0; k < r; ++k) {
253 palpha[k] = -ld11(k, k);
254 T const* src_ptr = util::matrix_elem_addr(l21, 0, k);
255 std::copy(src_ptr, src_ptr + rem, pw + k * w_stride);
256 }
257
259 ld22,
260 pw,
261 w_stride,
262 palpha,
263 _detail::ConstantR{ r });
264}
265} // namespace _detail
266
267template<typename T>
268auto
270 isize n,
271 isize r) noexcept
273{
274
276 _detail::adjusted_stride<T>(n - r) * r * isize{ sizeof(T) },
277 _detail::align<T>(),
278 };
280 r * isize{ sizeof(T) },
281 alignof(T),
282 };
283 return w_req & alpha_req;
284}
285
286template<typename Mat>
287void
289 Mat&& ld,
290 isize* indices,
291 isize r,
293{
295 util::to_view_dyn(ld), indices, r, stack);
296}
297
298template<typename T>
299auto
301 isize n,
302 isize r) noexcept
304{
306
308 _detail::adjusted_stride<T>(n) * r * isize{ sizeof(T) },
309 _detail::align<T>(),
310 };
312 r * isize{ sizeof(T) },
313 alignof(T),
314 };
315
316 return (w_req & alpha_req) | factorize_req;
317}
318
319template<typename Mat, typename A_1>
320void
322 isize pos,
323 A_1 const& a_1,
325{
327 util::to_view_dyn(ld), pos, util::to_view_dyn_rows(a_1), stack);
328}
329} // namespace dense
330} // namespace linalg
331} // namespace proxsuite
332
333#endif /* end of include guard PROXSUITE_LINALG_DENSE_LDLT_MODIFY_HPP */
#define VEG_INLINE
Definition macros.hpp:118
void delete_rows_and_cols_triangular_impl(Mat mat, isize const *indices, isize r)
Definition modify.hpp:21
void ldlt_delete_rows_and_cols_impl(Mat ld, isize *indices, isize r, proxsuite::linalg::veg::dynstack::DynStackMut stack)
Definition modify.hpp:82
void delete_rows_and_cols_triangular(Mat &&mat, isize const *indices, isize r)
Definition modify.hpp:52
void rank_r_update_clobber_w_impl(LD ld, T *pw, isize w_stride, T *palpha, Fn r_fn)
Definition update.hpp:221
void ldlt_insert_rows_and_cols_impl(Mat ld, isize pos, A_1 a_1, proxsuite::linalg::veg::dynstack::DynStackMut stack)
Definition modify.hpp:131
auto matrix_elem_addr(Mat &&mat, isize row, isize col) noexcept -> decltype(mat.data())
Definition core.hpp:563
auto trans(Mat &&mat) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, Eigen::Matrix< typename proxsuite::linalg::veg::uncvref_t< Mat >::Scalar, proxsuite::linalg::veg::uncvref_t< Mat >::ColsAtCompileTime, proxsuite::linalg::veg::uncvref_t< Mat >::RowsAtCompileTime, bool(proxsuite::linalg::veg::uncvref_t< Mat >::IsRowMajor) ? Eigen::ColMajor :Eigen::RowMajor > >, Eigen::Unaligned, _detail::StrideOf< proxsuite::linalg::veg::uncvref_t< Mat > > >
Definition core.hpp:597
void noalias_mul_add(Dst &&dst, Lhs const &lhs, Rhs const &rhs, T factor)
Definition core.hpp:839
auto to_view_dyn_rows(Mat &&mat) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, _detail::OwnedRows< proxsuite::linalg::veg::uncvref_t< Mat > > >, Eigen::Unaligned, _detail::StrideOf< proxsuite::linalg::veg::uncvref_t< Mat > > >
Definition core.hpp:690
auto diagonal(Mat &&mat) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, Eigen::Matrix< typename proxsuite::linalg::veg::uncvref_t< Mat >::Scalar, Eigen::Dynamic, 1, Eigen::ColMajor > >, Eigen::Unaligned, Eigen::InnerStride< Eigen::Dynamic > >
Definition core.hpp:624
auto subrows(Mat &&mat, isize row_start, isize nrows) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, _detail::OwnedRows< proxsuite::linalg::veg::uncvref_t< Mat > > >, Eigen::Unaligned, _detail::StrideOf< proxsuite::linalg::veg::uncvref_t< Mat > > >
Definition core.hpp:750
auto submatrix(Mat &&mat, isize row_start, isize col_start, isize nrows, isize ncols) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, _detail::OwnedMatrix< proxsuite::linalg::veg::uncvref_t< Mat > > >, Eigen::Unaligned, _detail::StrideOf< proxsuite::linalg::veg::uncvref_t< Mat > > >
Definition core.hpp:645
auto to_view_dyn(Mat &&mat) noexcept -> Eigen::Map< _detail::const_if< _detail::ptr_is_const< decltype(mat.data())>::value, _detail::OwnedMatrix< proxsuite::linalg::veg::uncvref_t< Mat > > >, Eigen::Unaligned, _detail::StrideOf< proxsuite::linalg::veg::uncvref_t< Mat > > >
Definition core.hpp:730
auto ldlt_insert_rows_and_cols_req(proxsuite::linalg::veg::Tag< T > tag, isize n, isize r) noexcept -> proxsuite::linalg::veg::dynstack::StackReq
Definition modify.hpp:300
void ldlt_delete_rows_and_cols_sort_indices(Mat &&ld, isize *indices, isize r, proxsuite::linalg::veg::dynstack::DynStackMut stack)
Definition modify.hpp:288
void ldlt_insert_rows_and_cols(Mat &&ld, isize pos, A_1 const &a_1, proxsuite::linalg::veg::dynstack::DynStackMut stack)
Definition modify.hpp:321
void factorize(Mat &&mat, proxsuite::linalg::veg::dynstack::DynStackMut stack)
auto ldlt_delete_rows_and_cols_req(proxsuite::linalg::veg::Tag< T >, isize n, isize r) noexcept -> proxsuite::linalg::veg::dynstack::StackReq
Definition modify.hpp:269
auto factorize_req(proxsuite::linalg::veg::Tag< T > tag, isize n) noexcept -> proxsuite::linalg::veg::dynstack::StackReq
VEG_INLINE auto operator()() noexcept -> isize
Definition modify.hpp:64
VEG_NODISCARD auto ptr_mut() const VEG_NOEXCEPT -> void *