26 #include "superscs_interface.hpp"
27 #include "casadi/core/casadi_misc.hpp"
29 #include <linsys/amatrix.h>
30 #include <linsys/common.h>
36 int CASADI_CONIC_SUPERSCS_EXPORT
39 plugin->name =
"superscs";
41 plugin->version = CASADI_VERSION;
53 const std::map<std::string, Sparsity>& st)
65 "Options to be passed to superscs."}}
75 scs_set_default_settings(&dummy);
80 for (
auto&& op : opts) {
81 if (op.first==
"superscs") {
82 const Dict& opts = op.second;
83 for (
auto&& op : opts) {
84 if (op.first==
"normalize") {
86 }
else if (op.first==
"scale") {
88 }
else if (op.first==
"rho_x") {
90 }
else if (op.first==
"max_time_milliseconds") {
91 settings_.max_time_milliseconds = op.second;
92 }
else if (op.first==
"max_iters") {
94 }
else if (op.first==
"previous_max_iters") {
96 }
else if (op.first==
"eps") {
98 }
else if (op.first==
"alpha") {
100 }
else if (op.first==
"cg_rate") {
102 }
else if (op.first==
"verbose") {
104 }
else if (op.first==
"warm_start") {
106 }
else if (op.first==
"do_super_scs") {
108 }
else if (op.first==
"k0") {
110 }
else if (op.first==
"c_bl") {
112 }
else if (op.first==
"k1") {
114 }
else if (op.first==
"k2") {
116 }
else if (op.first==
"c1") {
118 }
else if (op.first==
"sse") {
120 }
else if (op.first==
"ls") {
122 }
else if (op.first==
"beta") {
124 }
else if (op.first==
"sigma") {
126 }
else if (op.first==
"direction") {
127 if (op.second==
"restarted_broyden") {
129 }
else if (op.second==
"anderson_acceleration") {
130 settings_.direction = anderson_acceleration;
131 }
else if (op.second==
"fixed_point_residual") {
132 settings_.direction = fixed_point_residual;
133 }
else if (op.second==
"full_broyden") {
136 casadi_error(
"Unknown argument for direction.");
138 }
else if (op.first==
"thetabar") {
140 }
else if (op.first==
"memory") {
142 }
else if (op.first==
"tRule") {
144 }
else if (op.first==
"broyden_init_scaling") {
145 settings_.broyden_init_scaling = op.second;
146 }
else if (op.first==
"do_record_progress") {
147 settings_.do_record_progress = op.second;
148 }
else if (op.first==
"do_override_streams") {
149 settings_.do_override_streams = op.second;
151 casadi_error(
"Not recognised");
200 for (casadi_int i=1;i<sm.
r.size();++i) {
202 for (casadi_int k=sm.
r[i-1];k<sm.
r[i]-1;++k) {
207 casadi_int offset = 0;
232 const casadi_int* colind = sp.
colind();
233 const casadi_int* row = sp.
row();
234 const casadi_int* ddata = sm.
map_Q.
ptr();
237 casadi_int n_c = sp.
size2();
239 std::vector<casadi_int> c_row, c_col, c_data;
241 for (casadi_int j=0; j<n_c; ++j) {
243 for (casadi_int k=colind[i]; k<colind[i+1]-1; ++k) {
244 c_col.push_back(row[k]);
246 c_data.push_back(offset+ddata[k]);
257 F = blockcat(
IM(1,
nx_), offset, F,
IM(
nx_, 1));
258 F = vertcat(F, horzcat(
IM(1,
nx_), offset+1));
262 A = horzcat(A,
IM(A.
size1(), 1));
263 B = horzcat(B,
IM(B.
size1(), 1));
264 C = horzcat(
C,
IM(
C.size1(), 1));
280 m->ldl_w.resize(
nx_);
286 m->data.stgs = &m->settings;
291 m->A.p =
get_ptr(m->at_colind);
300 m->cone.qsize = sm.
r.size();
302 m->q.push_back(
nx_+2);
308 m->fstats[
"preprocessing"] =
FStats();
309 m->fstats[
"solver"] =
FStats();
310 m->fstats[
"postprocessing"] =
FStats();
315 solve(
const double** arg,
double** res, casadi_int* iw,
double* w,
void* mem)
const {
320 bool H_all_zero =
true;
321 for (casadi_int k=0;k<
H_.
nnz();++k) {
322 H_all_zero = H_all_zero && arg[
CONIC_H][k]==0;
336 double* a_ptr = w; w+=
At_.
nnz();
342 for (casadi_int k=0;k<
nx_;++k) {
343 a_ptr[*lookup++] = 1;
345 for (casadi_int k=0;k<
nx_;++k) {
346 a_ptr[*lookup++] = -1;
349 for (casadi_int k=0;k<
A_.
nnz();++k) {
350 a_ptr[*lookup++] = arg[
CONIC_A][k];
352 for (casadi_int k=0;k<
A_.
nnz();++k) {
353 a_ptr[*lookup++] = -arg[
CONIC_A][k];
357 a_ptr[*lookup++] = -1;
360 for (casadi_int k=0;k<
Q_.
nnz();++k) {
361 casadi_int loc = *lookup++;
368 for (casadi_int k=0;k<
F_.
nnz_out(0);++k) {
369 a_ptr[*lookup++] = -m->F_res[k];
371 a_ptr[*lookup++] = -1;
372 a_ptr[*lookup++] = 1;
396 for (casadi_int j=0; j<sm.
map_Q.
size2(); ++j) {
415 std::vector<casadi_int> s;
416 for (casadi_int k=0;k<
At_.
size1();++k) {
417 if (!isinf(m->data.b[k])) s.push_back(k);
420 std::vector<casadi_int> mapping;
426 m->A.m = Anew.
size1();
427 m->data.m = Anew.
size1();
428 for (casadi_int k=0;k<Anew.
nnz();++k) {
429 m->A.x[k] = m->A.x[mapping[k]];
433 for (casadi_int k=0;k<
At_.
size1();++k) {
434 casadi_int e = sl[k];
435 if (e>=0) m->data.b[e] = m->data.b[k];
457 if (m->sol) scs_free_sol(m->sol);
458 if (m->info) scs_free_info(m->info);
460 m->sol = scs_init_sol();
461 m->info = scs_init_info();
464 std::memcpy(m->data.stgs, &
settings_,
sizeof(ScsSettings));
466 casadi_int status = scs(&m->data, &m->cone, m->sol, m->info);
468 m->d_qp.success = SCS_SOLVED==status;
490 if (
sol) scs_free_sol(
sol);
495 s.
version(
"SuperscsInterface", 1);
498 scs_set_default_settings(&dummy);
499 s.
unpack(
"SuperscsInterface::settings::normalize",
settings_.normalize);
502 s.
unpack(
"SuperscsInterface::settings::max_time_milliseconds",
settings_.max_time_milliseconds);
503 s.
unpack(
"SuperscsInterface::settings::max_iters",
settings_.max_iters);
504 s.
unpack(
"SuperscsInterface::settings::previous_max_iters",
settings_.previous_max_iters);
509 s.
unpack(
"SuperscsInterface::settings::warm_start",
settings_.warm_start);
510 s.
unpack(
"SuperscsInterface::settings::do_super_scs",
settings_.do_super_scs);
521 s.
unpack(
"SuperscsInterface::settings::direction", dir);
522 settings_.direction =
static_cast<direction_enum
>(dir);
526 s.
unpack(
"SuperscsInterface::settings::broyden_init_scaling",
settings_.broyden_init_scaling);
527 s.
unpack(
"SuperscsInterface::settings::do_record_progress",
settings_.do_record_progress);
528 s.
unpack(
"SuperscsInterface::settings::do_override_streams",
settings_.do_override_streams);
531 s.
unpack(
"SuperscsInterface::f",
F_);
541 s.
version(
"SuperscsInterface", 1);
542 s.
pack(
"SuperscsInterface::settings::normalize",
settings_.normalize);
543 s.
pack(
"SuperscsInterface::settings::scale",
settings_.scale);
544 s.
pack(
"SuperscsInterface::settings::rho_x",
settings_.rho_x);
545 s.
pack(
"SuperscsInterface::settings::max_time_milliseconds",
settings_.max_time_milliseconds);
546 s.
pack(
"SuperscsInterface::settings::max_iters",
settings_.max_iters);
547 s.
pack(
"SuperscsInterface::settings::previous_max_iters",
settings_.previous_max_iters);
549 s.
pack(
"SuperscsInterface::settings::alpha",
settings_.alpha);
550 s.
pack(
"SuperscsInterface::settings::cg_rate",
settings_.cg_rate);
551 s.
pack(
"SuperscsInterface::settings::verbose",
settings_.verbose);
552 s.
pack(
"SuperscsInterface::settings::warm_start",
settings_.warm_start);
553 s.
pack(
"SuperscsInterface::settings::do_super_scs",
settings_.do_super_scs);
562 s.
pack(
"SuperscsInterface::settings::sigma",
settings_.sigma);
563 s.
pack(
"SuperscsInterface::settings::direction",
static_cast<casadi_int
>(
settings_.direction));
564 s.
pack(
"SuperscsInterface::settings::thetabar",
settings_.thetabar);
565 s.
pack(
"SuperscsInterface::settings::memory",
settings_.memory);
566 s.
pack(
"SuperscsInterface::settings::tRule",
settings_.tRule);
567 s.
pack(
"SuperscsInterface::settings::broyden_init_scaling",
settings_.broyden_init_scaling);
568 s.
pack(
"SuperscsInterface::settings::do_record_progress",
settings_.do_record_progress);
569 s.
pack(
"SuperscsInterface::settings::do_override_streams",
settings_.do_override_streams);
570 s.
pack(
"SuperscsInterface::Hp",
Hp_);
572 s.
pack(
"SuperscsInterface::f",
F_);
573 s.
pack(
"SuperscsInterface::At",
At_);
576 s.
pack(
"SuperscsInterface::opts",
opts_);
static const Options options_
Options.
casadi_int nx_
Number of decision variables.
int init_mem(void *mem) const override
Initalize memory block.
casadi_int na_
The number of constraints (counting both equality and inequality) == A.size1()
Sparsity H_
Problem structure.
void init(const Dict &opts) override
Initialize.
void deserialize(DeserializingStream &s, SDPToSOCPMem &m)
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Dict get_stats(void *mem) const override
Get all statistics.
void sdp_to_socp_init(SDPToSOCPMem &mem) const
SDP to SOCP conversion initialization.
void serialize(SerializingStream &s, const SDPToSOCPMem &m) const
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
casadi_int nnz_out() const
Get number of output nonzeros.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
casadi_int nnz() const
Get the number of (structural) non-zero elements.
casadi_int size2() const
Get the second dimension (i.e. number of columns)
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.
std::vector< Scalar > & nonzeros()
const Sparsity & sparsity() const
Const access the sparsity - reference to data member.
static Matrix< casadi_int > triplet(const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, const Matrix< casadi_int > &d)
Construct a sparse matrix from triplet form.
static Matrix< casadi_int > vertcat(const std::vector< Matrix< casadi_int > > &v)
static Matrix< double > eye(casadi_int n)
create an n-by-n identity matrix
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
Class representing a Slice.
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 *.
static Sparsity unit(casadi_int n, casadi_int el)
Create the sparsity pattern for a unit vector of length n and a nonzero on.
casadi_int nnz() const
Get the number of (structural) non-zeros.
casadi_int size2() const
Get the number of columns.
const casadi_int * row() const
Get a reference to row-vector,.
std::vector< casadi_int > get_colind() const
Get the column index for each column.
Sparsity ldl(std::vector< casadi_int > &p, bool amd=true) const
Symbolic LDL factorization.
std::vector< casadi_int > get_row() const
Get the row for each non-zero entry.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
std::vector< casadi_int > lookup_
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static const std::string meta_doc
A documentation string.
SuperscsInterface(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new Solver.
static Conic * creator(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new QP Solver.
~SuperscsInterface() override
Destructor.
std::vector< casadi_int > perturb_
SDPToSOCPMem sdp_to_socp_mem_
SDP to SOCP conversion memory.
void init(const Dict &opts) override
Initialize.
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Dict opts_
Superscs options.
Dict get_stats(void *mem) const override
Get all statistics.
static const Options options_
Options.
std::vector< casadi_int > Hp_
int solve(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Solve the QP.
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
@ CONIC_UBA
dense, (nc x 1)
@ CONIC_A
The matrix A: sparse, (nc x n) - product with x must be dense.
@ CONIC_G
The vector g: dense, (n x 1)
@ CONIC_Q
The matrix Q: sparse symmetric, (np^2 x n)
@ CONIC_LBA
dense, (nc x 1)
@ CONIC_UBX
dense, (n x 1)
@ CONIC_LBX
dense, (n x 1)
@ CONIC_P
The matrix P: sparse symmetric, (np x np)
T1 casadi_bilin(const T1 *A, const casadi_int *sp_A, const T1 *x, const T1 *y)
void CASADI_CONIC_SUPERSCS_EXPORT casadi_load_conic_superscs()
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
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.
T1 casadi_dot(casadi_int n, const T1 *x, const T1 *y)
Inner product.
std::vector< T > diff(const std::vector< T > &values)
diff
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
void casadi_axpy(casadi_int n, T1 alpha, const T1 *x, T1 *y)
AXPY: y <- a*x + y.
int CASADI_CONIC_SUPERSCS_EXPORT casadi_register_conic_superscs(Conic::Plugin *plugin)
void casadi_clear(T1 *x, casadi_int n)
CLEAR: x <- 0.
@ CONIC_X
The primal solution.
@ CONIC_COST
The optimal cost.
SDP to SOCP conversion memory.
std::vector< casadi_int > r
std::vector< casadi_int > map_P
Options metadata for a class.
~SuperscsMemory()
Destructor.
SuperscsMemory()
Constructor.
std::vector< double > ldl_d