54 p->
dmin = std::numeric_limits<T1>::min();
55 p->
inf = std::numeric_limits<T1>::infinity();
113 template<
typename T1>
115 casadi_int* sz_iw, casadi_int* sz_w) {
117 casadi_int nnz_a, nnz_kkt, nnz_v, nnz_r;
118 casadi_qp_work(p->
qp, sz_arg, sz_res, sz_iw, sz_w);
120 nnz_a = p->
qp->sp_a[2+p->
qp->sp_a[1]];
125 *sz_w = casadi_max(*sz_w, p->
qp->nz);
126 *sz_iw = casadi_max(*sz_iw, p->
qp->nz);
127 *sz_w = casadi_max(*sz_w, 2*p->
qp->nz);
136 *sz_w += casadi_max(nnz_v+nnz_r, nnz_kkt);
149 template<
typename T1>
152 casadi_int nnz_a, nnz_kkt, nnz_v, nnz_r;
155 nnz_a = p->
qp->sp_a[2+p->
qp->sp_a[1]];
159 d->
nz_kkt = *w; *w += nnz_kkt;
160 d->
z = *w; *w += p->
qp->nz;
161 d->
lbz = *w; *w += p->
qp->nz;
162 d->
ubz = *w; *w += p->
qp->nz;
163 d->
lam = *w; *w += p->
qp->nz;
164 d->
dz = *w; *w += p->
qp->nz;
165 d->
dlam = *w; *w += p->
qp->nz;
166 d->
nz_v = *w; *w += casadi_max(nnz_v+nnz_r, nnz_kkt);
167 d->
beta = *w; *w += p->
qp->nz;
168 d->
nz_at = *w; *w += nnz_a;
171 d->
sens = *w; *w += p->
qp->nz;
183 template<
typename T1>
193 for (i=0; i<p->
qp->nz; ++i) {
225 template<
typename T1>
232 for (i=0; i<p->
qp->nz; ++i) {
233 if (d->
z[i] > d->
ubz[i]+d->
pr) {
234 d->
pr = d->
z[i]-d->
ubz[i];
236 }
else if (d->
z[i] < d->
lbz[i]-d->
pr) {
237 d->
pr = d->
lbz[i]-d->
z[i];
244 template<
typename T1>
251 for (i=0; i<p->
qp->nx; ++i) {
263 template<
typename T1>
268 const casadi_int *at_colind, *at_row;
271 at_colind = p->
sp_at + 2;
272 at_row = at_colind + p->
qp->na + 1;
278 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
279 new_du = fmax(new_du, fabs(d->
infeas[at_row[k]]-d->
nz_at[k]*d->
lam[i]));
282 return new_du <= d->
du;
286 template<
typename T1>
296 for (i = 0; i < p->
qp->nz; ++i) {
298 if (d->
sens[i] == 0.)
continue;
300 if (d->
lam[i] == 0) {
302 s = d->
sens[i] > 0 ? 1 : -1;
311 if (d->
lam[i] > 0. ? d->
sens[i] > 0. : d->
sens[i] < 0.)
continue;
313 if (!casadi_qrqp_du_check(d, i))
continue;
316 if (fabs(d->
sens[i]) > best_sens) {
317 best_sens = fabs(d->
sens[i]);
325 d->
msg =
"Enforced ubz to reduce |du|";
326 }
else if (d->
sign < 0) {
327 d->
msg =
"Enforced lbz to reduce |du|";
329 d->
msg =
"Dropped ubz to reduce |du|";
331 d->
msg =
"Dropped lbz to reduce |du|";
338 template<
typename T1>
341 if (d->
lam[d->
ipr] == 0.) {
345 d->
msg =
"Added lbz to reduce |pr|";
348 d->
msg =
"Added ubz to reduce |pr|";
359 template<
typename T1>
363 const casadi_int *h_colind, *h_row, *a_colind, *a_row, *at_colind, *at_row,
364 *kkt_colind, *kkt_row;
367 a_row = (a_colind = p->
qp->sp_a+2) + p->
qp->nx + 1;
368 at_row = (at_colind = p->
sp_at+2) + p->
qp->na + 1;
369 h_row = (h_colind = p->
qp->sp_h+2) + p->
qp->nx + 1;
370 kkt_row = (kkt_colind = p->
sp_kkt+2) + p->
qp->nz + 1;
372 casadi_clear(d->
w, p->
qp->nz);
374 for (i=0; i<p->
qp->nz; ++i) {
378 for (k=h_colind[i]; k<h_colind[i+1]; ++k) d->
w[h_row[k]] = d->
qp->h[k];
379 for (k=a_colind[i]; k<a_colind[i+1]; ++k) d->
w[p->
qp->nx+a_row[k]] = d->
qp->a[k];
387 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
388 d->
w[at_row[k]] = d->
nz_at[k];
393 for (k=kkt_colind[i]; k<kkt_colind[i+1]; ++k) {
394 d->
nz_kkt[k] = d->
w[kkt_row[k]];
395 d->
w[kkt_row[k]] = 0;
401 template<
typename T1>
405 const casadi_int *h_colind, *h_row, *a_colind, *a_row, *at_colind, *at_row;
408 a_row = (a_colind = p->
qp->sp_a+2) + p->
qp->nx + 1;
409 at_row = (at_colind = p->
sp_at+2) + p->
qp->na + 1;
410 h_row = (h_colind = p->
qp->sp_h+2) + p->
qp->nx + 1;
412 casadi_clear(kkt_i, p->
qp->nz);
415 for (k=h_colind[i]; k<h_colind[i+1]; ++k) kkt_i[h_row[k]] = d->
qp->h[k];
416 for (k=a_colind[i]; k<a_colind[i+1]; ++k) kkt_i[p->
qp->nx+a_row[k]] = d->
qp->a[k];
418 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
419 kkt_i[at_row[k]] = -d->
nz_at[k];
427 template<
typename T1>
431 const casadi_int *h_colind, *h_row, *a_colind, *a_row, *at_colind, *at_row;
435 a_row = (a_colind = p->
qp->sp_a + 2) + p->
qp->nx + 1;
436 at_row = (at_colind = p->
sp_at + 2) + p->
qp->na + 1;
437 h_row = (h_colind = p->
qp->sp_h + 2) + p->
qp->nx + 1;
442 for (k=h_colind[i]; k<h_colind[i+1]; ++k) r -= v[h_row[k]] * d->
qp->h[k];
443 for (k=a_colind[i]; k<a_colind[i+1]; ++k) r -= v[p->
qp->nx+a_row[k]] * d->
qp->a[k];
445 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
446 r += v[at_row[k]] * d->
nz_at[k];
453 template<
typename T1>
457 for (i=0; i<p->
qp->nz; ++i) {
459 r[i] = d->
ubz[i]-d->
z[i];
460 }
else if (d->
lam[i]<0.) {
461 r[i] = d->
lbz[i]-d->
z[i];
462 }
else if (i<p->qp->nx) {
471 template<
typename T1>
478 for (i = 0; i < p->
qp->nz; ++i) {
479 if (d->
dz[i] < -dz_max && d->
lbz[i] - d->
z[i] >= d->
epr) {
483 d->
msg =
"lbz violated with zero step";
485 }
else if (d->
dz[i] > dz_max && d->
z[i] - d->
ubz[i] >= d->
epr) {
489 d->
msg =
"ubz violated with zero step";
497 template<
typename T1>
504 if (casadi_qrqp_zero_blocking(d)) {
509 for (i = 0; i < p->
qp->nz; ++i) {
510 if (d->
dz[i] == 0.)
continue;
512 trial_z = d->
z[i] + d->
tau * d->
dz[i];
513 if (d->
dz[i] < 0 && trial_z < d->lbz[i] - d->
epr) {
518 d->
msg =
"Enforcing lbz";
520 }
else if (d->
dz[i] > 0 && trial_z > d->
ubz[i] + d->
epr) {
525 d->
msg =
"Enforcing ubz";
528 if (d->
tau <= 0)
return;
533 template<
typename T1>
535 casadi_int* ind_list, T1 tau) {
537 casadi_int i, n_tau, loc, next_ind, tmp_ind, j;
538 T1 trial_lam, new_tau, next_tau, tmp_tau;
545 for (i=0; i<p->
qp->nz; ++i) {
546 if (d->
dlam[i]==0.)
continue;
547 if (d->
lam[i]==0.)
continue;
549 trial_lam = d->
lam[i] + tau*d->
dlam[i];
551 if (d->
lam[i]>0 ? trial_lam>=0 : trial_lam<=0)
continue;
553 new_tau = -d->
lam[i]/d->
dlam[i];
555 for (loc=0; loc<n_tau-1; ++loc) {
556 if (new_tau<tau_list[loc])
break;
562 for (j=loc; j<n_tau; ++j) {
563 tmp_tau = tau_list[j];
564 tau_list[j] = next_tau;
566 tmp_ind = ind_list[j];
567 ind_list[j] = next_ind;
575 template<
typename T1>
578 casadi_int i, n_tau, j, k, du_index;
579 T1 tau_k, dtau, new_infeas, tau1, infeas, tinfeas;
580 const casadi_int *at_colind, *at_row;
583 at_row = (at_colind = p->
sp_at+2) + p->
qp->na + 1;
585 n_tau = casadi_qrqp_dual_breakpoints(d, d->
w, d->
iw, d->
tau);
590 for (j=0; j<n_tau; ++j) {
592 dtau = d->
w[j] - tau_k;
594 for (k=0; k<p->
qp->nx; ++k) {
599 if (fabs(tinfeas)<1e-14) {
602 }
else if (tinfeas<0) {
608 new_infeas = infeas + dtau*tinfeas;
610 if (new_infeas > d->
edu) {
612 tau1 = fmax(tau_k, tau_k + (d->
edu - infeas)/tinfeas);
623 if (du_index>=0)
return du_index;
637 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
647 template<
typename T1>
653 for (i=0; i<p->
qp->nz; ++i) d->
iw[i] = d->
lam[i]>0. ? 1 : d->
lam[i]<0 ? -1 : 0;
655 casadi_axpy(p->
qp->nz, d->
tau, d->
dz, d->
z);
658 for (i=0; i<p->
qp->nz; ++i) {
665 case -1: d->
lam[i] = fmin(d->
lam[i], -p->
dmin);
break;
666 case 1: d->
lam[i] = fmax(d->
lam[i], p->
dmin);
break;
667 case 0: d->
lam[i] = 0.;
break;
673 template<
typename T1>
677 casadi_qrqp_kkt_vector(d, d->
dlam, d->
index);
679 if (d->
sign == 0) casadi_scal(p->
qp->nz, -1., d->
dlam);
684 if (fabs(d->
dlam[d->
index]-1.) >= 1e-12)
return 0;
686 casadi_clear(d->
dz, p->
qp->nz);
691 casadi_scal(p->
qp->nz, 1./sqrt(casadi_dot(p->
qp->nz, d->
dlam, d->
dlam)), d->
dlam);
692 casadi_scal(p->
qp->nz, 1./sqrt(casadi_dot(p->
qp->nz, d->
dz, d->
dz)), d->
dz);
698 template<
typename T1>
716 template<
typename T1>
722 casadi_clear(d->
dlam, p->
qp->nx);
723 casadi_mv(d->
qp->h, p->
qp->sp_h, d->
dz, d->
dlam, 0);
724 casadi_mv(d->
qp->a, p->
qp->sp_a, d->
dz + p->
qp->nx, d->
dlam, 1);
726 casadi_scal(p->
qp->nx, -1., d->
dlam);
728 for (i = 0; i < p->
qp->nx; ++i)
if (d->
lam[i] == 0.) d->
dlam[i] = 0.;
730 casadi_copy(d->
dz+p->
qp->nx, p->
qp->na, d->
dlam + p->
qp->nx);
732 casadi_clear(d->
dz + p->
qp->nx, p->
qp->na);
733 casadi_mv(d->
qp->a, p->
qp->sp_a, d->
dz, d->
dz + p->
qp->nx, 0);
735 for (i = 0; i < p->
qp->nz; ++i)
if (fabs(d->
dz[i]) < 1e-14) d->
dz[i] = 0.;
744 template<
typename T1>
748 for (i=0; i<p->
qp->nz; ++i) {
749 if (d->
lbz[i] - d->
z[i] >= d->
epr) {
751 if (d->
dz[i] < 0 || d->
dlam[i] > 0)
return 1;
752 }
else if (d->
z[i] - d->
ubz[i] >= d->
epr) {
754 if (d->
dz[i] > 0 || d->
dlam[i] < 0)
return 1;
761 template<
typename T1>
765 for (i=0; i<p->
qp->nx; ++i) {
777 template<
typename T1>
781 const casadi_int *at_colind, *at_row;
784 if (fabs(d->
infeas[i]) < d->
edu)
return 1;
786 at_colind = p->
sp_at + 2;
787 at_row = at_colind + p->
qp->na + 1;
790 return (s < 0) == (d->
infeas[i] > 0);
792 for (k=at_colind[i-p->
qp->nx]; k<at_colind[i-p->
qp->nx+1]; ++k) {
793 if (d->
nz_at[k] > 0) {
794 if ((s > 0) == (d->
infeas[at_row[k]] > 0))
return 0;
795 }
else if (d->
nz_at[k] < 0) {
796 if ((s < 0) == (d->
infeas[at_row[k]] > 0))
return 0;
805 template<
typename T1>
809 casadi_int nnz_kkt, nk, k, i, best_k, best_neg, neg;
812 for (i = 0; i < p->
qp->nz; ++i) d->
lincomb[i] = 0;
813 for (k = 0; k < d->
sing; ++k) {
817 for (i = 0; i < p->
qp->nz; ++i)
if (fabs(d->
dlam[i]) >= 1e-12) d->
lincomb[i]++;
831 nk = casadi_qr_singular(
static_cast<T1*
>(0), 0, d->
nz_r, p->
sp_r, p->
pc, 1e-12);
834 best_k = best_neg = -1;
836 for (k=0; k<nk; ++k) {
839 casadi_qr_colcomb(d->
dz, d->
nz_r, p->
sp_r, p->
pc, 1e-12, k);
842 for (i=0; i<p->
qp->nz; ++i) {
843 d->
iw[i] = d->
lincomb[i] && fabs(casadi_qrqp_kkt_dot(d, d->
dz, i)) > 1e-12;
846 casadi_qrqp_expand_step(d);
848 for (neg = 0; neg < 2; ++neg) {
851 casadi_scal(p->
qp->nz, -1., d->
dz);
852 casadi_scal(p->
qp->nz, -1., d->
dlam);
856 if (casadi_qrqp_pr_direction(d))
continue;
858 if (casadi_qrqp_du_direction(d))
continue;
860 for (i=0; i<p->
qp->nz; ++i) {
862 if (!d->
iw[i])
continue;
865 if (d->
z[i] <= d->
ubz[i] && (d->
z[i] >= d->
lbz[i] ?
866 d->
dz[i] < -1e-12 : d->
dz[i] > 1e-12)) {
869 && (tau_test = (d->
lbz[i] - d->
z[i]) / d->
dz[i]) < tau
870 && casadi_qrqp_enforceable(d, i, -1)) {
877 }
else if (d->
z[i] >= d->
lbz[i] && (d->
z[i] <= d->
ubz[i] ?
878 d->
dz[i] > 1e-12 : d->
dz[i] < -1e-12)) {
881 && (tau_test = (d->
ubz[i] - d->
z[i]) / d->
dz[i]) < tau
882 && casadi_qrqp_enforceable(d, i, 1)) {
892 if (d->
lam[i] > 0 ? d->
dlam[i] < -1e-12 : d->
dlam[i] > 1e-12) {
893 if ((tau_test = -d->
lam[i] / d->
dlam[i]) < tau) {
910 casadi_qr_colcomb(d->
dz, d->
nz_r, p->
sp_r, p->
pc, 1e-12, best_k);
911 casadi_qrqp_expand_step(d);
912 if (best_neg) tau *= -1;
913 }
else if (--neg != best_neg) {
918 casadi_scal(p->
qp->nz, tau, d->
dz);
919 casadi_scal(p->
qp->nz, tau, d->
dlam);
925 template<
typename T1>
933 if (d->
sing)
return casadi_qrqp_singular_step(d);
935 casadi_qrqp_kkt_residual(d, d->
dz);
940 casadi_qrqp_expand_step(d);
946 template<
typename T1>
951 casadi_clear(d->
sens, p->
qp->nz);
954 casadi_mv(d->
qp->a, p->
qp->sp_a, d->
sens, d->
sens + p->
qp->nx, 0);
959 template<
typename T1>
966 d->
f = casadi_bilin(d->
qp->h, p->
qp->sp_h, d->
z, d->
z)/2.
967 + casadi_dot(p->
qp->nx, d->
z, d->
qp->g);
969 casadi_clear(d->
z+p->
qp->nx, p->
qp->na);
970 casadi_mv(d->
qp->a, p->
qp->sp_a, d->
z, d->
z+p->
qp->nx, 0);
973 casadi_mv(d->
qp->h, p->
qp->sp_h, d->
z, d->
infeas, 0);
976 for (i=0; i<p->
qp->nx; ++i) {
978 if (d->
lam[i]==0)
continue;
983 d->
lam[i] = r==0 ? p->
dmin : r;
989 d->
lam[i] = r==0 ? -p->
dmin : r;
1004 casadi_qrqp_calc_sens(d, d->
idu);
1008 template<
typename T1>
1011 casadi_int du_index;
1017 casadi_qrqp_primal_blocking(d);
1019 du_index = casadi_qrqp_dual_blocking(d);
1021 casadi_qrqp_take_step(d);
1023 if (du_index >= 0) {
1025 casadi_qrqp_calc_sens(d, du_index);
1027 casadi_qrqp_du_index(d);
1032 template<
typename T1>
1038 if (d->
r_sign != 0 || casadi_qrqp_du_check(d, d->
r_index)) {
1042 d->
msg =
"Enforced ubz for regularity";
1043 }
else if (d->
sign < 0) {
1044 d->
msg =
"Enforced lbz for regularity";
1046 d->
msg =
"Dropped ubz for regularity";
1048 d->
msg =
"Dropped lbz for regularity";
1066 if (d->
index >= 0) {
1072 casadi_qrqp_calc_dependent(d);
1077 template<
typename T1>
1082 casadi_qrqp_calc_dependent(d);
1084 casadi_qrqp_flip(d);
1086 casadi_qrqp_factorize(d);
1090 d->
msg =
"Converged";
1095 d->
msg =
"Max iter";
1098 }
else if (!d->
sing && d->
ipr < 0 && d->
idu < 0) {
1100 d->
msg =
"No primal or dual error";
1110 template<
typename T1>
1117 if (casadi_qrqp_calc_step(d)) {
1118 d->
status = QP_NO_SEARCH_DIR;
1122 casadi_qrqp_linesearch(d);
1128 template<
typename T1>
1130 #ifdef CASADI_SNPRINTF
1133 flag = CASADI_SNPRINTF(buf, buf_sz,
"%5s %5s %9s %9s %5s %9s %5s %9s %5s %9s %4s",
1134 "Iter",
"Sing",
"fk",
"|pr|",
"con",
"|du|",
"var",
1135 "min_R",
"con",
"last_tau",
"Note");
1138 d->
status = QP_PRINTING_ERROR;
1142 if (buf_sz) buf[0] =
'\0';
1149 template<
typename T1>
1150 int casadi_qrqp_print_colcomb(
casadi_qrqp_data<T1>* d,
char* buf,
size_t buf_sz, casadi_int j) {
1151 #ifdef CASADI_SNPRINTF
1152 casadi_int num_size, n_print, i, k, buf_offset, val;
1165 if (buf_sz<=4)
return 1;
1170 n_print = (buf_sz-4)/num_size;
1173 for (b=0;b<buf_sz;++b) buf[b]=
' ';
1176 for (i=0;i<p->
qp->nz;++i) {
1177 if (fabs(d->
dlam[i]) >= 1e-12) {
1179 buf[buf_sz-4] =
'.';
1180 buf[buf_sz-3] =
'.';
1181 buf[buf_sz-2] =
'.';
1182 buf[buf_sz-1] =
'\0';
1186 CASADI_SNPRINTF(buf+buf_offset, num_size,
"%d",
static_cast<int>(i));
1188 for (k=0;k<num_size;++k) {
1189 if (buf[buf_offset+k]==
'\0') buf[buf_offset+k] =
' ';
1191 buf_offset += num_size;
1194 buf[buf_sz-1] =
'\0';
1196 if (buf_sz) buf[0] =
'\0';
1203 template<
typename T1>
1205 #ifdef CASADI_SNPRINTF
1208 flag = CASADI_SNPRINTF(buf, buf_sz,
1209 "%5d %5d %9.2g %9.2g %5d %9.2g %5d %9.2g %5d %9.2g ",
1210 static_cast<int>(d->
iter),
static_cast<int>(d->
sing), d->
f, d->
pr,
1211 static_cast<int>(d->
ipr), d->
du,
static_cast<int>(d->
idu),
1215 d->
status = QP_PRINTING_ERROR;
1224 flag = CASADI_SNPRINTF(buf, buf_sz,
"%s, i=%d", d->
msg,
static_cast<int>(d->
msg_ind));
1226 flag = CASADI_SNPRINTF(buf, buf_sz,
"%s", d->
msg);
1230 d->
status = QP_PRINTING_ERROR;
1235 if (buf_sz) buf[0] =
'\0';
casadi_qp_data< T1 > * qp
casadi_qrqp_flag_t status
const casadi_qrqp_prob< T1 > * prob
const casadi_qp_prob< T1 > * qp
const casadi_int * sp_kkt