13#include <pybind11/cast.h>
14#include <pybind11/pybind11.h>
15namespace py = pybind11;
19template <
class InnerSolver>
23 alpaqa::vec y) -> std::tuple<alpaqa::vec, alpaqa::vec, alpaqa::vec, py::dict> {
26 return std::make_tuple(std::move(
x), std::move(
y), std::move(
z),
27 stats.ptr->to_dict());
32 :
public std::enable_shared_from_this<
33 PolymorphicInnerSolverStatsAccumulatorBase> {
41 :
public std::enable_shared_from_this<PolymorphicInnerSolverStatsBase> {
45 virtual std::shared_ptr<PolymorphicInnerSolverStatsAccumulatorBase>
50 :
public std::enable_shared_from_this<PolymorphicInnerSolverBase> {
53 std::shared_ptr<PolymorphicInnerSolverStatsBase>
ptr;
62 struct AccStats : PolyAccStats {
63 AccStats(py::dict dict) : dict(std::move(dict)) {}
65 py::dict to_dict()
const override {
return dict; }
66 void accumulate(
const PolyStats &s)
override {
67 if (this->dict.contains(
"accumulate"))
68 this->dict[
"accumulate"](this->dict, s.to_dict());
70 throw py::key_error(
"Stats accumulator does not define "
71 "an accumulate function");
74 struct Stats : PolyStats {
75 Stats(py::dict dict) : dict(std::move(dict)) {}
77 py::dict to_dict()
const override {
return dict; }
78 std::shared_ptr<PolyAccStats> accumulator()
const override {
79 if (this->dict.contains(
"accumulator"))
81 std::make_shared<AccStats>(
82 dict[
"accumulator"].cast<py::dict>()),
86 "Stats do not define an accumulator");
89 bool ok =
d.contains(
"status") &&
d.contains(
"ε") &&
90 d.contains(
"iterations");
93 "Stats should contain status, ε and iterations");
95 std::static_pointer_cast<PolyStats>(std::make_shared<Stats>(
d)),
96 d[
"status"].cast<
decltype(InnerStats::status)>(),
98 d[
"iterations"].cast<
decltype(InnerStats::iterations)>(),
112 bool always_overwrite_results,
126 std::shared_ptr<PolymorphicInnerSolverBase>
solver;
128 std::shared_ptr<PolymorphicInnerSolverBase> &&
solver)
132 bool always_overwrite_results,
rvec x,
rvec y,
142template <
class InnerSolverStats>
147 std::shared_ptr<PolymorphicInnerSolverStatsAccumulatorBase>
ptr;
148 py::dict
to_dict()
const {
return ptr->to_dict(); }
151inline InnerStatsAccumulator<PolymorphicInnerSolverWrapper::Stats> &
156 acc.
ptr = s.
ptr->accumulator();
157 acc.
ptr->accumulate(*s.
ptr);
164 bool always_overwrite_results,
rvec x,
rvec y,
171 virtual std::tuple<alpaqa::vec, alpaqa::vec, alpaqa::vec, py::dict>
174 using ret = std::tuple<alpaqa::vec, alpaqa::vec, alpaqa::vec, py::dict>;
177 always_overwrite_results,
x,
y);
193 using py::operator
""_a;
209 using py::operator
""_a;
223 using py::operator
""_a;
239 using py::operator
""_a;
249 using py::operator
""_a;
261 using py::operator
""_a;
263 "elapsed_time"_a = s.elapsed_time,
264 "iterations"_a = s.iterations,
265 "linesearch_failures"_a = s.linesearch_failures,
266 "lbfgs_failures"_a = s.lbfgs_failures,
267 "lbfgs_rejected"_a = s.lbfgs_rejected,
268 "τ_1_accepted"_a = s.τ_1_accepted,
269 "count_τ"_a = s.count_τ,
276 using py::operator
""_a;
285 using py::operator
""_a;
293template <
class InnerSolver>
300 template <
class... Args>
302 :
innersolver(InnerSolver{std::forward<Args>(args)...}) {}
315 using Stats =
typename InnerSolver::Stats;
318 std::shared_ptr<PolymorphicInnerSolverStatsAccumulatorBase>
320 return std::static_pointer_cast<
322 std::make_shared<WrappedStatsAccumulator>());
335 bool always_overwrite_results,
345 std::static_pointer_cast<PolymorphicInnerSolverStatsBase>(
346 std::make_shared<WrappedStats>(
stats)),
359 std::function<
void(
const typename InnerSolver::ProgressInfo &)>
cb) {
383 using py::operator
""_a;
394 "inner"_a = s.
inner.to_dict(),
Augmented Lagrangian Method solver.
unsigned penalty_reduced
The number of times that the penalty update factor ALMParams::Δ was reduced, that the tolerance updat...
real_t δ
Final dual tolerance or constraint violation that was reached:
real_t norm_penalty
2-norm of the final penalty factors .
unsigned initial_penalty_reduced
The number of times that the initial penalty factor was reduced by ALMParams::Σ₀_lower and that the i...
InnerStatsAccumulator< typename InnerSolver::Stats > inner
The statistics of the inner solver invocations, accumulated over all ALM iterations.
unsigned inner_convergence_failures
The total number of times that the inner solver failed to converge.
real_t ε
Final primal tolerance that was reached, depends on the stopping criterion used by the inner solver,...
unsigned outer_iterations
Total number of outer ALM iterations (i.e.
std::chrono::microseconds elapsed_time
Total elapsed time.
SolverStatus status
Whether the solver converged or not.
std::chrono::microseconds elapsed_time
unsigned accelerated_steps_accepted
std::chrono::microseconds elapsed_time
virtual ~PolymorphicInnerSolverBase()=default
virtual std::string get_name() const =0
virtual py::object get_params() const =0
virtual Stats operator()(const Problem &problem, crvec Σ, real_t ε, bool always_overwrite_results, rvec x, rvec y, rvec err_z)=0
virtual py::dict to_dict() const =0
virtual ~PolymorphicInnerSolverStatsAccumulatorBase()=default
virtual void accumulate(const class PolymorphicInnerSolverStatsBase &)=0
virtual std::shared_ptr< PolymorphicInnerSolverStatsAccumulatorBase > accumulator() const =0
virtual py::dict to_dict() const =0
virtual ~PolymorphicInnerSolverStatsBase()=default
py::object get_params() const override
Stats operator()(const Problem &problem, crvec Σ, real_t ε, bool always_overwrite_results, rvec x, rvec y, rvec err_z) override
virtual std::tuple< alpaqa::vec, alpaqa::vec, alpaqa::vec, py::dict > call(const alpaqa::Problem &problem, alpaqa::crvec Σ, alpaqa::real_t ε, bool always_overwrite_results, alpaqa::vec x, alpaqa::vec y)
std::string get_name() const override
PolymorphicInnerSolver(Args... args)
py::object get_params() const override
Stats operator()(const Problem &problem, crvec Σ, real_t ε, bool always_overwrite_results, rvec x, rvec y, rvec err_z) override
void set_progress_callback(std::function< void(const typename InnerSolver::ProgressInfo &)> cb)
PolymorphicInnerSolver(const InnerSolver &innersolver)
PolymorphicInnerSolver(InnerSolver &&innersolver)
std::string get_name() const override
InnerStatsAccumulator< PolymorphicInnerSolverWrapper::Stats > & operator+=(InnerStatsAccumulator< PolymorphicInnerSolverWrapper::Stats > &acc, const PolymorphicInnerSolverWrapper::Stats &s)
Eigen::Ref< const vec > crvec
Default type for immutable references to vectors.
py::dict stats_to_dict(const PANOCStats &s)
SolverStatus
Exit status of a numerical solver such as ALM or PANOC.
realvec vec
Default type for vectors.
std::chrono::microseconds elapsed_time
double real_t
Default floating point type.
unsigned linesearch_failures
unsigned accelerated_steps_accepted
auto InnerSolverCallWrapper()
Eigen::Ref< vec > rvec
Default type for mutable references to vectors.
std::shared_ptr< PolymorphicInnerSolverStatsAccumulatorBase > ptr
static Stats from_dict(py::dict d)
std::shared_ptr< PolymorphicInnerSolverStatsBase > ptr
std::string get_name() const
py::object get_params() const
Stats operator()(const Problem &problem, crvec Σ, real_t ε, bool always_overwrite_results, rvec x, rvec y, rvec err_z)
std::shared_ptr< PolymorphicInnerSolverBase > solver
PolymorphicInnerSolverWrapper(std::shared_ptr< PolymorphicInnerSolverBase > &&solver)
InnerStatsAccumulator< typename InnerSolver::Stats > acc
void accumulate(const PolymorphicInnerSolverStatsBase &bstats) override
py::dict to_dict() const override
WrappedStats(const Stats &stats)
typename InnerSolver::Stats Stats
py::dict to_dict() const override
std::shared_ptr< PolymorphicInnerSolverStatsAccumulatorBase > accumulator() const override
Problem description for minimization problems.