51 p->
dmin = std::numeric_limits<T1>::min();
52 p->
inf = std::numeric_limits<T1>::infinity();
76 IPQP_SOLVE} casadi_ipqp_task_t;
85 IPQP_CORRECTOR} casadi_ipqp_next_t;
142 template<
typename T1>
169 template<
typename T1>
173 d->
lbz = *w; *w += p->
nz;
174 d->
ubz = *w; *w += p->
nz;
175 d->
z = *w; *w += p->
nz;
176 d->
lam = *w; *w += p->
nz;
179 d->
dz = *w; *w += p->
nz;
180 d->
dlam = *w; *w += p->
nz;
183 d->
rz = *w; *w += p->
nz;
184 d->
rlam = *w; *w += p->
nz;
187 d->
D = *w; *w += p->
nz;
188 d->
S = *w; *w += p->
nz;
192 d->
next = IPQP_RESET;
196 template<
typename T1>
198 const T1* lbx,
const T1* ubx,
const T1* lba,
const T1* uba) {
204 casadi_copy(lbx, p->
nx, d->
lbz);
205 casadi_copy(lba, p->
na, d->
lbz + p->
nx);
206 casadi_copy(ubx, p->
nx, d->
ubz);
207 casadi_copy(uba, p->
na, d->
ubz + p->
nx);
211 template<
typename T1>
213 const T1* x0,
const T1* lam_x0,
const T1* lam_a0) {
217 casadi_copy(x0, p->
nx, d->
z);
218 casadi_fill(d->
z + p->
nx, p->
na, 0.);
219 casadi_copy(lam_x0, p->
nx, d->
lam);
220 casadi_copy(lam_a0, p->
na, d->
lam + p->
nx);
226 template<
typename T1>
237 for (k = p->
nx; k < p->nz; ++k) d->
z[k] = 0;
239 for (k = 0; k < p->
nz; ++k) {
240 if (d->
lbz[k] > -p->
inf) {
243 mid = .5 * (d->
lbz[k] + d->
ubz[k]);
246 d->
z[k] = fmin(fmax(d->
z[k], d->
lbz[k] + margin), mid);
247 }
else if (d->
z[k] > mid) {
248 d->
z[k] = fmax(fmin(d->
z[k], d->
ubz[k] - margin), mid);
257 d->
z[k] = fmax(d->
z[k], d->
lbz[k] + margin);
264 d->
z[k] = fmin(d->
z[k], d->
ubz[k] - margin);
271 casadi_clear(d->
rz, p->
nz);
280 template<
typename T1>
286 for (k = 0; k < p->
nx; ++k) {
296 for (; k < p->
nz; ++k) {
300 }
else if (d->
ubz[k] <= d->
lbz[k] + p->
dmin) {
309 for (k = 0; k < p->
nz; ++k) {
316 d->
S[k] = fmin(1., std::sqrt(1. / d->
D[k]));
317 d->
D[k] = fmin(1., d->
D[k]);
323 template<
typename T1>
335 d->
status = IPQP_MAX_ITER;
347 template<
typename T1>
354 casadi_axpy(p->
nx, 1., d->
g, d->
rz);
355 for (k = 0; k < p->
nx; ++k) {
358 d->
lam[k] = -d->
rz[k];
362 d->
rz[k] += d->
lam[k];
368 for (k = p->
nx; k < p->nz; ++k) {
375 if (d->
rz[k] + d->
pr < d->
lbz[k]) {
378 }
else if (d->
rz[k] - d->
pr > d->
ubz[k]) {
387 for (k = 0; k < p->
nx; ++k) {
388 if (fabs(d->
rz[k]) > d->
du) {
389 d->
du = fabs(d->
rz[k]);
394 casadi_axpy(p->
na, -1., d->
z + p->
nx, d->
rz + p->
nx);
396 for (k = 0; k < p->
nz; ++k) {
411 for (k = 0; k < p->
nz; ++k) {
415 bdiff = d->
z[k] - d->
lbz[k];
419 viol = bdiff * fmax(-d->
lam[k], 0.);
432 bdiff = d->
ubz[k] - d->
z[k];
436 viol = bdiff * fmax(d->
lam[k], 0.);
452 template<
typename T1>
462 for (k=0; k<p->
nx; ++k) d->
dz[k] += d->
rz[k];
464 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] = d->
dz[k];
466 for (k=p->
nx; k<p->nz; ++k) {
471 d->
dz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
472 d->
dz[k] += d->
rz[k];
476 for (k=0; k<p->
nz; ++k) d->
dz[k] *= -d->
S[k];
481 for (k=0; k<p->
nx; ++k) d->
dlam[k] = d->
rlam[k];
487 template<
typename T1>
491 casadi_int k, blocking_k;
500 for (k=0; k<p->
nz; ++k) {
501 if (d->
dz[k] < 0 && d->
lbz[k] > -p->
inf) {
502 if ((test = (d->
lbz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
505 flag = IPQP_PRIMAL | IPQP_LOWER;
508 if (d->
dz[k] > 0 && d->
ubz[k] < p->
inf) {
509 if ((test = (d->
ubz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
512 flag = IPQP_PRIMAL | IPQP_UPPER;
517 for (k=0; k<p->
nz; ++k) {
522 flag = IPQP_DUAL | IPQP_LOWER;
529 flag = IPQP_DUAL | IPQP_UPPER;
534 if (ind) *ind = blocking_k;
539 template<
typename T1>
546 for (k=0; k<p->
nz; ++k) d->
dz[k] *= d->
S[k];
548 for (k=p->
nx; k<p->nz; ++k) {
551 d->
dlam[k] = d->
dz[k] = 0;
553 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
dz[k] - d->
dlam[k]);
559 for (k=0; k<p->
nz; ++k) {
563 for (k=0; k<p->
nz; ++k) {
570 (
void)casadi_ipqp_maxstep(d, &alpha, 0);
572 sigma = casadi_ipqp_sigma(d, alpha);
574 casadi_ipqp_corrector_prepare(d, -sigma * d->
mu);
580 template<
typename T1>
586 for (k=0; k<p->
nz; ++k) d->
z[k] += alpha_pr * d->
dz[k];
588 for (k=0; k<p->
nz; ++k) d->
lam[k] += alpha_du * d->
dlam[k];
594 template<
typename T1>
601 if (d->
n_con == 0)
return 0;
604 for (k = 0; k < p->
nz; ++k) {
608 * (d->
z[k] - d->
lbz[k] + alpha * d->
dz[k]);
613 * (d->
ubz[k] - d->
z[k] - alpha * d->
dz[k]);
622 template<
typename T1>
627 if (d->
n_con == 0)
return 0;
629 sigma = casadi_ipqp_mu(d, alpha);
632 sigma *= sigma * sigma;
637 template<
typename T1>
646 for (k=0; k<p->
nz; ++k)
650 for (k=p->
nx; k<p->nz; ++k) {
653 d->
rlam[k] = d->
rz[k] = 0;
656 d->
rz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
660 for (k=0; k<p->
nz; ++k) d->
rz[k] *= -d->
S[k];
664 template<
typename T1>
667 T1 t, mu_test, primal_slack, primal_step, dual_slack, dual_step, max_tau;
672 for (k=0; k<p->
nz; ++k) d->
rz[k] *= d->
S[k];
674 for (k=p->
nx; k<p->nz; ++k) {
677 d->
rlam[k] = d->
rz[k] = 0;
679 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
rz[k] - d->
rlam[k]);
685 for (k=0; k<p->
nz; ++k) d->
dz[k] += d->
rz[k];
686 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] += d->
rlam[k];
688 for (k=0; k<p->
nz; ++k) {
691 if (k<p->nx) d->
dlam[k] -= t;
694 for (k=0; k<p->
nz; ++k) {
697 if (k<p->nx) d->
dlam[k] += t;
700 flag = casadi_ipqp_maxstep(d, &max_tau, &k);
702 if (flag == IPQP_NONE) {
707 mu_test = casadi_ipqp_mu(d, max_tau);
709 if (flag & IPQP_UPPER) {
710 primal_slack = d->
ubz[k] - d->
z[k];
711 primal_step = -d->
dz[k];
715 primal_slack = d->
z[k] - d->
lbz[k];
716 primal_step = d->
dz[k];
721 if (flag & IPQP_PRIMAL) {
722 d->
tau = (0.01 * mu_test / (dual_slack + max_tau * dual_step)
723 - primal_slack) / primal_step;
725 d->
tau = (0.01 * mu_test / (primal_slack + max_tau * primal_step)
726 - dual_slack) / dual_step;
728 d->
tau = fmax(d->
tau, 0.99 * max_tau);
731 casadi_ipqp_step(d, d->
tau, d->
tau);
733 casadi_clear(d->
rz, p->
nz);
737 template<
typename T1>
741 casadi_ipqp_reset(d);
743 d->
next = IPQP_RESIDUAL;
747 if (d->
status == IPQP_MV_ERROR)
break;
748 casadi_ipqp_residual(d);
749 d->
task = IPQP_PROGRESS;
750 d->
next = IPQP_NEWITER;
754 if (d->
status == IPQP_PROGRESS_ERROR)
break;
755 if (casadi_ipqp_newiter(d))
break;
756 d->
task = IPQP_FACTOR;
757 d->
next = IPQP_PREPARE;
761 if (d->
status == IPQP_FACTOR_ERROR)
break;
762 casadi_ipqp_predictor_prepare(d);
763 d->
task = IPQP_SOLVE;
764 d->
next = IPQP_PREDICTOR;
768 if (d->
status == IPQP_SOLVE_ERROR)
break;
769 casadi_ipqp_predictor(d);
770 d->
task = IPQP_SOLVE;
771 d->
next = IPQP_CORRECTOR;
775 if (d->
status == IPQP_SOLVE_ERROR)
break;
776 casadi_ipqp_corrector(d);
778 d->
next = IPQP_RESIDUAL;
784 d->
next = IPQP_RESET;
790 const char* casadi_ipqp_return_status(casadi_ipqp_flag_t status) {
792 case IPQP_SUCCESS:
return "success";
793 case IPQP_MAX_ITER:
return "Maximum number of iterations reached";
794 case IPQP_NO_SEARCH_DIR:
return "Failed to calculate search direction";
795 case IPQP_MV_ERROR:
return "Matrix-vector evaluation error";
796 case IPQP_FACTOR_ERROR:
return "Linear solver factorization error";
797 case IPQP_SOLVE_ERROR:
return "Linear solver solution error";
798 case IPQP_PROGRESS_ERROR:
return "Printing error";
804 template<
typename T1>
809 casadi_copy(d->
z, p->
nx, x);
810 casadi_copy(d->
lam, p->
nx, lam_x);
811 casadi_copy(d->
lam + p->
nx, p->
na, lam_a);
815 template<
typename T1>
817 #ifdef CASADI_SNPRINTF
820 flag = CASADI_SNPRINTF(buf, buf_sz,
"%5s %9s %9s %5s %9s %5s "
822 "Iter",
"mu",
"|pr|",
"con",
"|du|",
"var",
"|co|",
"con",
826 d->
status = IPQP_PROGRESS_ERROR;
830 if (buf_sz) buf[0] =
'\0';
837 template<
typename T1>
839 #ifdef CASADI_SNPRINTF
842 flag = CASADI_SNPRINTF(buf, buf_sz,
843 "%5d %9.2g %9.2g %5d %9.2g %5d %9.2g %5d %9.2g ",
844 static_cast<int>(d->
iter), d->
mu,
845 d->
pr,
static_cast<int>(d->
ipr),
846 d->
du,
static_cast<int>(d->
idu),
847 d->
co,
static_cast<int>(d->
ico),
851 d->
status = IPQP_PROGRESS_ERROR;
859 flag = CASADI_SNPRINTF(buf, buf_sz,
"%s", d->
msg);
862 d->
status = IPQP_PROGRESS_ERROR;
867 if (buf_sz) buf[0] =
'\0';
const casadi_ipqp_prob< T1 > * prob
casadi_ipqp_flag_t status