26 #include "convexify.hpp"
32 case CVX_REGULARIZE:
return "regularize";
33 case CVX_EIGEN_REFLECT:
return "eigen-reflect";
34 case CVX_EIGEN_CLIP:
return "eigen-clip";
53 return "convexify(" + arg.at(0) +
")";
57 const std::vector<bool>& unique)
const {
62 res[0] = convexify(arg[0], options);
65 int Convexify::eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
67 casadi_assert(!ret,
"Failure in convexification.");
73 const std::string& Hin,
const std::string& Hout,
74 const std::string& iw,
const std::string& w) {
75 g.
local(
"cvx_config",
"struct casadi_convexify_config");
77 g <<
"cvx_config.strategy = CVX_REGULARIZE;\n";
79 g <<
"cvx_config.strategy = CVX_EIGEN_CLIP;\n";
81 g <<
"cvx_config.strategy = CVX_EIGEN_REFLECT;\n";
84 g <<
"cvx_config.type_in = CVX_SYMM;\n";
86 g <<
"cvx_config.type_in = CVX_TRIL;\n";
88 g <<
"cvx_config.type_in = CVX_TRIU;\n";
90 g <<
"cvx_config.Hsp = " << g.
sparsity(d.
Hsp) <<
";\n";
91 g <<
"cvx_config.Hrsp = " << g.
sparsity(d.
Hrsp) <<
";\n";
97 g <<
"cvx_config.scc_offset_size = " << d.
scc_offset.size() <<
";\n";
100 return "casadi_convexify_eval(&cvx_config, " + Hin +
"," + Hout +
"," + iw +
"," +
"w)";
114 s.
version(prefix +
"Convexify", 1);
124 s.
pack(prefix +
"Convexify::Hsp", d.
Hsp);
125 s.
pack(prefix +
"Convexify::Hrsp", d.
Hrsp);
130 s.
version(prefix +
"Convexify", 1);
132 s.
unpack(prefix +
"Convexify::type_in", type_in);
133 d.
config.
type_in =
static_cast<casadi_convexify_type_in_t
>(type_in);
135 s.
unpack(prefix +
"Convexify::strategy", strategy);
136 d.
config.
strategy =
static_cast<casadi_convexify_strategy_t
>(strategy);
144 s.
unpack(prefix +
"Convexify::Hsp", d.
Hsp);
158 const std::vector<casadi_int>& arg,
159 const std::vector<casadi_int>& res,
160 const std::vector<bool>& arg_is_ref,
161 std::vector<bool>& res_is_ref)
const {
163 g.
work(arg[0],
dep(0).
nnz(), arg_is_ref[0]), g.
work(res[0],
nnz(),
false),
"iw",
"w");
164 g <<
"if (" << ret <<
") return 1;\n";
169 casadi_assert(H.
is_square(),
"Convexify ");
177 casadi_error(
"Convexify operation requires symmetric or triangular input");
183 std::string strategy =
"eigen-clip";
186 for (
auto&&
op : opts) {
187 if (
op.first==
"strategy") {
188 strategy =
op.second.to_string();
189 }
else if (
op.first==
"margin") {
191 casadi_assert(d.
config.
margin>=0,
"Margin must be >=0");
192 }
else if (
op.first==
"max_iter_eig") {
194 }
else if (
op.first==
"verbose") {
197 casadi_error(
"Unknown option '" +
op.first +
"'.");
202 if (strategy==
"regularize") {
204 casadi_assert(d.
config.
type_in==CVX_SYMM,
"Only truly symmetric matrices supported");
205 }
else if (strategy==
"eigen-reflect") {
207 }
else if (strategy==
"eigen-clip") {
210 casadi_error(
"Invalid convexify strategy. "
211 "Choose from regularize|eigen-reflect|eigen-clip. Got '" + strategy +
"'.");
220 casadi_int block_size = 0;
224 std::vector<casadi_int> scc_index;
228 std::vector<Sparsity> sp;
229 for (casadi_int i=0;i<scc_nb;++i) {
239 sp.push_back(stencil);
242 std::vector<casadi_int> ssc_perm =
lookupvector(scc_index);
243 std::vector<casadi_int> mapping_dummy;
244 Hsp = diagcat(sp).
sub(ssc_perm, ssc_perm, mapping_dummy);
248 for (casadi_int i=0;i<scc_nb;++i) {
250 if (block>block_size) block_size = block;
255 if (d.
config.
verbose) casadi_message(
"Identified " +
str(scc_nb) +
" blocks "
256 "with maximum size " +
str(block_size) +
".");
Helper class for C code generation.
std::string work(casadi_int n, casadi_int sz, bool is_ref) const
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string convexify_eval(const ConvexifyData &d, const std::string &Hin, const std::string &Hout, const std::string &iw, const std::string &w)
convexify
std::string sparsity(const Sparsity &sp, bool canonical=true)
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res, const std::vector< bool > &unique={}) const override
Evaluate symbolically (MX)
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static void serialize(SerializingStream &s, const std::string &prefix, const ConvexifyData &d)
std::string disp(const std::vector< std::string > &arg) const override
Print expression.
struct ConvexifyData convexify_data_
size_t sz_w() const override
Get required length of w field.
size_t sz_iw() const override
Get required length of iw field.
casadi_int op() const override
Get the operation.
void generate(CodeGenerator &g, const std::vector< casadi_int > &arg, const std::vector< casadi_int > &res, const std::vector< bool > &arg_is_ref, std::vector< bool > &res_is_ref) const override
Generate code for the operation.
Convexify(const MX &H, const Dict &opts=Dict())
Constructor.
int eval(const double **arg, double **res, casadi_int *iw, double *w) const override
Evaluate the function numerically.
static Sparsity setup(ConvexifyData &d, const Sparsity &H, const Dict &opts=Dict(), bool inplace=true)
static MXNode * deserialize(DeserializingStream &s)
Deserialize without type information.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
Node class for MX objects.
casadi_int nnz(casadi_int i=0) const
const MX & dep(casadi_int ind=0) const
dependencies - functions that have to be evaluated before this one
virtual void serialize_body(SerializingStream &s) const
Serialize an object without type information.
void set_sparsity(const Sparsity &sparsity)
Set the sparsity.
void set_dep(const MX &dep)
Set unary dependency.
const Sparsity & sparsity() const
Get the sparsity pattern.
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
static Sparsity upper(casadi_int n)
Create a upper triangular square sparsity pattern *.
Sparsity sub(const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, std::vector< casadi_int > &mapping, bool ind1=false) const
Get a submatrix.
casadi_int size1() const
Get the number of rows.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
casadi_int scc(std::vector< casadi_int > &index, std::vector< casadi_int > &offset) const
Find the strongly connected components of the bigraph defined by the sparsity pattern.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
static Sparsity triu(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
Sparsity T() const
Transpose the matrix.
static Sparsity tril(const Sparsity &x, bool includeDiagonal=true)
Enlarge matrix.
bool is_tril(bool strictly=false) const
Is lower triangular?
casadi_int nnz() const
Get the number of (structural) non-zeros.
static Sparsity lower(casadi_int n)
Create a lower triangular square sparsity pattern *.
bool is_square() const
Is square?
bool is_triu(bool strictly=false) const
Is upper triangular?
bool is_symmetric() const
Is symmetric?
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
std::string str(const T &v)
String representation, any type.
std::vector< casadi_int > lookupvector(const std::vector< casadi_int > &v, casadi_int size)
Returns a vector for quickly looking up entries of supplied list.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
std::string strategy_to_string(casadi_convexify_strategy_t s)
std::vector< casadi_int > scc_offset
casadi_convexify_config< double > config
std::vector< casadi_int > scc_mapping
casadi_int max_iter_eig
For eigen-* convexification strategies: maximum iterations for symmetric Schur decomposition.
casadi_convexify_strategy_t strategy
casadi_int scc_offset_size
casadi_convexify_type_in_t type_in
const casadi_int * scc_offset
Block structure of Hessian for certain convexification methods.
const casadi_int * scc_mapping