alpaqa 0.0.1
Nonconvex constrained optimization
kwargs-to-struct.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * This file defines mappings from Python dicts (kwargs) to simple parameter
4 * structs.
5 */
6
7#pragma once
8
9#include <functional>
10#include <map>
11#include <variant>
12
13#include <pybind11/detail/typeid.h>
14#include <pybind11/pybind11.h>
15namespace py = pybind11;
16
17struct cast_error_with_types : py::cast_error {
18 cast_error_with_types(const py::cast_error &e, std::string from,
19 std::string to)
20 : py::cast_error(e), from(std::move(from)), to(std::move(to)) {}
21 std::string from;
22 std::string to;
23};
24
25template <class T, class A>
26auto attr_setter(A T::*attr) {
27 return [attr](T &t, const py::handle &h) {
28 try {
29 t.*attr = h.cast<A>();
30 } catch (const py::cast_error &e) {
31 throw cast_error_with_types(e, py::str(py::type::handle_of(h)),
32 py::type_id<A>());
33 }
34 };
35}
36template <class T, class A>
37auto attr_getter(A T::*attr) {
38 return [attr](const T &t) { return py::cast(t.*attr); };
39}
40
41template <class T>
43 public:
44 template <class A>
46 : set(attr_setter(attr)), get(attr_getter(attr)) {}
47
48 std::function<void(T &, const py::handle &)> set;
49 std::function<py::object(const T &)> get;
50};
51
52template <class T>
53using kwargs_to_struct_table_t = std::map<std::string, attr_setter_fun_t<T>>;
54
55template <class T>
57
58template <class T>
59void kwargs_to_struct_helper(T &t, const py::kwargs &kwargs) {
60 const auto &m = kwargs_to_struct_table<T>;
61 for (auto &&[key, val] : kwargs) {
62 auto skey = key.template cast<std::string>();
63 auto it = m.find(skey);
64 if (it == m.end())
65 throw py::key_error("Unknown parameter " + skey);
66 try {
67 it->second.set(t, val);
68 } catch (const cast_error_with_types &e) {
69 throw std::runtime_error("Error converting parameter '" + skey +
70 "' from " + e.from + " to '" + e.to +
71 "': " + e.what());
72 } catch (const std::runtime_error &e) {
73 throw std::runtime_error("Error setting parameter '" + skey +
74 "': " + e.what());
75 }
76 }
77}
78
79template <class T>
80py::dict struct_to_dict_helper(const T &t) {
81 const auto &m = kwargs_to_struct_table<T>;
82 py::dict d;
83 for (auto &&[key, val] : m) {
84 py::object o = val.get(t);
85 if (py::hasattr(o, "to_dict"))
86 o = o.attr("to_dict")();
87 d[key.c_str()] = std::move(o);
88 }
89 return d;
90}
91
92template <class T>
93T kwargs_to_struct(const py::kwargs &kwargs) {
94 T t{};
96 return t;
97}
98
99template <class T>
100py::dict struct_to_dict(const T &t) {
101 return struct_to_dict_helper<T>(t);
102}
103
104template <class T>
105T var_kwargs_to_struct(const std::variant<T, py::dict> &p) {
106 return std::holds_alternative<T>(p)
107 ? std::get<T>(p)
108 : kwargs_to_struct<T>(std::get<py::dict>(p));
109}
110
112
113template <>
115 kwargs_to_struct_table<alpaqa::PANOCParams>{
116 {"Lipschitz", &alpaqa::PANOCParams::Lipschitz},
117 {"max_iter", &alpaqa::PANOCParams::max_iter},
118 {"max_time", &alpaqa::PANOCParams::max_time},
119 {"τ_min", &alpaqa::PANOCParams::τ_min},
120 {"L_min", &alpaqa::PANOCParams::L_min},
121 {"L_max", &alpaqa::PANOCParams::L_max},
122 {"stop_crit", &alpaqa::PANOCParams::stop_crit},
123 {"max_no_progress", &alpaqa::PANOCParams::max_no_progress},
124 {"print_interval", &alpaqa::PANOCParams::print_interval},
125 {"quadratic_upperbound_tolerance_factor",
127 {"update_lipschitz_in_linesearch",
129 {"alternative_linesearch_cond",
131 {"lbfgs_stepsize", &alpaqa::PANOCParams::lbfgs_stepsize},
132 };
133
134template <>
136 kwargs_to_struct_table<alpaqa::LipschitzEstimateParams>{
141 };
142
143#include <alpaqa/inner/pga.hpp>
144
145template <>
147 kwargs_to_struct_table<alpaqa::PGAParams>{
148 {"Lipschitz", &alpaqa::PGAParams::Lipschitz},
149 {"max_iter", &alpaqa::PGAParams::max_iter},
150 {"max_time", &alpaqa::PGAParams::max_time},
151 {"L_min", &alpaqa::PGAParams::L_min},
152 {"L_max", &alpaqa::PGAParams::L_max},
153 {"stop_crit", &alpaqa::PGAParams::stop_crit},
154 {"print_interval", &alpaqa::PGAParams::print_interval},
155 {"quadratic_upperbound_tolerance_factor",
157 };
158
160
161template <>
163 kwargs_to_struct_table<alpaqa::GAAPGAParams>{
164 {"Lipschitz", &alpaqa::GAAPGAParams::Lipschitz},
165 {"limitedqr_mem", &alpaqa::GAAPGAParams::limitedqr_mem},
166 {"max_iter", &alpaqa::GAAPGAParams::max_iter},
167 {"max_time", &alpaqa::GAAPGAParams::max_time},
168 {"L_min", &alpaqa::GAAPGAParams::L_min},
169 {"L_max", &alpaqa::GAAPGAParams::L_max},
170 {"stop_crit", &alpaqa::GAAPGAParams::stop_crit},
171 {"print_interval", &alpaqa::GAAPGAParams::print_interval},
172 {"quadratic_upperbound_tolerance_factor",
174 {"max_no_progress", &alpaqa::GAAPGAParams::max_no_progress},
175 {"full_flush_on_γ_change", &alpaqa::GAAPGAParams::full_flush_on_γ_change},
176 };
177
179
180template <>
182 kwargs_to_struct_table<alpaqa::StructuredPANOCLBFGSParams>{
189 {"nonmonotone_linesearch",
194 {"quadratic_upperbound_tolerance_factor",
195 &alpaqa::StructuredPANOCLBFGSParams::
196 quadratic_upperbound_tolerance_factor},
197 {"update_lipschitz_in_linesearch",
199 {"alternative_linesearch_cond",
202 {"hessian_vec_finite_differences",
204 {"full_augmented_hessian",
206 {"hessian_step_size_heuristic",
209 };
210
212
213template <>
215 kwargs_to_struct_table<alpaqa::LBFGSParams>{
216 {"memory", &alpaqa::LBFGSParams::memory},
217 {"cbfgs", &alpaqa::LBFGSParams::cbfgs},
218 {"rescale_when_γ_changes", &alpaqa::LBFGSParams::rescale_when_γ_changes},
219 };
220
221template <>
224 {"α", &decltype(alpaqa::LBFGSParams::cbfgs)::α},
225 {"ϵ", &decltype(alpaqa::LBFGSParams::cbfgs)::ϵ},
226 };
227
228#include <alpaqa/decl/alm.hpp>
229
230template <>
232 kwargs_to_struct_table<alpaqa::ALMParams>{
233 {"ε", &alpaqa::ALMParams::ε},
234 {"δ", &alpaqa::ALMParams::δ},
235 {"Δ", &alpaqa::ALMParams::Δ},
236 {"Δ_lower", &alpaqa::ALMParams::Δ_lower},
237 {"Σ_0", &alpaqa::ALMParams::Σ₀},
238 {"σ_0", &alpaqa::ALMParams::σ₀},
239 {"Σ_0_lower", &alpaqa::ALMParams::Σ₀_lower},
240 {"ε_0", &alpaqa::ALMParams::ε₀},
241 {"ε_0_increase", &alpaqa::ALMParams::ε₀_increase},
242 {"ρ", &alpaqa::ALMParams::ρ},
243 {"ρ_increase", &alpaqa::ALMParams::ρ_increase},
244 {"θ", &alpaqa::ALMParams::θ},
245 {"M", &alpaqa::ALMParams::M},
246 {"Σ_max", &alpaqa::ALMParams::Σ_max},
247 {"Σ_min", &alpaqa::ALMParams::Σ_min},
248 {"max_iter", &alpaqa::ALMParams::max_iter},
249 {"max_time", &alpaqa::ALMParams::max_time},
250 {"max_num_initial_retries", &alpaqa::ALMParams::max_num_initial_retries},
251 {"max_num_retries", &alpaqa::ALMParams::max_num_retries},
252 {"max_total_num_retries", &alpaqa::ALMParams::max_total_num_retries},
253 {"print_interval", &alpaqa::ALMParams::print_interval},
254 {"preconditioning", &alpaqa::ALMParams::preconditioning},
255 {"single_penalty_factor", &alpaqa::ALMParams::single_penalty_factor},
256 };
std::function< py::object(const T &)> get
attr_setter_fun_t(A T::*attr)
std::function< void(T &, const py::handle &)> set
py::dict struct_to_dict(const T &t)
void kwargs_to_struct_helper(T &t, const py::kwargs &kwargs)
std::map< std::string, attr_setter_fun_t< T > > kwargs_to_struct_table_t
kwargs_to_struct_table_t< T > kwargs_to_struct_table
auto attr_setter(A T::*attr)
T kwargs_to_struct(const py::kwargs &kwargs)
T var_kwargs_to_struct(const std::variant< T, py::dict > &p)
auto attr_getter(A T::*attr)
py::dict struct_to_dict_helper(const T &t)
int m
Definition: test.py:41
real_t Δ_lower
Factor to reduce ALMParams::Δ when inner convergence fails.
Definition: decl/alm.hpp:21
real_t Σ_min
Minimum penalty factor (used during initialization).
Definition: decl/alm.hpp:50
LipschitzEstimateParams Lipschitz
Parameters related to the Lipschitz constant estimate and step size.
real_t ε₀_increase
Factor to increase the initial primal tolerance if convergence fails in the first iteration.
Definition: decl/alm.hpp:37
real_t θ
Error tolerance for penalty increase.
Definition: decl/alm.hpp:44
real_t ε₀
Initial primal tolerance.
Definition: decl/alm.hpp:34
unsigned max_total_num_retries
Combined limit for ALMParams::max_num_initial_retries and ALMParams::max_num_retries.
Definition: decl/alm.hpp:65
real_t Lγ_factor
Factor that relates step size γ and Lipschitz constant.
Definition: lipschitz.hpp:15
real_t Δ
Factor used in updating the penalty parameters.
Definition: decl/alm.hpp:19
unsigned limitedqr_mem
Length of the history to keep in the limited-memory QR algorithm.
real_t Σ₀_lower
Factor to reduce the initial penalty factor by if convergence fails in in the first iteration.
Definition: decl/alm.hpp:32
real_t δ
Minimum step size for initial finite difference Lipschitz estimate.
Definition: lipschitz.hpp:13
unsigned max_no_progress
Maximum number of iterations without any progress before giving up.
real_t L_max
Maximum Lipschitz constant estimate.
real_t σ₀
Initial penalty parameter factor.
Definition: decl/alm.hpp:29
real_t ρ
Update factor for primal tolerance.
Definition: decl/alm.hpp:39
unsigned int max_iter
Maximum number of outer ALM iterations.
Definition: decl/alm.hpp:52
unsigned memory
Length of the history to keep.
Definition: decl/lbfgs.hpp:14
std::chrono::microseconds max_time
Maximum duration.
unsigned max_num_retries
How many times can the penalty update factor ALMParams::Δ and the primal tolerance factor ALMParams::...
Definition: decl/alm.hpp:62
real_t Σ₀
Initial penalty parameter.
Definition: decl/alm.hpp:26
real_t ε
Relative step size for initial finite difference Lipschitz estimate.
Definition: lipschitz.hpp:11
real_t L₀
Initial estimate of the Lipschitz constant of ∇ψ(x)
Definition: lipschitz.hpp:9
unsigned max_num_initial_retries
How many times can the initial penalty ALMParams::Σ₀ or ALMParams::σ₀ and the initial primal toleranc...
Definition: decl/alm.hpp:59
struct alpaqa::LBFGSParams::@0 cbfgs
Parameters in the cautious BFGS update condition.
real_t quadratic_upperbound_tolerance_factor
unsigned print_interval
When to print progress.
real_t τ_min
Minimum weight factor between Newton step and projected gradient step.
real_t L_min
Minimum Lipschitz constant estimate.
real_t ρ_increase
Factor to increase the primal tolerance update factor by if convergence fails.
Definition: decl/alm.hpp:42
LBFGSStepSize lbfgs_stepsize
bool preconditioning
Apply preconditioning to the problem, based on the gradients in the starting point.
Definition: decl/alm.hpp:73
unsigned max_iter
Maximum number of inner PANOC iterations.
PANOCStopCrit stop_crit
What stopping criterion to use.
bool single_penalty_factor
Use one penalty factor for all m constraints.
Definition: decl/alm.hpp:75
real_t Σ_max
Maximum penalty factor.
Definition: decl/alm.hpp:48
real_t M
Lagrange multiplier bound.
Definition: decl/alm.hpp:46
real_t nonmonotone_linesearch
Factor used in update for exponentially weighted nonmonotone line search.
A
Definition: main.py:10
cast_error_with_types(const py::cast_error &e, std::string from, std::string to)