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;
 
  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);
 
  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);
 
  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;
 
  288            vN      = μN.asDiagonal() * projecting_difference(ζ, D_N);
 
  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;
 
  317                vk      = μk.asDiagonal() * projecting_difference(ζ, D);
 
  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)
 
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
 
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)