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) +
")";
61 res[0] = convexify(arg[0], options);
64 int Convexify::eval(
const double** arg,
double** res, casadi_int* iw,
double* w)
const {
66 casadi_assert(!ret,
"Failure in convexification.");
72 const std::string& Hin,
const std::string& Hout,
73 const std::string& iw,
const std::string& w) {
74 g.
local(
"cvx_config",
"struct casadi_convexify_config");
76 g <<
"cvx_config.strategy = CVX_REGULARIZE;\n";
78 g <<
"cvx_config.strategy = CVX_EIGEN_CLIP;\n";
80 g <<
"cvx_config.strategy = CVX_EIGEN_REFLECT;\n";
83 g <<
"cvx_config.type_in = CVX_SYMM;\n";
85 g <<
"cvx_config.type_in = CVX_TRIL;\n";
87 g <<
"cvx_config.type_in = CVX_TRIU;\n";
89 g <<
"cvx_config.Hsp = " << g.
sparsity(d.
Hsp) <<
";\n";
90 g <<
"cvx_config.Hrsp = " << g.
sparsity(d.
Hrsp) <<
";\n";
96 g <<
"cvx_config.scc_offset_size = " << d.
scc_offset.size() <<
";\n";
99 return "convexify_eval(&cvx_config, " + Hin +
"," + Hout +
"," + iw +
"," +
"w)";
113 s.
version(prefix +
"Convexify", 1);
123 s.
pack(prefix +
"Convexify::Hsp", d.
Hsp);
124 s.
pack(prefix +
"Convexify::Hrsp", d.
Hrsp);
129 s.
version(prefix +
"Convexify", 1);
131 s.
unpack(prefix +
"Convexify::type_in", type_in);
132 d.
config.
type_in =
static_cast<casadi_convexify_type_in_t
>(type_in);
134 s.
unpack(prefix +
"Convexify::strategy", strategy);
135 d.
config.
strategy =
static_cast<casadi_convexify_strategy_t
>(strategy);
143 s.
unpack(prefix +
"Convexify::Hsp", d.
Hsp);
157 const std::vector<casadi_int>& arg,
158 const std::vector<casadi_int>& res,
159 const std::vector<bool>& arg_is_ref,
160 std::vector<bool>& res_is_ref)
const {
162 g.
work(arg[0],
dep(0).
nnz(), arg_is_ref[0]), g.
work(res[0],
nnz(),
false),
"iw",
"w");
163 g <<
"if (" << ret <<
") return 1;\n";
168 casadi_assert(H.
is_square(),
"Convexify ");
176 casadi_error(
"Convexify operation requires symmetric or triangular input");
182 std::string strategy =
"eigen-clip";
185 for (
auto&&
op : opts) {
186 if (
op.first==
"strategy") {
187 strategy =
op.second.to_string();
188 }
else if (
op.first==
"margin") {
190 casadi_assert(d.
config.
margin>=0,
"Margin must be >=0");
191 }
else if (
op.first==
"max_iter_eig") {
193 }
else if (
op.first==
"verbose") {
196 casadi_error(
"Unknown option '" +
op.first +
"'.");
201 if (strategy==
"regularize") {
203 casadi_assert(d.
config.
type_in==CVX_SYMM,
"Only truly symmetric matrices supported");
204 }
else if (strategy==
"eigen-reflect") {
206 }
else if (strategy==
"eigen-clip") {
209 casadi_error(
"Invalid convexify strategy. "
210 "Choose from regularize|eigen-reflect|eigen-clip. Got '" + strategy +
"'.");
219 casadi_int block_size = 0;
223 std::vector<casadi_int> scc_index;
227 std::vector<Sparsity> sp;
228 for (casadi_int i=0;i<scc_nb;++i) {
238 sp.push_back(stencil);
241 std::vector<casadi_int> ssc_perm =
lookupvector(scc_index);
242 std::vector<casadi_int> mapping_dummy;
243 Hsp = diagcat(sp).
sub(ssc_perm, ssc_perm, mapping_dummy);
247 for (casadi_int i=0;i<scc_nb;++i) {
249 if (block>block_size) block_size = block;
254 if (d.
config.
verbose) casadi_message(
"Identified " +
str(scc_nb) +
" blocks "
255 "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 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.
void eval_mx(const std::vector< MX > &arg, std::vector< MX > &res) const override
Evaluate symbolically (MX)
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