alpaqa 1.0.0a13
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
63 throw std::invalid_argument("NewtonTR without finite differences "
64 "requires Problem::eval_hess_ψ_prod()");
66 throw std::invalid_argument(
67 "NewtonTR requires "
68 "Problem::eval_inactive_indices_res_lna()");
69 // Store references to problem and ALM variables
70 this->problem = &problem;
71 this->y.emplace(y);
72 this->Σ.emplace(Σ);
73 // Resize workspaces
74 const auto n = problem.get_n(), m = problem.get_m();
75 JK_sto.resize(n);
76 rJ_sto.resize(n);
77 qJ_sto.resize(n);
78 work.resize(n);
79 work_2.resize(n);
82 work_n_fd.resize(n);
83 work_m_fd.resize(m);
84 }
85 }
86
87 /// @see @ref PANTRDirection::has_initial_direction
88 bool has_initial_direction() const { return true; }
89
90 /// @see @ref PANTRDirection::update
98
99 /// @see @ref PANTRDirection::apply
103 rvec qₖ) const {
104
105 if (!std::isfinite(radius))
106 throw std::logic_error("Invalid trust radius");
107 if (radius < std::numeric_limits<real_t>::epsilon())
108 throw std::logic_error("Trust radius too small");
109
110 // Newton with exact Hessian
111
112 // Find inactive and active constraints
113 const auto n = problem->get_n();
114 index_t nJ =
116 crindexvec J = JK_sto.topRows(nJ);
117 rindexvec K = JK_sto.bottomRows(n - nJ);
119 auto rJ = rJ_sto.topRows(nJ);
120 auto qJ = qJ_sto.topRows(nJ);
121 rJ = (-real_t(1) / γₖ) * pₖ(J);
122 qₖ(K) = pₖ(K);
123 qₖ(J).setZero();
124 real_t norm_qK_sq = pₖ(K).squaredNorm();
125
126 // Hessian-vector term
129 real_t ε =
131 /// TODO: use a better rule to determine the step size
132 work = xₖ + ε * qₖ;
134 work_m_fd);
135 rJ.noalias() += (work_2 - grad_ψxₖ)(J) *
137 } else {
140 }
141 }
142
143 // Hessian-vector product on subset J
144 auto hess_vec_mult = [&](crvec p, rvec Bp) {
146 real_t ε =
148 /// TODO: use a better rule to determine the step size
149 work = xₖ;
150 work(J) += ε * p;
152 work_m_fd);
153 Bp.topRows(nJ) = (work_2 - grad_ψxₖ)(J) / ε;
154 } else {
155 work.setZero();
156 work(J) = p;
158 Bp.topRows(nJ) = work_2(J);
159 }
160 };
161
162 // Steihaug conjugate gradients
164 qₖ(J) = qJ;
165 return qJ_model - norm_qK_sq / (2 * γₖ);
166 }
167
168 /// @see @ref PANTRDirection::changed_γ
171
172 /// @see @ref PANTRDirection::reset
173 void reset() {}
174
175 /// @see @ref PANTRDirection::get_name
176 std::string get_name() const {
177 return "NewtonTRDirection<" + std::string(config_t::get_name()) + '>';
178 }
179
180 auto get_params() const {
181 return std::tie(steihaug.params, direction_params);
182 }
183
186 const Problem *problem = nullptr;
187#ifndef _WIN32
188 std::optional<crvec> y = std::nullopt;
189 std::optional<crvec> Σ = std::nullopt;
190#else
191 std::optional<vec> y = std::nullopt;
192 std::optional<vec> Σ = std::nullopt;
193#endif
195 mutable vec rJ_sto;
196 mutable vec qJ_sto;
198};
199
200} // 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...
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:56
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:78
typename Conf::real_t real_t
Definition config.hpp:65
typename Conf::rindexvec rindexvec
Definition config.hpp:79
typename Conf::index_t index_t
Definition config.hpp:77
constexpr const auto inf
Definition config.hpp:85
typename Conf::rvec rvec
Definition config.hpp:69
typename Conf::crvec crvec
Definition config.hpp:70
typename Conf::vec vec
Definition config.hpp:66
typename Conf::crindexvec crindexvec
Definition config.hpp:80
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:91
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:88
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