aligator  0.10.0
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
Loading...
Searching...
No Matches
quad-costs.hpp
Go to the documentation of this file.
1#pragma once
2
5#include <proxsuite-nlp/manifold-base.hpp>
6#include <proxsuite-nlp/modelling/spaces/vector-space.hpp>
7
8namespace aligator {
9
10template <typename Scalar> struct QuadraticCostDataTpl;
11
13template <typename _Scalar> struct QuadraticCostTpl : CostAbstractTpl<_Scalar> {
14public:
15 using Scalar = _Scalar;
19
21 using VectorSpace = proxsuite::nlp::VectorSpaceTpl<Scalar, Eigen::Dynamic>;
22 using Manifold = proxsuite::nlp::ManifoldAbstractTpl<Scalar>;
23
25 MatrixXs Wxx_;
27 MatrixXs Wuu_;
28
29protected:
31 MatrixXs Wxu_;
32
33public:
35 VectorXs interp_x;
37 VectorXs interp_u;
38
39 static auto get_vector_space(Eigen::Index nx) {
40 return xyz::polymorphic<Manifold>(VectorSpace((int)nx));
41 }
42
43 QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u,
44 const ConstVectorRef &interp_x,
45 const ConstVectorRef &interp_u)
46 : Base(get_vector_space(w_x.cols()), (int)w_u.cols()), Wxx_(w_x),
47 Wuu_(w_u), Wxu_(this->ndx(), this->nu), interp_x(interp_x),
49 debug_check_dims();
50 Wxu_.setZero();
51 }
52
53 QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u,
54 const ConstMatrixRef &w_cross,
55 const ConstVectorRef &interp_x,
56 const ConstVectorRef &interp_u)
57 : Base(get_vector_space(w_x.cols()), (int)w_u.cols()), Wxx_(w_x),
58 Wuu_(w_u), Wxu_(w_cross), interp_x(interp_x), interp_u(interp_u),
59 has_cross_term_(true) {
60 debug_check_dims();
61 }
62
63 QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u)
64 : QuadraticCostTpl(w_x, w_u, VectorXs::Zero(w_x.cols()),
65 VectorXs::Zero(w_u.cols())) {}
66
67 QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u,
68 const ConstMatrixRef &w_cross)
69 : QuadraticCostTpl(w_x, w_u, w_cross, VectorXs::Zero(w_x.cols()),
70 VectorXs::Zero(w_u.cols())) {}
71
72 void evaluate(const ConstVectorRef &x, const ConstVectorRef &u,
73 CostData &data) const {
74 Data &d = static_cast<Data &>(data);
75 d.w_times_x_.noalias() = Wxx_ * x;
76 d.w_times_u_.noalias() = Wuu_ * u;
77 if (has_cross_term_) {
78 d.cross_x_.noalias() = Wxu_ * u;
79 d.cross_u_.noalias() = Wxu_.transpose() * x;
80
81 d.w_times_x_ += d.cross_x_;
82 d.w_times_u_ += d.cross_u_;
83 }
84 data.value_ = Scalar(0.5) * x.dot(d.w_times_x_ + 2 * interp_x) +
85 Scalar(0.5) * u.dot(d.w_times_u_ + 2 * interp_u);
86 }
87
88 void computeGradients(const ConstVectorRef &, const ConstVectorRef &,
89 CostData &data) const {
90 Data &d = static_cast<Data &>(data);
91 d.Lx_ = d.w_times_x_ + interp_x;
92 d.Lu_ = d.w_times_u_ + interp_u;
93 }
94
95 void computeHessians(const ConstVectorRef &, const ConstVectorRef &,
96 CostData &) const {}
97
98 shared_ptr<CostData> createData() const {
99 auto data = std::make_shared<Data>(this->ndx(), this->nu);
100 data->Lxx_ = Wxx_;
101 data->Luu_ = Wuu_;
102 data->Lxu_ = Wxu_;
103 data->Lux_ = Wxu_.transpose();
104 return data;
105 }
106
107 ConstMatrixRef getCrossWeights() const { return Wxu_; }
108 void setCrossWeight(const ConstMatrixRef &w) {
109 Wxu_ = w;
110 has_cross_term_ = true;
111 debug_check_dims();
112 }
113
115 bool hasCrossTerm() const { return has_cross_term_; }
116
117protected:
120
121private:
122 static void _check_dim_equal(long n, long m, const std::string &msg = "") {
123 if (n != m)
124 ALIGATOR_RUNTIME_ERROR("Dimensions inconsistent: got {:d} and {:d}{}.\n",
125 n, m, msg);
126 }
127
128 void debug_check_dims() const {
129 _check_dim_equal(Wxx_.rows(), Wxx_.cols(), " for x weights");
130 _check_dim_equal(Wuu_.rows(), Wuu_.cols(), " for u weights");
131 _check_dim_equal(Wxu_.rows(), this->ndx(), " for cross-term weight");
132 _check_dim_equal(Wxu_.cols(), this->nu, " for cross-term weight");
133 _check_dim_equal(interp_x.rows(), Wxx_.rows(),
134 " for x weights and intercept");
135 _check_dim_equal(interp_u.rows(), Wuu_.rows(),
136 " for u weights and intercept");
137 }
138};
139
140template <typename Scalar>
143 using VectorXs = typename Base::VectorXs;
145
146 QuadraticCostDataTpl(const int nx, const int nu)
147 : Base(nx, nu), w_times_x_(nx), w_times_u_(nu), cross_x_(nu),
148 cross_u_(nu) {
149 w_times_x_.setZero();
150 w_times_u_.setZero();
151 cross_x_.setZero();
152 cross_u_.setZero();
153 }
154};
155
156} // namespace aligator
157
158#ifdef ALIGATOR_ENABLE_TEMPLATE_INSTANTIATION
159#include "./quad-costs.txx"
160#endif
#define ALIGATOR_RUNTIME_ERROR(...)
Definition exceptions.hpp:7
Main package namespace.
Stage costs for control problems.
Definition fwd.hpp:62
Data struct for CostAbstractTpl.
Definition fwd.hpp:65
QuadraticCostDataTpl(const int nx, const int nu)
typename Base::VectorXs VectorXs
Euclidean quadratic cost.
proxsuite::nlp::ManifoldAbstractTpl< Scalar > Manifold
VectorXs interp_x
Affine term in .
QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u)
VectorXs interp_u
Affine term in .
void computeGradients(const ConstVectorRef &, const ConstVectorRef &, CostData &data) const
QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u, const ConstMatrixRef &w_cross)
shared_ptr< CostData > createData() const
void evaluate(const ConstVectorRef &x, const ConstVectorRef &u, CostData &data) const
MatrixXs Wxu_
Weight N for term .
bool has_cross_term_
Whether a cross term exists.
ConstMatrixRef getCrossWeights() const
bool hasCrossTerm() const
Whether a cross term exists.
QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u, const ConstVectorRef &interp_x, const ConstVectorRef &interp_u)
static auto get_vector_space(Eigen::Index nx)
proxsuite::nlp::VectorSpaceTpl< Scalar, Eigen::Dynamic > VectorSpace
void computeHessians(const ConstVectorRef &, const ConstVectorRef &, CostData &) const
void setCrossWeight(const ConstMatrixRef &w)
QuadraticCostTpl(const ConstMatrixRef &w_x, const ConstMatrixRef &w_u, const ConstMatrixRef &w_cross, const ConstVectorRef &interp_x, const ConstVectorRef &interp_u)