cyqlone develop
Fast, parallel and vectorized solver for linear systems with optimal control structure.
Loading...
Searching...
No Matches
cyqlone-storage.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// Data structure for optimal control problems where the initial states are eliminated.
5/// @ingroup topic-ocp-formulations
6
7#include <cyqlone/config.hpp>
8#include <cyqlone/ocp.hpp>
9#include <batmat/matrix/matrix.hpp>
10#include <span>
11#include <vector>
12
13namespace cyqlone {
14
15/// Storage for a linear-quadratic OCP with the initial states x₀ eliminated.
16/// ~~~
17/// ₙ₋₁
18/// minimize ∑ [½ uᵢᵀ Rᵢ uᵢ + uᵢᵀ Sᵢ xᵢ + ½ xᵢᵀ Qᵢ xᵢ + rᵢᵀuᵢ + qᵢᵀxᵢ]
19/// ⁱ⁼¹
20/// + ½ u₀ᵀ R₀ u₀ + (r₀ + S₀ xᵢₙᵢₜ)ᵀ u₀
21/// + ½ xₙᵀ Qₙ xₙ + qₙᵀ xₙ
22/// s.t. xᵢ₊₁ = Aᵢ xᵢ + Bᵢ uᵢ + cᵢ
23/// lᵢ ≤ Cᵢ xᵢ + Dᵢ uᵢ ≤ uᵢ
24/// l₀ - C₀ xᵢₙᵢₜ ≤ D₀ U₀ ≤ u₀ - C₀ xᵢₙᵢₜ
25/// lₙ ≤ Cₙ xₙ ≤ uₙ
26/// ~~~
27/// The matrices are combined per stage, with inputs ordered first.
28/// The first and last stage are special because of the lack of x₀ and uₙ.
29/// ~~~
30/// Hᵢ = [ Rᵢ Sᵢ ], H₀ = [ R₀ 0 ], Fᵢ = [ Bᵢ Aᵢ ], Gᵢ = [ Dᵢ Cᵢ ], G₀ = [ D₀ Cₙ ]
31/// [ Sᵢᵀ Qᵢ ] [ 0 Qₙ ]
32/// ~~~
33/// Due to the elimination of x₀, there may be fewer constraints for the first stage, which is
34/// tracked by the Ju0 mask. When reconstructing the solution, the multipliers for eliminated
35/// constraints are set to zero (we assume that the initial state is feasible w.r.t. the state
36/// constraints).
37/// @ingroup topic-ocp-formulations
38template <class T = real_t>
40 using value_type = T;
41 index_t N_horiz;
42 index_t nx, nu, ny, ny_0, ny_N;
43 std::vector<bool> Ju0;
45 matrix data_H = [this] {
46 return matrix{{.depth = N_horiz, .rows = nu + nx, .cols = nu + nx}};
47 }();
48 matrix data_F = [this] { return matrix{{.depth = N_horiz, .rows = nx, .cols = nu + nx}}; }();
49 matrix data_G = [this] {
50 return matrix{{.depth = N_horiz - 1, .rows = ny, .cols = nu + nx}};
51 }();
52 matrix data_G0N = [this] {
53 return matrix{{.depth = 1, .rows = ny_0 + ny_N, .cols = nu + nx}};
54 }();
55 matrix data_rq = [this] { return matrix{{.depth = N_horiz, .rows = nu + nx, .cols = 1}}; }();
56 matrix data_c = [this] { return matrix{{.depth = N_horiz, .rows = nx, .cols = 1}}; }();
57 matrix data_lb = [this] { return matrix{{.depth = N_horiz - 1, .rows = ny, .cols = 1}}; }();
58 matrix data_lb0N = [this] { return matrix{{.depth = 1, .rows = ny_0 + ny_N, .cols = 1}}; }();
59 matrix data_ub = [this] { return matrix{{.depth = N_horiz - 1, .rows = ny, .cols = 1}}; }();
60 matrix data_ub0N = [this] { return matrix{{.depth = 1, .rows = ny_0 + ny_N, .cols = 1}}; }();
61 std::vector<index_t> indices_G0 = std::vector<index_t>(ny_0);
62
63 void update_impl(const LinearOCPStorage &ocp);
64 void update(const LinearOCPStorage &ocp);
65 static CyqloneStorage build(const LinearOCPStorage &ocp, index_t ny_0 = -1);
66 void reconstruct_ineq_multipliers(std::span<const value_type> y_compressed,
67 std::span<value_type> y) const;
68 std::vector<value_type>
69 reconstruct_ineq_multipliers(std::span<const value_type> y_compressed) const;
70 static index_t count_constr_0(const LinearOCPStorage &ocp, std::vector<bool> &Ju0);
71
74
76 std::span<const value_type> ux_compressed,
77 std::span<const value_type> y_compressed,
78 std::span<const value_type> λ_compressed) const;
79
81 std::span<const value_type> ux_compressed,
82 std::span<const value_type> y_compressed,
83 std::span<const value_type> λ_compressed) const;
84};
85
86} // namespace cyqlone
Data structure for optimal control problems.
Storage for a linear-quadratic OCP with the initial states x₀ eliminated.
static index_t count_constr_0(const LinearOCPStorage &ocp, std::vector< bool > &Ju0)
Solution reconstruct_solution(const LinearOCPStorage &ocp, std::span< const value_type > ux_compressed, std::span< const value_type > y_compressed, std::span< const value_type > λ_compressed) const
std::vector< index_t > indices_G0
batmat::matrix::Matrix< value_type, index_t > matrix
LinearOCPStorage::Solution Solution
void reconstruct_ineq_multipliers(std::span< const value_type > y_compressed, std::span< value_type > y) const
void update_impl(const LinearOCPStorage &ocp)
LinearOCPStorage::KKTError KKTError
void update(const LinearOCPStorage &ocp)
KKTError compute_kkt_error(const LinearOCPStorage &ocp, std::span< const value_type > ux_compressed, std::span< const value_type > y_compressed, std::span< const value_type > λ_compressed) const
std::vector< bool > Ju0
static CyqloneStorage build(const LinearOCPStorage &ocp, index_t ny_0=-1)
Storage for a linear-quadratic OCP of the form.
Definition ocp.hpp:37