alpaqa 1.1.0a1
Nonconvex constrained optimization
Loading...
Searching...
No Matches
problem-with-counters.hpp
Go to the documentation of this file.
1#pragma once
2
6#include <guanaqo/timed.hpp>
7
8#include <type_traits>
9
10namespace alpaqa {
11
12/// @addtogroup grp_Problems
13/// @{
14
15/// Problem wrapper that keeps track of the number of evaluations and the run
16/// time of each function.
17/// You probably want to use @ref problem_with_counters or
18/// @ref problem_with_counters_ref instead of instantiating this class directly.
19/// @note The evaluation counters are stored using a `std::shared_pointers`,
20/// which means that different copies of a @ref ProblemWithCounters
21/// instance all share the same counters. To opt out of this behavior,
22/// you can use the @ref decouple_evaluations function.
23template <class Problem>
25 USING_ALPAQA_CONFIG_TEMPLATE(std::remove_cvref_t<Problem>::config_t);
27
28 // clang-format off
29 [[gnu::always_inline]] void eval_projecting_difference_constraints(crvec z, rvec e) const { ++evaluations->projecting_difference_constraints; return timed(evaluations->time.projecting_difference_constraints, [&] { return problem.eval_projecting_difference_constraints(z, e); }); }
30 [[gnu::always_inline]] void eval_projection_multipliers(rvec y, real_t M) const { ++evaluations->projection_multipliers; return timed(evaluations->time.projection_multipliers, [&] { return problem.eval_projection_multipliers(y, M); }); }
31 [[gnu::always_inline]] real_t eval_proximal_gradient_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const { ++evaluations->proximal_gradient_step; return timed(evaluations->time.proximal_gradient_step, [&] { return problem.eval_proximal_gradient_step(γ, x, grad_ψ, x̂, p); }); }
32 [[gnu::always_inline]] index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const requires requires { &std::remove_cvref_t<Problem>::eval_inactive_indices_res_lna; } { ++evaluations->inactive_indices_res_lna; return timed(evaluations->time.inactive_indices_res_lna, [&] { return problem.eval_inactive_indices_res_lna(γ, x, grad_ψ, J); }); }
33 [[gnu::always_inline]] real_t eval_objective(crvec x) const { ++evaluations->objective; return timed(evaluations->time.objective, [&] { return problem.eval_objective(x); }); }
34 [[gnu::always_inline]] void eval_objective_gradient(crvec x, rvec grad_fx) const { ++evaluations->objective_gradient; return timed(evaluations->time.objective_gradient, [&] { return problem.eval_objective_gradient(x, grad_fx); }); }
35 [[gnu::always_inline]] void eval_constraints(crvec x, rvec gx) const { ++evaluations->constraints; return timed(evaluations->time.constraints, [&] { return problem.eval_constraints(x, gx); }); }
36 [[gnu::always_inline]] void eval_constraints_gradient_product(crvec x, crvec y, rvec grad_gxy) const { ++evaluations->constraints_gradient_product; return timed(evaluations->time.constraints_gradient_product, [&] { return problem.eval_constraints_gradient_product(x, y, grad_gxy); }); }
37 [[gnu::always_inline]] void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const requires requires { &std::remove_cvref_t<Problem>::eval_grad_gi; } { ++evaluations->grad_gi; return timed(evaluations->time.grad_gi, [&] { return problem.eval_grad_gi(x, i, grad_gi); }); }
38 [[gnu::always_inline]] void eval_constraints_jacobian(crvec x, rvec J_values) const requires requires { &std::remove_cvref_t<Problem>::eval_constraints_jacobian; } { ++evaluations->constraints_jacobian; return timed(evaluations->time.constraints_jacobian, [&] { return problem.eval_constraints_jacobian(x, J_values); }); }
39 [[gnu::always_inline]] Sparsity get_constraints_jacobian_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_constraints_jacobian_sparsity; } { return problem.get_constraints_jacobian_sparsity(); }
40 [[gnu::always_inline]] void eval_lagrangian_hessian_product(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const requires requires { &std::remove_cvref_t<Problem>::eval_lagrangian_hessian_product; } { ++evaluations->lagrangian_hessian_product; return timed(evaluations->time.lagrangian_hessian_product, [&] { return problem.eval_lagrangian_hessian_product(x, y, scale, v, Hv); }); }
41 [[gnu::always_inline]] void eval_lagrangian_hessian(crvec x, crvec y, real_t scale, rvec H_values) const requires requires { &std::remove_cvref_t<Problem>::eval_lagrangian_hessian; } { ++evaluations->lagrangian_hessian; return timed(evaluations->time.lagrangian_hessian, [&] { return problem.eval_lagrangian_hessian(x, y, scale, H_values); }); }
42 [[gnu::always_inline]] Sparsity get_lagrangian_hessian_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_lagrangian_hessian_sparsity; } { return problem.get_lagrangian_hessian_sparsity(); }
43 [[gnu::always_inline]] void eval_augmented_lagrangian_hessian_product(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const requires requires { &std::remove_cvref_t<Problem>::eval_augmented_lagrangian_hessian_product; } { ++evaluations->augmented_lagrangian_hessian_product; return timed(evaluations->time.augmented_lagrangian_hessian_product, [&] { return problem.eval_augmented_lagrangian_hessian_product(x, y, Σ, scale, v, Hv); }); }
44 [[gnu::always_inline]] void eval_augmented_lagrangian_hessian(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const requires requires { &std::remove_cvref_t<Problem>::eval_augmented_lagrangian_hessian; } { ++evaluations->augmented_lagrangian_hessian; return timed(evaluations->time.augmented_lagrangian_hessian, [&] { return problem.eval_augmented_lagrangian_hessian(x, y, Σ, scale, H_values); }); }
45 [[gnu::always_inline]] Sparsity get_augmented_lagrangian_hessian_sparsity() const requires requires { &std::remove_cvref_t<Problem>::get_augmented_lagrangian_hessian_sparsity; } { return problem.get_augmented_lagrangian_hessian_sparsity(); }
46 [[gnu::always_inline]] real_t eval_objective_and_gradient(crvec x, rvec grad_fx) const requires requires { &std::remove_cvref_t<Problem>::eval_objective_and_gradient; } { ++evaluations->objective_and_gradient; return timed(evaluations->time.objective_and_gradient, [&] { return problem.eval_objective_and_gradient(x, grad_fx); }); }
47 [[gnu::always_inline]] real_t eval_objective_and_constraints(crvec x, rvec g) const requires requires { &std::remove_cvref_t<Problem>::eval_objective_and_constraints; } { ++evaluations->objective_and_constraints; return timed(evaluations->time.objective_and_constraints, [&] { return problem.eval_objective_and_constraints(x, g); }); }
48 [[gnu::always_inline]] void eval_objective_gradient_and_constraints_gradient_product(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const requires requires { &std::remove_cvref_t<Problem>::eval_objective_gradient_and_constraints_gradient_product; } { ++evaluations->objective_gradient_and_constraints_gradient_product; return timed(evaluations->time.objective_gradient_and_constraints_gradient_product, [&] { return problem.eval_objective_gradient_and_constraints_gradient_product(x, y, grad_f, grad_gxy); }); }
49 [[gnu::always_inline]] void eval_lagrangian_gradient(crvec x, crvec y, rvec grad_L, rvec work_n) const requires requires { &std::remove_cvref_t<Problem>::eval_lagrangian_gradient; } { ++evaluations->lagrangian_gradient; return timed(evaluations->time.lagrangian_gradient, [&] { return problem.eval_lagrangian_gradient(x, y, grad_L, work_n); }); }
50 [[gnu::always_inline]] real_t eval_augmented_lagrangian(crvec x, crvec y, crvec Σ, rvec ŷ) const requires requires { &std::remove_cvref_t<Problem>::eval_augmented_lagrangian; } { ++evaluations->augmented_lagrangian; return timed(evaluations->time.augmented_lagrangian, [&] { return problem.eval_augmented_lagrangian(x, y, Σ, ŷ); }); }
51 [[gnu::always_inline]] void eval_augmented_lagrangian_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const requires requires { &std::remove_cvref_t<Problem>::eval_augmented_lagrangian_gradient; } { ++evaluations->augmented_lagrangian_gradient; return timed(evaluations->time.augmented_lagrangian_gradient, [&] { return problem.eval_augmented_lagrangian_gradient(x, y, Σ, grad_ψ, work_n, work_m); }); }
52 [[gnu::always_inline]] real_t eval_augmented_lagrangian_and_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const requires requires { &std::remove_cvref_t<Problem>::eval_augmented_lagrangian_and_gradient; } { ++evaluations->augmented_lagrangian_and_gradient; return timed(evaluations->time.augmented_lagrangian_and_gradient, [&] { return problem.eval_augmented_lagrangian_and_gradient(x, y, Σ, grad_ψ, work_n, work_m); }); }
53 const Box &get_variable_bounds() const requires requires { &std::remove_cvref_t<Problem>::get_variable_bounds; } { return problem.get_variable_bounds(); }
54 const Box &get_general_bounds() const requires requires { &std::remove_cvref_t<Problem>::get_general_bounds; } { return problem.get_general_bounds(); }
55 void check() const requires requires { &std::remove_cvref_t<Problem>::check; } { return problem.check(); }
56 [[nodiscard]] std::string get_name() const requires requires { &std::remove_cvref_t<Problem>::get_name; } { return problem.get_name(); }
57
58 [[nodiscard]] bool provides_eval_grad_gi() const requires requires (Problem p) { { p.provides_eval_grad_gi() } -> std::convertible_to<bool>; } { return problem.provides_eval_grad_gi(); }
59 [[nodiscard]] bool provides_eval_inactive_indices_res_lna() const requires requires (Problem p) { { p.provides_eval_inactive_indices_res_lna() } -> std::convertible_to<bool>; } { return problem.provides_eval_inactive_indices_res_lna(); }
60 [[nodiscard]] bool provides_eval_constraints_jacobian() const requires requires (Problem p) { { p.provides_eval_constraints_jacobian() } -> std::convertible_to<bool>; } { return problem.provides_eval_constraints_jacobian(); }
61 [[nodiscard]] bool provides_get_constraints_jacobian_sparsity() const requires requires (Problem p) { { p.provides_get_constraints_jacobian_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_constraints_jacobian_sparsity(); }
62 [[nodiscard]] bool provides_eval_lagrangian_hessian_product() const requires requires (Problem p) { { p.provides_eval_lagrangian_hessian_product() } -> std::convertible_to<bool>; } { return problem.provides_eval_lagrangian_hessian_product(); }
63 [[nodiscard]] bool provides_eval_lagrangian_hessian() const requires requires (Problem p) { { p.provides_eval_lagrangian_hessian() } -> std::convertible_to<bool>; } { return problem.provides_eval_lagrangian_hessian(); }
64 [[nodiscard]] bool provides_get_lagrangian_hessian_sparsity() const requires requires (Problem p) { { p.provides_get_lagrangian_hessian_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_lagrangian_hessian_sparsity(); }
65 [[nodiscard]] bool provides_eval_augmented_lagrangian_hessian_product() const requires requires (Problem p) { { p.provides_eval_augmented_lagrangian_hessian() } -> std::convertible_to<bool>; } { return problem.provides_eval_augmented_lagrangian_hessian_product(); }
66 [[nodiscard]] bool provides_eval_augmented_lagrangian_hessian() const requires requires (Problem p) { { p.provides_eval_augmented_lagrangian_hessian() } -> std::convertible_to<bool>; } { return problem.provides_eval_augmented_lagrangian_hessian(); }
67 [[nodiscard]] bool provides_get_augmented_lagrangian_hessian_sparsity() const requires requires (Problem p) { { p.provides_get_augmented_lagrangian_hessian_sparsity() } -> std::convertible_to<bool>; } { return problem.provides_get_augmented_lagrangian_hessian_sparsity(); }
68 [[nodiscard]] bool provides_eval_objective_and_gradient() const requires requires (Problem p) { { p.provides_eval_objective_and_gradient() } -> std::convertible_to<bool>; } { return problem.provides_eval_objective_and_gradient(); }
69 [[nodiscard]] bool provides_eval_objective_and_constraints() const requires requires (Problem p) { { p.provides_eval_objective_and_constraints() } -> std::convertible_to<bool>; } { return problem.provides_eval_objective_and_constraints(); }
70 [[nodiscard]] bool provides_eval_objective_gradient_and_constraints_gradient_product() const requires requires (Problem p) { { p.provides_eval_objective_gradient_and_constraints_gradient_product() } -> std::convertible_to<bool>; } { return problem.provides_eval_objective_gradient_and_constraints_gradient_product(); }
71 [[nodiscard]] bool provides_eval_lagrangian_gradient() const requires requires (Problem p) { { p.provides_eval_lagrangian_gradient() } -> std::convertible_to<bool>; } { return problem.provides_eval_lagrangian_gradient(); }
72 [[nodiscard]] bool provides_eval_augmented_lagrangian() const requires requires (Problem p) { { p.provides_eval_augmented_lagrangian() } -> std::convertible_to<bool>; } { return problem.provides_eval_augmented_lagrangian(); }
73 [[nodiscard]] bool provides_eval_augmented_lagrangian_gradient() const requires requires (Problem p) { { p.provides_eval_augmented_lagrangian_gradient() } -> std::convertible_to<bool>; } { return problem.provides_eval_augmented_lagrangian_gradient(); }
74 [[nodiscard]] bool provides_eval_augmented_lagrangian_and_gradient() const requires requires (Problem p) { { p.provides_eval_augmented_lagrangian_and_gradient() } -> std::convertible_to<bool>; } { return problem.provides_eval_augmented_lagrangian_and_gradient(); }
75 [[nodiscard]] bool provides_get_variable_bounds() const requires requires (Problem p) { { p.provides_get_variable_bounds() } -> std::convertible_to<bool>; } { return problem.provides_get_variable_bounds(); }
76 [[nodiscard]] bool provides_get_general_bounds() const requires requires (Problem p) { { p.provides_get_general_bounds() } -> std::convertible_to<bool>; } { return problem.provides_get_general_bounds(); }
77 [[nodiscard]] bool provides_check() const requires requires (Problem p) { { p.provides_check() } -> std::convertible_to<bool>; } { return problem.provides_check(); }
78 [[nodiscard]] bool provides_get_name() const requires requires (Problem p) { { p.provides_get_name() } -> std::convertible_to<bool>; } { return problem.provides_get_name(); }
79 // clang-format on
80
81 [[nodiscard]] length_t get_num_variables() const { return problem.get_num_variables(); }
82 [[nodiscard]] length_t get_num_constraints() const { return problem.get_num_constraints(); }
83
84 std::shared_ptr<EvalCounter> evaluations = std::make_shared<EvalCounter>();
85 Problem problem;
86
88 requires std::is_default_constructible_v<Problem>
89 = default;
90 template <class P>
92 requires std::is_same_v<std::remove_cvref_t<P>, std::remove_cvref_t<Problem>>
93 : problem{std::forward<P>(problem)} {}
94 template <class... Args>
95 explicit ProblemWithCounters(std::in_place_t, Args &&...args)
96 requires(!std::is_lvalue_reference_v<Problem>)
97 : problem{std::forward<Args>(args)...} {}
98
99 /// Reset all evaluation counters and timers to zero. Affects all instances
100 /// that share the same evaluations. If you only want to reset the counters
101 /// of this instance, use @ref decouple_evaluations first.
102 void reset_evaluations() { evaluations.reset(); }
103 /// Give this instance its own evaluation counters and timers, decoupling
104 /// it from any other instances they might have previously been shared with.
105 /// The evaluation counters and timers are preserved (a copy is made).
106 void decouple_evaluations() { evaluations = std::make_shared<EvalCounter>(*evaluations); }
107
108 private:
109 template <class TimeT, class FunT>
110 [[gnu::always_inline]] static decltype(auto) timed(TimeT &time, FunT &&f) {
111 guanaqo::Timed timed{time};
112 return std::forward<FunT>(f)();
113 }
114};
115
116/// Wraps the given problem into a @ref ProblemWithCounters and keeps track of
117/// how many times each function is called, and how long these calls took.
118/// The wrapper has its own copy of the given problem. Making copies of the
119/// wrapper also copies the underlying problem, but does not copy the evaluation
120/// counters, all copies share the same counters.
121template <class Problem>
122[[nodiscard]] auto problem_with_counters(Problem &&p) {
123 using Prob = std::remove_cvref_t<Problem>;
124 using ProbWithCnt = ProblemWithCounters<Prob>;
125 return ProbWithCnt{std::forward<Problem>(p)};
126}
127
128/// Wraps the given problem into a @ref ProblemWithCounters and keeps track of
129/// how many times each function is called, and how long these calls took.
130/// The wrapper keeps only a reference to the given problem, it is the
131/// responsibility of the caller to make sure that the wrapper does not outlive
132/// the original problem. Making copies of the wrapper does not copy the
133/// evaluation counters, all copies share the same counters.
134template <class Problem>
135[[nodiscard]] auto problem_with_counters_ref(Problem &p) {
136 using Prob = std::remove_cvref_t<Problem>;
137 using ProbWithCnt = ProblemWithCounters<const Prob &>;
138 return ProbWithCnt{p};
139}
140
141/// @}
142
143} // namespace alpaqa
alpaqa::Box< config_t > Box
#define USING_ALPAQA_CONFIG_TEMPLATE(Conf)
Definition config.hpp:81
auto problem_with_counters(Problem &&p)
Wraps the given problem into a ProblemWithCounters and keeps track of how many times each function is...
auto problem_with_counters_ref(Problem &p)
Wraps the given problem into a ProblemWithCounters and keeps track of how many times each function is...
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
typename Conf::length_t length_t
Definition config.hpp:103
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
Problem wrapper that keeps track of the number of evaluations and the run time of each function.
void eval_constraints(crvec x, rvec gx) const
void decouple_evaluations()
Give this instance its own evaluation counters and timers, decoupling it from any other instances the...
real_t eval_objective_and_gradient(crvec x, rvec grad_fx) const
bool provides_eval_augmented_lagrangian_gradient() const
void eval_augmented_lagrangian_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
real_t eval_objective_and_constraints(crvec x, rvec g) const
bool provides_eval_objective_gradient_and_constraints_gradient_product() const
void eval_projection_multipliers(rvec y, real_t M) const
void eval_augmented_lagrangian_hessian_product(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
void eval_augmented_lagrangian_hessian(crvec x, crvec y, crvec Σ, real_t scale, rvec H_values) const
void eval_lagrangian_gradient(crvec x, crvec y, rvec grad_L, rvec work_n) const
std::shared_ptr< EvalCounter > evaluations
real_t eval_augmented_lagrangian(crvec x, crvec y, crvec Σ, rvec ŷ) const
void eval_objective_gradient_and_constraints_gradient_product(crvec x, crvec y, rvec grad_f, rvec grad_gxy) const
bool provides_get_constraints_jacobian_sparsity() const
bool provides_eval_augmented_lagrangian_and_gradient() const
real_t eval_proximal_gradient_step(real_t γ, crvec x, crvec grad_ψ, rvec x̂, rvec p) const
void reset_evaluations()
Reset all evaluation counters and timers to zero.
void eval_lagrangian_hessian(crvec x, crvec y, real_t scale, rvec H_values) const
void eval_constraints_jacobian(crvec x, rvec J_values) const
typename TypeErasedProblem< config_t >::Box Box
bool provides_get_augmented_lagrangian_hessian_sparsity() const
void eval_lagrangian_hessian_product(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
index_t eval_inactive_indices_res_lna(real_t γ, crvec x, crvec grad_ψ, rindexvec J) const
void eval_projecting_difference_constraints(crvec z, rvec e) const
Sparsity get_constraints_jacobian_sparsity() const
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
real_t eval_augmented_lagrangian_and_gradient(crvec x, crvec y, crvec Σ, rvec grad_ψ, rvec work_n, rvec work_m) const
void eval_objective_gradient(crvec x, rvec grad_fx) const
void eval_constraints_gradient_product(crvec x, crvec y, rvec grad_gxy) const
Sparsity get_lagrangian_hessian_sparsity() const
ProblemWithCounters(std::in_place_t, Args &&...args)
bool provides_eval_augmented_lagrangian_hessian_product() const
Sparsity get_augmented_lagrangian_hessian_sparsity() const
bool provides_eval_augmented_lagrangian_hessian() const
static decltype(auto) timed(TimeT &time, FunT &&f)