alpaqa guanaqo
Nonconvex constrained optimization
Loading...
Searching...
No Matches
CasADiControlProblem.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <guanaqo/copyable-unique_ptr.hpp>
9#include <guanaqo/dl-flags.hpp>
10#include <filesystem>
11
12namespace alpaqa {
13
14using guanaqo::DynamicLoadFlags;
15
17
18namespace casadi_loader {
19template <Config>
21} // namespace casadi_loader
22
23template <Config Conf>
25 public:
32 mutable vec work;
33
34 /// Components of the constraint function with indices below this number are
35 /// handled using a quadratic penalty method rather than using an
36 /// augmented Lagrangian method. Specifically, the Lagrange multipliers for
37 /// these components (which determine the shifts in ALM) are kept at zero.
39 /// Same as @ref penalty_alm_split, but for the terminal constraint.
41
42 CasADiControlProblem(const std::string &filename, length_t N,
43 DynamicLoadFlags dl_flags = {});
45
50
51 /// Load the numerical problem data (bounds and parameters) from a CSV file.
52 /// The file should contain 8 rows, with the following contents:
53 /// 1. @ref U lower bound [nu]
54 /// 2. @ref U upper bound [nu]
55 /// 3. @ref D lower bound [nc]
56 /// 4. @ref D upper bound [nc]
57 /// 5. @ref D_N lower bound [nc_N]
58 /// 6. @ref D_N upper bound [nc_N]
59 /// 7. @ref x_init [nx]
60 /// 8. @ref param [p]
61 ///
62 /// Line endings are encoded using a single line feed (`\n`), and the column
63 /// separator can be specified using the @p sep argument.
64 void load_numerical_data(const std::filesystem::path &filepath,
65 char sep = ',');
66
67 void get_U(Box &U) const { U = this->U; }
68 void get_D(Box &D) const { D = this->D; }
69 void get_D_N(Box &D_N) const { D_N = this->D_N; }
70 void get_x_init(rvec x_init) const { x_init = this->x_init; }
71
72 void eval_f(index_t timestep, crvec x, crvec u, rvec fxu) const;
73 void eval_jac_f(index_t timestep, crvec x, crvec u, rmat J_fxu) const;
74 void eval_grad_f_prod(index_t timestep, crvec x, crvec u, crvec p,
75 rvec grad_fxu_p) const;
76 void eval_h(index_t timestep, crvec x, crvec u, rvec h) const;
77 void eval_h_N(crvec x, rvec h) const;
78 [[nodiscard]] real_t eval_l(index_t timestep, crvec h) const;
79 [[nodiscard]] real_t eval_l_N(crvec h) const;
80 void eval_qr(index_t timestep, crvec xu, crvec h, rvec qr) const;
81 void eval_q_N(crvec x, crvec h, rvec q) const;
82 void eval_add_Q(index_t timestep, crvec xu, crvec h, rmat Q) const;
83 void eval_add_Q_N(crvec x, crvec h, rmat Q) const;
84 void eval_add_R_masked(index_t timestep, crvec xu, crvec h, crindexvec mask,
85 rmat R, rvec work) const;
86 void eval_add_S_masked(index_t timestep, crvec xu, crvec h, crindexvec mask,
87 rmat S, rvec work) const;
88 void eval_add_R_prod_masked(index_t timestep, crvec xu, crvec h,
89 crindexvec mask_J, crindexvec mask_K, crvec v,
90 rvec out, rvec work) const;
91 void eval_add_S_prod_masked(index_t timestep, crvec xu, crvec h,
92 crindexvec mask_K, crvec v, rvec out,
93 rvec work) const;
94 [[nodiscard]] length_t get_R_work_size() const;
95 [[nodiscard]] length_t get_S_work_size() const;
96 void eval_constr(index_t timestep, crvec x, rvec c) const;
97 void eval_grad_constr_prod(index_t timestep, crvec x, crvec p,
98 rvec grad_cx_p) const;
99 void eval_add_gn_hess_constr(index_t timestep, crvec x, crvec M,
100 rmat out) const;
101 void eval_constr_N(crvec x, rvec c) const;
102 void eval_grad_constr_prod_N(crvec x, crvec p, rvec grad_cx_p) const;
103 void eval_add_gn_hess_constr_N(crvec x, crvec M, rmat out) const;
104
105 void check() const {
106 util::check_dim_msg(U.lower, nu,
107 "Length of problem.U.lower does not "
108 "match problem size problem.nu");
109 util::check_dim_msg(U.upper, nu,
110 "Length of problem.U.upper does not "
111 "match problem size problem.nu");
112 util::check_dim_msg(D.lower, nc,
113 "Length of problem.D.lower does not "
114 "match problem size problem.nc");
115 util::check_dim_msg(D.upper, nc,
116 "Length of problem.D.upper does not "
117 "match problem size problem.nc");
119 "Length of problem.D_N.lower does not "
120 "match problem size problem.nc_N");
122 "Length of problem.D_N.upper does not "
123 "match problem size problem.nc_N");
125 throw std::invalid_argument("Invalid penalty_alm_split");
127 throw std::invalid_argument("Invalid penalty_alm_split_N");
128 }
129
130 [[nodiscard]] length_t get_N() const { return N; }
131 [[nodiscard]] length_t get_nx() const { return nx; }
132 [[nodiscard]] length_t get_nu() const { return nu; }
133 [[nodiscard]] length_t get_nh() const { return nh; }
134 [[nodiscard]] length_t get_nh_N() const { return nh_N; }
135 [[nodiscard]] length_t get_nc() const { return nc; }
136 [[nodiscard]] length_t get_nc_N() const { return nc_N; }
137
138 /// @see @ref TypeErasedControlProblem::eval_projecting_difference_constraints
140 for (index_t t = 0; t < N; ++t)
141 e.segment(t * nc, nc) =
142 projecting_difference(z.segment(t * nc, nc), D);
143 e.segment(N * nc, nc_N) =
144 projecting_difference(z.segment(N * nc, nc_N), D_N);
145 }
146 /// @see @ref TypeErasedControlProblem::eval_projection_multipliers
148 // If there's no lower bound, the multipliers can only be positive
149 auto max_lb = [M](real_t y, real_t z_lb) {
150 real_t y_lb = z_lb == -alpaqa::inf<config_t> ? 0 : -M;
151 return std::max(y, y_lb);
152 };
153 // If there's no upper bound, the multipliers can only be negative
154 auto min_ub = [M](real_t y, real_t z_ub) {
155 real_t y_ub = z_ub == alpaqa::inf<config_t> ? 0 : M;
156 return std::min(y, y_ub);
157 };
158 for (index_t t = 0; t < N; ++t) {
159 auto num_alm = nc - penalty_alm_split;
160 auto &&yt = y.segment(t * nc, nc);
161 auto &&y_qpm = yt.topRows(penalty_alm_split);
162 auto &&y_alm = yt.bottomRows(num_alm);
163 auto &&z_alm_lb = D.lower.bottomRows(num_alm);
164 auto &&z_alm_ub = D.upper.bottomRows(num_alm);
165 y_qpm.setZero();
166 y_alm =
167 y_alm.binaryExpr(z_alm_lb, max_lb).binaryExpr(z_alm_ub, min_ub);
168 }
169 {
170 auto &&yt = y.segment(N * nc, nc_N);
171 auto num_alm = nc_N - penalty_alm_split_N;
172 auto &&y_qpm = yt.topRows(penalty_alm_split_N);
173 auto &&y_alm = yt.bottomRows(num_alm);
174 auto &&z_alm_lb = D.lower.bottomRows(num_alm);
175 auto &&z_alm_ub = D.upper.bottomRows(num_alm);
176 y_qpm.setZero();
177 y_alm =
178 y_alm.binaryExpr(z_alm_lb, max_lb).binaryExpr(z_alm_ub, min_ub);
179 }
180 }
181
182 private:
184 guanaqo::copyable_unique_ptr<Functions> impl;
185};
186
190} // namespace alpaqa
#define BEGIN_ALPAQA_CASADI_LOADER_NAMESPACE
#define END_ALPAQA_CASADI_LOADER_NAMESPACE
#define CASADI_OCP_LOADER_EXPORT_EXTERN_TEMPLATE(strcls, name,...)
void eval_jac_f(index_t timestep, crvec x, crvec u, rmat J_fxu) const
CasADiControlProblem(const CasADiControlProblem &)
guanaqo::copyable_unique_ptr< Functions > impl
void eval_add_R_prod_masked(index_t timestep, crvec xu, crvec h, crindexvec mask_J, crindexvec mask_K, crvec v, rvec out, rvec work) const
casadi_loader::CasADiControlFunctionsWithParam< Conf > Functions
CasADiControlProblem & operator=(const CasADiControlProblem &)
void eval_add_gn_hess_constr_N(crvec x, crvec M, rmat out) const
void eval_projection_multipliers(rvec y, real_t M) const
void eval_qr(index_t timestep, crvec xu, crvec h, rvec qr) const
index_t penalty_alm_split_N
Same as penalty_alm_split, but for the terminal constraint.
void eval_add_S_prod_masked(index_t timestep, crvec xu, crvec h, crindexvec mask_K, crvec v, rvec out, rvec work) const
void eval_constr_N(crvec x, rvec c) const
void load_numerical_data(const std::filesystem::path &filepath, char sep=',')
Load the numerical problem data (bounds and parameters) from a CSV file.
void eval_grad_constr_prod_N(crvec x, crvec p, rvec grad_cx_p) const
void eval_add_R_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat R, rvec work) const
real_t eval_l(index_t timestep, crvec h) const
void eval_grad_f_prod(index_t timestep, crvec x, crvec u, crvec p, rvec grad_fxu_p) const
index_t penalty_alm_split
Components of the constraint function with indices below this number are handled using a quadratic pe...
void eval_add_gn_hess_constr(index_t timestep, crvec x, crvec M, rmat out) const
void eval_constr(index_t timestep, crvec x, rvec c) const
CasADiControlProblem(const std::string &filename, length_t N, DynamicLoadFlags dl_flags={})
void eval_h(index_t timestep, crvec x, crvec u, rvec h) const
void eval_add_S_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat S, rvec work) const
void get_x_init(rvec x_init) const
void eval_q_N(crvec x, crvec h, rvec q) const
void eval_projecting_difference_constraints(crvec z, rvec e) const
void eval_add_Q_N(crvec x, crvec h, rmat Q) const
void eval_grad_constr_prod(index_t timestep, crvec x, crvec p, rvec grad_cx_p) const
void eval_add_Q(index_t timestep, crvec xu, crvec h, rmat Q) const
void eval_f(index_t timestep, crvec x, crvec u, rvec fxu) const
void eval_h_N(crvec x, rvec h) const
CasADiControlProblem(CasADiControlProblem &&) noexcept
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
void check_dim_msg(const V &v, auto sz, std::string msg)
Definition check-dim.hpp:11
typename Conf::rmat rmat
Definition config.hpp:96
typename Conf::real_t real_t
Definition config.hpp:86
typename Conf::index_t index_t
Definition config.hpp:104
typename Conf::length_t length_t
Definition config.hpp:103
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88
typename Conf::crindexvec crindexvec
Definition config.hpp:107
Double-precision double configuration.
Definition config.hpp:176