26 #include "dple_impl.hpp"
39 std::string
doc_dple(
const std::string& name) {
57 casadi_assert(A.size()==V.size(),
58 "dplesol: sizes of A vector (" +
str(A.size()) +
") and V vector "
59 "(" +
str(V.size()) +
") must match.");
60 std::vector<MX> Adense, Vdense;
62 for (casadi_int i=0;i<A.size();++i) {
63 Adense.push_back(densify(A[i]));
64 Vdense.push_back(densify(V[i]));
67 MX ret =
dplesol(diagcat(Adense), diagcat(Vdense), solver, opts);
68 return diagsplit(ret, ret.
size1()/A.size());
73 casadi_assert(A.size()==V.size(),
74 "dplesol: sizes of A vector (" +
str(A.size()) +
") and V vector "
75 "(" +
str(V.size()) +
") must match.");
76 std::vector<DM> Adense, Vdense;
78 for (casadi_int i=0;i<A.size();++i) {
79 Adense.push_back(densify(A[i]));
80 Vdense.push_back(densify(V[i]));
83 DM Afull = diagcat(Adense);
84 DM Vfull = diagcat(Vdense);
94 return diagsplit(f_out[
"p"], f_out[
"p"].size1()/A.size());
103 std::vector<std::string> ret(
dple_n_in());
104 for (
size_t i=0; i<ret.size(); ++i) ret[i]=
dple_in(i);
110 for (
size_t i=0; i<ret.size(); ++i) ret[i]=
dple_out(i);
120 return std::string();
128 return std::string();
142 for (
auto i=st.begin(); i!=st.end(); ++i) {
145 }
else if (i->first==
"v") {
148 casadi_error(
"Unrecognized field in Dple structure: " +
str(i->first));
178 "Assume constant dimension of P"}},
181 "Assume P positive definite"}},
184 "Throw an exception when it is detected that Product(A_i, i=N..1)"
185 "has eigenvalues greater than 1-eps_unstable"}},
188 "A margin for unstability detection"}}
203 for (
auto&& op : opts) {
204 if (op.first==
"const_dim") {
206 }
else if (op.first==
"pos_def") {
208 }
else if (op.first==
"error_unstable") {
210 }
else if (op.first==
"eps_unstable") {
217 casadi_assert_dev(
nrhs_>=1);
219 std::vector<Sparsity> Vs = horzsplit(
V_,
V_.
size1());
222 "V must be symmetric but got " + Vref.
dim() +
".");
225 casadi_assert_dev(s==Vref);
229 casadi_int blocksize = Vref.
colind()[1];
233 std::vector<Sparsity> blocks(
K_, block);
234 casadi_assert(Vref==diagcat(blocks),
"Structure not recognised.");
235 casadi_assert(
A_==Vref,
"Structure not recognised.");
241 const std::vector<std::string>& inames,
242 const std::vector<std::string>& onames,
243 const Dict& opts)
const {
252 MX temp = mtimes(std::vector<MX>{Adot,
P, A.
T()}) +
253 mtimes(std::vector<MX>{A,
P, Adot.
T()}) + Vdot;
254 Vdotf =
Function(
"PAVbar", {A,
P, Adot, Vdot},
255 { (temp+temp.
T())/2});
261 MX Qdot = Vdotf.
map(
"map",
"serial",
nrhs_, {0, 2}, std::vector<casadi_int>{})
262 .
map(
"map",
"serial", nfwd, {0, 1}, std::vector<casadi_int>{})({A,
P, Adot, Vdot})[0];
267 options[
"allow_duplicate_io_names"] =
true;
268 return Function(name, {A, V,
P, Adot, Vdot}, {Pdot}, inames, onames, options);
273 const std::vector<std::string>& inames,
274 const std::vector<std::string>& onames,
275 const Dict& opts)
const {
283 std::vector<MX> ret = diagsplit(A, n);
284 std::reverse(ret.begin(), ret.end());
285 std::vector<MX> retT;
286 std::vector<MX> retS;
287 for (
auto & e : ret) retT.push_back(e.T());
288 for (
auto & e : ret) retS.push_back((e+e.T())/2);
300 Abarf =
Function(
"PAVbar", {
P, A_rev, Vbar_rev},
301 {2*revT(mtimes(std::vector<MX>{rev(
P)[0], A_rev, Vbar_rev}))[0]});
313 MX A_rev = revT(A)[0];
319 MX Vbar = rev.map(
nrhs_).map(nadj)(Vbar_rev)[0];
321 MX Abar = Abarf.map(
"map",
"serial",
nrhs_, std::vector<casadi_int>{1}, {0}).
322 map(
"map",
"serial", nadj, {0, 1}, std::vector<casadi_int>{})(
323 {
P, A_rev, Vbar_rev})[0];
326 options[
"allow_duplicate_io_names"] =
true;
329 return Function(name, {A, V,
P, Pbar}, {Abar, Vbar}, inames, onames, options);
337 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
338 std::mutex Dple::mutex_solvers_;
Sparsity A_
List of sparsities of A_i.
Sparsity get_sparsity_in(casadi_int i) override
Sparsities of function inputs and outputs.
static std::map< std::string, Plugin > solvers_
Collection of solvers.
double eps_unstable_
Margin for instability detection.
static const std::string infix_
Infix.
bool error_unstable_
Throw an error when system is unstable.
void init(const Dict &opts) override
Initialize.
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates nfwd forward derivatives.
bool const_dim_
Constant dimensions.
casadi_int nrhs_
Number of right hand sides.
static const Options options_
Options.
Dple(const std::string &name, const SpDict &st)
Sparsity get_sparsity_out(casadi_int i) override
Sparsities of function inputs and outputs.
Sparsity V_
List of sparsities of V_i.
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates nadj adjoint derivatives.
bool pos_def_
Assume positive definiteness of P_i.
Internal class for Function.
void init(const Dict &opts) override
Initialize.
Function map(casadi_int n, const std::string ¶llelization) const
Generate/retrieve cached serial map.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Input/output dimensions.
static const Options options_
Options.
static Function create(FunctionInternal *node)
Create from node.
Function map(casadi_int n, const std::string ¶llelization="serial") const
Create a mapped version of this function.
casadi_int size1() const
Get the first dimension (i.e. number of rows)
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
const Sparsity & sparsity() const
Get the sparsity pattern.
MX T() const
Transpose the matrix.
const Sparsity & sparsity() const
Const access the sparsity - reference to data member.
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
static Dple * instantiate(const std::string &fname, const std::string &pname, Problem problem)
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.
virtual const char * plugin_name() const=0
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.
casadi_int size1() const
Get the number of rows.
std::string dim(bool with_nz=false) const
Get the dimension as a string.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
casadi_int size2() const
Get the number of columns.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
bool is_symmetric() const
Is symmetric?
std::vector< std::string > dple_in()
Get input scheme of DPLE solvers.
bool has_dple(const std::string &name)
Check if a particular plugin is available.
MX dplesol(const MX &A, const MX &V, const std::string &solver, const Dict &opts)
std::vector< std::string > dple_out()
Get output scheme of DPLE solvers.
void load_dple(const std::string &name)
Explicitly load a plugin dynamically.
casadi_int dple_n_in()
Get the number of QP solver inputs.
casadi_int dple_n_out()
Get the number of QP solver outputs.
std::string doc_dple(const std::string &name)
Get the documentation string for a plugin.
std::map< std::string, MX > MXDict
DpleInput
Input arguments of a dple solver [dpleIn].
@ DPLE_A
A matrices (horzcat when const_dim, diagcat otherwise) [a].
@ DPLE_V
V matrices (horzcat when const_dim, diagcat otherwise) [v].
DpleOutput
Output arguments of a dple solver [dpleOut].
@ DPLE_NUM_OUT
Number of arguments.
@ DPLE_P
Lyapunov matrix (horzcat when const_dim, diagcat otherwise) (Cholesky of P if pos_def) [p].
std::vector< MX > MXVector
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::vector< DM > DMVector
std::map< std::string, Sparsity > SpDict
std::map< std::string, DM > DMDict
Options metadata for a class.