25 #include "conopt_interface.hpp"
26 #include "casadi/core/casadi_misc.hpp"
27 #include "casadi/core/casadi_interrupt.hpp"
40 plugin->name =
"conopt";
42 plugin->version = CASADI_VERSION;
54 {
"exact_hessian", {
OT_BOOL,
"Provide exact Hessian to CONOPT"}},
56 "Warm-start CONOPT using multipliers from a prior solve to infer "
57 "basis status (IniStat=2)"}},
58 {
"conopt", {
OT_DICT,
"Options to be passed to CONOPT"}},
60 "Path to a CONOPT option file (for string-valued CR-cells such as Algorithm)"}},
62 "Print debug output: constraint values at each FDEval, solution vector, "
77 for (
auto&& op : opts) {
78 if (op.first ==
"conopt")
opts_ = op.second;
79 else if (op.first ==
"optfile")
optfile_ = op.second.to_string();
80 else if (op.first ==
"warm_start")
warm_start_ = op.second.to_bool();
81 else if (op.first ==
"debug")
debug_ = op.second.to_bool();
84 for (
auto&& op :
opts_) {
86 "CONOPT option name '" + op.first +
"' is " +
str(op.first.size()) +
102 const casadi_int* dj_row = djac_dx.
row();
103 for (casadi_int el = 0; el < djac_dx.
nnz(); ++el)
106 [](
int f) { return f == 0; });
111 if (opts.find(
"exact_hessian") != opts.end())
exact_hessian_ = opts.at(
"exact_hessian");
115 {
"tril:hess:gamma:x:x"}, {{
"gamma", {
"f",
"g"}}});
132 const casadi_int* dg_row = dgradf_dx.
row();
133 for (casadi_int el = 0; el < dgradf_dx.
nnz(); ++el) {
137 [](
int f) { return f == 0; });
147 for (casadi_int el = 0; el < nnz_g; ++el)
149 for (
int r = 0; r <
ng_; ++r)
153 std::vector<int> fill_pos(
ng_, 0);
154 for (
int c = 0; c <
nx_; ++c) {
155 for (casadi_int el = g_colind[c]; el < g_colind[c+1]; ++el) {
157 int r =
static_cast<int>(g_row[el]);
159 "CSR fill overflow for row r - count/fill pass mismatch in jacg_rowstart_");
169 s.
version(
"ConoptInterface", 1);
183 const casadi_int* dj_row = djac_dx.
row();
184 for (casadi_int el = 0; el < djac_dx.
nnz(); ++el)
187 [](
int f) { return f == 0; });
202 const casadi_int* dg_row = dgradf_dx.
row();
203 for (casadi_int el = 0; el < dgradf_dx.
nnz(); ++el)
206 [](
int f) { return f == 0; });
213 for (casadi_int el = 0; el < nnz_g; ++el)
215 for (
int r = 0; r <
ng_; ++r)
219 std::vector<int> fill_pos(
ng_, 0);
220 for (
int c = 0; c <
nx_; ++c)
221 for (casadi_int el = g_colind[c]; el < g_colind[c+1]; ++el) {
223 int r =
static_cast<int>(g_row[el]);
225 "CSR fill overflow for row r - count/fill pass mismatch in jacg_rowstart_");
234 s.
version(
"ConoptInterface", 1);
249 iter(0), return_status(
"Unset"),
250 cache_valid(false), cache_valid_jac(false), nan_encountered(false),
251 ng_expanded(0), numnz_expanded(0) {}
265 m->cached_g.resize(
ng_, 0.0);
267 m->casadi_to_conopt_lb_row.resize(
ng_);
268 m->casadi_to_conopt_ub_row.assign(
ng_, -1);
269 m->hess_lam_g_.resize(
ng_, 0.0);
270 m->row_const_.assign(
ng_, 0.0);
271 m->row_nnz.assign(
ng_, 0);
276 casadi_int initial_row_reserve =
ng_;
277 m->conopt_to_casadi.reserve(initial_row_reserve);
278 m->conopt_type.reserve(initial_row_reserve);
279 m->conopt_rhs.reserve(initial_row_reserve);
283 m->linear_at_x0.resize(
ng_, 0.0);
287 if (COI_Create(&m->cntvect) != 0 || m->cntvect ==
nullptr) {
288 casadi::uerr() <<
"CONOPT: COI_Create failed" << std::endl;
294 COIDEF_NumVar(m->cntvect,
nx_);
298 COIDEF_ObjCon(m->cntvect, 0);
299 COIDEF_OptDir(m->cntvect, -1);
302 m->custom_options.clear();
303 for (
auto&& op :
opts_) {
305 if (op.first ==
"itlim") COIDEF_ItLim(m->cntvect, op.second.to_int());
306 else if (op.first ==
"errlim") COIDEF_ErrLim(m->cntvect, op.second.to_int());
307 else if (op.first ==
"reslim" || op.first ==
"timelim")
308 COIDEF_ResLim(m->cntvect, op.second.to_double());
309 else if (op.first ==
"maxheap") COIDEF_MaxHeap(m->cntvect, op.second.to_double());
310 else if (op.second.is_string()) {
311 casadi_warning(
"CONOPT option '" + op.first +
"' is a string; string options cannot be "
312 "passed via the CONOPT option callback (no SVAL parameter). "
313 "Use the 'optfile' option instead.");
315 m->custom_options.push_back(op);
334 COIDEF_FVincLin(m->cntvect, 1);
340 COIDEF_UsrMem(m->cntvect, m);
346 casadi_int*& iw,
double*& w)
const {
356 casadi_int growth = std::max<casadi_int>(
357 std::min<casadi_int>(remaining_rows, 10), remaining_rows / 4);
368 m->cache_valid_jac =
false;
370 m->nan_encountered =
false;
374 m->return_status =
"Unset";
377 std::fill(m->row_const_.begin(), m->row_const_.end(), 0.0);
378 m->obj_const_lin_ = 0.0;
379 m->conopt_to_casadi.clear();
380 m->casadi_to_conopt_ub_row.assign(
ng_, -1);
381 m->conopt_type.clear();
382 m->conopt_rhs.clear();
385 std::fill(m->row_nnz.begin(), m->row_nnz.end(), 0);
388 for (casadi_int el = 0; el < (casadi_int)
jacg_sp_.
nnz(); ++el)
389 m->row_nnz[g_row_s[el]]++;
392 casadi_int ng_expanded = 0;
397 for (casadi_int i = 0; i <
ng_; ++i) {
398 double lbg = m->d_nlp.lbz[
nx_ + i];
399 double ubg = m->d_nlp.ubz[
nx_ + i];
400 bool is_range = !std::isinf(lbg) && !std::isinf(ubg) && lbg != ubg;
404 m->casadi_to_conopt_lb_row[i] =
static_cast<int>(ng_expanded + 1);
406 m->conopt_to_casadi.push_back(
static_cast<int>(i));
409 }
else if (!std::isinf(lbg) && std::isinf(ubg)) {
411 }
else if (std::isinf(lbg) && !std::isinf(ubg)) {
413 }
else if (std::isinf(lbg) && std::isinf(ubg)) {
418 m->conopt_rhs.push_back(lbg);
423 m->casadi_to_conopt_ub_row[i] =
static_cast<int>(ng_expanded + 1);
425 m->conopt_to_casadi.push_back(
static_cast<int>(i));
427 m->conopt_rhs.push_back(ubg);
429 numnz += m->row_nnz[i];
432 casadi_assert(ng_expanded <= std::numeric_limits<int>::max(),
"ng_expanded overflows int");
433 m->ng_expanded =
static_cast<int>(ng_expanded);
437 std::any_of(m->row_nnz.begin(), m->row_nnz.end(), [](
int n) { return n == 0; });
439 m->arg[0] = m->d_nlp.z;
440 m->arg[1] = m->d_nlp.p;
441 m->res[0] = m->cached_g.data();
447 m->return_status =
"Initial evaluation failed";
450 }
catch (std::exception& ex) {
451 casadi::uerr() <<
"CONOPT: initial evaluation failed: " << ex.what() << std::endl;
454 casadi::uerr() <<
"CONOPT: initial evaluation failed (unknown exception)" << std::endl;
465 std::fill(m->linear_at_x0.begin(), m->linear_at_x0.end(), 0.0);
466 for (
int c = 0; c <
nx_; ++c) {
467 for (casadi_int el = g_colind_c[c]; el < g_colind_c[c + 1]; ++el) {
469 m->linear_at_x0[g_row_c[el]] += m->const_jac_vals[el] * m->d_nlp.z[c];
473 for (
int ci = 0; ci <
ng_; ++ci) {
476 double constant = m->cached_g[ci] - m->linear_at_x0[ci];
477 if (std::abs(constant) < 1e-14)
continue;
478 m->row_const_[ci] = constant;
479 int lb_row = m->casadi_to_conopt_lb_row[ci];
480 m->conopt_rhs[lb_row - 1] -= constant;
481 int ub_row = m->casadi_to_conopt_ub_row[ci];
482 if (ub_row >= 0) m->conopt_rhs[ub_row - 1] -= constant;
488 m->obj_const_ = std::numeric_limits<double>::quiet_NaN();
490 m->arg[0] = m->d_nlp.z;
491 m->arg[1] = m->d_nlp.p;
492 m->res[0] = &m->cached_f;
498 m->return_status =
"Initial evaluation failed";
501 }
catch (std::exception& ex) {
502 casadi::uerr() <<
"CONOPT: initial evaluation failed: " << ex.what() << std::endl;
505 casadi::uerr() <<
"CONOPT: initial evaluation failed (unknown exception)" << std::endl;
515 [](
int f) { return f == 1; });
517 std::all_of(m->gradf_const_vals.begin(), m->gradf_const_vals.end(),
518 [](
double v) { return v == 0.0; });
519 if (!has_nl_gradf && (
gradf_sp_.
nnz() == 0 || all_const_zero)) {
520 m->obj_const_ = m->cached_f;
521 COIDEF_OptDir(m->cntvect, 0);
526 double lin_at_x0 = 0.0;
528 lin_at_x0 += m->gradf_const_vals[k] * m->d_nlp.z[f_row_c[k]];
529 m->obj_const_lin_ = m->cached_f - lin_at_x0;
534 COIDEF_OptDir(m->cntvect, -1);
541 casadi_int num_nl_nz = 0;
542 for (casadi_int k = 0; k < (casadi_int)
gradf_sp_.
nnz(); ++k)
544 for (casadi_int c = 0; c <
nx_; ++c) {
545 for (casadi_int el = g_colind_s[c]; el < g_colind_s[c+1]; ++el) {
547 int ci =
static_cast<int>(g_row_s[el]);
548 num_nl_nz += (m->casadi_to_conopt_ub_row[ci] >= 0) ? 2 : 1;
553 casadi_assert(num_nl_nz <= std::numeric_limits<int>::max(),
"num_nl_nz overflows int");
560 casadi_int numnz_f = 0;
561 for (casadi_int k = 0; k < (casadi_int)
gradf_sp_.
nnz(); ++k) {
568 casadi_assert(numnz <= std::numeric_limits<int>::max(),
"numnz overflows int");
569 m->numnz_expanded =
static_cast<int>(numnz);
571 COIDEF_NumCon(m->cntvect,
static_cast<int>(ng_expanded + 1));
572 COIDEF_NumNz(m->cntvect,
static_cast<int>(numnz));
573 COIDEF_NumNlNz(m->cntvect,
static_cast<int>(num_nl_nz));
575 int ret = COI_Solve(m->cntvect);
578 m->d_nlp.objective += m->obj_const_lin_;
581 if (!std::isnan(m->obj_const_)) m->d_nlp.objective = m->obj_const_;
589 m->success = !m->nan_encountered &&
596 }
else if (m->success) {
616 stats[
"modsta"] =
static_cast<int>(m->modsta);
617 stats[
"solsta"] =
static_cast<int>(m->solsta);
618 stats[
"iter_count"] = m->iter;
624 int* LVAL,
char* NAME,
void* USRMEM) {
627 if (NCALL >=
static_cast<int>(m->custom_options.size())) {
635 std::memcpy(NAME, opt.first.c_str(), name_len);
636 NAME[name_len] =
'\0';
638 if (opt.second.is_double()) {
639 *RVAL = opt.second.to_double();
641 casadi::uout() <<
"CONOPT option: " << opt.first <<
" = " << *RVAL << std::endl;
642 }
else if (opt.second.is_int()) {
643 *IVAL = opt.second.to_int();
645 casadi::uout() <<
"CONOPT option: " << opt.first <<
" = " << *IVAL << std::endl;
646 }
else if (opt.second.is_bool()) {
647 *LVAL = opt.second.to_bool() ? 1 : 0;
648 if (m->self.debug_) {
649 casadi::uout() <<
"CONOPT option: " << opt.first <<
" = "
650 << (opt.second.to_bool() ?
"true" :
"false") << std::endl;
652 }
else if (opt.second.is_string()) {
659 casadi_error(
"CONOPT option '" + opt.first +
"' is a string type in cb_option. "
660 "String options cannot be passed via the CONOPT option callback "
661 "(COI_OPTION_t has no SVAL parameter). Use the 'optfile' option "
662 "instead. The init_mem filter should have removed this option "
663 "before it reached custom_options; reaching this branch is a "
664 "programming error.");
667 casadi_error(
"CONOPT option '" + opt.first +
"' has an unknown GenericType in "
668 "cb_option. Only double, int, and bool options are valid here. "
669 "Reaching this branch is a programming error.");
677 const double RL[],
const double X[],
683 int phase = (LEN_INT > 1) ? INTX[1] : -1;
685 double obj_val = m->cached_f;
686 if (LEN_RL > 1 && phase >= 3) {
690 std::fill_n(m->arg,
self.fcallback_.n_in(),
nullptr);
694 std::fill_n(m->res,
self.fcallback_.n_out(),
nullptr);
695 double ret_double = 0;
696 m->res[0] = &ret_double;
699 self.fcallback_(m->arg, m->res, m->iw, m->w, 0);
700 if (ret_double != 0.0)
return 1;
703 }
catch (std::exception& ex) {
704 casadi_warning(std::string(
"intermediate_callback: ") + ex.
what());
712 double UPPER[],
int VSTA[],
int TYPEX[],
713 double RHS[],
int ESTA[],
int COLSTA[],
714 int ROWNO[],
double VALUE[],
715 int NLFLAG[],
int NUMVAR,
int NUMCON,
716 int NUMNZ,
void* USRMEM) {
723 casadi_assert(NUMVAR ==
self.
nx_,
"cb_read_matrix: NUMVAR != nx_");
724 casadi_assert(NUMCON == m->ng_expanded + 1,
"cb_read_matrix: NUMCON != ng_expanded + 1");
727 for (
int i = 0; i < NUMVAR; ++i) {
728 double lb = m->d_nlp.lbz[i];
729 double ub = m->d_nlp.ubz[i];
730 if (!std::isinf(lb)) LOWER[i] = lb;
731 if (!std::isinf(ub)) UPPER[i] = ub;
732 double x0 = m->d_nlp.z[i];
733 if (!std::isinf(ub)) x0 = std::min(x0, ub);
734 if (!std::isinf(lb)) x0 = std::max(x0, lb);
743 for (
int r = 0; r < m->ng_expanded; ++r) {
744 TYPEX[r + 1] =
static_cast<int>(m->conopt_type[r]);
745 RHS[r + 1] = m->conopt_rhs[r];
755 const double* lam = m->d_nlp.lam;
756 bool all_zero = std::all_of(lam, lam +
self.
nx_ +
self.
ng_,
757 [](
double v) {
return v == 0.0; });
759 for (
int i = 0; i < NUMVAR; ++i) {
760 double lbi = m->d_nlp.lbz[i];
761 double ubi = m->d_nlp.ubz[i];
762 double xi = m->d_nlp.z[i];
764 if (!std::isinf(lbi) && std::fabs(xi - lbi) < 1e-8 && li <= 0.0)
766 else if (!std::isinf(ubi) && std::fabs(xi - ubi) < 1e-8 && li >= 0.0)
772 for (
int r = 0; r < m->ng_expanded; ++r) {
773 int ci = m->conopt_to_casadi[r];
775 double lam_ci = lam[NUMVAR + ci];
776 int row1 = m->casadi_to_conopt_lb_row[ci];
777 int row2 = m->casadi_to_conopt_ub_row[ci];
783 ESTA[r + 1] =
static_cast<int>(
787 ESTA[r + 1] =
static_cast<int>(
792 }
else if (r + 1 == row2) {
794 ESTA[r + 1] =
static_cast<int>(
808 const casadi_int* g_colind =
self.jacg_sp_.colind();
809 const casadi_int* g_row =
self.jacg_sp_.row();
811 for (
int c = 0; c < NUMVAR; ++c) {
815 casadi_int k =
self.gradf_col_to_nz_[c];
820 }
else if (m->gradf_const_vals[k] != 0.0) {
823 VALUE[nz] = m->gradf_const_vals[k];
829 for (casadi_int el = g_colind[c]; el < g_colind[c+1]; ++el) {
830 int ci =
static_cast<int>(g_row[el]);
831 int nlflag =
self.jacg_nlflag_[el];
832 ROWNO[nz] = m->casadi_to_conopt_lb_row[ci];
834 if (nlflag == 0)
VALUE[nz] = m->const_jac_vals[el];
836 if (m->casadi_to_conopt_ub_row[ci] >= 0) {
837 ROWNO[nz] = m->casadi_to_conopt_ub_row[ci];
839 if (nlflag == 0)
VALUE[nz] = m->const_jac_vals[el];
846 casadi_assert(nz == NUMNZ,
847 "cb_read_matrix: nz != NUMNZ - Jacobian nonzero count mismatch "
848 "between solve()'s numnz computation and this callback's writes");
854 int MODE,
int LISTSIZE,
int NUMTHREAD,
855 int IGNERR,
int* ERRCNT,
int NUMVAR,
860 casadi_assert(NUMVAR ==
self.
nx_,
"cb_fdevalini: NUMVAR != nx_");
861 casadi_assert(
static_cast<size_t>(NUMVAR) == m->cached_x.size(),
862 "cb_fdevalini: NUMVAR != cached_x size");
864 std::memcpy(m->cached_x.data(),
X, NUMVAR *
sizeof(
double));
868 for (
int i = 0; i < NUMVAR; ++i)
873 const bool need_jac = (MODE != 1);
875 m->cache_valid_jac.store(
false, std::memory_order_relaxed);
876 m->cache_valid.store(
false, std::memory_order_relaxed);
878 m->arg[0] = m->cached_x.data();
879 m->arg[1] = m->d_nlp.p;
881 m->res[0] = &m->cached_f;
882 m->res[1] = need_jac ? m->cached_grad_f.data() :
nullptr;
883 int ret =
self.calc_function(m,
"nlp_grad_f");
885 m->res[0] = m->cached_g.data();
886 m->res[1] = need_jac ? m->cached_jac_g.data() :
nullptr;
887 ret =
self.calc_function(m,
"nlp_jac_g");
891 m->cache_valid_jac.store(need_jac, std::memory_order_relaxed);
892 m->cache_valid.store(
true, std::memory_order_release);
894 }
catch (std::exception& ex) {
898 if (!m->cache_valid.load(std::memory_order_relaxed)) {
900 m->nan_encountered =
true;
906 int ROWNO,
const int JACNUM[],
int MODE,
907 int IGNERR,
int* ERRCNT,
int NUMVAR,
908 int NUMJAC,
int THREAD,
void* USRMEM) {
914 if (!m->cache_valid.load(std::memory_order_acquire)) {
919 if ((MODE == 2 || MODE == 3) &&
920 !m->cache_valid_jac.load(std::memory_order_relaxed)) {
927 std::memcmp(
X, m->cached_x.data(), NUMVAR *
sizeof(
double)) == 0,
928 "cb_fd_eval: X does not match cached_x — CONOPT API contract violated");
932 if (MODE == 1 || MODE == 3) *G = m->cached_f;
933 if (MODE == 2 || MODE == 3) {
934 const casadi_int* f_row =
self.gradf_sp_.row();
935 for (casadi_int k = 0; k <
self.gradf_sp_.nnz(); ++k) {
937 JAC[f_row[k]] = m->cached_grad_f[k];
940 << m->cached_grad_f[k] <<
"\n";
945 casadi_assert(ROWNO >= 1 && ROWNO <= m->ng_expanded,
946 "cb_fd_eval: ROWNO out of range");
947 int ci = m->conopt_to_casadi[ROWNO - 1];
948 if (MODE == 1 || MODE == 3) {
949 *G = m->cached_g[ci];
952 double rhs = m->conopt_rhs[ROWNO - 1];
957 casadi::uout() <<
" g[" << ci <<
"](x) = " << *G <<
" (free)\n";
960 << rel <<
" " << rhs <<
"\n";
963 if (MODE == 2 || MODE == 3) {
964 int base =
self.jacg_rowstart_[ci];
965 int count =
self.jacg_rowstart_[ci + 1] -
self.jacg_rowstart_[ci];
966 for (
int k = 0; k < count; ++k) {
967 int col =
self.jacg_col_[base + k];
968 double val = m->cached_jac_g[
self.jacg_nzidx_[base + k]];
971 casadi::uout() <<
" dg[" << ci <<
"]/dx[" << col <<
"] = " << val <<
"\n";
981 m->cache_valid.store(
false, std::memory_order_relaxed);
986 int NUMVAR,
int NUMCON,
int NHESS,
990 const casadi_int* colind =
self.hesslag_sp_.colind();
991 const casadi_int* row =
self.hesslag_sp_.row();
994 for (
int c = 0; c < NUMVAR; ++c) {
995 for (casadi_int el = colind[c]; el < colind[c+1]; ++el) {
1001 casadi_assert(idx == NHESS,
1002 "cb_2dlagrstr: idx != NHESS - Hessian nonzero count mismatch");
1007 const int HSRW[],
const int HSCL[],
1008 double HSVL[],
int* NODRV,
int NUMVAR,
1009 int NUMCON,
int NHESS,
void* USRMEM) {
1015 double obj_factor =
U[0];
1017 for (
int ci = 0; ci <
self.ng_; ++ci) {
1018 int row1 = m->casadi_to_conopt_lb_row[ci];
1019 int row2 = m->casadi_to_conopt_ub_row[ci];
1020 m->hess_lam_g_[ci] =
U[row1] + (row2 >= 0 ?
U[row2] : 0.0);
1024 casadi::uout() <<
"Hessian lam_f=" << obj_factor <<
" lam_g:";
1025 for (
int ci = 0; ci <
self.ng_; ++ci)
1031 m->arg[1] = m->d_nlp.p;
1032 m->arg[2] = &obj_factor;
1033 m->arg[3] = m->hess_lam_g_.data();
1043 for (
int i = 0; i < NHESS; ++i)
1047 }
catch (std::exception& ex) {
1048 casadi::uerr() <<
"CONOPT: nlp_hess_l failed: " << ex.what() << std::endl;
1051 casadi::uerr() <<
"CONOPT: nlp_hess_l failed (unknown exception)" << std::endl;
1058 double OBJVAL,
void* USRMEM) {
1063 m->d_nlp.objective = OBJVAL;
1065 const char* modsta_str;
1066 switch (m->modsta) {
1076 default: modsta_str =
"Unknown model status";
break;
1079 const char* solsta_str;
1080 switch (m->solsta) {
1082 solsta_str =
"Normal completion";
break;
1084 solsta_str =
"Iteration limit";
break;
1086 solsta_str =
"Time limit";
break;
1088 solsta_str =
"Terminated by solver";
break;
1090 solsta_str =
"Evaluation error limit";
break;
1092 solsta_str =
"User interrupt";
break;
1094 solsta_str =
"Setup failure";
break;
1096 solsta_str =
"Major solver error";
break;
1098 solsta_str =
"Major solver error (feasible point)";
break;
1100 solsta_str =
"System error";
break;
1102 solsta_str =
"Quick Mode termination";
break;
1104 solsta_str =
"Unknown solver status";
break;
1107 m->return_status = std::string(modsta_str) +
" / " + std::string(solsta_str);
1112 const int XBAS[],
const int XSTA[],
1113 const double YVAL[],
const double YMAR[],
1114 const int YBAS[],
const int YSTA[],
1115 int NUMVAR,
int NUMCON,
void* USRMEM) {
1120 if (m->self.debug_) {
1122 for (
int i = 0; i < NUMVAR; ++i)
1128 for (casadi_int ci = 0; ci < m->self.ng_; ++ci)
1129 m->d_nlp.z[NUMVAR + ci] = YVAL[m->casadi_to_conopt_lb_row[ci]] + m->row_const_[ci];
1132 for (
int i = 0; i < NUMVAR; ++i)
1133 m->d_nlp.lam[i] = -XMAR[i];
1137 for (casadi_int ci = 0; ci < m->self.ng_; ++ci) {
1138 int row1 = m->casadi_to_conopt_lb_row[ci];
1139 int row2 = m->casadi_to_conopt_ub_row[ci];
1140 double ymar = YMAR[row1] + (row2 >= 0 ? YMAR[row2] : 0.0);
1141 m->d_nlp.lam[NUMVAR + ci] = -ymar;
1151 int message_length = SMSG;
1152 if (m->self.debug_) message_length = std::max(message_length, std::max(DMSG, NMSG));
1154 for (
int i = 0; i < message_length; ++i) {
1155 if (MSGV[i] !=
nullptr) {
1163 const char* MSG,
void* USRMEM) {
1164 if (MSG ==
nullptr)
return 0;
1166 std::string prefix =
"CONOPT Error: ";
1167 if (COLNO == -1 && ROWNO >= 0) {
1168 prefix +=
"Row " + std::to_string(ROWNO) +
" - ";
1169 }
else if (ROWNO == -1 && COLNO >= 0) {
1170 prefix +=
"Column " + std::to_string(COLNO) +
" - ";
1171 }
else if (ROWNO >= 0 && COLNO >= 0) {
1173 prefix +=
"Jacobian Pos " + std::to_string(POSNO) +
" (Row " +
1174 std::to_string(ROWNO) +
", Col " + std::to_string(COLNO) +
") - ";
1175 }
else if (POSNO == -1) {
1176 prefix +=
"Pair (Row " + std::to_string(ROWNO) +
", Col " +
1177 std::to_string(COLNO) +
") - ";
const char * what() const override
Display error.
static int COI_CALLCONV cb_fdevalini(const double X[], const int ROWLIST[], int MODE, int LISTSIZE, int NUMTHREAD, int IGNERR, int *ERRCNT, int NUMVAR, void *USRMEM)
static int COI_CALLCONV cb_read_matrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPEX[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
std::vector< int > jacg_nlflag_
int init_mem(void *mem) const override
Initalize memory block.
void ensure_row_capacity(ConoptMemory *m, casadi_int remaining_rows) const
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static int COI_CALLCONV cb_solution(const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[], const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[], int NUMVAR, int NUMCON, void *USRMEM)
static int COI_CALLCONV cb_fdevalend(int IGNERR, int *ERRCNT, void *USRMEM)
static int COI_CALLCONV cb_status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
std::vector< bool > gradf_col_flag_
std::vector< int > jacg_rowstart_
Dict get_stats(void *mem) const override
Get all statistics.
static int COI_CALLCONV cb_progress(int LEN_INT, const int INTX[], int LEN_RL, const double RL[], const double X[], void *USRMEM)
std::vector< casadi_int > gradf_col_to_nz_
static int COI_CALLCONV cb_2dlagrstr(int HSRW[], int HSCL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
ConoptInterface(const std::string &name, const Function &nlp)
static int COI_CALLCONV cb_option(int NCALL, double *RVAL, int *IVAL, int *LVAL, char *NAME, void *USRMEM)
std::vector< int > gradf_nlflag_
static int COI_CALLCONV cb_2dlagrval(const double X[], const double U[], const int HSRW[], const int HSCL[], double HSVL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
static int COI_CALLCONV cb_message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
~ConoptInterface() override
static const Options options_
std::vector< int > jacg_nzidx_
int solve(void *mem) const override
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
static int COI_CALLCONV cb_fd_eval(const double X[], double *G, double JAC[], int ROWNO, const int JACNUM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
static Nlpsol * creator(const std::string &name, const Function &nlp)
void free_mem(void *mem) const override
Free memory block.
static const std::string meta_doc
A documentation string.
static int COI_CALLCONV cb_errmsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
static ProtoFunction * deserialize(DeserializingStream &s)
void init(const Dict &opts) override
Initialize.
std::vector< int > jacg_col_
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
Function self() const
Get a public class instance.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
const Sparsity sparsity_jac(casadi_int iind, casadi_int oind, bool compact=false, bool symmetric=false) const
bool is_null() const
Is a null pointer?
NLP solver storage class.
bool iteration_callback_ignore_errors_
Options.
Dict get_stats(void *mem) const override
Get all statistics.
static const Options options_
Options.
void init(const Dict &opts) override
Initialize.
casadi_int ng_
Number of constraints.
int init_mem(void *mem) const override
Initalize memory block.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
casadi_int nx_
Number of variables.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
Function fcallback_
callback function, executed at each iteration
Function create_function(const Function &oracle, const std::string &fname, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux=Function::AuxOut(), const Dict &opts=Dict())
int calc_function(OracleMemory *m, const std::string &fcn, const double *const *arg=nullptr, int thread_id=0) const
std::vector< std::string > get_function() const override
Get list of dependency functions.
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.
casadi_int nnz() const
Get the number of (structural) non-zeros.
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 CASADI_NLPSOL_CONOPT_EXPORT casadi_load_nlpsol_conopt()
@ NLPSOL_X
Decision variables at the optimal solution (nx x 1)
@ NLPSOL_F
Cost function value at the optimal solution (1 x 1)
static const size_t conopt_max_option_name
int CASADI_NLPSOL_CONOPT_EXPORT casadi_register_nlpsol_conopt(Nlpsol::Plugin *plugin)
bool is_range(const std::vector< casadi_int > &v, casadi_int start, casadi_int stop, casadi_int step)
Check if a vector matches a range.
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::atomic< bool > cache_valid_jac
std::atomic< bool > cache_valid
std::string return_status
std::vector< std::pair< std::string, GenericType > > custom_options
std::vector< double > conopt_rhs
std::vector< ConoptRowType > conopt_type
std::vector< int > conopt_to_casadi
std::vector< double > cached_x
ConoptMemory(const ConoptInterface &interface)