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()},
70 return [v,
this](
index_t t) {
return xk(v, t); };
82 return [v,
this](
index_t t) {
return uk(v, t); };
90 return v.segment(t *
indices.back() +
101 return [v,
this](
index_t t) {
return qk(v, t); };
104 return [&v,
this]() {
return qk(v,
N); };
111 return [v,
this](
index_t t) {
return rk(v, t); };
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());
139 return AB.middleCols(t *
nxu(),
nx());
146 return AB.middleCols(t *
nxu() +
nx(),
nu());
149 return AB.middleCols(t *
nxu() +
nx(),
nu());
152 return AB.middleCols(t *
nxu() +
nx(),
nu());
159template <Config Conf>
186 auto nc_N =
vars.nc_N();
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);
196 auto xuk =
vars.xuk(storage, t);
200 problem->eval_constr(t, xk, ck);
201 auto yk = y.segment(t * nc, nc);
202 auto μk = μ.segment(t * nc, nc);
203 auto ζ = ck + μk.asDiagonal().inverse() * yk;
204 V +=
real_t(0.5) * dist_squared(ζ, D, μk);
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);
218 problem->eval_constr_N(xN, cN);
219 auto yN = y.segment(
N * nc, nc_N);
220 auto μN = μ.segment(
N * nc, nc_N);
221 auto ζ = cN + μN.asDiagonal().inverse() * yN;
222 V +=
real_t(0.5) * dist_squared(ζ, D_N, μN);
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);
239 problem->eval_constr(t, xk, ck);
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());
249 problem->eval_constr_N(xN, cN);
254 assert(u.size() ==
vars.N *
vars.nu());
255 assert(x.size() ==
vars.nx());
257 auto uk = u.segment(t *
vars.nu(),
vars.nu());
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;
288 vN = μN.asDiagonal() * projecting_difference(ζ, D_N);
289 problem->eval_grad_constr_prod_N(xN, vN, w);
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);
304 problem->eval_grad_f_prod(t, xk, uk, λ, qrk);
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;
317 vk = μk.asDiagonal() * projecting_difference(ζ, D);
318 problem->eval_grad_constr_prod(t, xk, vk, w);
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);
339 problem->eval_add_Q(k, xuk, hk, out);
341 problem->eval_add_Q_N(xk, hk, out);
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.
lower(i) ||
351 problem->eval_add_gn_hess_constr(k, xk, work_ck, out);
353 for (
index_t i = 0; i < nc_N; ++i)
354 work_cN(i) = μk(i) * (ζ(i) < D_N.
lower(i) ||
355 ζ(i) > D_N.
upper(i));
356 problem->eval_add_gn_hess_constr_N(xk, work_cN, out);
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);
410 problem->eval_add_R_prod_masked(k, xuk, hk, mask_J, mask_K, v, out,
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);
430 problem->eval_add_S_prod_masked(k, xuk, hk, mask_K, v, out,
work_S);
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 .
length_t get_nc() const
Number of constraints.
length_t get_nu() const
Number of inputs.
length_t get_nh() const
Number of outputs.
length_t get_nx() const
Number of states.
#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)
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
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
TypeErasedControlProblem< config_t > Problem
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
alpaqa::Box< config_t > Box
void Sk_prod(crvec storage, index_t k, crindexvec mask_K, crvec v, rvec out) const
OCPVariables< config_t > OCPVars
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)