26 #include "nlpsol_impl.hpp"
27 #include "external.hpp"
28 #include "casadi/core/timing.hpp"
29 #include "nlp_builder.hpp"
30 #include "nlp_tools.hpp"
48 size_t pos = name.find(
"g");
51 if (pos == std::string::npos)
return false;
54 bool left = pos==0 || !isalnum(name[pos-1]);
57 bool right = pos+1 == name.size() || !isalnum(name[pos+1]);
64 const std::map<std::string, X>& nlp,
const Dict& opts) {
72 if (g.size1()>0 || g.size2()>0) {
74 casadi_assert(g.is_dense() && g.is_vector(),
75 "Expected a dense vector 'g', but got " + g.dim(
true) +
".");
79 casadi_int ng = g.size1();
80 casadi_int nx = x.size1();
83 Sparsity sp = jacobian_sparsity(g, x).
T();
86 std::vector<bool> is_simple(ng,
true);
89 std::vector<bool> is_nonlin = which_depends(g, x, 2,
true);
91 const casadi_int* row = sp.
colind();
92 for (casadi_int i=0;i<ng;++i) {
94 bool single_dependency = row[i+1]-row[i]==1;
95 is_simple[i] = single_dependency && !is_nonlin[i];
105 std::vector<X>{jtimes(g_bounds, x, X::ones(nx, 1)), g_bounds});
108 std::vector<casadi_int> target_x;
110 for (casadi_int i=0;i<ng;++i) {
112 if (!is_simple[i])
continue;
113 target_x.push_back(sp.
row()[row[i]]);
116 Dict nlpsol_opts = opts;
117 nlpsol_opts[
"detect_simple_bounds_is_simple"] = is_simple;
118 nlpsol_opts[
"detect_simple_bounds_parts"] = gf;
119 nlpsol_opts[
"detect_simple_bounds_target_x"] = target_x;
123 for (
auto&& e : cache) {
127 bool needs_update =
false;
128 for (casadi_int i=0;i<f.
n_in();++i) {
132 if (f.
size1_in(i)==gi.size())
continue;
134 if (f.
size1_in(i)==ng) needs_update =
true;
138 for (casadi_int i=0;i<f.
n_out();++i) {
142 if (f.
size1_out(i)==ng) needs_update =
true;
147 if (!needs_update)
continue;
150 std::vector<X> args = f.
sym_in<
X>();
152 std::vector<X> f_args = args;
154 for (casadi_int i=0;i<f.
n_in();++i) {
157 args[i] = X::sym(f.
name_in(i), gi.size());
160 f_args[i] = X::zeros(ng);
161 f_args[i](gi) = args[i];
167 f.
call(f_args, res,
false,
false);
169 for (casadi_int i=0;i<f.
n_out();++i) {
180 nlpsol_opts[
"cache"] = cache;
182 if (opts.find(
"equality")!=opts.end()) {
183 std::vector<bool> equality = opts.find(
"equality")->second;
184 nlpsol_opts[
"equality"] =
vector_select(equality, is_simple,
true);
187 std::map<std::string, X> nlpsol_nlp = nlp;
188 nlpsol_nlp[
"g"] = g(gi);
205 template<
typename XType>
211 nl_in[
NL_X]=i.second;
212 }
else if (i.first==
"p") {
213 nl_in[
NL_P]=i.second;
214 }
else if (i.first==
"f") {
215 nl_out[
NL_F]=i.second;
216 }
else if (i.first==
"g") {
217 nl_out[
NL_G]=i.second;
219 casadi_error(
"No such field: " + i.first);
222 if (nl_out[
NL_F].is_empty()) nl_out[
NL_F] = 0;
223 if (nl_out[
NL_G].is_empty()) nl_out[
NL_G] = XType(0, 1);
227 Dict::const_iterator it = opts.find(
"oracle_options");
228 if (it != opts.end()) {
230 oracle_options = it->second;
233 for (
const char* op : {
"verbose",
"regularity_check"}) {
235 if (it != opts.end()) {
236 oracle_options[op] = it->second;
248 nlp[
"x"] = vertcat(nl.
x);
250 nlp[
"g"] = vertcat(nl.
g);
251 return nlpsol(name, solver, nlp, opts);
255 const std::string& fname,
const Dict& opts) {
257 if (fname.size()>2 && fname.compare(fname.size()-2, fname.size(),
".c")==0) {
259 return nlpsol(name, solver, compiler, opts);
274 casadi_error(
"Cannot create '" + name +
"' since " +
str(nlp.
get_free()) +
" are free.");
281 for (
size_t i=0; i<ret.size(); ++i) ret[i]=
nlpsol_in(i);
287 for (
size_t i=0; i<ret.size(); ++i) ret[i]=
nlpsol_out(i);
295 return -std::numeric_limits<double>::infinity();
298 return std::numeric_limits<double>::infinity();
322 return std::string();
335 return std::string();
414 {{
"iteration_callback",
416 "A function that will be called at each iteration with the solver as input. "
417 "Check documentation of Callback."}},
418 {
"iteration_callback_step",
420 "Only call the callback function every few iterations."}},
421 {
"iteration_callback_ignore_errors",
423 "If set to true, errors thrown by iteration_callback will be ignored."}},
426 "If set to true, the input shape of F will not be checked."}},
427 {
"warn_initial_bounds",
429 "Warn if the initial guess does not satisfy LBX and UBX"}},
430 {
"eval_errors_fatal",
432 "When errors occur during evaluation of f,g,...,"
433 "stop the iterations"}},
436 "Print out timing information about "
437 "the different stages of initialization"}},
440 "Indicates which of the variables are discrete, i.e. integer-valued"}},
443 "Indicate an upfront hint which of the constraints are equalities. "
444 "Some solvers may be able to exploit this knowledge. "
445 "When true, the corresponding lower and upper bounds are assumed equal. "
446 "When false, the corresponding bounds may be equal or different."}},
449 "Calculate Lagrange multipliers in the Nlpsol base class"}},
452 "Calculate 'lam_x' in the Nlpsol base class"}},
455 "Calculate 'lam_p' in the Nlpsol base class"}},
458 "Calculate 'f' in the Nlpsol base class"}},
461 "Calculate 'g' in the Nlpsol base class"}},
464 "Prevent the creation of the 'nlp_grad' function"}},
465 {
"bound_consistency",
467 "Ensure that primal-dual solution is consistent with the bounds"}},
470 "Minimum allowed multiplier value"}},
473 "Options to be passed to the oracle function"}},
476 "Linear solver used for parametric sensitivities (default 'qr')."}},
477 {
"sens_linsol_options",
479 "Linear solver options used for parametric sensitivities."}},
480 {
"detect_simple_bounds",
482 "Automatically detect simple bounds (lbx/ubx) (default false). "
483 "This is hopefully beneficial to speed and robustness but may also have adverse affects: "
484 "1) Subtleties in heuristics and stopping criteria may change the solution, "
485 "2) IPOPT may lie about multipliers of simple equality bounds unless "
486 "'fixed_variable_treatment' is set to 'relax_bounds'."}},
487 {
"detect_simple_bounds_is_simple",
489 "For internal use only."}},
490 {
"detect_simple_bounds_parts",
492 "For internal use only."}},
493 {
"detect_simple_bounds_target_x",
495 "For internal use only."}}
504 for (
auto&& op : opts) {
505 if (op.first==
"expand") {
507 }
else if (op.first==
"detect_simple_bounds_is_simple") {
510 }
else if (op.first==
"detect_simple_bounds_parts") {
512 }
else if (op.first==
"detect_simple_bounds_target_x") {
532 for (
auto&& op : opts) {
533 if (op.first==
"iteration_callback") {
535 }
else if (op.first==
"iteration_callback_step") {
537 }
else if (op.first==
"eval_errors_fatal") {
539 }
else if (op.first==
"warn_initial_bounds") {
541 }
else if (op.first==
"iteration_callback_ignore_errors") {
543 }
else if (op.first==
"discrete") {
545 }
else if (op.first==
"equality") {
547 }
else if (op.first==
"calc_multipliers") {
549 }
else if (op.first==
"calc_lam_x") {
551 }
else if (op.first==
"calc_lam_p") {
553 }
else if (op.first==
"calc_f") {
555 }
else if (op.first==
"calc_g") {
557 }
else if (op.first==
"no_nlp_grad") {
559 }
else if (op.first==
"bound_consistency") {
561 }
else if (op.first==
"min_lam") {
563 }
else if (op.first==
"sens_linsol") {
565 }
else if (op.first==
"sens_linsol_options") {
587 casadi_assert(!
calc_lam_p_,
"Options 'no_nlp_grad' and 'calc_lam_p' inconsistent");
588 casadi_assert(!
calc_lam_x_,
"Options 'no_nlp_grad' and 'calc_lam_x' inconsistent");
589 casadi_assert(!
calc_f_,
"Options 'no_nlp_grad' and 'calc_f' inconsistent");
590 casadi_assert(!
calc_g_,
"Options 'no_nlp_grad' and 'calc_g' inconsistent");
608 casadi_assert(
discrete_.size()==
nx_,
"\"discrete\" option has wrong length");
611 "Discrete variables require a solver with integer support");
616 casadi_assert(
equality_.size()==
ng_,
"\"equality\" option has wrong length. "
617 "Expected " +
str(
ng_) +
" elements, but got " +
635 "Callback function must return a scalar.");
637 "Callback input signature must match the NLP solver output signature");
638 for (casadi_int i=0; i<
n_out_; ++i) {
642 "Callback function input size mismatch. For argument '" +
nlpsol_out(i) +
"', "
647 "Callback function input size mismatch. "
648 "For argument " +
nlpsol_out(i) +
"', callback has shape " +
660 {
"f",
"g",
"grad:gamma:x",
"grad:gamma:p"},
661 {{
"gamma", {
"f",
"g"}}});
666 casadi_int* iw,
double* w,
void* callback_data) {
668 return f->operator()(arg, res, iw, w);
671 void Nlpsol::set_nlpsol_prob() {
697 m->d_nlp.prob =
nullptr;
704 auto *d_nlp = &m->
d_nlp;
709 const double inf = std::numeric_limits<double>::infinity();
715 for (casadi_int i=0; i<
nx_; ++i) {
719 casadi_assert(lb <= ub && lb!=
inf && ub!=-
inf,
720 "Ill-posed problem detected: "
721 "LBX[" +
str(i) +
"] <= UBX[" +
str(i) +
"] was violated. "
722 "Got LBX[" +
str(i) +
"]=" +
str(lb) +
" and UBX[" +
str(i) +
"] = " +
str(ub) +
".");
724 casadi_warning(
"Nlpsol: The initial guess does not satisfy LBX and UBX. "
725 "Option 'warn_initial_bounds' controls this warning.");
735 casadi_assert(lb <= ub && lb!=
inf && ub!=-
inf,
736 "Ill-posed problem detected: "
737 "LBG[" +
str(i) +
"] <= UBG[" +
str(i) +
"] was violated. "
738 "Got LBG[" +
str(i) +
"] = " +
str(lb) +
" and UBG[" +
str(i) +
"] = " +
str(ub) +
".");
745 casadi_warning(
"NLP is overconstrained: There are " +
str(n_eq) +
746 " equality constraints but only " +
str(
nx_) +
" variables.");
752 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
753 std::mutex Nlpsol::mutex_solvers_;
759 casadi_error(
"getReducedHessian not defined for class " +
class_name());
764 casadi_error(
"setOptionsFromFile not defined for class " +
class_name());
768 const double* lbz,
const double* ubz) {
769 casadi_assert_dev(z!=
nullptr);
770 casadi_assert_dev(lam!=
nullptr);
771 casadi_assert_dev(lbz!=
nullptr);
772 casadi_assert_dev(ubz!=
nullptr);
776 for (i=0; i<n; ++i) {
778 z[i] = std::fmin(std::fmax(z[i], lbz[i]), ubz[i]);
780 if (std::isinf(lbz[i]) && std::isinf(ubz[i])) {
783 }
else if (std::isinf(lbz[i]) || z[i] - lbz[i] > ubz[i] - z[i]) {
785 lam[i] = std::fmax(0., lam[i]);
786 }
else if (std::isinf(ubz[i]) || z[i] - lbz[i] < ubz[i] - z[i]) {
788 lam[i] = std::fmin(0., lam[i]);
793 int Nlpsol::eval(
const double** arg,
double** res, casadi_int* iw,
double* w,
void* mem)
const {
796 auto *d_nlp = &m->
d_nlp;
799 setup(m, arg, res, iw, w);
800 const auto *p_nlp = d_nlp->prob;
810 if (p_nlp->detect_bounds.ng==0) {
816 if (casadi_nlpsol_detect_bounds_before(d_nlp))
return 1;
823 d_nlp->objective =
nan;
837 const double lam_f = 1.;
838 m->arg[0] = d_nlp->z;
839 m->arg[1] = d_nlp->p;
841 m->arg[3] = d_nlp->lam +
nx_;
842 m->res[0] =
calc_f_ ? &d_nlp->objective :
nullptr;
843 m->res[1] =
calc_g_ ? d_nlp->z +
nx_ :
nullptr;
847 casadi_warning(
"Failed to calculate multipliers");
861 if (p_nlp->detect_bounds.ng==0) {
866 if (casadi_nlpsol_detect_bounds_after(d_nlp))
return 1;
875 casadi_error(
"nlpsol process failed. "
876 "Set 'error_on_fail' option to false to ignore this error.");
879 casadi_error(
"An exception was raised in the solver.");
885 casadi_int*& iw,
double*& w)
const {
893 m->d_nlp.oracle = &m->d_oracle;
916 casadi_nlpsol_set_work(&m->d_nlp, &arg, &res, &iw, &w);
932 stream <<
"minimize f(x;p) subject to lbx<=x<=ubx, lbg<=g(x;p)<=ubg defined by:\n";
937 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
939 std::lock_guard<std::mutex> lock(kkt_mtx_);
944 return shared_cast<Function>(temp);
949 {
"jac:g:x",
"hess:gamma:x:x"}, {{
"gamma", {
"f",
"g"}}});
958 get_forward(casadi_int nfwd,
const std::string& name,
959 const std::vector<std::string>& inames,
960 const std::vector<std::string>& onames,
961 const Dict& opts)
const {
963 "Simple bound detection not compatible with get_forward");
970 std::string name = arg[i].is_symbolic() ? arg[i].name() :
"tmp_get_forward";
993 std::vector<MX> HJ_res =
kkt({x, p, 1, lam_g});
994 MX JG = HJ_res.at(0);
995 MX HL = HJ_res.at(1);
1000 MX bIx = ubIx + lbIx;
1004 MX bIg = ubIg + lbIg;
1008 MX H_11 = mtimes(diag(iIx), HL) + diag(bIx);
1009 MX H_12 = mtimes(diag(iIx), JG.T());
1010 MX H_21 = mtimes(diag(bIg), JG);
1011 MX H_22 = diag(-iIg);
1024 fseed[i] =
MX(repmat(
Sparsity(arg[i].size()), 1, nfwd));
1039 std::vector<MX> vv = {x, p, 1, lam_g, f, g, -lam_x, -lam_p, 0., fwd_p, 0., 0.};
1040 vv = fwd_nlp_grad(vv);
1041 MX fwd_g_p = vv.at(1);
1042 MX fwd_gL_p = vv.at(2);
1055 std::vector<MX> v_split = vertsplit(v, {0,
nx_,
nx_+
ng_});
1056 MX fwd_x = v_split.at(0);
1057 MX fwd_lam_g = v_split.at(1);
1060 vv = {x, p, 1, lam_g, f, g, -lam_x, -lam_p,
1061 fwd_x, fwd_p, 0, fwd_lam_g};
1062 vv = fwd_nlp_grad(vv);
1063 MX fwd_f = vv.at(0);
1064 MX fwd_g = vv.at(1);
1065 MX fwd_lam_x = -vv.at(2);
1066 MX fwd_lam_p = -vv.at(3);
1078 arg.insert(arg.end(), res.begin(), res.end());
1079 arg.insert(arg.end(), fseed.begin(), fseed.end());
1082 Dict options = opts;
1083 options[
"allow_duplicate_io_names"] =
true;
1085 return Function(name, arg, res, inames, onames, options);
1089 get_reverse(casadi_int nadj,
const std::string& name,
1090 const std::vector<std::string>& inames,
1091 const std::vector<std::string>& onames,
1092 const Dict& opts)
const {
1094 "Simple bound detection not compatible with get_reverse");
1101 std::string name = arg[i].is_symbolic() ? arg[i].name() :
"tmp_get_reverse";
1124 std::vector<MX> HJ_res =
kkt({x, p, 1, lam_g});
1125 MX JG = HJ_res.at(0);
1126 MX HL = HJ_res.at(1);
1131 MX bIx = ubIx + lbIx;
1135 MX bIg = ubIg + lbIg;
1139 MX H_11 = mtimes(diag(iIx), HL) + diag(bIx);
1140 MX H_12 = mtimes(diag(iIx), JG.T());
1141 MX H_21 = mtimes(diag(bIg), JG);
1142 MX H_22 = diag(-iIg);
1166 std::vector<MX> vv = {x, p, 1, lam_g, f, g, -lam_x, -lam_p,
1167 adj_f, adj_g, -adj_lam_x, -adj_lam_p};
1168 vv = rev_nlp_grad(vv);
1169 MX adj_x0 = vv.at(0);
1170 MX adj_p0 = vv.at(1);
1171 MX adj_lam_g0 = vv.at(3);
1174 MX v =
MX::vertcat({adj_x + adj_x0, adj_lam_g + adj_lam_g0});
1176 std::vector<MX> v_split = vertsplit(v, {0,
nx_,
nx_+
ng_});
1177 MX beta_x_bar = v_split.at(0);
1178 MX beta_g_bar = v_split.at(1);
1181 vv = {x, p, 1, lam_g, f, g, -lam_x, -lam_p,
1182 0, bIg*beta_g_bar, iIx*beta_x_bar, 0};
1183 vv = rev_nlp_grad(vv);
1184 MX adj_p = vv.at(1);
1196 asens[i] =
MX(repmat(
Sparsity(arg[i].size()), 1, nadj));
1200 arg.insert(arg.end(), res.begin(), res.end());
1201 arg.insert(arg.end(), aseed.begin(), aseed.end());
1204 Dict options = opts;
1205 options[
"allow_duplicate_io_names"] =
true;
1207 return Function(name, arg, res, inames, onames, options);
1216 auto *d_nlp = &m->
d_nlp;
1230 m->
fstats.at(
"callback_fun").tic();
1237 }
catch(std::exception& ex) {
1238 print(
"WARNING: intermediate_callback error: %s\n", ex.
what());
1243 if (
static_cast<casadi_int
>(ret))
return 1;
1246 m->
fstats.at(
"callback_fun").toc();
1254 casadi_assert(m->d_nlp.prob,
1255 "No stats available: nlp Solver instance has not yet been called with numerical arguments.");
1256 auto *d_nlp = &m->d_nlp;
1257 stats[
"success"] = m->success;
1259 if (d_nlp->prob && d_nlp->prob->detect_bounds.ng) {
1260 std::vector<bool> is_simple;
1262 stats[
"detect_simple_bounds_is_simple"] = is_simple;
1270 g.
local(
"d_nlp",
"struct casadi_nlpsol_data");
1271 g.
local(
"p_nlp",
"struct casadi_nlpsol_prob");
1282 const std::string& d_nlp,
const std::string& p_nlp,
1283 const std::string& d_oracle)
const {
1284 g << d_nlp <<
".oracle = &" << d_oracle <<
";\n";
1285 g << d_nlp <<
".prob = &" << p_nlp <<
";\n";
1286 g << p_nlp <<
".nx = " <<
nx_ <<
";\n";
1287 g << p_nlp <<
".ng = " <<
ng_ <<
";\n";
1288 g << p_nlp <<
".np = " <<
np_ <<
";\n";
1297 g << p_nlp <<
".detect_bounds.target_x = "
1299 g << p_nlp <<
".detect_bounds.target_g = "
1301 g << p_nlp <<
".detect_bounds.is_simple = "
1305 g << p_nlp <<
".detect_bounds.callback = " << w <<
";\n";
1306 g << p_nlp <<
".detect_bounds.callback_data = 0;\n";
1314 g << d_nlp <<
".p = arg[" <<
NLPSOL_P <<
"];\n";
1315 g << d_nlp <<
".lbx = arg[" <<
NLPSOL_LBX <<
"];\n";
1316 g << d_nlp <<
".ubx = arg[" <<
NLPSOL_UBX <<
"];\n";
1317 g << d_nlp <<
".lbg = arg[" <<
NLPSOL_LBG <<
"];\n";
1318 g << d_nlp <<
".ubg = arg[" <<
NLPSOL_UBG <<
"];\n";
1319 g << d_nlp <<
".x0 = arg[" <<
NLPSOL_X0 <<
"];\n";
1324 g << d_nlp <<
".x = res[" <<
NLPSOL_X <<
"];\n";
1325 g << d_nlp <<
".f = res[" <<
NLPSOL_F <<
"];\n";
1326 g << d_nlp <<
".g = res[" <<
NLPSOL_G <<
"];\n";
1327 g << d_nlp <<
".lam_x = res[" <<
NLPSOL_LAM_X <<
"];\n";
1328 g << d_nlp <<
".lam_g = res[" <<
NLPSOL_LAM_G <<
"];\n";
1329 g << d_nlp <<
".lam_p = res[" <<
NLPSOL_LAM_P <<
"];\n";
1332 g <<
"casadi_nlpsol_set_work(&" << d_nlp <<
", &arg, &res, &iw, &w);\n";
1335 g.
copy_default(d_nlp +
".lbx",
nx_, d_nlp +
".lbz",
"-casadi_inf",
false);
1336 g.
copy_default(d_nlp +
".ubx",
nx_, d_nlp +
".ubz",
"casadi_inf",
false);
1344 g <<
"if (casadi_nlpsol_detect_bounds_before(&" << d_nlp <<
")) return 1;\n";
1360 <<
"(const casadi_real** arg, casadi_real** res, "
1361 <<
"casadi_int* iw, casadi_real* w, void* callback_data) {\n";
1363 g <<
"return " + flag +
";\n";
1375 g.
local(
"one",
"const casadi_real");
1377 g <<
"d->arg[0] = " << d_nlp <<
".z;\n";
1378 g <<
"d->arg[1] = " << d_nlp <<
".p;\n";
1379 g <<
"d->arg[2] = &one;\n";
1380 g <<
"d->arg[3] = " << d_nlp <<
".lam+" <<
str(
nx_) <<
";\n";
1381 g <<
"d->res[0] = " << (
calc_f_ ?
"&" + d_nlp +
".objective" :
"0") <<
";\n";
1382 g <<
"d->res[1] = " << (
calc_g_ ? d_nlp +
".z+" +
str(
nx_) :
"0") <<
";\n";
1383 g <<
"d->res[2] = " << (
calc_lam_x_ ? d_nlp +
".lam+" +
str(
nx_) :
"0") <<
";\n";
1384 g <<
"d->res[3] = " << (
calc_lam_p_ ? d_nlp +
".lam_p" :
"0") <<
";\n";
1385 std::string nlp_grad = g(
get_function(
"nlp_grad"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1386 g <<
"if (" << nlp_grad <<
") return 1;\n";
1392 d_nlp +
".lbz", d_nlp +
".ubz") <<
";\n";
1395 g << g.
copy(d_nlp +
".z",
nx_, d_nlp +
".x") <<
"\n";
1398 g << g.
copy(d_nlp +
".z + " +
str(
nx_),
ng_, d_nlp +
".g") <<
"\n";
1399 g << g.
copy(d_nlp +
".lam",
nx_, d_nlp +
".lam_x") <<
"\n";
1400 g << g.
copy(d_nlp +
".lam + " +
str(
nx_),
ng_, d_nlp +
".lam_g") <<
"\n";
1402 g <<
"if (casadi_nlpsol_detect_bounds_after(&" << d_nlp <<
")) return 1;\n";
1405 g.
copy_check(
"&" + d_nlp +
".objective", 1, d_nlp +
".f",
false,
true);
1406 g.
copy_check(d_nlp +
".lam_p",
np_, d_nlp +
".lam_p",
false,
true);
1449 int version = s.
version(
"Nlpsol", 1, 5);
1485 casadi_error(
"Saved detect_simple_bounds_parts changed signature");
const char * what() const override
Display error.
Helper class for C code generation.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string wrapper(const Function &base, const std::string &name)
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
std::string scal(casadi_int n, const std::string &alpha, const std::string &x)
What does scal do??
std::string bound_consistency(casadi_int n, const std::string &x, const std::string &lam, const std::string &lbx, const std::string &ubx)
bound_consistency
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 shorthand(const std::string &name) const
Get a shorthand.
void copy_check(const std::string &arg, std::size_t n, const std::string &res, bool check_lhs=true, bool check_rhs=true)
void copy_default(const std::string &arg, std::size_t n, const std::string &res, const std::string &def, bool check_rhs=true)
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
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.
virtual const std::vector< MX > mx_in() const
Get function input(s) and output(s)
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
virtual bool is_a(const std::string &type, bool recursive) const
Check if the function is of a particular type.
bool inputs_check_
Errors are thrown if numerical values of inputs look bad.
size_t sz_res() const
Get required length of res field.
std::pair< casadi_int, casadi_int > size_out(casadi_int ind) const
Input/output dimensions.
casadi_int nnz_in() const
Number of input/output nonzeros.
std::vector< Sparsity > sparsity_out_
void serialize_type(SerializingStream &s) const override
Serialize type information.
size_t sz_w() const
Get required length of w field.
virtual const std::vector< MX > mx_out() const
Get function input(s) and output(s)
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
casadi_int nnz_out() const
Number of input/output nonzeros.
size_t sz_arg() const
Get required length of arg field.
void setup(void *mem, const double **arg, double **res, casadi_int *iw, double *w) const
Set the (persistent and temporary) work vectors.
void alloc(const Function &f, bool persistent=false, int num_threads=1)
Ensure work vectors long enough to evaluate function.
size_t sz_iw() const
Get required length of iw field.
static std::string string_from_UnifiedReturnStatus(UnifiedReturnStatus status)
Function forward(casadi_int nfwd) const
Get a function that calculates nfwd forward derivatives.
size_t sz_res() const
Get required length of res field.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
casadi_int size1_in(casadi_int ind) const
Get input dimension.
Function expand() const
Expand a function to SX.
const std::vector< std::string > & name_in() const
Get input scheme.
const std::string & name() const
Name of the function.
casadi_int numel_out() const
Get number of output elements.
Function reverse(casadi_int nadj) const
Get a function that calculates nadj adjoint derivatives.
const T sym_in(casadi_int iind) const
Get symbolic primitives equivalent to the input expressions.
static Function create(FunctionInternal *node)
Create from node.
const Sparsity & sparsity_in(casadi_int ind) const
Get sparsity of a given input.
size_t sz_iw() const
Get required length of iw field.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
std::vector< std::string > get_free() const
Get free variables as a string.
size_t sz_w() const
Get required length of w field.
size_t sz_arg() const
Get required length of arg field.
bool has_free() const
Does the function have free variables.
casadi_int size1_out(casadi_int ind) const
Get output dimension.
std::pair< casadi_int, casadi_int > size_in(casadi_int ind) const
Get input dimension.
void call(const std::vector< DM > &arg, std::vector< DM > &res, bool always_inline=false, bool never_inline=false) const
Evaluate the function symbolically or numerically.
Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const AuxOut &aux=AuxOut(), const Dict &opts=Dict()) const
const std::vector< std::string > & name_out() const
Get output scheme.
static MX sym(const std::string &name, casadi_int nrow=1, casadi_int ncol=1)
Create an nrow-by-ncol symbolic primitive.
bool is_null() const
Is a null pointer?
bool shared_if_alive(Shared &shared) const
Thread-safe alternative to alive()/shared()
const Sparsity & sparsity() const
Get the sparsity pattern.
static MX blockcat(const std::vector< std::vector< MX > > &v)
MX T() const
Transpose the matrix.
static MX solve(const MX &a, const MX &b)
static MX vertcat(const std::vector< MX > &x)
A symbolic NLP representation.
std::vector< MX > x
Variables.
std::vector< MX > g
Constraints.
void serialize_type(SerializingStream &s) const override
Serialize type information.
Nlpsol(const std::string &name, const Function &oracle)
Constructor.
bool iteration_callback_ignore_errors_
Options.
void codegen_post_solve(CodeGenerator &g, const std::string &d_nlp) const
WeakRef kkt_
Cache for KKT function.
void codegen_body_exit(CodeGenerator &g) const override
Generate code for the function body.
Sparsity get_sparsity_out(casadi_int i) override
Sparsities of function inputs and outputs.
virtual DM getReducedHessian()
Dict get_stats(void *mem) const override
Get all statistics.
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates forward mode derivatives.
static const Options options_
Options.
void codegen_body_enter(CodeGenerator &g) const override
Generate code for the function body.
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
void init(const Dict &opts) override
Initialize.
casadi_int ng_
Number of constraints.
int eval(const double **arg, double **res, casadi_int *iw, double *w, void *mem) const final
Evaluate numerically.
virtual void check_inputs(void *mem) const
Check if the inputs correspond to a well-posed problem.
void codegen_setup_per_call(CodeGenerator &g, const std::string &d_nlp) const
bool eval_errors_fatal_
Options.
int init_mem(void *mem) const override
Initalize memory block.
void codegen_setup_constants(CodeGenerator &g, const std::string &d_nlp, const std::string &p_nlp, const std::string &d_oracle) const
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Function detect_simple_bounds_parts_
bool calc_multipliers_
Options.
static void bound_consistency(casadi_int n, double *z, double *lam, const double *lbz, const double *ubz)
std::vector< bool > equality_
Options.
bool warn_initial_bounds_
Options.
static const std::string infix_
Infix.
Dict sens_linsol_options_
casadi_nlpsol_prob< double > p_nlp_
void disp_more(std::ostream &stream) const override
Print description.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static std::map< std::string, Plugin > solvers_
Collection of solvers.
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Generate a function that calculates reverse mode derivatives.
std::string class_name() const override
Get type name.
std::vector< char > detect_simple_bounds_is_simple_
casadi_int np_
Number of parameters.
Sparsity get_sparsity_in(casadi_int i) override
Sparsities of function inputs and outputs.
static Function create_oracle(const std::map< std::string, XType > &d, const Dict &opts)
Convert dictionary to Problem.
std::vector< casadi_int > detect_simple_bounds_target_g_
casadi_int callback_step_
Execute the callback function only after this amount of iterations.
virtual void setOptionsFromFile(const std::string &file)
Read options from parameter xml.
std::vector< casadi_int > detect_simple_bounds_target_x_
int callback(NlpsolMemory *m) const
~Nlpsol() override=0
Destructor.
std::vector< bool > discrete_
Options.
casadi_int nx_
Number of variables.
virtual bool integer_support() const
Can discrete variables be treated.
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
bool bound_consistency_
Options.
bool no_nlp_grad_
Options.
std::string sens_linsol_
Linear solver and options.
virtual int solve(void *mem) const =0
Function fcallback_
callback function, executed at each iteration
bool is_a(const std::string &type, bool recursive) const override
Check if the function is of a particular type.
double get_default_in(casadi_int ind) const override
Get default input value.
Base class for functions that perform calculation with an oracle.
Function oracle_
Oracle: Used to generate other functions.
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())
void join_results(OracleMemory *m) const
Combine results from different threads.
void init(const Dict &opts) override
int init_mem(void *mem) const override
Initalize memory block.
virtual void codegen_body_enter(CodeGenerator &g) const
Generate code for the function body.
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 const Options options_
Options.
Dict get_stats(void *mem) const override
Get all statistics.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
virtual void codegen_body_exit(CodeGenerator &g) const
Generate code for the function body.
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
static Nlpsol * instantiate(const std::string &fname, const std::string &pname, Problem problem)
void serialize_type(SerializingStream &s) const
Serialize type information.
static const Options & plugin_options(const std::string &pname)
Get the plugin options.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.
Base class for FunctionInternal and LinsolInternal.
bool error_on_fail_
Throw an exception on failure?
void print(const char *fmt,...) const
C-style formatted printing during evaluation.
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.
GenericShared implements a reference counting framework similar for efficient and.
void disp(std::ostream &stream, bool more=false) const
Print a description of the object.
Class representing a Slice.
casadi_int numel() const
The total number of elements, including structural zeros, i.e. size2()*size1()
std::string dim(bool with_nz=false) const
Get the dimension as a string.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
Sparsity T() const
Transpose the matrix.
const casadi_int * row() const
Get a reference to row-vector,.
bool is_empty(bool both=false) const
Check if the sparsity is empty.
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
std::string doc_nlpsol(const std::string &name)
Get the documentation string for a plugin.
bool has_nlpsol(const std::string &name)
Check if a particular plugin is available.
void load_nlpsol(const std::string &name)
Explicitly load a plugin dynamically.
std::string nlpsol_option_info(const std::string &name, const std::string &op)
Get documentation for a particular option.
casadi_int nlpsol_n_in()
Number of NLP solver inputs.
std::string nlpsol_option_type(const std::string &name, const std::string &op)
Get type info for a particular option.
std::vector< std::string > nlpsol_options(const std::string &name)
Get all options for a plugin.
std::vector< std::string > nlpsol_in()
Get input scheme of NLP solvers.
Function nlpsol(const std::string &name, const std::string &solver, const SXDict &nlp, const Dict &opts)
casadi_int nlpsol_n_out()
Number of NLP solver outputs.
std::vector< std::string > nlpsol_out()
Get NLP solver output scheme of NLP solvers.
double nlpsol_default_in(casadi_int ind)
Default input for an NLP solver.
NlpsolInput
Input arguments of an NLP Solver.
@ NLPSOL_P
Value of fixed parameters (np x 1)
@ NLPSOL_UBX
Decision variables upper bound (nx x 1), default +inf.
@ NLPSOL_X0
Decision variables, initial guess (nx x 1)
@ NLPSOL_LAM_G0
Lagrange multipliers for bounds on G, initial guess (ng x 1)
@ NLPSOL_UBG
Constraints upper bound (ng x 1), default +inf.
@ NLPSOL_LAM_X0
Lagrange multipliers for bounds on X, initial guess (nx x 1)
@ NLPSOL_LBG
Constraints lower bound (ng x 1), default -inf.
@ NLPSOL_LBX
Decision variables lower bound (nx x 1), default -inf.
std::map< std::string, MX > MXDict
bool name_has_g(const std::string &name)
NlpsolOutput
Output arguments of an NLP Solver.
@ NLPSOL_G
Constraints function at the optimal solution (ng x 1)
@ NLPSOL_X
Decision variables at the optimal solution (nx x 1)
@ NLPSOL_LAM_P
Lagrange multipliers for bounds on P at the solution (np x 1)
@ NLPSOL_F
Cost function value at the optimal solution (1 x 1)
@ NLPSOL_LAM_G
Lagrange multipliers for bounds on G at the solution (ng x 1)
@ NLPSOL_LAM_X
Lagrange multipliers for bounds on X at the solution (nx x 1)
T get_from_dict(const std::map< std::string, T > &d, const std::string &key, const T &default_value)
void assign_vector(const std::vector< S > &s, std::vector< D > &d)
@ NL_NUM_IN
Number of NLP inputs.
double if_else(double x, double y, double z)
@ NL_F
Objective function.
@ NL_G
Constraint function.
@ NL_NUM_OUT
Number of NLP outputs.
int detect_bounds_callback(const double **arg, double **res, casadi_int *iw, double *w, void *callback_data)
void casadi_copy(const T1 *x, casadi_int n, T1 *y)
COPY: y <-x.
void casadi_fill(T1 *x, casadi_int n, T1 alpha)
FILL: x <- alpha.
std::map< std::string, SX > SXDict
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::vector< bool > boolvec_not(const std::vector< bool > &v)
Invert all entries.
const std::vector< std::string > NL_INPUTS
Shortname for onput arguments of an NLP function.
const double nan
Not a number.
void casadi_scal(casadi_int n, T1 alpha, T1 *x)
SCAL: x <- alpha*x.
std::vector< T > vector_select(const std::vector< T > &v, const std::vector< bool > &s, bool invert=false)
Select subset of vector.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
Function construct_nlpsol(const std::string &name, const std::string &solver, const std::map< std::string, X > &nlp, const Dict &opts)
Function external(const std::string &name, const Importer &li, const Dict &opts)
Load a just-in-time compiled external function.
std::vector< casadi_int > boolvec_to_index(const std::vector< bool > &v)
const std::vector< std::string > NL_OUTPUTS
Shortname for output arguments of an NLP function.
casadi_nlpsol_data< double > d_nlp
Options metadata for a class.
std::string type(const std::string &name) const
std::vector< std::string > all() const
std::string info(const std::string &name) const
std::map< std::string, FStats > fstats
void add_stat(const std::string &s)
casadi_nlpsol_detect_bounds_prob< T1 > detect_bounds