proxsuite-nlp  0.10.0
A primal-dual augmented Lagrangian-type solver for nonlinear programming on manifolds.
Loading...
Searching...
No Matches
proxsuite-ldlt-wrap.hpp
Go to the documentation of this file.
1
3#pragma once
4
5#include <proxsuite/linalg/dense/ldlt.hpp>
6
8
9namespace {
10
11namespace veg = proxsuite::linalg::veg;
12namespace dense_linalg = proxsuite::linalg::dense;
13using byte = proxsuite::linalg::veg::mem::byte;
14using StackType = proxsuite::linalg::veg::Vec<byte>;
15using StackReq = proxsuite::linalg::veg::dynstack::StackReq;
16
17template <typename Mat, typename Rhs> void solve_impl(Mat &&ld_, Rhs &&rhs_) {
18 auto ld = dense_linalg::util::to_view(ld_);
19 auto rhs = dense_linalg::util::to_view_dyn_rows(rhs_);
20 using Scalar = typename Mat::Scalar;
21
22 auto l = ld.template triangularView<Eigen::UnitLower>();
23 auto lt =
24 dense_linalg::util::trans(ld).template triangularView<Eigen::UnitUpper>();
25 auto d = dense_linalg::util::diagonal(ld);
26 l.solveInPlace(rhs);
27 constexpr Scalar eps = std::numeric_limits<Scalar>::min();
28
29 using std::abs;
30 for (Eigen::Index i = 0; i < d.size(); ++i) {
31 if (abs(d[i]) > eps) {
32 rhs.row(i) /= d[i];
33 } else {
34 rhs.row(i).setZero();
35 }
36 }
37 lt.solveInPlace(rhs);
38}
39
40} // anonymous namespace
41
42namespace proxsuite {
43namespace nlp {
44namespace linalg {
45
47template <typename _Scalar> struct ProxSuiteLDLTWrapper : ldlt_base<_Scalar> {
48 using Scalar = _Scalar;
51 using psldlt_t = dense_linalg::Ldlt<Scalar>;
52 using DView = typename Base::DView;
53
55 StackType ldl_stack;
56 using Base::m_info;
57
58 ProxSuiteLDLTWrapper(isize nr, isize rhs_max_cols) : m_ldlt{} {
59 m_ldlt.reserve_uninit(nr);
60
61 // quick runthrough: no block insertions, no diagonal updates
62 // just need space for solve in place with nr rows, rhs_max_cols columns.
63 auto req_mat = psldlt_t::solve_in_place_req(rhs_max_cols * nr);
64
65 StackReq req{psldlt_t::factorize_req(nr) | req_mat};
66
67 ldl_stack.resize_for_overwrite(req.alloc_req());
68 }
69
70 ProxSuiteLDLTWrapper &compute(const ConstMatrixRef &mat) {
71 using veg::dynstack::DynStackMut;
72
73 DynStackMut stack{veg::from_slice_mut, ldl_stack.as_mut()};
74
75 m_ldlt.factorize(mat, stack);
76
77 m_info = Eigen::ComputationInfo::Success;
78 return *this;
79 }
80
81 template <typename Derived>
82 bool solveInPlace(Eigen::MatrixBase<Derived> &rhs) const {
83 using veg::dynstack::DynStackMut;
84 isize nrows = rhs.rows();
85 isize ncols = rhs.cols();
86 auto perm = m_ldlt.p();
87 auto perm_inv = m_ldlt.pt();
88 DynStackMut stack{veg::from_slice_mut,
89 const_cast<StackType &>(ldl_stack).as_mut()};
90 LDLT_TEMP_MAT_UNINIT(Scalar, work, nrows, ncols, stack);
91
92 work = perm_inv * rhs;
93
94 solve_impl(m_ldlt.ld_col(), work);
95
96 rhs = perm * work;
97
98 return true;
99 }
100
101 template <typename Rhs>
102 typename Rhs::PlainObject solve(const Eigen::MatrixBase<Rhs> &rhs) const {
103 typename Rhs::PlainObject out = rhs;
104 solveInPlace(out);
105 return out;
106 }
107
108 inline DView vectorD() const {
109 return dense_linalg::util::diagonal(m_ldlt.ld_col());
110 }
111
112 MatrixXs reconstructedMatrix() const {
113
114 auto L = m_ldlt.l();
115 auto D = m_ldlt.d();
116 auto U = m_ldlt.lt();
117 MatrixXs r = U;
118 r = D.asDiagonal() * r;
119 r = L * r;
120 r = r * m_ldlt.pt();
121 r = m_ldlt.p() * r;
122
123 return r;
124 }
125};
126
127} // namespace linalg
128} // namespace nlp
129} // namespace proxsuite
#define PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar)
Definition math.hpp:26
Main package namespace.
Definition bcl-params.hpp:5
Rhs::PlainObject solve(const Eigen::MatrixBase< Rhs > &rhs) const
ProxSuiteLDLTWrapper & compute(const ConstMatrixRef &mat)
bool solveInPlace(Eigen::MatrixBase< Derived > &rhs) const
Base interface for LDLT solvers.
Definition ldlt-base.hpp:24
Eigen::ComputationInfo m_info
Definition ldlt-base.hpp:48
Eigen::Map< const VectorXs, Eigen::Unaligned, Eigen::InnerStride< Eigen::Dynamic > > DView
Definition ldlt-base.hpp:26