alpaqa pi-pico
Nonconvex constrained optimization
Loading...
Searching...
No Matches
newton-tr.hpp
Go to the documentation of this file.
1#pragma once
2
7#include <cmath>
8#include <limits>
9#include <optional>
10#include <stdexcept>
11
12namespace alpaqa {
13
14/// Parameters for the @ref NewtonTRDirection class.
15/// @ingroup grp_Parameters
16template <Config Conf>
19 /// The factor in front of the term @f$ \langle H_{\mathcal{JK}}
20 /// d_{\mathcal {K}}, d_{\mathcal{J}} \rangle @f$ in equation (9) in
21 /// @cite bodard2023pantr.
22 /// Set it to zero to leave out that term (this usually only slightly
23 /// increases the number of iterations, and eliminates one Hessian-vector
24 /// product per iteration, improving the overall runtime).
26 /// Use finite differences to compute Hessian-vector products.
27 bool finite_diff = false;
28 /// Size of the perturbation for the finite differences computation.
29 /// Multiplied by @f$ 1+\|x\| @f$.
31 std::sqrt(std::numeric_limits<real_t>::epsilon());
32};
33
34/// @ingroup grp_DirectionProviders
35template <Config Conf>
38
42
47
48 NewtonTRDirection() = default;
50 : steihaug(params.accelerator), direction_params(params.direction) {}
54
55 /// @see @ref PANTRDirection::initialize
64 throw std::invalid_argument("NewtonTR without finite differences "
65 "requires Problem::eval_hess_ψ_prod()");
67 throw std::invalid_argument(
68 "NewtonTR requires "
69 "Problem::eval_inactive_indices_res_lna()");
70 // Store references to problem and ALM variables
71 this->problem = &problem;
72 this->y.emplace(y);
73 this->Σ.emplace(Σ);
74 // Resize workspaces
75 const auto n = problem.get_n(), m = problem.get_m();
76 JK_sto.resize(n);
77 rJ_sto.resize(n);
78 qJ_sto.resize(n);
79 work.resize(n);
80 work_2.resize(n);
83 work_n_fd.resize(n);
84 work_m_fd.resize(m);
85 }
86 }
87
88 /// @see @ref PANTRDirection::has_initial_direction
89 bool has_initial_direction() const { return true; }
90
91 /// @see @ref PANTRDirection::update
99
100 /// @see @ref PANTRDirection::apply
104 rvec qₖ) const {
105
106 if (!std::isfinite(radius))
107 throw std::logic_error("Invalid trust radius");
108 if (radius < std::numeric_limits<real_t>::epsilon())
109 throw std::logic_error("Trust radius too small");
110
111 // Newton with exact Hessian
112
113 // Find inactive and active constraints
114 const auto n = problem->get_n();
115 index_t nJ =
117 crindexvec J = JK_sto.topRows(nJ);
118 rindexvec K = JK_sto.bottomRows(n - nJ);
120 auto rJ = rJ_sto.topRows(nJ);
121 auto qJ = qJ_sto.topRows(nJ);
122 rJ = (-real_t(1) / γₖ) * pₖ(J);
123 qₖ(K) = pₖ(K);
124 qₖ(J).setZero();
125 real_t norm_qK_sq = pₖ(K).squaredNorm();
126
127 // Hessian-vector term
130 real_t ε =
132 /// TODO: use a better rule to determine the step size
133 work = xₖ + ε * qₖ;
135 work_m_fd);
136 rJ.noalias() += (work_2 - grad_ψxₖ)(J) *
138 } else {
141 }
142 }
143
144 // Hessian-vector product on subset J
145 auto hess_vec_mult = [&](crvec p, rvec Bp) {
147 real_t ε =
149 /// TODO: use a better rule to determine the step size
150 work = xₖ;
151 work(J) += ε * p;
153 work_m_fd);
154 Bp.topRows(nJ) = (work_2 - grad_ψxₖ)(J) / ε;
155 } else {
156 work.setZero();
157 work(J) = p;
159 Bp.topRows(nJ) = work_2(J);
160 }
161 };
162
163 // Steihaug conjugate gradients
165 qₖ(J) = qJ;
166 return qJ_model - norm_qK_sq / (2 * γₖ);
167 }
168
169 /// @see @ref PANTRDirection::changed_γ
172
173 /// @see @ref PANTRDirection::reset
174 void reset() {}
175
176 /// @see @ref PANTRDirection::get_name
177 std::string get_name() const {
178 return "NewtonTRDirection<" + std::string(config_t::get_name()) + '>';
179 }
180
181 auto get_params() const {
182 return std::tie(steihaug.params, direction_params);
183 }
184
187 const Problem *problem = nullptr;
188#ifndef _WIN32
189 std::optional<crvec> y = std::nullopt;
190 std::optional<crvec> Σ = std::nullopt;
191#else
192 std::optional<vec> y = std::nullopt;
193 std::optional<vec> Σ = std::nullopt;
194#endif
196 mutable vec rJ_sto;
197 mutable vec qJ_sto;
199};
200
201} // namespace alpaqa
bool provides_eval_hess_ψ_prod() const
Returns true if the problem provides an implementation of eval_hess_ψ_prod.
length_t get_n() const
[Required] Number of decision variables.
length_t get_m() const
[Required] Number of constraints.
bool provides_eval_inactive_indices_res_lna() const
Returns true if the problem provides an implementation of eval_inactive_indices_res_lna.
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
[Optional] Function that computes the inactive indices for the evaluation of the linear Newton appro...
bool provides_eval_hess_L_prod() const
Returns true if the problem provides an implementation of eval_hess_L_prod.
void eval_grad_ψ(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
[Optional] Calculate the gradient ∇ψ(x).
void eval_hess_ψ_prod(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
[Optional] Function that evaluates the Hessian of the augmented Lagrangian multiplied by a vector,
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
real_t hessian_vec_factor
The factor in front of the term in equation (9) in .
Definition newton-tr.hpp:25
bool finite_diff
Use finite differences to compute Hessian-vector products.
Definition newton-tr.hpp:27
real_t finite_diff_stepsize
Size of the perturbation for the finite differences computation.
Definition newton-tr.hpp:30
Parameters for the NewtonTRDirection class.
Definition newton-tr.hpp:17
Parameters for SteihaugCG.
typename Conf::indexvec indexvec
Definition config.hpp:105
typename Conf::real_t real_t
Definition config.hpp:86
typename Conf::rindexvec rindexvec
Definition config.hpp:106
typename Conf::index_t index_t
Definition config.hpp:104
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88
typename Conf::crindexvec crindexvec
Definition config.hpp:107
std::string get_name() const
void changed_γ(real_t γₖ, real_t old_γₖ)
SteihaugCG< config_t > steihaug
real_t apply(real_t γₖ, crvec xₖ, crvec x̂ₖ, crvec pₖ, crvec grad_ψxₖ, real_t radius, rvec qₖ) const
NewtonTRDirection(const Params &params)
Definition newton-tr.hpp:49
NewtonTRDirection(const AcceleratorParams &params, const DirectionParams &directionparams={})
Definition newton-tr.hpp:51
DirectionParams direction_params
bool update(real_t γₖ, real_t γₙₑₓₜ, crvec xₖ, crvec xₙₑₓₜ, crvec pₖ, crvec pₙₑₓₜ, crvec grad_ψxₖ, crvec grad_ψxₙₑₓₜ)
Definition newton-tr.hpp:92
std::optional< crvec > y
void initialize(const Problem &problem, crvec y, crvec Σ, real_t γ_0, crvec x_0, crvec x̂_0, crvec p_0, crvec grad_ψx_0)
Definition newton-tr.hpp:56
const Problem * problem
bool has_initial_direction() const
Definition newton-tr.hpp:89
std::optional< crvec > Σ
Steihaug conjugate gradients procedure based on https://github.com/scipy/scipy/blob/583e70a50573169fc...
void resize(length_t n)
real_t solve(const auto &grad, const HessFun &hess_prod, real_t trust_radius, rvec step) const
static void compute_complement(std::span< const index_t > in, std::span< index_t > out)
Definition index-set.hpp:36