10template <
class V,
class Conf>
12 std::convertible_to<V, rvec<Conf>> || std::convertible_to<V, crvec<Conf>>;
14template <Config Conf, VectorRefLike<Conf> V>
16 if constexpr (Eigen::internal::is_lvalue<std::remove_reference_t<V>>::value)
28 const std::array<index_t, 4> &sizes,
30 const std::array<index_t, 3> &sizes_N,
34 std::partial_sum(sizes.begin(), sizes.end(),
indices.begin());
35 std::partial_sum(sizes_N.begin(), sizes_N.end(),
indices_N.begin());
40 {prob.get_nx(), prob.get_nh_N(), prob.get_nc_N()},
54 length_t size(
size_t i)
const {
return indices[i + 1] - indices[i]; }
65 vec create()
const {
return vec(N * indices.back() + indices_N.back()); }
67 return const_or_mut_rvec<config_t>(v.segment(t * indices.back(), nx()));
70 return [v,
this](
index_t t) {
return xk(v, t); };
73 return const_or_mut_rvec<config_t>(
74 v.segment(t * indices.back(), nxu()));
78 return const_or_mut_rvec<config_t>(
79 v.segment(t * indices.back() + indices[0], nu()));
82 return [v,
this](
index_t t) {
return uk(v, t); };
85 return const_or_mut_rvec<config_t>(v.segment(
86 t * indices.back() + (t < N ? indices[i_h] : indices_N[i_h_N]),
87 (t < N ? nh() : nh_N())));
90 return v.segment(t * indices.back() +
91 (t < N ? indices[i_c] : indices_N[i_c_N]),
92 (t < N ? nc() : nc_N()));
98 return const_or_mut_rvec<config_t>(v.segment(t * nxu(), nx()));
101 return [v,
this](
index_t t) {
return qk(v, t); };
104 return [&v,
this]() {
return qk(v, N); };
108 return const_or_mut_rvec<config_t>(v.segment(t * nxu() + nx(), nu()));
111 return [v,
this](
index_t t) {
return rk(v, t); };
115 return const_or_mut_rvec<config_t>(v.segment(t * nxu(), nxu()));
118 return [v,
this](
index_t t) {
return qrk(v, t); };
121 return [&v,
this](
index_t t) {
return qrk(v, t); };
126 return AB.middleCols(t * nxu(), nxu());
129 return AB.middleCols(t * nxu(), nxu());
132 return AB.middleCols(t * nxu(), nxu());
135 return [AB,
this](
index_t t) {
return ABk(AB, t); };
139 return AB.middleCols(t * nxu(), nx());
141 auto Ak(
mat &AB,
index_t t)
const {
return AB.middleCols(t * nxu(), nx()); }
143 return [AB,
this](
index_t t) {
return Ak(AB, t); };
146 return AB.middleCols(t * nxu() + nx(), nu());
149 return AB.middleCols(t * nxu() + nx(), nu());
152 return AB.middleCols(t * nxu() + nx(), nu());
155 return [AB,
this](
index_t t) {
return Bk(AB, t); };
159template <Config Conf>
186 auto nc_N = vars.
nc_N();
187 for (
index_t t = 0; t < N; ++t) {
188 auto xk = vars.
xk(storage, t);
189 auto uk = vars.
uk(storage, t);
190 auto ck = vars.
ck(storage, t);
192 auto hk = vars.
hk(storage, t);
193 problem->
eval_h(t, xk, uk, hk);
194 V += problem->
eval_l(t, hk);
196 auto xuk = vars.
xuk(storage, t);
197 V += problem->
eval_l(t, xuk);
201 auto yk = y.segment(t * nc, nc);
202 auto μk = μ.segment(t * nc, nc);
203 auto ζ = ck + μk.asDiagonal().inverse() * yk;
206 problem->
eval_f(t, xk, uk, vars.
xk(storage, t + 1));
208 auto xN = vars.
xk(storage, N);
209 auto cN = vars.
ck(storage, N);
210 if (vars.
nh_N() > 0) {
211 auto hN = vars.
hk(storage, N);
219 auto yN = y.segment(N * nc, nc_N);
220 auto μN = μ.segment(N * nc, nc_N);
221 auto ζ = cN + μN.asDiagonal().inverse() * yN;
230 for (
index_t t = 0; t < N(); ++t) {
231 auto xk = vars.
xk(storage, t);
232 auto uk = vars.
uk(storage, t);
233 auto ck = vars.
ck(storage, t);
235 auto hk = vars.
hk(storage, t);
236 problem->
eval_h(t, xk, uk, hk);
240 problem->
eval_f(t, xk, uk, vars.
xk(storage, t + 1));
242 auto xN = vars.
xk(storage, N());
243 auto cN = vars.
ck(storage, N());
244 if (vars.
nh_N() > 0) {
245 auto hN = vars.
hk(storage, N());
254 assert(u.size() == vars.
N * vars.
nu());
255 assert(x.size() == vars.
nx());
256 for (
index_t t = 0; t < N(); ++t) {
257 auto uk = u.segment(t * vars.
nu(), vars.
nu());
258 problem->
eval_f(t, x, uk, x);
267 auto nc_N = vars.
nc_N();
273 assert((nc <= 0 && nc_N <= 0) || w.size() == nx);
274 assert((nc <= 0 && nc_N <= 0) || v.size() == std::max(nc, nc_N));
276 auto xN = vars.
xk(storage, N);
277 auto hN = vars.
hk(storage, N);
278 auto vN = v.topRows(nc_N);
279 auto vk = v.topRows(nc);
284 auto cN = vars.
ck(storage, N);
285 auto yN = y.segment(N * nc, nc_N);
286 auto μN = μ.segment(N * nc, nc_N);
287 auto ζ = cN + μN.asDiagonal().inverse() * yN;
293 for (
index_t t = N; t-- > 0;) {
294 auto gt = g.segment(t * nu, nu);
295 auto hk = vars.
hk(storage, t);
296 auto xuk = vars.
xuk(storage, t);
297 auto xk = vars.
xk(storage, t);
298 auto uk = vars.
uk(storage, t);
300 auto &&qk = qrk.topRows(nx);
301 auto &&rk = qrk.bottomRows(nu);
310 problem->
eval_qr(t, xuk, hk, qrk);
313 auto ck = vars.
ck(storage, t);
314 auto yk = y.segment(t * nc, nc);
315 auto μk = μ.segment(t * nc, nc);
316 auto ζ = ck + μk.asDiagonal().inverse() * yk;
331 auto nc_N = vars.
nc_N();
332 auto work_cN = work_c.topRows(nc_N);
333 auto work_ck = work_c.topRows(nc);
335 auto hk = vars.
hk(storage, k);
336 auto xuk = vars.
xuk(storage, k);
337 auto xk = vars.
xk(storage, k);
342 if (nc > 0 || nc_N > 0) {
343 auto ck = vars.
ck(storage, k);
344 auto yk = y.segment(k * nc, k < N ? nc : nc_N);
345 auto μk = μ.segment(k * nc, k < N ? nc : nc_N);
346 auto ζ = ck + μk.asDiagonal().inverse() * yk;
348 for (
index_t i = 0; i < nc; ++i)
349 work_ck(i) = μk(i) * (ζ(i) < D.
lowerbound(i) ||
353 for (
index_t i = 0; i < nc_N; ++i)
354 work_cN(i) = μk(i) * (ζ(i) < D_N.
lowerbound(i) ||
362 const Box &D_N)
const {
363 return [=,
this, &D, &D_N](
index_t k) {
364 return [=,
this, &D, &D_N](
rmat out) {
365 return Qk(storage, y, μ, D, D_N, k, out);
373 auto hk = vars.
hk(storage, k);
374 auto xuk = vars.
xuk(storage, k);
381 return Rk(storage, k, mask, out);
389 auto hk = vars.
hk(storage, k);
390 auto xuk = vars.
xuk(storage, k);
397 return Sk(storage, k, mask, out);
408 auto hk = vars.
hk(storage, k);
409 auto xuk = vars.
xuk(storage, k);
418 return Rk_prod(storage, k, mask_J, mask_K, v, out);
428 auto hk = vars.
hk(storage, k);
429 auto xuk = vars.
xuk(storage, k);
436 return Sk_prod(storage, k, mask_K, v, out);
444template <Config Conf>
448 dim.uk(storage, t) = u.segment(t * dim.nu(), dim.nu());
450template <Config Conf>
454 dim.xk(storage, t) = x.segment(t * dim.nx(), dim.nx());
455 dim.uk(storage, t) = u.segment(t * dim.nu(), dim.nu());
457 dim.xk(storage, dim.N) = x.segment(dim.N * dim.nx(), dim.nx());
459template <Config Conf>
463 u.segment(t * dim.nu(), dim.nu()) = dim.uk(storage, t);
465template <Config Conf>
469 x.segment(t * dim.nx(), dim.nx()) =
470 storage.segment(t * (dim.nx() + dim.nu()), dim.nx());
473template <Config Conf>
481template <Config Conf>
Nonlinear optimal control problem with finite horizon .
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
.
length_t get_nc() const
Number of constraints.
void eval_add_gn_hess_constr_N(crvec x, crvec M, rmat out) const
Gauss-Newton Hessian of terminal constraints .
length_t get_S_work_size() const
Size of the workspace required by eval_add_S_masked() and eval_add_S_prod_masked().
void eval_qr(index_t timestep, crvec xu, crvec h, rvec qr) const
Cost gradients w.r.t.
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
Terminal constraints .
void eval_grad_constr_prod_N(crvec x, crvec p, rvec grad_cx_p) const
Gradient-vector product of terminal constraints .
length_t get_nu() const
Number of inputs.
void eval_add_R_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat R, rvec work) const
Cost Hessian w.r.t.
real_t eval_l_N(crvec h) const
Terminal cost .
real_t eval_l(index_t timestep, crvec h) const
Stage cost .
void eval_grad_f_prod(index_t timestep, crvec x, crvec u, crvec p, rvec grad_fxu_p) const
Gradient-vector product of discrete-time dynamics .
void eval_add_gn_hess_constr(index_t timestep, crvec x, crvec M, rmat out) const
Gauss-Newton Hessian of stage constraints .
void eval_constr(index_t timestep, crvec x, rvec c) const
Stage constraints .
length_t get_nh() const
Number of outputs.
void eval_h(index_t timestep, crvec x, crvec u, rvec h) const
Stage output mapping .
length_t get_R_work_size() const
Size of the workspace required by eval_add_R_masked() and eval_add_R_prod_masked().
length_t get_nx() const
Number of states.
void eval_add_S_masked(index_t timestep, crvec xu, crvec h, crindexvec mask, rmat S, rvec work) const
Cost Hessian w.r.t.
void eval_q_N(crvec x, crvec h, rvec q) const
Terminal cost gradient w.r.t.
void eval_add_Q_N(crvec x, crvec h, rmat Q) const
Terminal cost Hessian w.r.t.
void eval_grad_constr_prod(index_t timestep, crvec x, crvec p, rvec grad_cx_p) const
Gradient-vector product of stage constraints .
void eval_add_Q(index_t timestep, crvec xu, crvec h, rmat Q) const
Cost Hessian w.r.t.
void eval_f(index_t timestep, crvec x, crvec u, rvec fxu) const
Discrete-time dynamics .
void eval_h_N(crvec x, rvec h) const
Terminal output mapping .
#define USING_ALPAQA_CONFIG(Conf)
void assign_extract_x(const OCPVariables< Conf > &dim, crvec< Conf > storage, rvec< Conf > x)
void assign_extract_u(const OCPVariables< Conf > &dim, crvec< Conf > storage, rvec< Conf > u)
vec< Conf > extract_u(const TypeErasedControlProblem< Conf > &problem, crvec< Conf > xu)
vec< Conf > extract_x(const TypeErasedControlProblem< Conf > &problem, crvec< Conf > xu)
void assign_interleave_xu(const OCPVariables< Conf > &dim, crvec< Conf > u, rvec< Conf > storage)
auto projecting_difference(const auto &v, const Box< Conf > &box)
Get the difference between the given vector and its projection.
constexpr auto const_or_mut_rvec(V &&v)
typename Conf::crmat crmat
typename Conf::real_t real_t
typename Conf::index_t index_t
void check_finiteness(const auto &v, std::string_view msg)
If the given vector v is not finite, break or throw an exception with the given message msg.
typename Conf::length_t length_t
typename Conf::crvec crvec
auto dist_squared(const auto &v, const Box< Conf > &box)
Get the distance squared between the given vector and its projection.
typename Conf::crindexvec crindexvec
void forward_simulate(rvec storage) const
OCPEvaluator(const Problem &problem)
void forward_simulate(crvec u, rvec x) const
void Rk(crvec storage, index_t k, crindexvec mask, rmat out)
auto R_prod(crvec storage) const
void Sk(crvec storage, index_t k, crindexvec mask, rmat out)
auto Q(crvec storage, crvec y, crvec μ, const Box &D, const Box &D_N) const
real_t forward(rvec storage, const Box &D, const Box &D_N, crvec μ, crvec y) const
void backward(rvec storage, rvec g, const auto &qr, const auto &q_N, const Box &D, const Box &D_N, crvec μ, crvec y) const
void Sk_prod(crvec storage, index_t k, crindexvec mask_K, crvec v, rvec out) const
void Qk(crvec storage, crvec y, crvec μ, const Box &D, const Box &D_N, index_t k, rmat out) const
void Rk_prod(crvec storage, index_t k, crindexvec mask_J, crindexvec mask_K, crvec v, rvec out) const
auto S_prod(crvec storage) const
rmat Bk(rmat AB, index_t t) const
rmat Ak(rmat AB, index_t t) const
auto ck(VectorRefLike< config_t > auto &&v, index_t t) const
crmat Ak(crmat AB, index_t t) const
rmat ABk(rmat AB, index_t t) const
auto qN_mut(vec &v) const
auto xk(VectorRefLike< config_t > auto &&v, index_t t) const
length_t size(size_t i) const
std::array< index_t, 4 > indices
auto qr_mut(vec &v) const
auto uk(VectorRefLike< config_t > auto &&v, index_t t) const
crmat Bk(crmat AB, index_t t) const
auto qrk(VectorRefLike< config_t > auto &&v, index_t t) const
auto ABk(mat &AB, index_t t) const
auto qk(VectorRefLike< config_t > auto &&v, index_t t) const
crmat ABk(crmat AB, index_t t) const
auto rk(VectorRefLike< config_t > auto &&v, index_t t) const
auto Ak(mat &AB, index_t t) const
auto xuk(VectorRefLike< config_t > auto &&v, index_t t) const
auto hk(VectorRefLike< config_t > auto &&v, index_t t) const
std::array< index_t, 3 > indices_N
length_t size_N(size_t i) const
auto Bk(mat &AB, index_t t) const
OCPVariables(const std::array< index_t, 4 > &sizes, const std::array< index_t, 3 > &sizes_N, length_t N)
OCPVariables(const TypeErasedControlProblem< config_t > &prob)