25 #include "sqpmethod.hpp"
27 #include "casadi/core/casadi_misc.hpp"
28 #include "casadi/core/calculus.hpp"
29 #include "casadi/core/conic.hpp"
30 #include "casadi/core/conic_impl.hpp"
31 #include "casadi/core/convexify.hpp"
42 int CASADI_NLPSOL_SQPMETHOD_EXPORT
45 plugin->name =
"sqpmethod";
47 plugin->version = CASADI_VERSION;
70 "The QP solver to be used by the SQP method [qpoases]"}},
73 "Options to be passed to the QP solver"}},
74 {
"hessian_approximation",
76 "limited-memory|exact"}},
79 "Maximum number of SQP iterations"}},
82 "Minimum number of SQP iterations"}},
85 "Maximum number of linesearch iterations"}},
88 "Stopping criterion for primal infeasibility"}},
91 "Stopping criterion for dual infeasability"}},
94 "Armijo condition, coefficient of decrease in merit"}},
97 "Line-search parameter, restoration factor of stepsize"}},
100 "Size of memory to store history of merit function values"}},
103 "Size of L-BFGS memory."}},
106 "Print the header with problem statistics"}},
109 "Print the iterations"}},
112 "Print a status message after solving"}},
115 "The size (inf-norm) of the step size should not become smaller than this."}},
118 "Function for calculating the Hessian of the Lagrangian (autogenerated by default)"}},
121 "Function for calculating the gradient of the objective and Jacobian of the constraints "
122 "(autogenerated by default)"}},
123 {
"convexify_strategy",
125 "NONE|regularize|eigen-reflect|eigen-clip. "
126 "Strategy to convexify the Lagrange Hessian before passing it to the solver."}},
129 "When using a convexification strategy, make sure that "
130 "the smallest eigenvalue is at least this (default: 1e-7)."}},
133 "Maximum number of iterations to compute an eigenvalue decomposition (default: 50)."}},
136 "Enable the elastic mode which is used when the QP is infeasible (default: false)."}},
139 "Starting value for the penalty parameter of elastic mode (default: 1)."}},
142 "Maximum value for the penalty parameter of elastic mode (default: 1e20)."}},
145 "Minimum value for gamma_1 (default: 1e-5)."}},
146 {
"second_order_corrections",
148 "Enable second order corrections. "
149 "These are used when a step is considered bad by the merit function and constraint norm "
150 "(default: false)."}},
153 "Initialize the QP subproblems with a feasible initial value (default: false)."}}
171 std::string hessian_approximation =
"exact";
173 std::string qpsol_plugin =
"qpoases";
185 std::string convexify_strategy =
"none";
186 double convexify_margin = 1e-7;
187 casadi_int max_iter_eig = 200;
190 for (
auto&& op : opts) {
191 if (op.first==
"max_iter") {
193 }
else if (op.first==
"min_iter") {
195 }
else if (op.first==
"max_iter_ls") {
197 }
else if (op.first==
"c1") {
199 }
else if (op.first==
"beta") {
201 }
else if (op.first==
"merit_memory") {
203 }
else if (op.first==
"lbfgs_memory") {
205 }
else if (op.first==
"tol_pr") {
207 }
else if (op.first==
"tol_du") {
209 }
else if (op.first==
"hessian_approximation") {
210 hessian_approximation = op.second.to_string();
211 }
else if (op.first==
"min_step_size") {
213 }
else if (op.first==
"qpsol") {
214 qpsol_plugin = op.second.to_string();
215 }
else if (op.first==
"qpsol_options") {
216 qpsol_options = op.second;
217 }
else if (op.first==
"print_header") {
219 }
else if (op.first==
"print_iteration") {
221 }
else if (op.first==
"print_status") {
223 }
else if (op.first==
"hess_lag") {
225 casadi_assert_dev(f.
n_in()==4);
226 casadi_assert_dev(f.
n_out()==1);
228 }
else if (op.first==
"jac_fg") {
230 casadi_assert_dev(f.
n_in()==2);
231 casadi_assert_dev(f.
n_out()==4);
233 }
else if (op.first==
"convexify_strategy") {
234 convexify_strategy = op.second.to_string();
235 }
else if (op.first==
"convexify_margin") {
236 convexify_margin = op.second;
237 }
else if (op.first==
"max_iter_eig") {
238 max_iter_eig = op.second;
239 }
else if (op.first==
"elastic_mode") {
241 }
else if (op.first==
"gamma_0") {
243 }
else if (op.first==
"gamma_max") {
245 }
else if (op.first==
"gamma_1_min") {
247 }
else if (op.first==
"second_order_corrections") {
249 }
else if (op.first==
"init_feasible") {
255 auto it = qpsol_options.find(
"error_on_fail");
256 if (it==qpsol_options.end()) {
257 qpsol_options[
"error_on_fail"] =
false;
259 casadi_assert(!it->second,
260 "QP solver with setting error_on_fail is incompatible with elastic mode sqpmethod.");
275 {
"f",
"grad:f:x",
"g",
"jac:g:x"});
282 {
"hess:gamma:x:x"}, {{
"gamma", {
"f",
"g"}}});
286 if (convexify_strategy!=
"none") {
289 opts[
"strategy"] = convexify_strategy;
290 opts[
"margin"] = convexify_margin;
291 opts[
"max_iter_eig"] = max_iter_eig;
299 casadi_assert(!qpsol_plugin.empty(),
"'qpsol' option has not been set");
309 std::vector<casadi_int> n_v =
range(
nx_);
317 Dict qpsol_ela_options =
Dict(qpsol_options);
319 casadi_assert(!qpsol_plugin.empty(),
"'qpsol' option has not been set");
320 qpsol_ela_ =
conic(
"qpsol_ela", qpsol_plugin, {{
"h", Hsp_ela}, {
"a", Asp_ela}},
333 print(
"-------------------------------------------\n");
334 print(
"This is casadi::Sqpmethod.\n");
336 print(
"Using exact Hessian\n");
338 print(
"Using limited memory BFGS Hessian approximation\n");
340 print(
"Number of variables: %9d\n",
nx_);
341 print(
"Number of constraints: %9d\n",
ng_);
342 print(
"Number of nonzeros in constraint Jacobian: %9d\n",
Asp_.
nnz());
343 print(
"Number of nonzeros in Lagrangian Hessian: %9d\n",
Hsp_.
nnz());
348 set_sqpmethod_prob();
360 void Sqpmethod::set_sqpmethod_prob() {
371 casadi_int*& iw,
double*& w)
const {
378 casadi_sqpmethod_set_work(&m->d, &arg, &res, &iw, &w);
390 m->add_stat(
"linesearch");
403 auto d_nlp = &m->
d_nlp;
410 casadi_int ls_iter = 0;
413 bool ls_success =
true;
416 bool so_succes =
false;
427 const double one = 1.;
430 std::string
info =
"";
433 double gamma_1 = 0.0;
436 casadi_int ela_it = -1;
443 m->arg[0] = d_nlp->z;
444 m->arg[1] = d_nlp->p;
445 m->res[0] = &d_nlp->objective;
447 m->res[2] = d_nlp->z +
nx_;
451 m->return_status =
"Non_Regular_Sensitivities";
454 print(
"MESSAGE(sqpmethod): No regularity of sensitivities at current point.\n");
478 print_iteration(m->iter_count, d_nlp->objective, pr_inf, du_inf, dx_norminf,
479 m->reg, ls_iter, ls_success, so_succes,
info);
487 m->return_status =
"User_Requested_Stop";
494 print(
"MESSAGE(sqpmethod): Convergence achieved after %d iterations\n", m->iter_count);
495 m->return_status =
"Solve_Succeeded";
501 if (
print_status_)
print(
"MESSAGE(sqpmethod): Maximum number of iterations reached.\n");
502 m->return_status =
"Maximum_Iterations_Exceeded";
508 if (
print_status_)
print(
"MESSAGE(sqpmethod): Search direction becomes too small without "
509 "convergence criteria being met.\n");
510 m->return_status =
"Search_Direction_Becomes_Too_Small";
516 m->arg[0] = d_nlp->z;
517 m->arg[1] = d_nlp->p;
519 m->arg[3] = d_nlp->lam +
nx_;
526 }
else if (m->iter_count==0) {
530 casadi_bfgs_reset(
Hsp_, d->Bk);
536 casadi_bfgs(
Hsp_, d->Bk, d->dx, d->gLag, d->gLag_old, m->w);
561 int ret =
solve_QP(m, d->Bk, d->gf, d->lbdz, d->ubdz, d->Jk, d->dx, d->dlam, 0);
573 pr_inf, du_inf, dx_norminf, &
info, 0);
576 }
else if (ela_it == -1) {
580 if (pi_inf > gamma_1) {
583 pr_inf, du_inf, dx_norminf, &
info, 0);
596 double l1_infeas, l1;
603 l1 = d_nlp->objective + m->sigma * l1_infeas;
607 double l1_infeas_cand, l1_cand, fk_cand;
615 m->arg[0] = d->z_cand;
616 m->arg[1] = d_nlp->p;
617 m->res[0] = &fk_cand;
618 m->res[1] = d->z_cand +
nx_;
623 l1_cand = fk_cand + m->sigma*l1_infeas_cand;
627 if (
so_corr_ && l1_cand > l1 && l1_infeas_cand > l1_infeas) {
656 for (casadi_int i = 0; i <
nx_; ++i) {
657 if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];
658 else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];
663 ret =
solve_QP(m, d->Bk, d->gf, d->lbdz, d->ubdz, d->Jk,
675 pr_inf, du_inf, dx_norminf, &
info, 1);
686 double l1_cand_norm = l1_cand;
694 m->arg[0] = d->z_cand;
695 m->arg[1] = d_nlp->p;
696 m->res[0] = &fk_cand;
697 m->res[1] = d->z_cand +
nx_;
702 l1_cand_soc = fk_cand + m->sigma*l1_infeas_cand;
705 if (l1_cand_norm < l1_cand_soc) {
729 double tl1 =
casadi_dot(
nx_, d->dx, d->gf) - m->sigma*l1_infeas;
732 d->merit_mem[m->merit_ind] = l1;
750 m->arg[0] = d->z_cand;
751 m->arg[1] = d_nlp->p;
752 m->res[0] = &fk_cand;
753 m->res[1] = d->z_cand +
nx_;
769 if (l1_cand <= l1 + t *
c1_ * tl1) {
814 print(
"%4s %14s %9s %9s %9s %7s %2s %7s\n",
"iter",
"objective",
"inf_pr",
815 "inf_du",
"||d||",
"lg(rg)",
"ls",
"info");
819 double pr_inf,
double du_inf,
820 double dx_norm,
double rg,
821 casadi_int ls_trials,
bool ls_success,
822 bool so_succes, std::string info)
const {
823 print(
"%4d %14.6e %9.2e %9.2e %9.2e ", iter, obj, pr_inf, du_inf, dx_norm);
825 print(
"%7.2f ", log10(rg));
830 print(
"%2d", ls_trials);
847 const double* lbdz,
const double* ubdz,
const double* A,
848 double* x_opt,
double* dlam,
int mode)
const {
876 if (!m_qpsol->d_qp.success) {
888 const double* lbdz,
const double* ubdz,
const double* A,
889 double* x_opt,
double* dlam)
const {
917 if (!m_qpsol_ela->d_qp.success) {
929 casadi_int* ela_it,
double gamma_1,
930 casadi_int ls_iter,
bool ls_success,
bool so_succes,
double pr_inf,
931 double du_inf,
double dx_norminf, std::string* info,
int mode)
const {
932 auto d_nlp = &m->
d_nlp;
935 if (mode != 0 && mode != 1) casadi_error(
"Wrong mode provided to solve_elastic_mode.");
939 if (mode == 0) (*ela_it)++;
942 double *temp_1, *temp_2;
951 temp_1 = d->lbdz +
nx_;
952 temp_2 = d->lbdz +
nx_+2*
ng_;
956 temp_1 = d->ubdz +
nx_;
957 temp_2 = d->ubdz +
nx_+2*
ng_;
962 gamma = pow(10, *ela_it * (*ela_it - 1) / 2) * gamma_1;
968 casadi_error(
"Error in elastic mode of QP solver."
969 "Gamma became larger than gamma_max.");
976 m->
reg, ls_iter, ls_success, so_succes, *
info);
980 temp_1 = d->gf +
nx_;
991 for (casadi_int i = 0; i <
nx_; ++i) {
992 if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];
993 else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];
998 for (casadi_int i = 0; i <
ng_; ++i) {
999 if (d->ubdz[
nx_+2*
ng_+i]-d->temp_mem[i] < 0) {
1000 d->dx[
nx_+i] = -d->ubdz[
nx_+2*
ng_+i]+d->temp_mem[i];
1003 if (d->lbdz[
nx_+2*
ng_+i]-d->temp_mem[i] > 0) {
1004 d->dx[
nx_+
ng_+i] = d->lbdz[
nx_+2*
ng_+i]-d->temp_mem[i];
1010 int ret =
solve_ela_QP(m, d->Bk, d->gf, d->lbdz, d->ubdz, d->Jk, d->dx, d->dlam);
1012 if (mode == 0) *
info =
"Elastic mode QP (gamma = " +
str(gamma) +
")";
1043 g.
local(
"d",
"struct casadi_sqpmethod_data*");
1045 g.
local(
"p",
"struct casadi_sqpmethod_prob");
1047 g <<
"d->prob = &p;\n";
1052 g <<
"p.nlp = &p_nlp;\n";
1054 g <<
"p.so_corr = " <<
so_corr_ <<
";\n";
1055 g <<
"casadi_sqpmethod_set_work(d, &arg, &res, &iw, &w);\n";
1058 g.
local(
"gamma_1",
"double");
1059 g.
local(
"ela_it",
"casadi_int");
1061 g.
local(
"temp_norm",
"double");
1063 g.
local(
"ret",
"int");
1065 g.
local(
"iter_count",
"casadi_int");
1070 g.
local(
"sigma",
"casadi_real");
1074 g.
local(
"ls_iter",
"casadi_int");
1076 g.
local(
"t",
"casadi_real");
1081 g.
local(
"ls_success",
"casadi_int");
1085 g << g.
clear(
"d->dx",
nx_) <<
"\n";
1086 g.
comment(
"MAIN OPTIMIZATION LOOP");
1087 g <<
"while (1) {\n";
1088 g.
comment(
"Evaluate f, g and first order derivative information");
1089 g <<
"d->arg[0] = d_nlp.z;\n";
1090 g <<
"d->arg[1] = d_nlp.p;\n";
1091 g <<
"d->res[0] = &d_nlp.objective;\n";
1092 g <<
"d->res[1] = d->gf;\n";
1093 g <<
"d->res[2] = d_nlp.z+" +
str(
nx_) +
";\n";
1094 g <<
"d->res[3] = d->Jk;\n";
1095 std::string nlp_jac_fg = g(
get_function(
"nlp_jac_fg"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1096 g <<
"if (" + nlp_jac_fg +
") return 1;\n";
1097 g.
comment(
"Evaluate the gradient of the Lagrangian");
1098 g << g.
copy(
"d->gf",
nx_,
"d->gLag") <<
"\n";
1099 g << g.
mv(
"d->Jk",
Asp_,
"d_nlp.lam+"+
str(
nx_),
"d->gLag",
true) <<
"\n";
1100 g << g.
axpy(
nx_,
"1.0",
"d_nlp.lam",
"d->gLag") <<
"\n";
1101 g.
comment(
"Primal infeasability");
1102 g.
local(
"pr_inf",
"casadi_real");
1103 g <<
"pr_inf = " << g.
max_viol(
nx_+
ng_,
"d_nlp.z",
"d_nlp.lbz",
"d_nlp.ubz") <<
";\n";
1104 g.
comment(
"inf-norm of lagrange gradient");
1105 g.
local(
"du_inf",
"casadi_real");
1106 g <<
"du_inf = " << g.
norm_inf(
nx_,
"d->gLag") <<
";\n";
1107 g.
comment(
"inf-norm of step");
1108 g.
local(
"dx_norminf",
"casadi_real");
1109 g <<
"dx_norminf = " << g.
norm_inf(
nx_,
"d->dx") <<
";\n";
1110 g.
comment(
"Checking convergence criteria");
1112 " && du_inf < " <<
tol_du_ <<
") break;\n";
1113 g <<
"if (iter_count >= " <<
max_iter_ <<
") break;\n";
1114 g <<
"if (iter_count >= 1 && iter_count >= " <<
min_iter_ <<
" && dx_norminf <= " <<
1117 g.
comment(
"Update/reset exact Hessian");
1118 g <<
"d->arg[0] = d_nlp.z;\n";
1119 g <<
"d->arg[1] = d_nlp.p;\n";
1120 g.
local(
"one",
"const casadi_real");
1122 g <<
"d->arg[2] = &one;\n";
1123 g <<
"d->arg[3] = d_nlp.lam+" +
str(
nx_) +
";\n";
1124 g <<
"d->res[0] = d->Bk;\n";
1125 std::string nlp_hess_l = g(
get_function(
"nlp_hess_l"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1126 g <<
"if (" + nlp_hess_l +
") return 1;\n";
1130 g <<
"if (" << ret <<
") return 1;\n";
1133 g <<
"if (iter_count==0) {\n";
1136 g <<
"casadi_bfgs_reset(p.sp_h, d->Bk);\n";
1140 g <<
"casadi_bfgs_reset(p.sp_h, d->Bk);\n";
1141 g.
comment(
"Update the Hessian approximation");
1142 g <<
"casadi_bfgs(p.sp_h, d->Bk, d->dx, d->gLag, d->gLag_old, d->w);\n";
1146 g.
comment(
"Formulate the QP");
1147 g << g.
copy(
"d_nlp.lbz",
nx_+
ng_,
"d->lbdz") <<
"\n";
1148 g << g.
axpy(
nx_+
ng_,
"-1.0",
"d_nlp.z",
"d->lbdz") <<
"\n";
1149 g << g.
copy(
"d_nlp.ubz",
nx_+
ng_,
"d->ubdz") <<
"\n";
1150 g << g.
axpy(
nx_+
ng_,
"-1.0",
"d_nlp.z",
"d->ubdz") <<
"\n";
1152 g << g.
copy(
"d_nlp.lam",
nx_+
ng_,
"d->dlam") <<
"\n";
1153 g << g.
clear(
"d->dx",
nx_) <<
"\n";
1156 g.
comment(
"Make initial guess feasible");
1157 g <<
"for (casadi_int i = 0; i < " <<
nx_ <<
"; ++i) {\n";
1158 g <<
"if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];\n";
1159 g <<
"else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];\n";
1163 g.
comment(
"Increase counter");
1164 g <<
"iter_count++;\n";
1166 codegen_qp_solve(g,
"d->Bk",
"d->gf",
"d->lbdz",
"d->ubdz",
"d->Jk",
"d->dx",
"d->dlam", 0);
1169 g.
comment(
"Elastic mode calculations");
1170 g <<
"if (ret == " << 0 <<
") {\n";
1171 g <<
"ela_it = -1;\n";
1173 g <<
"if (ela_it == -1) {\n";
1174 g <<
"ela_it = 0;\n";
1180 g <<
"} else if (ela_it == -1) {\n";
1183 g <<
"if (pi_inf > gamma_1) {\n";
1184 g <<
"ela_it = 0;\n";
1192 g.
comment(
"Calculate penalty parameter of merit function");
1193 g <<
"sigma = " << g.
fmax(
"sigma",
"(1.01*" + g.
norm_inf(
nx_+
ng_,
"d->dlam")+
")") <<
";\n";
1194 g.
comment(
"Calculate L1-merit function in the actual iterate");
1195 g.
local(
"l1_infeas",
"casadi_real");
1196 g <<
"l1_infeas = " << g.
sum_viol(
nx_+
ng_,
"d_nlp.z",
"d_nlp.lbz",
"d_nlp.ubz") <<
";\n";
1197 g.
local(
"l1",
"casadi_real");
1198 g <<
"l1 = d_nlp.objective + sigma * l1_infeas;\n";
1201 g.
local(
"l1_infeas_cand",
"casadi_real");
1203 g.
local(
"l1_cand",
"casadi_real");
1204 g.
local(
"fk_cand",
"casadi_real");
1205 g.
comment(
"Take candidate step");
1206 g << g.
copy(
"d_nlp.z",
nx_,
"d->z_cand") <<
";\n";
1207 g << g.
axpy(
nx_,
"1.",
"d->dx",
"d->z_cand") <<
";\n";
1209 g.
comment(
"Evaluate objective and constraints");
1210 g <<
"d->arg[0] = d->z_cand;\n;";
1211 g <<
"d->arg[1] = d_nlp.p;\n;";
1212 g <<
"d->res[0] = &fk_cand;\n;";
1213 g <<
"d->res[1] = d->z_cand+" +
str(
nx_) +
";\n;";
1214 std::string nlp_fg = g(
get_function(
"nlp_fg"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1215 g <<
"if (" << nlp_fg <<
") {\n";
1216 g <<
"l1_cand = -casadi_inf;\n";
1218 g <<
"l1_infeas_cand = " << g.
sum_viol(
nx_+
ng_,
"d->z_cand",
"d_nlp.lbz",
"d_nlp.ubz") <<
";\n";
1219 g <<
"l1_cand = fk_cand + sigma*l1_infeas_cand;\n";
1222 g <<
"if (l1_cand > l1 && l1_infeas_cand > l1_infeas) {\n";
1223 g.
comment(
"Copy in case of fail");
1224 g << g.
copy(
"d->dx",
nx_,
"d->temp_sol") <<
"\n";
1227 g.
comment(
"Add gradient times proposal step to bounds");
1229 g << g.
mv(
"d->Jk",
Asp_,
"d->dx",
"d->lbdz+" +
str(
nx_),
false) <<
";\n";
1230 g << g.
copy(
"d->lbdz",
nx_+
ng_,
"d->ubdz") <<
";\n";
1233 g << g.
axpy(
nx_+
ng_,
"1.",
"d_nlp.lbz",
"d->lbdz") <<
";\n";
1234 g << g.
axpy(
nx_+
ng_,
"1.",
"d_nlp.ubz",
"d->ubdz") <<
";\n";
1236 g.
comment(
"Subtract constraints in candidate step from bounds");
1237 g << g.
axpy(
nx_,
"-1.",
"d_nlp.z",
"d->lbdz") <<
";\n";
1239 g << g.
axpy(
nx_,
"-1.",
"d_nlp.z",
"d->ubdz") <<
";\n";
1244 g << g.
copy(
"d_nlp.lam",
nx_+
ng_,
"d->dlam") <<
"\n";
1248 g.
comment(
"Make initial guess feasible");
1249 g <<
"for (casadi_int i = 0; i < " <<
nx_ <<
"; ++i) {\n";
1250 g <<
"if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];\n";
1251 g <<
"else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];\n";
1255 codegen_qp_solve(g,
"d->Bk",
"d->gf",
"d->lbdz",
"d->ubdz",
"d->Jk",
"d->dx",
"d->dlam", 1);
1258 g.
comment(
"Second order corrections without elastic mode");
1259 g <<
"if (ela_it == -1) {\n";
1262 g << g.
copy(
"d_nlp.lam",
nx_+
ng_,
"d->dlam") <<
"\n";
1266 g.
comment(
"Make initial guess feasible");
1267 g <<
"for (casadi_int i = 0; i < " <<
nx_ <<
"; ++i) {\n";
1268 g <<
"if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];\n";
1269 g <<
"else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];\n";
1273 codegen_qp_solve(g,
"d->Bk",
"d->gf",
"d->lbdz",
"d->ubdz",
"d->Jk",
"d->dx",
"d->dlam", 1);
1276 g.
comment(
"Second order corrections in elastic mode");
1278 g <<
"if (ela_it == -1) {\n";
1279 g <<
"ela_it = 0;\n";
1286 g.
comment(
"Fallback on previous solution if the second order correction failed");
1287 g <<
"if (ret != " << 0 <<
") {\n";
1288 g << g.
copy(
"d->temp_sol",
nx_,
"d->dx") <<
"\n";
1291 g.
comment(
"Check if corrected step is better than the original one using the merit function");
1292 g <<
"double l1_cand_norm = l1_cand;\n";
1293 g <<
"double l1_cand_soc;\n";
1295 g.
comment(
"Take candidate step");
1296 g << g.
copy(
"d_nlp.z",
nx_,
"d->z_cand") <<
"\n";
1297 g << g.
axpy(
nx_,
"1.",
"d->dx",
"d->z_cand") <<
"\n";
1299 g.
comment(
"Evaluate objective and constraints");
1300 g <<
"d->arg[0] = d->z_cand;\n;";
1301 g <<
"d->arg[1] = d_nlp.p;\n;";
1302 g <<
"d->res[0] = &fk_cand;\n;";
1303 g <<
"d->res[1] = d->z_cand+" +
str(
nx_) +
";\n;";
1304 nlp_fg = g(
get_function(
"nlp_fg"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1305 g <<
"if (" << nlp_fg <<
") {\n";
1306 g <<
"l1_cand_soc = casadi_inf;\n";
1308 g <<
"l1_infeas_cand = " << g.
sum_viol(
nx_+
ng_,
"d->z_cand",
"d_nlp.lbz",
"d_nlp.ubz") <<
";\n";
1309 g <<
"l1_cand_soc = fk_cand + sigma*l1_infeas_cand;\n";
1312 g <<
"if (l1_cand_norm < l1_cand_soc) {\n";
1313 g.
comment(
"Copy normal step if merit function increases");
1314 g << g.
copy(
"d->temp_sol",
nx_,
"d->dx") <<
"\n";
1322 g.
comment(
"Detecting indefiniteness");
1323 g.
comment(
"Right-hand side of Armijo condition");
1324 g.
local(
"F_sens",
"casadi_real");
1325 g <<
"F_sens = " << g.
dot(
nx_,
"d->dx",
"d->gf") <<
";\n";
1326 g.
local(
"tl1",
"casadi_real");
1327 g <<
"tl1 = F_sens - sigma * l1_infeas;\n";
1338 g.
local(
"fk_cand",
"casadi_real");
1339 g.
comment(
"Merit function value in candidate");
1340 g.
local(
"l1_cand",
"casadi_real");
1341 g <<
"l1_cand = 0.0;\n";
1342 g.
comment(
"Reset line-search counter, success marker");
1343 g <<
"ls_iter = 0;\n";
1345 g.
comment(
"Line-search loop");
1346 g <<
"while (1) {\n";
1347 g.
comment(
" Increase counter");
1348 g <<
"ls_iter++;\n";
1351 g << g.
copy(
"d_nlp.z",
nx_,
"d->z_cand") <<
"\n";
1352 g << g.
axpy(
nx_,
"t",
"d->dx",
"d->z_cand") <<
"\n";
1353 g.
comment(
"Evaluating objective and constraints");
1354 g <<
"d->arg[0] = d->z_cand;\n";
1355 g <<
"d->arg[1] = d_nlp.p;\n";
1356 g <<
"d->res[0] = &fk_cand;\n";
1357 g <<
"d->res[1] = d->z_cand+" +
str(
nx_) +
";\n";
1358 std::string nlp_fg = g(
get_function(
"nlp_fg"),
"d->arg",
"d->res",
"d->iw",
"d->w");
1359 g <<
"if (" << nlp_fg <<
") {\n";
1360 g.
comment(
"Avoid infinite recursion");
1365 g.
comment(
"line-search failed, skip iteration");
1366 g <<
"t = " <<
beta_ <<
"* t;\n";
1370 g.
comment(
"Calculating merit-function in candidate");
1371 g <<
"l1_cand = fk_cand + sigma * "
1372 << g.
sum_viol(
nx_+
ng_,
"d->z_cand",
"d_nlp.lbz",
"d_nlp.ubz") +
";\n";
1373 g <<
"if (l1_cand <= l1 + t * " <<
c1_ <<
"* tl1) {\n";
1376 g.
comment(
"Line-search not successful, but we accept it.");
1382 g <<
"t = " <<
beta_ <<
"* t;\n";
1384 g.
comment(
"Candidate accepted, update dual variables");
1385 g << g.
scal(
nx_+
ng_,
"1-t",
"d_nlp.lam") <<
"\n";
1386 g << g.
axpy(
nx_+
ng_,
"t",
"d->dlam",
"d_nlp.lam") <<
"\n";
1387 g << g.
scal(
nx_,
"t",
"d->dx") <<
"\n";
1390 g << g.
copy(
"d->dlam",
nx_ +
ng_,
"d_nlp.lam") <<
"\n";
1394 g << g.
axpy(
nx_,
"1.0",
"d->dx",
"d_nlp.z") <<
"\n";
1397 g.
comment(
"Evaluate the gradient of the Lagrangian with the old x but new lam (for BFGS)");
1398 g << g.
copy(
"d->gf",
nx_,
"d->gLag_old") <<
"\n";
1399 g << g.
mv(
"d->Jk",
Asp_,
"d_nlp.lam+"+
str(
nx_),
"d->gLag_old",
true) <<
"\n";
1400 g << g.
axpy(
nx_,
"1.0",
"d_nlp.lam",
"d->gLag_old") <<
"\n";
1404 g.
comment(
"If linesearch failed enter elastic mode");
1405 g <<
"if (ls_success == 0 && ela_it == -1) {\n";
1406 g <<
"ela_it = 0;\n";
1414 const std::string& lbdz,
const std::string& ubdz,
1415 const std::string& A,
const std::string& x_opt,
const std::string& dlam,
int mode)
const {
1416 for (casadi_int i=0;i<
qpsol_.
n_in();++i) cg <<
"d->arg[" << i <<
"] = 0;\n";
1417 cg <<
"d->arg[" <<
CONIC_H <<
"] = " << H <<
";\n";
1418 cg <<
"d->arg[" <<
CONIC_G <<
"] = " << g <<
";\n";
1419 cg <<
"d->arg[" <<
CONIC_X0 <<
"] = " << x_opt <<
";\n";
1420 cg <<
"d->arg[" <<
CONIC_LAM_X0 <<
"] = " << dlam <<
";\n";
1421 cg <<
"d->arg[" <<
CONIC_LAM_A0 <<
"] = " << dlam <<
"+" <<
nx_ <<
";\n";
1422 cg <<
"d->arg[" <<
CONIC_LBX <<
"] = " << lbdz <<
";\n";
1423 cg <<
"d->arg[" <<
CONIC_UBX <<
"] = " << ubdz <<
";\n";
1424 cg <<
"d->arg[" <<
CONIC_A <<
"] = " << A <<
";\n";
1425 cg <<
"d->arg[" <<
CONIC_LBA <<
"] = " << lbdz <<
"+" <<
nx_ <<
";\n";
1426 cg <<
"d->arg[" <<
CONIC_UBA <<
"] = " << ubdz <<
"+" <<
nx_ <<
";\n";
1427 for (casadi_int i=0;i<
qpsol_.
n_out();++i) cg <<
"d->res[" << i <<
"] = 0;\n";
1428 cg <<
"d->res[" <<
CONIC_X <<
"] = " << x_opt <<
";\n";
1429 cg <<
"d->res[" <<
CONIC_LAM_X <<
"] = " << dlam <<
";\n";
1430 cg <<
"d->res[" <<
CONIC_LAM_A <<
"] = " << dlam <<
"+" <<
nx_ <<
";\n";
1431 std::string flag = cg(
qpsol_,
"d->arg",
"d->res",
"d->iw",
"d->w");
1432 cg <<
"ret = " << flag <<
";\n";
1433 cg <<
"if (ret == -1000) return -1000;\n";
1437 const std::string& g,
const std::string& lbdz,
const std::string& ubdz,
1438 const std::string& A,
const std::string& x_opt,
const std::string& dlam)
const {
1439 for (casadi_int i=0;i<
qpsol_ela_.
n_in();++i) cg <<
"d->arg[" << i <<
"] = 0;\n";
1440 cg <<
"d->arg[" <<
CONIC_H <<
"] = " << H <<
";\n";
1441 cg <<
"d->arg[" <<
CONIC_G <<
"] = " << g <<
";\n";
1442 cg <<
"d->arg[" <<
CONIC_X0 <<
"] = " << x_opt <<
";\n";
1443 cg <<
"d->arg[" <<
CONIC_LAM_X0 <<
"] = " << dlam <<
";\n";
1445 cg <<
"d->arg[" <<
CONIC_LBX <<
"] = " << lbdz <<
";\n";
1446 cg <<
"d->arg[" <<
CONIC_UBX <<
"] = " << ubdz <<
";\n";
1447 cg <<
"d->arg[" <<
CONIC_A <<
"] = " << A <<
";\n";
1448 cg <<
"d->arg[" <<
CONIC_LBA <<
"] = " << lbdz <<
"+" <<
nx_+2*
ng_ <<
";\n";
1449 cg <<
"d->arg[" <<
CONIC_UBA <<
"] = " << ubdz <<
"+" <<
nx_+2*
ng_ <<
";\n";
1450 for (casadi_int i=0;i<
qpsol_.
n_out();++i) cg <<
"d->res[" << i <<
"] = 0;\n";
1451 cg <<
"d->res[" <<
CONIC_X <<
"] = " << x_opt <<
";\n";
1452 cg <<
"d->res[" <<
CONIC_LAM_X <<
"] = " << dlam <<
";\n";
1454 std::string flag = cg(
qpsol_ela_,
"d->arg",
"d->res",
"d->iw",
"d->w");
1455 cg <<
"ret = " << flag <<
";\n";
1456 cg <<
"if (ret == -1000) return -1000;\n";
1460 cg <<
"double gamma = 0.;\n";
1462 if (mode == 0) cg <<
"ela_it++;\n";
1464 cg.
comment(
"Temp datastructs for data copy");
1465 cg <<
"double *temp_1, *temp_2;\n";
1467 cg.
comment(
"Make larger jacobian (has 2 extra diagonal matrices with -1 and 1 respectively)");
1468 cg <<
"temp_1 = d->Jk + " <<
Asp_.
nnz() <<
";\n";
1469 cg << cg.
fill(
"temp_1",
ng_,
"-1.") <<
";\n";
1470 cg <<
"temp_1 += " <<
ng_ <<
";\n";
1471 cg << cg.
fill(
"temp_1",
ng_,
"1.") <<
";\n";
1473 cg.
comment(
"Initialize bounds");
1474 cg <<
"temp_1 = d->lbdz + " <<
nx_ <<
";\n";
1475 cg <<
"temp_2 = d->lbdz + " <<
nx_ + 2*
ng_ <<
";\n";
1476 cg << cg.
copy(
"temp_1",
ng_,
"temp_2") <<
";\n";
1477 cg << cg.
clear(
"temp_1", 2*
ng_) <<
";\n";
1478 cg <<
"temp_1 = d->ubdz + " <<
nx_ <<
";\n";
1479 cg <<
"temp_2 = d->ubdz + " <<
nx_ + 2*
ng_ <<
";\n";
1480 cg << cg.
copy(
"temp_1",
ng_,
"temp_2") <<
";\n";
1483 cg <<
"if (ela_it > 1) {\n";
1484 cg <<
"gamma = pow(10, ela_it*(ela_it-1)/2)*gamma_1;\n";
1486 cg <<
"gamma = gamma_1;\n";
1488 cg <<
"if (gamma > " <<
gamma_max_ <<
") " <<
"return -1" <<
";\n";
1490 cg.
comment(
"Make larger gradient (has gamma for slack variables)");
1491 cg <<
"temp_1 = d->gf + " <<
nx_ <<
";\n";
1492 cg << cg.
fill(
"temp_1", 2*
ng_,
"gamma") <<
";\n";
1496 cg << cg.
copy(
"d_nlp.lam",
nx_,
"d->dlam") <<
"\n";
1501 cg.
comment(
"Make initial guess feasible on x values");
1502 cg <<
"for (casadi_int i = 0; i < " <<
nx_ <<
"; ++i) {\n";
1503 cg <<
"if (d->lbdz[i] > 0) d->dx[i] = d->lbdz[i];\n";
1504 cg <<
"else if (d->ubdz[i] < 0) d->dx[i] = d->ubdz[i];\n";
1507 cg.
comment(
"Make initial guess feasible on constraints by altering slack variables");
1508 cg << cg.
mv(
"d->Jk",
Asp_,
"d->dx",
"d->temp_mem",
false) <<
"\n";
1509 cg <<
"for (casadi_int i = 0; i < " <<
ng_ <<
"; ++i) {\n";
1510 cg <<
"if (d->ubdz[" <<
nx_+2*
ng_ <<
"+i]-d->temp_mem[i] < 0) {\n";
1511 cg <<
"d->dx[" <<
nx_ <<
"+i] = -d->ubdz[" <<
nx_+2*
ng_ <<
"+i]+d->temp_mem[i];\n";
1514 cg <<
"if (d->lbdz[" <<
nx_+2*
ng_ <<
"+i]-d->temp_mem[i] > 0) {\n";
1515 cg <<
"d->dx[" <<
nx_+
ng_ <<
"+i] = d->lbdz[" <<
nx_+2*
ng_ <<
"+i]-d->temp_mem[i];\n";
1523 cg.
comment(
"Copy constraint dlam to the right place");
1537 stats[
"iter_count"] = m->iter_count;
1542 int version = s.
version(
"Sqpmethod", 1, 3);
1582 s.
unpack(
"Sqpmethod::Hrsp", Hrsp);
1586 double convexify_margin;
1587 s.
unpack(
"Sqpmethod::convexify_margin", convexify_margin);
1588 char convexify_strategy;
1589 s.
unpack(
"Sqpmethod::convexify_strategy", convexify_strategy);
1590 casadi_assert(convexify_strategy==0,
"deserializtion failed.");
1592 s.
unpack(
"Sqpmethod::Hsp_project", Hsp_project);
1594 s.
unpack(
"Sqpmethod::scc_transform", scc_transform);
1595 std::vector<casadi_int> scc_offset;
1596 s.
unpack(
"Sqpmethod::scc_offset", scc_offset);
1597 std::vector<casadi_int> scc_mapping;
1598 s.
unpack(
"Sqpmethod::scc_mapping", scc_mapping);
1599 casadi_int max_iter_eig;
1600 s.
unpack(
"Sqpmethod::max_iter_eig", max_iter_eig);
1601 casadi_int block_size;
1602 s.
unpack(
"Sqpmethod::block_size", block_size);
1604 s.
unpack(
"Sqpmethod::scc_sp", scc_sp);
1611 set_sqpmethod_prob();
Helper class for C code generation.
std::string fill(const std::string &res, std::size_t n, const std::string &v)
Create a fill operation.
std::string axpy(casadi_int n, const std::string &a, const std::string &x, const std::string &y)
Codegen axpy: y += a*x.
std::string add_dependency(const Function &f)
Add a function dependency.
std::string copy(const std::string &arg, std::size_t n, const std::string &res)
Create a copy operation.
void comment(const std::string &s)
Write a comment line (ignored if not verbose)
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 sum_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
sum_viol
std::string mv(const std::string &x, const Sparsity &sp_x, const std::string &y, const std::string &z, bool tr)
Codegen sparse matrix-vector multiplication.
void local(const std::string &name, const std::string &type, const std::string &ref="")
Declare a local variable.
std::string norm_inf(casadi_int n, const std::string &x)
norm_inf
void init_local(const std::string &name, const std::string &def)
Specify the default value for a local variable.
std::string dot(casadi_int n, const std::string &x, const std::string &y)
Codegen inner product.
std::string max_viol(casadi_int n, const std::string &x, const std::string &lb, const std::string &ub)
max_viol
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)
std::string fmax(const std::string &x, const std::string &y)
fmax
std::string clear(const std::string &res, std::size_t n)
Create a fill operation.
void add_auxiliary(Auxiliary f, const std::vector< std::string > &inst={"casadi_real"})
Add a built-in auxiliary function.
static void serialize(SerializingStream &s, const std::string &prefix, const ConvexifyData &d)
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)
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
std::string codegen_mem(CodeGenerator &g, const std::string &index="mem") const
Get thread-local memory object.
size_t sz_w() const
Get required length of w field.
virtual Dict info() const
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
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.
void release(int mem) const
Release a memory object.
casadi_int n_out() const
Get the number of function outputs.
casadi_int n_in() const
Get the number of function inputs.
NLP solver storage class.
void codegen_body_exit(CodeGenerator &g) const override
Generate code for the function body.
Dict get_stats(void *mem) const override
Get all statistics.
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 init_mem(void *mem) const override
Initalize memory block.
casadi_nlpsol_prob< double > p_nlp_
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
int callback(NlpsolMemory *m) const
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.
void set_function(const Function &fcn, const std::string &fname, bool jit=false)
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.
bool has_function(const std::string &fname) const override
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
void print(const char *fmt,...) const
C-style formatted printing during evaluation.
int checkout() const
Checkout a memory object.
void * memory(int ind) const
Memory objects.
bool verbose_
Verbose printout.
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.
void enlarge(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
Enlarge matrix.
static Sparsity diag(casadi_int nrow)
Create diagonal sparsity pattern *.
static Sparsity dense(casadi_int nrow, casadi_int ncol=1)
Create a dense rectangular sparsity pattern *.
casadi_int nnz() const
Get the number of (structural) non-zeros.
void appendColumns(const Sparsity &sp)
Append another sparsity patten horizontally.
bool is_symmetric() const
Is symmetric?
void codegen_qp_ela_solve(CodeGenerator &cg, const std::string &H, const std::string &g, const std::string &lbdz, const std::string &ubdz, const std::string &A, const std::string &x_opt, const std::string &dlam) const
double calc_gamma_1(SqpmethodMemory *m) const
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Function qpsol_
QP solver for the subproblems.
bool init_feasible_
Initialize feasible qp's.
void print_iteration() const
Print iteration header.
casadi_int lbfgs_memory_
Memory size of L-BFGS method.
virtual int solve_QP(SqpmethodMemory *m, const double *H, const double *g, const double *lbdz, const double *ubdz, const double *A, double *x_opt, double *dlam, int mode) const
static Nlpsol * creator(const std::string &name, const Function &nlp)
Create a new NLP Solver.
virtual int solve_ela_QP(SqpmethodMemory *m, const double *H, const double *g, const double *lbdz, const double *ubdz, const double *A, double *x_opt, double *dlam) const
void codegen_qp_solve(CodeGenerator &cg, const std::string &H, const std::string &g, const std::string &lbdz, const std::string &ubdz, const std::string &A, const std::string &x_opt, const std::string &dlam, int mode) const
double gamma_0_
Initial and maximum penalty parameter for elastic mode.
bool elastic_mode_
Elastic mode.
int solve(void *mem) const override
casadi_sqpmethod_prob< double > p_
void set_work(void *mem, const double **&arg, double **&res, casadi_int *&iw, double *&w) const override
Set the (persistent) work vectors.
ConvexifyData convexify_data_
Data for convexification.
static const Options options_
Options.
virtual int solve_elastic_mode(SqpmethodMemory *m, casadi_int *ela_it, double gamma_1, casadi_int ls_iter, bool ls_success, bool so_succes, double pr_inf, double du_inf, double dx_norminf, std::string *info, int mode) const
void codegen_solve_elastic_mode(CodeGenerator &cg, int mode) const
Dict get_stats(void *mem) const override
Get all statistics.
int init_mem(void *mem) const override
Initalize memory block.
casadi_int merit_memsize_
void free_mem(void *mem) const override
Free memory block.
double min_step_size_
Minimum step size allowed.
casadi_int max_iter_
Maximum, minimum number of SQP iterations.
bool convexify_
convexify?
bool exact_hessian_
Exact Hessian?
void codegen_body(CodeGenerator &g) const override
Generate code for the function body.
void codegen_calc_gamma_1(CodeGenerator &cg) const
void init(const Dict &opts) override
Initialize.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
static const std::string meta_doc
A documentation string.
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
Sqpmethod(const std::string &name, const Function &nlp)
Function qpsol_ela_
QP solver for elastic mode subproblems.
double tol_pr_
Tolerance of primal and dual infeasibility.
Function conic(const std::string &name, const std::string &solver, const SpDict &qp, const Dict &opts)
T1 casadi_max_viol(casadi_int n, const T1 *x, const T1 *lb, const T1 *ub)
Largest bound violation.
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_LBA
dense, (nc x 1)
@ CONIC_UBX
dense, (n x 1)
@ CONIC_LBX
dense, (n x 1)
T1 casadi_bilin(const T1 *A, const casadi_int *sp_A, const T1 *x, const T1 *y)
T1 casadi_sum_viol(casadi_int n, const T1 *x, const T1 *lb, const T1 *ub)
Sum of bound violations.
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::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
int CASADI_NLPSOL_SQPMETHOD_EXPORT casadi_register_nlpsol_sqpmethod(Nlpsol::Plugin *plugin)
T1 casadi_dot(casadi_int n, const T1 *x, const T1 *y)
Inner product.
const double nan
Not a number.
void casadi_scal(casadi_int n, T1 alpha, T1 *x)
SCAL: x <- alpha*x.
void casadi_axpy(casadi_int n, T1 alpha, const T1 *x, T1 *y)
AXPY: y <- a*x + y.
void CASADI_NLPSOL_SQPMETHOD_EXPORT casadi_load_nlpsol_sqpmethod()
T1 casadi_norm_inf(casadi_int n, const T1 *x)
void casadi_clear(T1 *x, casadi_int n)
CLEAR: x <- 0.
void casadi_mv(const T1 *x, const casadi_int *sp_x, const T1 *y, T1 *z, casadi_int tr)
Sparse matrix-vector multiplication: z <- z + x*y.
@ CONIC_X
The primal solution.
@ CONIC_LAM_A
The dual solution corresponding to linear bounds.
@ CONIC_COST
The optimal cost.
@ CONIC_LAM_X
The dual solution corresponding to simple bounds.
casadi_convexify_config< double > config
casadi_nlpsol_data< double > d_nlp
Options metadata for a class.
std::map< std::string, FStats > fstats
void add_stat(const std::string &s)
int iter_count
Iteration count.
const char * return_status
Last return status.
casadi_sqpmethod_data< double > d
double reg
Hessian regularization.
const casadi_nlpsol_prob< T1 > * nlp