25 #include "highs_interface.hpp"
26 #include "casadi/core/nlp_tools.hpp"
28 #include <highs_runtime_str.h>
32 int CASADI_CONIC_HIGHS_EXPORT
35 plugin->name =
"highs";
37 plugin->version = CASADI_VERSION;
50 const std::map<std::string, Sparsity>& st)
58 "Options to be passed to HiGHS."
68 for (
auto&& op : opts) {
69 if (op.first==
"highs") {
91 rowa_.resize(
A_.
nnz());
93 rowh_.resize(
H_.
nnz());
99 integrality_.resize(
nx_);
106 std::string n = name +
"[]";
107 g.
local(n,
"static const int");
108 std::stringstream init;
110 for (casadi_int i=0;i<v.size();++i) {
112 if (i<v.size()-1) init <<
", ";
115 if (v.empty()) init <<
"0";
121 g <<
"p.qp = &p_qp;\n";
129 g <<
"p.colinda = colinda;\n";
130 g <<
"p.rowa = rowa;\n";
131 g <<
"p.colindh = colindh;\n";
132 g <<
"p.rowh = rowh;\n";
134 g <<
"p.integrality = 0;\n";
136 g <<
"p.integrality = integrality;\n";
138 g <<
"casadi_highs_setup(&p);\n";
158 casadi_highs_setup(&p_);
165 highs_init_mem(&m->d);
167 m->add_stat(
"preprocessing");
168 m->add_stat(
"solver");
169 m->add_stat(
"postprocessing");
176 highs_free_mem(&m->d);
182 casadi_int*& iw,
double*& w)
const {
191 casadi_highs_init(&m->d, &arg, &res, &iw, &w);
193 for (
auto&& op :
opts_) {
195 casadi_assert(kHighsStatusOk == Highs_getOptionType(m->d.highs, op.first.c_str(), &type),
196 "Error getting option type for '" + op.first +
"'.");
198 if (type == kHighsOptionTypeBool) {
199 status = Highs_setBoolOptionValue(m->d.highs, op.first.c_str(), op.second.to_bool());
200 }
else if (type == kHighsOptionTypeInt) {
201 status = Highs_setIntOptionValue(m->d.highs, op.first.c_str(), op.second.to_int());
202 }
else if (type == kHighsOptionTypeDouble) {
203 status = Highs_setDoubleOptionValue(m->d.highs, op.first.c_str(), op.second.to_double());
204 }
else if (type == kHighsOptionTypeString) {
205 std::string v = op.second.to_string();
206 status = Highs_setStringOptionValue(m->d.highs, op.first.c_str(), v.c_str());
208 casadi_error(
"Unknown option type for '" + op.first +
"'.");
210 casadi_assert(kHighsStatusOk == status,
"Error setting option '" + op.first +
"'.");
215 solve(
const double** arg,
double** res, casadi_int* iw,
double* w,
void* mem)
const {
219 m->
fstats.at(
"solver").tic();
221 casadi_highs_solve(&m->d, arg, res, iw, w);
222 m->fstats.at(
"solver").toc();
249 g.
local(
"d",
"struct casadi_highs_data*");
251 g.
local(
"p",
"struct casadi_highs_prob");
255 g <<
"d->prob = &p;\n";
256 g <<
"d->qp = &d_qp;\n";
257 g <<
"casadi_highs_init(d, &arg, &res, &iw, &w);\n";
260 void* h = Highs_create();
261 for (
auto&& op :
opts_) {
263 casadi_assert(kHighsStatusOk == Highs_getOptionType(h, op.first.c_str(), &type),
264 "Error getting option type for '" + op.first +
"'.");
265 if (type==kHighsOptionTypeBool) {
266 g <<
"Highs_setBoolOptionValue(d->highs, " << g.
constant(op.first) <<
", "
267 <<
static_cast<int>(op.second.to_bool()) <<
");\n";
268 }
else if (type==kHighsOptionTypeInt) {
269 g <<
"Highs_setIntOptionValue(d->highs, " << g.
constant(op.first) <<
", "
270 <<
static_cast<int>(op.second.to_int()) <<
");\n";
271 }
else if (type==kHighsOptionTypeDouble) {
272 g <<
"Highs_setDoubleOptionValue(d->highs, " << g.
constant(op.first) <<
", "
273 << op.second.to_double() <<
");\n";
274 }
else if (type==kHighsOptionTypeString) {
275 g <<
"Highs_setStringOptionValue(d->highs, " << g.
constant(op.first) <<
", "
276 << g.
constant(op.second.to_string()) <<
");\n";
278 casadi_error(
"Unknown option type for '" + op.first +
"'.");
283 g <<
"casadi_highs_solve(d, arg, res, iw, w);\n";
285 g <<
"if (!d_qp.success) {\n";
287 g <<
"return -1000;\n";
299 stats[
"return_status"] =
300 highs.modelStatusToString(
static_cast<HighsModelStatus
>(m->d.return_status));
302 stats[
"simplex_iteration_count"] = m->d.simplex_iteration_count;
303 stats[
"ipm_iteration_count"] = m->d.ipm_iteration_count;
304 stats[
"qp_iteration_count"] = m->d.qp_iteration_count;
305 stats[
"crossover_iteration_count"] = m->d.crossover_iteration_count;
306 stats[
"primal_solution_status"] = highs.solutionStatusToString(m->d.primal_solution_status);
307 stats[
"dual_solution_status"] = highs.solutionStatusToString(m->d.dual_solution_status);
308 stats[
"basis_validity"] = highs.basisValidityToString(m->d.basis_validity);
309 stats[
"mip_dual_bound"] = m->d.mip_dual_bound;
310 stats[
"mip_gap"] = m->d.mip_gap;
311 stats[
"num_primal_infeasibilities"] = m->d.num_primal_infeasibilities;
312 stats[
"max_primal_infeasibility"] = m->d.max_primal_infeasibility;
313 stats[
"sum_primal_infeasibilities"] = m->d.sum_primal_infeasibilities;
314 stats[
"num_dual_infeasibilities"] = m->d.num_dual_infeasibilities;
315 stats[
"max_dual_infeasibility"] = m->d.max_dual_infeasibility;
316 stats[
"sum_dual_infeasibilities"] = m->d.sum_dual_infeasibilities;
321 s.
version(
"HighsInterface", 1);
330 s.
version(
"HighsInterface", 1);
Helper class for C code generation.
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.
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
std::string sanitize_source(const std::string &src, const std::vector< std::string > &inst, bool add_shorthand=true)
Sanitize source files for codegen.
void add_include(const std::string &new_include, bool relative_path=false, const std::string &use_ifdef=std::string())
Add an include file optionally using a relative path "..." instead of an absolute path <....
std::stringstream auxiliaries
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
static const Options options_
Options.
casadi_int nx_
Number of decision variables.
int init_mem(void *mem) const override
Initalize memory block.
Sparsity H_
Problem structure.
void init(const Dict &opts) override
Initialize.
std::vector< bool > discrete_
Options.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Dict get_stats(void *mem) const override
Get all statistics.
casadi_qp_prob< double > p_qp_
void qp_codegen_body(CodeGenerator &g) const
Generate code for the function body.
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_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void alloc_res(size_t sz_res, bool persistent=false)
Ensure required length of res field.
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
std::string codegen_mem(CodeGenerator &g, const std::string &index="mem") const
Get thread-local memory object.
size_t sz_res() const
Get required length of res field.
size_t sz_w() const
Get required length of w field.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.
static const std::string meta_doc
A documentation string.
int solve(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const override
Solve the QP.
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
~HighsInterface() override
Destructor.
HighsInterface(const std::string &name, const std::map< std::string, Sparsity > &st)
Constructor using sparsity patterns.
void init(const Dict &opts) override
Initialize.
static const Options options_
Options.
static Conic * creator(const std::string &name, const std::map< std::string, Sparsity > &st)
Create a new QP Solver.
Dict get_stats(void *mem) const override
Get all statistics.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void codegen_free_mem(CodeGenerator &g) const override
Codegen for free_mem.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
Dict opts_
All HiGHS options.
void codegen_init_mem(CodeGenerator &g) const override
Codegen decref for init_mem.
void free_mem(void *mem) const override
Free memory block.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
bool error_on_fail_
Throw an exception on failure?
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.
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,.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
void copy_vector(const std::vector< S > &s, std::vector< D > &d)
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
int CASADI_CONIC_HIGHS_EXPORT casadi_register_conic_highs(Conic::Plugin *plugin)
void CASADI_CONIC_HIGHS_EXPORT casadi_load_conic_highs()
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
void codegen_local(CodeGenerator &g, const std::string &name, const std::vector< int > &v)
casadi_highs_data< double > d
Options metadata for a class.
std::map< std::string, FStats > fstats
int simplex_iteration_count
const casadi_qp_prob< T1 > * qp