PANOC-ALM main
Nonconvex constrained optimization
panocpy.cpp
Go to the documentation of this file.
1
16
17#if PANOCPY_HAVE_CASADI
19#endif
20
21#include <pybind11/attr.h>
22#include <pybind11/cast.h>
23#include <pybind11/chrono.h>
24#include <pybind11/detail/common.h>
25#include <pybind11/eigen.h>
26#include <pybind11/functional.h>
27#include <pybind11/iostream.h>
28#include <pybind11/pybind11.h>
29#include <pybind11/pytypes.h>
30#include <pybind11/stl.h>
31
32#include <memory>
33#include <optional>
34#include <stdexcept>
35#include <string>
36#include <tuple>
37#include <type_traits>
38#include <utility>
39
40#include "kwargs-to-struct.hpp"
43#include "problem.hpp"
44
45namespace py = pybind11;
46
47template <class DirectionProviderT>
49 return [](const std::variant<pa::PANOCParams, py::dict> &pp,
50 const DirectionProviderT &dir) {
52 static_assert(std::is_base_of_v<Base, DirectionProviderT>);
53 auto full_python_copy = std::make_shared<py::object>(py::cast(dir));
54 auto base_copy = full_python_copy->template cast<Base *>();
55 return std::make_shared<pa::PolymorphicPANOCSolver>(
58 std::shared_ptr<Base>(full_python_copy, base_copy),
59 });
60 };
61}
62
63template <class DirectionProviderT, class... DirectionArgumentsT>
65 return [](const std::variant<pa::PANOCParams, py::dict> &pp,
66 const DirectionArgumentsT &...args) {
68 static_assert(std::is_base_of_v<Base, DirectionProviderT>);
69 static_assert(std::is_constructible_v<DirectionProviderT,
70 DirectionArgumentsT...>);
71 DirectionProviderT dir{args...};
72 return PolymorphicPANOCConstructor<DirectionProviderT>()(pp, dir);
73 };
74}
75
76template <class DirectionProviderT>
78 return [](const std::variant<pa::PANOCParams, py::dict> &pp,
79 const std::variant<pa::LBFGSParams, py::dict> &args) {
80 return PolymorphicPANOCConversion<DirectionProviderT,
82 pp, var_kwargs_to_struct(args));
83 };
84}
85
86template <class InnerSolverT>
88 return [](const std::variant<pa::ALMParams, py::dict> &pp,
89 const InnerSolverT &inner) {
91 static_assert(std::is_base_of_v<Base, InnerSolverT>);
92 auto full_python_copy = std::make_shared<py::object>(py::cast(inner));
93 auto base_copy = full_python_copy->template cast<Base *>();
95 var_kwargs_to_struct<pa::ALMParams>(pp),
96 std::shared_ptr<Base>(full_python_copy, base_copy),
97 };
98 };
99}
100
101template <class InnerSolverT>
103 return [](const InnerSolverT &inner) {
104 return PolymorphicALMConstructor<InnerSolverT>()(pa::ALMParams(),
105 inner);
106 };
107}
108
109template <class InnerSolverT, class... InnerSolverArgumentsT>
111 return [](const std::variant<pa::ALMParams, py::dict> &pp,
112 const InnerSolverArgumentsT &...args) {
114 static_assert(std::is_base_of_v<Base, InnerSolverT>);
115 static_assert(
116 std::is_constructible_v<InnerSolverT, InnerSolverArgumentsT...>);
117 InnerSolverT inner{args...};
118 return PolymorphicALMConstructor<InnerSolverT>()(pp, inner);
119 };
120}
121
122#define STRINGIFY(x) #x
123#define MACRO_STRINGIFY(x) STRINGIFY(x)
124
125PYBIND11_MODULE(PANOCPY_MODULE_NAME, m) {
126 using py::operator""_a;
127
128 py::options options;
129 options.enable_function_signatures();
130 options.enable_user_defined_docstrings();
131
132 m.doc() = "PANOC+ALM solvers"; // TODO
133
134#ifdef VERSION_INFO
135 m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
136#else
137 m.attr("__version__") = "dev";
138#endif
139
140 py::class_<pa::Box>(m, "Box", "C++ documentation: :cpp:class:`pa::Box`")
141 .def(py::init([](unsigned n) {
142 return pa::Box{pa::vec::Constant(n, pa::inf),
143 pa::vec::Constant(n, -pa::inf)};
144 }),
145 "n"_a,
146 "Create an :math:`n`-dimensional box at with bounds at "
147 ":math:`\\pm\\infty` (no constraints).")
148 .def(py::init([](pa::vec ub, pa::vec lb) {
149 if (ub.size() != lb.size())
150 throw std::invalid_argument(
151 "Upper bound and lower bound dimensions do not "
152 "match");
153 return pa::Box{std::move(ub), std::move(lb)};
154 }),
155 "ub"_a, "lb"_a, "Create a box with the given bounds.")
156 .def_readwrite("upperbound", &pa::Box::upperbound)
157 .def_readwrite("lowerbound", &pa::Box::lowerbound);
158
159 py::class_<pa::Problem>(m, "Problem",
160 "C++ documentation: :cpp:class:`pa::Problem`")
161 // .def(py::init())
162 .def(py::init<unsigned, unsigned>(), "n"_a, "m"_a,
163 ":param n: Number of unknowns\n"
164 ":param m: Number of constraints")
165 .def_readwrite("n", &pa::Problem::n,
166 "Number of unknowns, dimension of :math:`x`")
167 .def_readwrite(
168 "m", &pa::Problem::m,
169 "Number of general constraints, dimension of :math:`g(x)`")
170 .def_readwrite("C", &pa::Problem::C, "Box constraints on :math:`x`")
171 .def_readwrite("D", &pa::Problem::D, "Box constraints on :math:`g(x)`")
172 .def_property("f", prob_getter_f(), prob_setter_f(),
173 "Objective funcion, :math:`f(x)`")
174 .def_property(
176 "Gradient of the objective function, :math:`\\nabla f(x)`")
177 .def_property("g", prob_getter_g(), prob_setter_g(),
178 "Constraint function, :math:`g(x)`")
179 .def_property("grad_g_prod", prob_getter_grad_g_prod(),
181 "Gradient of constraint function times vector, "
182 ":math:`\\nabla g(x)\\, v`")
183 .def_property("grad_gi", prob_getter_grad_gi(), prob_setter_grad_gi(),
184 "Gradient vector of the :math:`i`-th component of the "
185 "constriant function, :math:`\\nabla g_i(x)`")
186 .def_property(
188 "Hessian of the Lagrangian function, :math:`\\nabla^2_{xx} L(x,y)`")
189 .def_property("hess_L_prod", prob_getter_hess_L_prod(),
191 "Hessian of the Lagrangian function times vector, "
192 ":math:`\\nabla^2_{xx} L(x,y)\\, v`");
193
194 py::class_<pa::ProblemWithParam, pa::Problem>(
195 m, "ProblemWithParam",
196 "C++ documentation: :cpp:class:`pa::ProblemWithParam`\n\n"
197 "See :py:class:`panocpy._panocpy.Problem` for the full documentation.")
198 .def_readwrite("n", &pa::ProblemWithParam::n)
199 .def_readwrite("m", &pa::ProblemWithParam::m)
200 .def_readwrite("C", &pa::ProblemWithParam::C)
201 .def_readwrite("D", &pa::ProblemWithParam::D)
202 .def_property_readonly("f", prob_getter_f())
203 .def_property_readonly("grad_f", prob_getter_grad_f())
204 .def_property_readonly("g", prob_getter_g())
205 .def_property_readonly("grad_g_prod", prob_getter_grad_g_prod())
206 .def_property_readonly("grad_gi", prob_getter_grad_gi())
207 .def_property_readonly("hess_L", prob_getter_hess_L())
208 .def_property_readonly("hess_L_prod", prob_getter_hess_L_prod())
209 .def_property(
210 "param", py::overload_cast<>(&pa::ProblemWithParam::get_param),
212 if (param.size() != p.get_param().size())
213 throw std::invalid_argument(
214 "Invalid parameter dimension: got " +
215 std::to_string(param.size()) + ", should be " +
216 std::to_string(p.get_param().size()) + ".");
217 p.set_param(param);
218 },
219 "Parameter vector :math:`p` of the problem");
220
221 py::class_<pa::EvalCounter::EvalTimer>(
222 m, "EvalTimer",
223 "C++ documentation: "
224 ":cpp:class:`pa::EvalCounter::EvalTimer`\n\n")
225 .def(py::pickle(
226 [](const pa::EvalCounter::EvalTimer &p) { // __getstate__
227 return py::make_tuple(p.f, p.grad_f, p.g, p.grad_g_prod,
228 p.grad_gi, p.hess_L_prod, p.hess_L);
229 },
230 [](py::tuple t) { // __setstate__
231 if (t.size() != 7)
232 throw std::runtime_error("Invalid state!");
234 return T{
235 py::cast<decltype(T::f)>(t[0]),
236 py::cast<decltype(T::grad_f)>(t[1]),
237 py::cast<decltype(T::g)>(t[2]),
238 py::cast<decltype(T::grad_g_prod)>(t[3]),
239 py::cast<decltype(T::grad_gi)>(t[4]),
240 py::cast<decltype(T::hess_L_prod)>(t[5]),
241 py::cast<decltype(T::hess_L)>(t[6]),
242 };
243 }))
244 .def_readwrite("f", &pa::EvalCounter::EvalTimer::f)
245 .def_readwrite("grad_f", &pa::EvalCounter::EvalTimer::grad_f)
246 .def_readwrite("g", &pa::EvalCounter::EvalTimer::g)
247 .def_readwrite("grad_g_prod", &pa::EvalCounter::EvalTimer::grad_g_prod)
248 .def_readwrite("grad_gi", &pa::EvalCounter::EvalTimer::grad_gi)
249 .def_readwrite("hess_L_prod", &pa::EvalCounter::EvalTimer::hess_L_prod)
250 .def_readwrite("hess_L", &pa::EvalCounter::EvalTimer::hess_L);
251
252 py::class_<pa::EvalCounter>(m, "EvalCounter",
253 "C++ documentation: "
254 ":cpp:class:`pa::EvalCounter`\n\n")
255 .def(py::pickle(
256 [](const pa::EvalCounter &p) { // __getstate__
257 return py::make_tuple(p.f, p.grad_f, p.g, p.grad_g_prod,
258 p.grad_gi, p.hess_L_prod, p.hess_L,
259 p.time);
260 },
261 [](py::tuple t) { // __setstate__
262 if (t.size() != 8)
263 throw std::runtime_error("Invalid state!");
264 using T = pa::EvalCounter;
265 return T{
266 py::cast<decltype(T::f)>(t[0]),
267 py::cast<decltype(T::grad_f)>(t[1]),
268 py::cast<decltype(T::g)>(t[2]),
269 py::cast<decltype(T::grad_g_prod)>(t[3]),
270 py::cast<decltype(T::grad_gi)>(t[4]),
271 py::cast<decltype(T::hess_L_prod)>(t[5]),
272 py::cast<decltype(T::hess_L)>(t[6]),
273 py::cast<decltype(T::time)>(t[7]),
274 };
275 }))
276 .def_readwrite("f", &pa::EvalCounter::f)
277 .def_readwrite("grad_f", &pa::EvalCounter::grad_f)
278 .def_readwrite("g", &pa::EvalCounter::g)
279 .def_readwrite("grad_g_prod", &pa::EvalCounter::grad_g_prod)
280 .def_readwrite("grad_gi", &pa::EvalCounter::grad_gi)
281 .def_readwrite("hess_L_prod", &pa::EvalCounter::hess_L_prod)
282 .def_readwrite("hess_L", &pa::EvalCounter::hess_L)
283 .def_readwrite("time", &pa::EvalCounter::time);
284
285 py::class_<pa::ProblemWithCounters<pa::Problem>, pa::Problem>(
286 m, "ProblemWithCounters",
287 "C++ documentation: "
288 ":cpp:class:`pa::ProblemWithCounters<pa::Problem>`\n\n"
289 "See :py:class:`panocpy._panocpy.Problem` for the full documentation.")
290 .def(py::init<const pa::Problem &>(), "problem"_a)
291 .def_readwrite("n", &pa::ProblemWithCounters<pa::Problem>::n)
292 .def_readwrite("m", &pa::ProblemWithCounters<pa::Problem>::m)
293 .def_readwrite("C", &pa::ProblemWithCounters<pa::Problem>::C)
294 .def_readwrite("D", &pa::ProblemWithCounters<pa::Problem>::D)
295 .def_property_readonly("f", prob_getter_f())
296 .def_property_readonly("grad_f", prob_getter_grad_f())
297 .def_property_readonly("g", prob_getter_g())
298 .def_property_readonly("grad_g_prod", prob_getter_grad_g_prod())
299 .def_property_readonly("grad_gi", prob_getter_grad_gi())
300 .def_property_readonly("hess_L", prob_getter_hess_L())
301 .def_property_readonly("hess_L_prod", prob_getter_hess_L_prod())
302 .def_property_readonly(
303 "evaluations", [](const pa::ProblemWithCounters<pa::Problem> &p) {
304 return *p.evaluations;
305 });
306
307 py::class_<pa::ProblemWithCounters<pa::ProblemWithParam>,
309 m, "ProblemWithParamWithCounters",
310 "C++ documentation: "
311 ":cpp:class:`pa::ProblemWithCounters<pa::ProblemWithParam>`\n\n"
312 "See :py:class:`panocpy._panocpy.Problem` for the full documentation.")
313 .def(py::init<const pa::ProblemWithParam &>(), "problem"_a)
318 .def_property_readonly("f", prob_getter_f())
319 .def_property_readonly("grad_f", prob_getter_grad_f())
320 .def_property_readonly("g", prob_getter_g())
321 .def_property_readonly("grad_g_prod", prob_getter_grad_g_prod())
322 .def_property_readonly("grad_gi", prob_getter_grad_gi())
323 .def_property_readonly("hess_L", prob_getter_hess_L())
324 .def_property_readonly("hess_L_prod", prob_getter_hess_L_prod())
325 .def_property(
326 "param",
327 py::overload_cast<>(
331 if (param.size() != p.get_param().size())
332 throw std::invalid_argument(
333 "Invalid parameter dimension: got " +
334 std::to_string(param.size()) + ", should be " +
335 std::to_string(p.get_param().size()) + ".");
336 p.set_param(param);
337 },
338 "Parameter vector :math:`p` of the problem")
339 .def_property_readonly(
340 "evaluations",
342 return *p.evaluations;
343 });
344
346 std::shared_ptr<pa::PolymorphicPANOCDirectionBase>,
348 m, "PANOCDirection",
349 "Class that provides fast directions for the PANOC algorithm (e.g. "
350 "L-BFGS)")
351 .def(py::init<>())
359
360 using paLBFGSParamCBFGS = decltype(pa::LBFGSParams::cbfgs);
361 py::class_<paLBFGSParamCBFGS>(
362 m, "LBFGSParamsCBFGS",
363 "C++ documentation: :cpp:member:`pa::LBFGSParams::cbfgs`")
364 .def(py::init())
365 .def(py::init(&kwargs_to_struct<paLBFGSParamCBFGS>))
366 .def("to_dict", &struct_to_dict<paLBFGSParamCBFGS>)
367 .def_readwrite("α", &paLBFGSParamCBFGS::α)
368 .def_readwrite("ϵ", &paLBFGSParamCBFGS::ϵ);
369
370 py::class_<pa::LBFGSParams>(
371 m, "LBFGSParams", "C++ documentation: :cpp:class:`pa::LBFGSParams`")
372 .def(py::init())
373 .def(py::init(&kwargs_to_struct<pa::LBFGSParams>))
374 .def("to_dict", &struct_to_dict<pa::LBFGSParams>)
375 .def_readwrite("memory", &pa::LBFGSParams::memory)
376 .def_readwrite("cbfgs", &pa::LBFGSParams::cbfgs)
377 .def_readwrite("rescale_when_γ_changes",
379
381 std::shared_ptr<pa::PolymorphicLBFGSDirection>,
383 m, "LBFGSDirection",
384 "C++ documentation: :cpp:class:`pa::LBFGSDirection`")
385 .def(py::init<pa::LBFGSParams>(), "params"_a)
393 .def_property_readonly("params",
395
396 py::enum_<pa::LBFGSStepSize>(
397 m, "LBFGSStepsize", "C++ documentation: :cpp:enum:`pa::LBFGSStepSize`")
398 .value("BasedOnGradientStepSize",
400 .value("BasedOnCurvature", pa::LBFGSStepSize::BasedOnCurvature)
401 .export_values();
402
403 py::class_<pa::LipschitzEstimateParams>(
404 m, "LipschitzEstimateParams",
405 "C++ documentation: :cpp:class:`pa::LipschitzEstimateParams`")
406 .def(py::init())
407 .def(py::init(&kwargs_to_struct<pa::LipschitzEstimateParams>))
408 .def("to_dict", &struct_to_dict<pa::LipschitzEstimateParams>)
409 .def_readwrite("L_0", &pa::LipschitzEstimateParams::L₀)
410 .def_readwrite("ε", &pa::LipschitzEstimateParams::ε)
411 .def_readwrite("δ", &pa::LipschitzEstimateParams::δ)
412 .def_readwrite("Lγ_factor", &pa::LipschitzEstimateParams::Lγ_factor);
413
414 py::class_<pa::PANOCParams>(
415 m, "PANOCParams", "C++ documentation: :cpp:class:`pa::PANOCParams`")
416 .def(py::init())
417 .def(py::init(&kwargs_to_struct<pa::PANOCParams>))
418 .def("to_dict", &struct_to_dict<pa::PANOCParams>)
419 .def_readwrite("Lipschitz", &pa::PANOCParams::Lipschitz)
420 .def_readwrite("max_iter", &pa::PANOCParams::max_iter)
421 .def_readwrite("max_time", &pa::PANOCParams::max_time)
422 .def_readwrite("τ_min", &pa::PANOCParams::τ_min)
423 .def_readwrite("L_min", &pa::PANOCParams::L_min)
424 .def_readwrite("L_max", &pa::PANOCParams::L_max)
425 .def_readwrite("max_no_progress", &pa::PANOCParams::max_no_progress)
426 .def_readwrite("print_interval", &pa::PANOCParams::print_interval)
427 .def_readwrite("quadratic_upperbound_tolerance_factor",
429 .def_readwrite("update_lipschitz_in_linesearch",
431 .def_readwrite("alternative_linesearch_cond",
433 .def_readwrite("lbfgs_stepsize", &pa::PANOCParams::lbfgs_stepsize);
434
435 py::enum_<pa::SolverStatus>(
436 m, "SolverStatus", py::arithmetic(),
437 "C++ documentation: :cpp:enum:`pa::SolverStatus`")
438 .value("Unknown", pa::SolverStatus::Unknown, "Initial value")
439 .value("Converged", pa::SolverStatus::Converged,
440 "Converged and reached given tolerance")
441 .value("MaxTime", pa::SolverStatus::MaxTime,
442 "Maximum allowed execution time exceeded")
443 .value("MaxIter", pa::SolverStatus::MaxIter,
444 "Maximum number of iterations exceeded")
445 .value("NotFinite", pa::SolverStatus::NotFinite,
446 "Intermediate results were infinite or not-a-number")
447 .value("NoProgress", pa::SolverStatus::NoProgress,
448 "No progress was made in the last iteration")
449 .value("Interrupted", pa::SolverStatus::Interrupted,
450 "Solver was interrupted by the user")
451 .export_values();
452
453 py::class_<pa::PolymorphicInnerSolverBase::Stats>(m, "InnerSolverStats")
455
457 std::shared_ptr<pa::PolymorphicInnerSolverBase>,
459 .def(py::init<>())
460 .def("__call__", &pa::PolymorphicInnerSolverBase::operator())
464
465 py::enum_<pa::PANOCStopCrit>(
466 m, "PANOCStopCrit", "C++ documentation: :cpp:enum:`pa::PANOCStopCrit`")
467 .value("ApproxKKT", pa::PANOCStopCrit::ApproxKKT)
468 .value("ApproxKKT2", pa::PANOCStopCrit::ApproxKKT2)
469 .value("ProjGradNorm", pa::PANOCStopCrit::ProjGradNorm)
470 .value("ProjGradNorm2", pa::PANOCStopCrit::ProjGradNorm2)
471 .value("ProjGradUnitNorm", pa::PANOCStopCrit::ProjGradUnitNorm)
472 .value("ProjGradUnitNorm2", pa::PANOCStopCrit::ProjGradUnitNorm2)
473 .value("FPRNorm", pa::PANOCStopCrit::FPRNorm)
474 .value("FPRNorm2", pa::PANOCStopCrit::FPRNorm2)
475 .value("Ipopt", pa::PANOCStopCrit::Ipopt)
476 .export_values();
477
478 py::class_<pa::PGAParams>(m, "PGAParams",
479 "C++ documentation: :cpp:class:`pa::PGAParams`")
480 .def(py::init())
481 .def(py::init(&kwargs_to_struct<pa::PGAParams>))
482 .def("to_dict", &struct_to_dict<pa::PGAParams>)
483 .def_readwrite("Lipschitz", &pa::PGAParams::Lipschitz)
484 .def_readwrite("max_iter", &pa::PGAParams::max_iter)
485 .def_readwrite("max_time", &pa::PGAParams::max_time)
486 .def_readwrite("L_min", &pa::PGAParams::L_min)
487 .def_readwrite("L_max", &pa::PGAParams::L_max)
488 .def_readwrite("stop_crit", &pa::PGAParams::stop_crit)
489 .def_readwrite("print_interval", &pa::PGAParams::print_interval)
490 .def_readwrite("quadratic_upperbound_tolerance_factor",
492
493 py::class_<pa::PGAProgressInfo>(
494 m, "PGAProgressInfo",
495 "C++ documentation: :cpp:class:`pa::PGAProgressInfo`")
496 .def_readonly("k", &pa::PGAProgressInfo::k)
497 .def_readonly("x", &pa::PGAProgressInfo::x)
498 .def_readonly("p", &pa::PGAProgressInfo::p)
499 .def_readonly("norm_sq_p", &pa::PGAProgressInfo::norm_sq_p)
500 .def_readonly("x_hat", &pa::PGAProgressInfo::x_hat)
501 .def_readonly("ψ", &pa::PGAProgressInfo::ψ)
502 .def_readonly("grad_ψ", &pa::PGAProgressInfo::grad_ψ)
503 .def_readonly("ψ_hat", &pa::PGAProgressInfo::ψ_hat)
504 .def_readonly("grad_ψ_hat", &pa::PGAProgressInfo::grad_ψ_hat)
505 .def_readonly("L", &pa::PGAProgressInfo::L)
506 .def_readonly("γ", &pa::PGAProgressInfo::γ)
507 .def_readonly("ε", &pa::PGAProgressInfo::ε)
508 .def_readonly("Σ", &pa::PGAProgressInfo::Σ)
509 .def_readonly("y", &pa::PGAProgressInfo::y)
510 .def_property_readonly("fpr", [](const pa::PGAProgressInfo &p) {
511 return std::sqrt(p.norm_sq_p) / p.γ;
512 });
513
514 py::class_<pa::GAAPGAParams>(
515 m, "GAAPGAParams", "C++ documentation: :cpp:class:`pa::GAAPGAParams`")
516 .def(py::init())
517 .def(py::init(&kwargs_to_struct<pa::GAAPGAParams>))
518 .def("to_dict", &struct_to_dict<pa::GAAPGAParams>)
519 .def_readwrite("Lipschitz", &pa::GAAPGAParams::Lipschitz)
520 .def_readwrite("limitedqr_mem", &pa::GAAPGAParams::limitedqr_mem)
521 .def_readwrite("max_iter", &pa::GAAPGAParams::max_iter)
522 .def_readwrite("max_time", &pa::GAAPGAParams::max_time)
523 .def_readwrite("L_min", &pa::GAAPGAParams::L_min)
524 .def_readwrite("L_max", &pa::GAAPGAParams::L_max)
525 .def_readwrite("stop_crit", &pa::GAAPGAParams::stop_crit)
526 .def_readwrite("print_interval", &pa::GAAPGAParams::print_interval)
527 .def_readwrite("quadratic_upperbound_tolerance_factor",
529 .def_readwrite("max_no_progress", &pa::GAAPGAParams::max_no_progress)
530 .def_readwrite("full_flush_on_γ_change",
532
533 py::class_<pa::GAAPGAProgressInfo>(
534 m, "GAAPGAProgressInfo",
535 "C++ documentation: :cpp:class:`pa::GAAPGAProgressInfo`")
536 .def_readonly("k", &pa::GAAPGAProgressInfo::k)
537 .def_readonly("x", &pa::GAAPGAProgressInfo::x)
538 .def_readonly("p", &pa::GAAPGAProgressInfo::p)
539 .def_readonly("norm_sq_p", &pa::GAAPGAProgressInfo::norm_sq_p)
540 .def_readonly("x_hat", &pa::GAAPGAProgressInfo::x_hat)
541 .def_readonly("ψ", &pa::GAAPGAProgressInfo::ψ)
542 .def_readonly("grad_ψ", &pa::GAAPGAProgressInfo::grad_ψ)
543 .def_readonly("ψ_hat", &pa::GAAPGAProgressInfo::ψ_hat)
544 .def_readonly("grad_ψ_hat", &pa::GAAPGAProgressInfo::grad_ψ_hat)
545 .def_readonly("L", &pa::GAAPGAProgressInfo::L)
546 .def_readonly("γ", &pa::GAAPGAProgressInfo::γ)
547 .def_readonly("ε", &pa::GAAPGAProgressInfo::ε)
548 .def_readonly("Σ", &pa::GAAPGAProgressInfo::Σ)
549 .def_readonly("y", &pa::GAAPGAProgressInfo::y)
550 .def_property_readonly("fpr", [](const pa::GAAPGAProgressInfo &p) {
551 return std::sqrt(p.norm_sq_p) / p.γ;
552 });
553
554 py::class_<pa::PANOCProgressInfo>(
555 m, "PANOCProgressInfo",
556 "Data passed to the PANOC progress callback.\n\n"
557 "C++ documentation: :cpp:class:`pa::PANOCProgressInfo`")
558 .def_readonly("k", &pa::PANOCProgressInfo::k, //
559 "Iteration")
560 .def_readonly("x", &pa::PANOCProgressInfo::x, //
561 "Decision variable :math:`x`")
562 .def_readonly("p", &pa::PANOCProgressInfo::p, //
563 "Projected gradient step :math:`p`")
564 .def_readonly("norm_sq_p", &pa::PANOCProgressInfo::norm_sq_p, //
565 ":math:`\\left\\|p\\right\\|^2`")
566 .def_readonly(
567 "x_hat", &pa::PANOCProgressInfo::x_hat, //
568 "Decision variable after projected gradient step :math:`\\hat x`")
569 .def_readonly("φγ", &pa::PANOCProgressInfo::φγ, //
570 "Forward-backward envelope :math:`\\varphi_\\gamma(x)`")
571 .def_readonly("ψ", &pa::PANOCProgressInfo::ψ, //
572 "Objective value :math:`\\psi(x)`")
573 .def_readonly("grad_ψ", &pa::PANOCProgressInfo::grad_ψ, //
574 "Gradient of objective :math:`\\nabla\\psi(x)`")
575 .def_readonly("ψ_hat", &pa::PANOCProgressInfo::ψ_hat)
576 .def_readonly("grad_ψ_hat", &pa::PANOCProgressInfo::grad_ψ_hat)
577 .def_readonly("L", &pa::PANOCProgressInfo::L, //
578 "Estimate of Lipschitz constant of objective :math:`L`")
579 .def_readonly("γ", &pa::PANOCProgressInfo::γ,
580 "Step size :math:`\\gamma`")
581 .def_readonly("τ", &pa::PANOCProgressInfo::τ, //
582 "Line search parameter :math:`\\tau`")
583 .def_readonly("ε", &pa::PANOCProgressInfo::ε, //
584 "Tolerance reached :math:`\\varepsilon_k`")
585 .def_readonly("Σ", &pa::PANOCProgressInfo::Σ, //
586 "Penalty factor :math:`\\Sigma`")
587 .def_readonly("y", &pa::PANOCProgressInfo::y, //
588 "Lagrange multipliers :math:`y`")
589 .def_property_readonly(
590 "fpr",
591 [](const pa::PANOCProgressInfo &p) {
592 return std::sqrt(p.norm_sq_p) / p.γ;
593 },
594 "Fixed-point residual :math:`\\left\\|p\\right\\| / \\gamma`");
595
596 py::class_<pa::StructuredPANOCLBFGSProgressInfo>(
597 m, "StructuredPANOCLBFGSProgressInfo",
598 "Data passed to the structured PANOC progress callback.\n\n"
599 "C++ documentation: :cpp:class:`pa::StructuredPANOCLBFGSProgressInfo`")
600 .def_readonly("k", &pa::StructuredPANOCLBFGSProgressInfo::k)
601 .def_readonly("x", &pa::StructuredPANOCLBFGSProgressInfo::x)
602 .def_readonly("p", &pa::StructuredPANOCLBFGSProgressInfo::p)
603 .def_readonly("norm_sq_p",
605 .def_readonly("x_hat", &pa::StructuredPANOCLBFGSProgressInfo::x_hat)
606 .def_readonly("φγ", &pa::StructuredPANOCLBFGSProgressInfo::φγ)
607 .def_readonly("ψ", &pa::StructuredPANOCLBFGSProgressInfo::ψ)
608 .def_readonly("grad_ψ", &pa::StructuredPANOCLBFGSProgressInfo::grad_ψ)
609 .def_readonly("ψ_hat", &pa::StructuredPANOCLBFGSProgressInfo::ψ_hat)
610 .def_readonly("grad_ψ_hat",
612 .def_readonly("L", &pa::StructuredPANOCLBFGSProgressInfo::L)
613 .def_readonly("γ", &pa::StructuredPANOCLBFGSProgressInfo::γ)
614 .def_readonly("τ", &pa::StructuredPANOCLBFGSProgressInfo::τ)
615 .def_readonly("ε", &pa::StructuredPANOCLBFGSProgressInfo::ε)
616 .def_readonly("Σ", &pa::StructuredPANOCLBFGSProgressInfo::Σ)
617 .def_readonly("y", &pa::StructuredPANOCLBFGSProgressInfo::y)
618 .def_property_readonly(
619 "fpr", [](const pa::StructuredPANOCLBFGSProgressInfo &p) {
620 return std::sqrt(p.norm_sq_p) / p.γ;
621 });
622
624 std::shared_ptr<pa::PolymorphicPANOCSolver>,
626 m, "PANOCSolver", "C++ documentation: :cpp:class:`pa::PANOCSolver`")
627 .def(py::init([] {
628 return std::make_shared<pa::PolymorphicPANOCSolver>(
631 std::static_pointer_cast<pa::PolymorphicPANOCDirectionBase>(
632 std::make_shared<pa::PolymorphicLBFGSDirection>(
633 pa::LBFGSParams{}))});
634 }))
635 .def(py::init(PolymorphicPANOCConstructor< //
637 "panoc_params"_a, "lbfgs_direction"_a)
638 .def(py::init(PolymorphicPANOCDefaultConversion< //
640 "panoc_params"_a, "lbfgs_params"_a)
641 .def(py::init(PolymorphicPANOCConstructor< //
643 "panoc_params"_a, "direction"_a)
644 .def(
645 "set_progress_callback",
647 "Attach a callback that is called on each iteration of the solver.")
648 .def("__call__",
649 pa::InnerSolverCallWrapper<pa::PolymorphicPANOCSolver>(),
650 py::call_guard<py::scoped_ostream_redirect,
651 py::scoped_estream_redirect>(),
652 "problem"_a, "Σ"_a, "ε"_a, "x"_a,
653 "y"_a, //
654 "Solve.\n\n"
655 ":param problem: Problem to solve\n"
656 ":param Σ: Penalty factor\n"
657 ":param ε: Desired tolerance\n"
658 ":param x: Initial guess\n"
659 ":param y: Initial Lagrange multipliers\n\n"
660 ":return: * Solution :math:`x`\n"
661 " * Updated Lagrange multipliers :math:`y`\n"
662 " * Slack variable error :math:`g(x) - z`\n"
663 " * Statistics\n\n")
665 .def_property_readonly("params",
667 .def_property_readonly(
668 "direction", [](const pa::PolymorphicPANOCSolver &s) {
669 return s.innersolver.direction_provider.direction;
670 });
671
672 py::class_<pa::PolymorphicPGASolver,
673 std::shared_ptr<pa::PolymorphicPGASolver>,
675 m, "PGASolver", "C++ documentation: :cpp:class:`pa::PGASolver`")
676 .def(py::init<pa::PGAParams>())
677 .def(
678 "set_progress_callback",
680 "Attach a callback that is called on each iteration of the solver.")
681 .def("__call__", pa::InnerSolverCallWrapper<pa::PolymorphicPGASolver>(),
682 py::call_guard<py::scoped_ostream_redirect,
683 py::scoped_estream_redirect>(),
684 "problem"_a, "Σ"_a, "ε"_a, "x"_a,
685 "y"_a, //
686 "Solve.\n\n"
687 ":param problem: Problem to solve\n"
688 ":param Σ: Penalty factor\n"
689 ":param ε: Desired tolerance\n"
690 ":param x: Initial guess\n"
691 ":param y: Initial Lagrange multipliers\n\n"
692 ":return: * Solution :math:`x`\n"
693 " * Updated Lagrange multipliers :math:`y`\n"
694 " * Slack variable error :math:`g(x) - z`\n"
695 " * Statistics\n\n")
696 .def("__str__", &pa::PolymorphicPGASolver::get_name)
697 .def_property_readonly("params", &pa::PolymorphicPGASolver::get_params);
698
700 std::shared_ptr<pa::PolymorphicGAAPGASolver>,
702 m, "GAAPGASolver", "C++ documentation: :cpp:class:`pa::GAAPGASolver`")
703 .def(py::init<pa::GAAPGAParams>())
704 .def(
705 "set_progress_callback",
707 "Attach a callback that is called on each iteration of the solver.")
708 .def("__call__",
709 pa::InnerSolverCallWrapper<pa::PolymorphicGAAPGASolver>(),
710 py::call_guard<py::scoped_ostream_redirect,
711 py::scoped_estream_redirect>(),
712 "problem"_a, "Σ"_a, "ε"_a, "x"_a,
713 "y"_a, //
714 "Solve.\n\n"
715 ":param problem: Problem to solve\n"
716 ":param Σ: Penalty factor\n"
717 ":param ε: Desired tolerance\n"
718 ":param x: Initial guess\n"
719 ":param y: Initial Lagrange multipliers\n\n"
720 ":return: * Solution :math:`x`\n"
721 " * Updated Lagrange multipliers :math:`y`\n"
722 " * Slack variable error :math:`g(x) - z`\n"
723 " * Statistics\n\n")
725 .def_property_readonly("params",
727
728 py::class_<pa::StructuredPANOCLBFGSParams>(
729 m, "StructuredPANOCLBFGSParams",
730 "C++ documentation: :cpp:class:`pa::StructuredPANOCLBFGSParams`")
731 .def(py::init(&kwargs_to_struct<pa::StructuredPANOCLBFGSParams>))
732 .def("to_dict", &struct_to_dict<pa::StructuredPANOCLBFGSParams>)
733
734 .def_readwrite("Lipschitz", &pa::StructuredPANOCLBFGSParams::Lipschitz)
735 .def_readwrite("max_iter", &pa::StructuredPANOCLBFGSParams::max_iter)
736 .def_readwrite("max_time", &pa::StructuredPANOCLBFGSParams::max_time)
737 .def_readwrite("τ_min", &pa::StructuredPANOCLBFGSParams::τ_min)
738 .def_readwrite("L_min", &pa::StructuredPANOCLBFGSParams::L_min)
739 .def_readwrite("L_max", &pa::StructuredPANOCLBFGSParams::L_max)
740 .def_readwrite("nonmonotone_linesearch",
742 .def_readwrite("stop_crit", &pa::StructuredPANOCLBFGSParams::stop_crit)
743 .def_readwrite("max_no_progress",
745 .def_readwrite("print_interval",
747 .def_readwrite("quadratic_upperbound_tolerance_factor",
749 quadratic_upperbound_tolerance_factor)
750 .def_readwrite(
751 "update_lipschitz_in_linesearch",
753 .def_readwrite(
754 "alternative_linesearch_cond",
756 .def_readwrite("hessian_vec",
758 .def_readwrite(
759 "hessian_vec_finite_differences",
761 .def_readwrite("full_augmented_hessian",
763 .def_readwrite(
764 "hessian_step_size_heuristic",
766 .def_readwrite("lbfgs_stepsize",
768
770 std::shared_ptr<pa::PolymorphicStructuredPANOCLBFGSSolver>,
772 m, "StructuredPANOCLBFGSSolver",
773 "C++ documentation: :cpp:class:`pa::StructuredPANOCLBFGSSolver`")
774 .def(py::init([] {
775 return std::make_shared<pa::PolymorphicStructuredPANOCLBFGSSolver>(
779 });
780 }))
781 .def(py::init([](const std::variant<pa::StructuredPANOCLBFGSParams,
782 py::dict> &pp,
783 const std::variant<pa::LBFGSParams, py::dict> &lp) {
784 return std::make_shared<
787 }),
788 "panoc_params"_a, "lbfgs_params"_a)
789 .def(
790 "set_progress_callback",
792 "callback"_a,
793 "Attach a callback that is called on each iteration of the solver.")
794 .def("__call__",
797 py::call_guard<py::scoped_ostream_redirect,
798 py::scoped_estream_redirect>(),
799 "problem"_a, "Σ"_a, "ε"_a, "x"_a,
800 "y"_a, //
801 "Solve.\n\n"
802 ":param problem: Problem to solve\n"
803 ":param Σ: Penalty factor\n"
804 ":param ε: Desired tolerance\n"
805 ":param x: Initial guess\n"
806 ":param y: Initial Lagrange multipliers\n\n"
807 ":return: * Solution :math:`x`\n"
808 " * Updated Lagrange multipliers :math:`y`\n"
809 " * Slack variable error :math:`g(x) - z`\n"
810 " * Statistics\n\n")
812 .def_property_readonly(
814
815 py::class_<pa::ALMParams>(m, "ALMParams",
816 "C++ documentation: :cpp:class:`pa::ALMParams`")
817 .def(py::init())
818 .def(py::init(&kwargs_to_struct<pa::ALMParams>))
819 .def("to_dict", &struct_to_dict<pa::ALMParams>)
820 .def_readwrite("ε", &pa::ALMParams::ε)
821 .def_readwrite("δ", &pa::ALMParams::δ)
822 .def_readwrite("Δ", &pa::ALMParams::Δ)
823 .def_readwrite("Δ_lower", &pa::ALMParams::Δ_lower)
824 .def_readwrite("Σ_0", &pa::ALMParams::Σ₀)
825 .def_readwrite("σ_0", &pa::ALMParams::σ₀)
826 .def_readwrite("Σ_0_lower", &pa::ALMParams::Σ₀_lower)
827 .def_readwrite("ε_0", &pa::ALMParams::ε₀)
828 .def_readwrite("ε_0_increase", &pa::ALMParams::ε₀_increase)
829 .def_readwrite("ρ", &pa::ALMParams::ρ)
830 .def_readwrite("ρ_increase", &pa::ALMParams::ρ_increase)
831 .def_readwrite("θ", &pa::ALMParams::θ)
832 .def_readwrite("M", &pa::ALMParams::M)
833 .def_readwrite("Σ_max", &pa::ALMParams::Σ_max)
834 .def_readwrite("Σ_min", &pa::ALMParams::Σ_min)
835 .def_readwrite("max_iter", &pa::ALMParams::max_iter)
836 .def_readwrite("max_time", &pa::ALMParams::max_time)
837 .def_readwrite("max_num_initial_retries",
839 .def_readwrite("max_num_retries", &pa::ALMParams::max_num_retries)
840 .def_readwrite("max_total_num_retries",
842 .def_readwrite("print_interval", &pa::ALMParams::print_interval)
843 .def_readwrite("preconditioning", &pa::ALMParams::preconditioning)
844 .def_readwrite("single_penalty_factor",
846
847 py::class_<pa::PolymorphicALMSolver>(
848 m, "ALMSolver",
849 "Main augmented Lagrangian solver.\n\n"
850 "C++ documentation: :cpp:class:`pa::ALMSolver`")
851 // Default constructor
852 .def(py::init([] {
855 std::static_pointer_cast<pa::PolymorphicInnerSolverBase>(
856 std::make_shared<
859 pa::LBFGSParams{})),
860 };
861 }),
862 "Build an ALM solver using Structured PANOC as inner solver.")
863 // Params and solver
864 .def(py::init(PolymorphicALMConstructor<pa::PolymorphicPANOCSolver>()),
865 "alm_params"_a, "panoc_solver"_a,
866 "Build an ALM solver using PANOC as inner solver.")
867 .def(py::init(PolymorphicALMConstructor<pa::PolymorphicPGASolver>()),
868 "alm_params"_a, "pga_solver"_a,
869 "Build an ALM solver using the projected gradient algorithm as "
870 "inner solver.")
871 .def(py::init(PolymorphicALMConstructor<
873 "alm_params"_a, "structuredpanoc_solver"_a,
874 "Build an ALM solver using Structured PANOC as inner solver.")
875 .def(py::init(PolymorphicALMConstructor<
877 "alm_params"_a, "inner_solver"_a,
878 "Build an ALM solver using a custom inner solver.")
879 // Only solver (default params)
882 "panoc_solver"_a,
883 "Build an ALM solver using PANOC as inner solver.")
886 "pga_solver"_a,
887 "Build an ALM solver using the projected gradient algorithm as "
888 "inner solver.")
891 "structuredpanoc_solver"_a,
892 "Build an ALM solver using Structured PANOC as inner solver.")
895 "inner_solver"_a,
896 "Build an ALM solver using a custom inner solver.")
897 // Only params (default solver)
898 .def(py::init([](const pa::ALMParams &params) {
900 params,
901 std::static_pointer_cast<pa::PolymorphicInnerSolverBase>(
902 std::make_shared<
905 pa::LBFGSParams{})),
906 };
907 }),
908 "alm_params"_a,
909 "Build an ALM solver using Structured PANOC as inner solver.")
910 // Other functions and properties
911 .def_property_readonly("inner_solver",
912 [](const pa::PolymorphicALMSolver &s) {
913 return s.inner_solver.solver;
914 })
915 .def(
916 "__call__",
918 std::optional<pa::vec> x, std::optional<pa::vec> y)
919 -> std::tuple<pa::vec, pa::vec, py::dict> {
920 if (!x)
921 x = pa::vec::Zero(p.n);
922 else if (x->size() != p.n)
923 throw std::invalid_argument(
924 "Length of x does not match problem size problem.n");
925 if (!y)
926 y = pa::vec::Zero(p.m);
927 else if (y->size() != p.m)
928 throw std::invalid_argument(
929 "Length of y does not match problem size problem.m");
930 if (p.C.lowerbound.size() != p.n)
931 throw std::invalid_argument(
932 "Length of problem.C.lowerbound does not match problem "
933 "size problem.n");
934 if (p.C.upperbound.size() != p.n)
935 throw std::invalid_argument(
936 "Length of problem.C.upperbound does not match problem "
937 "size problem.n");
938 if (p.D.lowerbound.size() != p.m)
939 throw std::invalid_argument(
940 "Length of problem.D.lowerbound does not match problem "
941 "size problem.m");
942 if (p.D.upperbound.size() != p.m)
943 throw std::invalid_argument(
944 "Length of problem.D.upperbound does not match problem "
945 "size problem.m");
946
947 auto stats = solver(p, *y, *x);
948 return std::make_tuple(std::move(*x), std::move(*y),
950 },
951 "problem"_a, "x"_a = std::nullopt, "y"_a = std::nullopt,
952 py::call_guard<py::scoped_ostream_redirect,
953 py::scoped_estream_redirect>(),
954 "Solve.\n\n"
955 ":param problem: Problem to solve.\n"
956 ":param y: Initial guess for Lagrange multipliers :math:`y`\n"
957 ":param x: Initial guess for decision variables :math:`x`\n\n"
958 ":return: * Lagrange multipliers :math:`y` at the solution\n"
959 " * Solution :math:`x`\n"
960 " * Statistics\n\n")
961 .def("__str__", &pa::PolymorphicALMSolver::get_name)
962 .def_property_readonly("params", &pa::PolymorphicALMSolver::get_params);
963
964 constexpr auto panoc = [](std::function<pa::real_t(pa::crvec)> ψ,
965 std::function<pa::vec(pa::crvec)> grad_ψ,
966 const pa::Box &C, std::optional<pa::vec> x0,
968 const pa::LBFGSParams &lbfgs_params) {
969 auto n = C.lowerbound.size();
970 if (C.upperbound.size() != n)
971 throw std::invalid_argument("Length of C.upperbound does not "
972 "match length of C.lowerbound");
973 if (!x0)
974 x0 = pa::vec::Zero(n);
975 else if (x0->size() != n)
976 throw std::invalid_argument(
977 "Length of x does not match length of bounds C");
978 auto grad_ψ_ = [&](pa::crvec x, pa::rvec gr) {
979 auto &&t = grad_ψ(x);
980 if (t.size() != x.size())
981 throw std::runtime_error("Invalid grad_ψ dimension");
982 gr = std::move(t);
983 };
984 auto stats =
985 pa::panoc<pa::LBFGS>(ψ, grad_ψ_, C, *x0, ε, params, {lbfgs_params});
986 return std::make_tuple(std::move(*x0), stats_to_dict(stats));
987 };
988
989 m.def("panoc", panoc, "ψ"_a, "grad_ψ"_a, "C"_a, "x0"_a = std::nullopt,
990 "ε"_a = 1e-8, "params"_a = pa::PANOCParams{},
991 "lbfgs_params"_a = pa::LBFGSParams{});
992
993#if !PANOCPY_HAVE_CASADI
994 auto load_CasADi_problem = [](const char *, unsigned, unsigned,
995 bool) -> pa::Problem {
996 throw std::runtime_error(
997 "This version of panocpy was compiled without CasADi support");
998 };
999 auto load_CasADi_problem_with_param = [](const char *, unsigned, unsigned,
1000 unsigned,
1001 bool) -> pa::ProblemWithParam {
1002 throw std::runtime_error(
1003 "This version of panocpy was compiled without CasADi support");
1004 };
1005#else
1008#endif
1009
1010 m.def("load_casadi_problem", load_CasADi_problem, "so_name"_a, "n"_a = 0,
1011 "m"_a = 0, "second_order"_a = false,
1012 "Load a compiled CasADi problem without parameters.\n\n"
1013 "C++ documentation: :cpp:func:`pa::load_CasADi_problem`");
1014 m.def("load_casadi_problem_with_param", load_CasADi_problem_with_param,
1015 "so_name"_a, "n"_a = 0, "m"_a = 0, "p"_a = 0,
1016 "second_order"_a = false,
1017 "Load a compiled CasADi problem with parameters.\n\n"
1018 "C++ documentation: :cpp:func:`pa::load_CasADi_problem_with_param`");
1019}
Augmented Lagrangian Method solver.
Definition: decl/alm.hpp:82
std::string get_name() const
Definition: decl/alm.hpp:142
const Params & get_params() const
Definition: decl/alm.hpp:150
PANOC solver for ALM.
virtual std::string get_name() const =0
virtual py::object get_params() const =0
py::object get_params() const override
void set_progress_callback(std::function< void(const typename InnerSolver::ProgressInfo &)> cb)
std::string get_name() const override
virtual void changed_γ(real_t γₖ, real_t old_γₖ)=0
virtual void initialize(crvec x₀, crvec x̂₀, crvec p₀, crvec grad₀)=0
vec apply_ret(crvec xₖ, crvec x̂ₖ, crvec pₖ, real_t γ)
virtual std::string get_name() const =0
virtual bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, crvec grad_new, const Box &C, real_t γ_new)=0
bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, crvec grad_new, const Box &C, real_t γ_new) override
void initialize(crvec x₀, crvec x̂₀, crvec p₀, crvec grad₀) override
void changed_γ(real_t γₖ, real_t old_γₖ) override
Second order PANOC solver for ALM.
ProblemWithParam load_CasADi_problem_with_param(const std::string &filename, unsigned n=0, unsigned m=0, unsigned p=0, bool second_order=false)
Load a problem generated by CasADi (with parameters).
pa::Problem load_CasADi_problem(const std::string &filename, unsigned n=0, unsigned m=0, bool second_order=false)
Load a problem generated by CasADi (without parameters).
This file defines mappings from Python dicts (kwargs) to simple parameter structs.
T var_kwargs_to_struct(const std::variant< T, py::dict > &p)
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.
PolymorphicInnerSolver< StructuredPANOCLBFGSSolver > PolymorphicStructuredPANOCLBFGSSolver
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
unsigned k
Definition: pga.hpp:41
real_t ε₀
Initial primal tolerance.
Definition: decl/alm.hpp:34
@ ProjGradUnitNorm
∞-norm of the projected gradient with unit step size:
@ ProjGradNorm
∞-norm of the projected gradient with step size γ:
@ Ipopt
The stopping criterion used by Ipopt, see https://link.springer.com/article/10.1007/s10107-004-0559-y...
@ FPRNorm2
2-norm of fixed point residual:
@ ProjGradNorm2
2-norm of the projected gradient with step size γ:
@ ApproxKKT
Find an ε-approximate KKT point in the ∞-norm:
@ FPRNorm
∞-norm of fixed point residual:
@ ApproxKKT2
Find an ε-approximate KKT point in the 2-norm:
@ ProjGradUnitNorm2
2-norm of the projected gradient with unit step size:
unsigned max_total_num_retries
Combined limit for ALMParams::max_num_initial_retries and ALMParams::max_num_retries.
Definition: decl/alm.hpp:65
crvec grad_ψ_hat
Definition: pga.hpp:49
real_t Lγ_factor
Factor that relates step size γ and Lipschitz constant.
Definition: lipschitz.hpp:15
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
Definition: vec.hpp:18
bool rescale_when_γ_changes
Definition: decl/lbfgs.hpp:24
PolymorphicInnerSolver< PANOCSolver< PolymorphicPANOCDirectionBase > > PolymorphicPANOCSolver
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
struct pa::LBFGSParams::@0 cbfgs
Parameters in the cautious BFGS update condition.
real_t δ
Minimum step size for initial finite difference Lipschitz estimate.
Definition: lipschitz.hpp:13
constexpr real_t inf
Definition: vec.hpp:26
bool update_lipschitz_in_linesearch
real_t norm_sq_p
Definition: pga.hpp:44
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
vec upperbound
Definition: box.hpp:8
unsigned int max_iter
Maximum number of outer ALM iterations.
Definition: decl/alm.hpp:52
PolymorphicPANOCDirection< LBFGS > PolymorphicLBFGSDirection
unsigned memory
Length of the history to keep.
Definition: decl/lbfgs.hpp:14
@ Interrupted
Solver was interrupted by the user.
@ Unknown
Initial value.
@ MaxTime
Maximum allowed execution time exceeded.
@ NoProgress
No progress was made in the last iteration.
@ MaxIter
Maximum number of iterations exceeded.
@ Converged
Converged and reached given tolerance.
@ NotFinite
Intermediate results were infinite or not-a-number.
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
realvec vec
Default type for vectors.
Definition: vec.hpp:14
vec lowerbound
Definition: box.hpp:9
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
real_t quadratic_upperbound_tolerance_factor
double real_t
Default floating point type.
Definition: vec.hpp:8
unsigned print_interval
When to print progress.
py::dict stats_to_dict(const PANOCStats &s)
PolymorphicInnerSolver< GAAPGASolver > PolymorphicGAAPGASolver
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
auto InnerSolverCallWrapper()
LBFGSStepSize lbfgs_stepsize
bool preconditioning
Apply preconditioning to the problem, based on the gradients in the starting point.
Definition: decl/alm.hpp:73
PANOCStats panoc(ObjFunT &ψ, ObjGradFunT &grad_ψ, const Box &C, rvec x, real_t ε, const PANOCParams &params, PANOCDirection< DirectionProviderT > direction, vec_allocator &alloc)
PolymorphicInnerSolver< PGASolver > PolymorphicPGASolver
unsigned max_iter
Maximum number of inner PANOC iterations.
PANOCStopCrit stop_crit
What stop criterion to use.
Definition: pga.hpp:30
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 ψ_hat
Definition: pga.hpp:48
real_t M
Lagrange multiplier bound.
Definition: decl/alm.hpp:46
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
Definition: vec.hpp:16
real_t nonmonotone_linesearch
Factor used in update for exponentially weighted nonmonotone line search.
Parameters for the Augmented Lagrangian solver.
Definition: decl/alm.hpp:13
Definition: box.hpp:7
Parameters for the LBFGS and SpecializedLBFGS classes.
Definition: decl/lbfgs.hpp:12
Tuning parameters for the PANOC algorithm.
Tuning parameters for the second order PANOC algorithm.
int m
Definition: test.py:41
int n
Definition: test.py:40
int ε
Definition: test.py:73
auto prob_getter_f()
auto prob_setter_grad_f()
auto prob_getter_grad_gi()
auto prob_setter_grad_gi()
auto prob_setter_g()
auto prob_getter_hess_L_prod()
auto prob_getter_g()
auto prob_setter_hess_L_prod()
auto prob_setter_grad_g_prod()
auto prob_getter_hess_L()
auto prob_setter_hess_L()
auto prob_getter_grad_g_prod()
auto prob_getter_grad_f()
auto prob_setter_f()
#define MACRO_STRINGIFY(x)
Definition: panocpy.cpp:123
auto PolymorphicALMConstructorDefaultParams()
Definition: panocpy.cpp:102
auto PolymorphicALMConversion()
Definition: panocpy.cpp:110
auto PolymorphicPANOCConversion()
Definition: panocpy.cpp:64
auto PolymorphicPANOCConstructor()
Definition: panocpy.cpp:48
auto PolymorphicALMConstructor()
Definition: panocpy.cpp:87
PYBIND11_MODULE(PANOCPY_MODULE_NAME, m)
Definition: panocpy.cpp:125
auto PolymorphicPANOCDefaultConversion()
Definition: panocpy.cpp:77
struct pa::EvalCounter::EvalTimer time
Problem description for minimization problems.
Box C
Constraints of the decision variables, .
unsigned int m
Number of constraints, dimension of g(x) and z.
unsigned int n
Number of decision variables, dimension of x.
Box D
Other constraints, .