48 p->
dmin = std::numeric_limits<T1>::min();
49 p->
inf = std::numeric_limits<T1>::infinity();
73 IPQP_SOLVE} casadi_ipqp_task_t;
82 IPQP_CORRECTOR} casadi_ipqp_next_t;
139 template<
typename T1>
166 template<
typename T1>
170 d->
lbz = *w; *w += p->
nz;
171 d->
ubz = *w; *w += p->
nz;
172 d->
z = *w; *w += p->
nz;
173 d->
lam = *w; *w += p->
nz;
176 d->
dz = *w; *w += p->
nz;
177 d->
dlam = *w; *w += p->
nz;
180 d->
rz = *w; *w += p->
nz;
181 d->
rlam = *w; *w += p->
nz;
184 d->
D = *w; *w += p->
nz;
185 d->
S = *w; *w += p->
nz;
189 d->
next = IPQP_RESET;
193 template<
typename T1>
195 const T1* lbx,
const T1* ubx,
const T1* lba,
const T1* uba) {
201 casadi_copy(lbx, p->
nx, d->
lbz);
202 casadi_copy(lba, p->
na, d->
lbz + p->
nx);
203 casadi_copy(ubx, p->
nx, d->
ubz);
204 casadi_copy(uba, p->
na, d->
ubz + p->
nx);
208 template<
typename T1>
210 const T1* x0,
const T1* lam_x0,
const T1* lam_a0) {
214 casadi_copy(x0, p->
nx, d->
z);
215 casadi_fill(d->
z + p->
nx, p->
na, 0.);
216 casadi_copy(lam_x0, p->
nx, d->
lam);
217 casadi_copy(lam_a0, p->
na, d->
lam + p->
nx);
223 template<
typename T1>
234 for (k = p->
nx; k < p->nz; ++k) d->
z[k] = 0;
236 for (k = 0; k < p->
nz; ++k) {
237 if (d->
lbz[k] > -p->
inf) {
240 mid = .5 * (d->
lbz[k] + d->
ubz[k]);
243 d->
z[k] = fmin(fmax(d->
z[k], d->
lbz[k] + margin), mid);
244 }
else if (d->
z[k] > mid) {
245 d->
z[k] = fmax(fmin(d->
z[k], d->
ubz[k] - margin), mid);
254 d->
z[k] = fmax(d->
z[k], d->
lbz[k] + margin);
261 d->
z[k] = fmin(d->
z[k], d->
ubz[k] - margin);
268 casadi_clear(d->
rz, p->
nz);
277 template<
typename T1>
283 for (k = 0; k < p->
nx; ++k) {
293 for (; k < p->
nz; ++k) {
297 }
else if (d->
ubz[k] <= d->
lbz[k] + p->
dmin) {
306 for (k = 0; k < p->
nz; ++k) {
313 d->
S[k] = fmin(1., std::sqrt(1. / d->
D[k]));
314 d->
D[k] = fmin(1., d->
D[k]);
320 template<
typename T1>
332 d->
status = IPQP_MAX_ITER;
344 template<
typename T1>
351 casadi_axpy(p->
nx, 1., d->
g, d->
rz);
352 for (k = 0; k < p->
nx; ++k) {
355 d->
lam[k] = -d->
rz[k];
359 d->
rz[k] += d->
lam[k];
365 for (k = p->
nx; k < p->nz; ++k) {
372 if (d->
rz[k] + d->
pr < d->
lbz[k]) {
375 }
else if (d->
rz[k] - d->
pr > d->
ubz[k]) {
384 for (k = 0; k < p->
nx; ++k) {
385 if (fabs(d->
rz[k]) > d->
du) {
386 d->
du = fabs(d->
rz[k]);
391 casadi_axpy(p->
na, -1., d->
z + p->
nx, d->
rz + p->
nx);
393 for (k = 0; k < p->
nz; ++k) {
408 for (k = 0; k < p->
nz; ++k) {
412 bdiff = d->
z[k] - d->
lbz[k];
416 viol = bdiff * fmax(-d->
lam[k], 0.);
429 bdiff = d->
ubz[k] - d->
z[k];
433 viol = bdiff * fmax(d->
lam[k], 0.);
449 template<
typename T1>
459 for (k=0; k<p->
nx; ++k) d->
dz[k] += d->
rz[k];
461 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] = d->
dz[k];
463 for (k=p->
nx; k<p->nz; ++k) {
468 d->
dz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
469 d->
dz[k] += d->
rz[k];
473 for (k=0; k<p->
nz; ++k) d->
dz[k] *= -d->
S[k];
478 for (k=0; k<p->
nx; ++k) d->
dlam[k] = d->
rlam[k];
484 template<
typename T1>
488 casadi_int k, blocking_k;
497 for (k=0; k<p->
nz; ++k) {
498 if (d->
dz[k] < 0 && d->
lbz[k] > -p->
inf) {
499 if ((test = (d->
lbz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
502 flag = IPQP_PRIMAL | IPQP_LOWER;
505 if (d->
dz[k] > 0 && d->
ubz[k] < p->
inf) {
506 if ((test = (d->
ubz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
509 flag = IPQP_PRIMAL | IPQP_UPPER;
514 for (k=0; k<p->
nz; ++k) {
519 flag = IPQP_DUAL | IPQP_LOWER;
526 flag = IPQP_DUAL | IPQP_UPPER;
531 if (ind) *ind = blocking_k;
536 template<
typename T1>
543 for (k=0; k<p->
nz; ++k) d->
dz[k] *= d->
S[k];
545 for (k=p->
nx; k<p->nz; ++k) {
548 d->
dlam[k] = d->
dz[k] = 0;
550 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
dz[k] - d->
dlam[k]);
556 for (k=0; k<p->
nz; ++k) {
560 for (k=0; k<p->
nz; ++k) {
567 (
void)casadi_ipqp_maxstep(d, &alpha, 0);
569 sigma = casadi_ipqp_sigma(d, alpha);
571 casadi_ipqp_corrector_prepare(d, -sigma * d->
mu);
577 template<
typename T1>
583 for (k=0; k<p->
nz; ++k) d->
z[k] += alpha_pr * d->
dz[k];
585 for (k=0; k<p->
nz; ++k) d->
lam[k] += alpha_du * d->
dlam[k];
591 template<
typename T1>
598 if (d->
n_con == 0)
return 0;
601 for (k = 0; k < p->
nz; ++k) {
605 * (d->
z[k] - d->
lbz[k] + alpha * d->
dz[k]);
610 * (d->
ubz[k] - d->
z[k] - alpha * d->
dz[k]);
619 template<
typename T1>
624 if (d->
n_con == 0)
return 0;
626 sigma = casadi_ipqp_mu(d, alpha);
629 sigma *= sigma * sigma;
634 template<
typename T1>
643 for (k=0; k<p->
nz; ++k)
647 for (k=p->
nx; k<p->nz; ++k) {
650 d->
rlam[k] = d->
rz[k] = 0;
653 d->
rz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
657 for (k=0; k<p->
nz; ++k) d->
rz[k] *= -d->
S[k];
661 template<
typename T1>
664 T1 t, mu_test, primal_slack, primal_step, dual_slack, dual_step, max_tau;
669 for (k=0; k<p->
nz; ++k) d->
rz[k] *= d->
S[k];
671 for (k=p->
nx; k<p->nz; ++k) {
674 d->
rlam[k] = d->
rz[k] = 0;
676 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
rz[k] - d->
rlam[k]);
682 for (k=0; k<p->
nz; ++k) d->
dz[k] += d->
rz[k];
683 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] += d->
rlam[k];
685 for (k=0; k<p->
nz; ++k) {
688 if (k<p->nx) d->
dlam[k] -= t;
691 for (k=0; k<p->
nz; ++k) {
694 if (k<p->nx) d->
dlam[k] += t;
697 flag = casadi_ipqp_maxstep(d, &max_tau, &k);
699 if (flag == IPQP_NONE) {
704 mu_test = casadi_ipqp_mu(d, max_tau);
706 if (flag & IPQP_UPPER) {
707 primal_slack = d->
ubz[k] - d->
z[k];
708 primal_step = -d->
dz[k];
712 primal_slack = d->
z[k] - d->
lbz[k];
713 primal_step = d->
dz[k];
718 if (flag & IPQP_PRIMAL) {
719 d->
tau = (0.01 * mu_test / (dual_slack + max_tau * dual_step)
720 - primal_slack) / primal_step;
722 d->
tau = (0.01 * mu_test / (primal_slack + max_tau * primal_step)
723 - dual_slack) / dual_step;
725 d->
tau = fmax(d->
tau, 0.99 * max_tau);
728 casadi_ipqp_step(d, d->
tau, d->
tau);
730 casadi_clear(d->
rz, p->
nz);
734 template<
typename T1>
738 casadi_ipqp_reset(d);
740 d->
next = IPQP_RESIDUAL;
744 if (d->
status == IPQP_MV_ERROR)
break;
745 casadi_ipqp_residual(d);
746 d->
task = IPQP_PROGRESS;
747 d->
next = IPQP_NEWITER;
751 if (d->
status == IPQP_PROGRESS_ERROR)
break;
752 if (casadi_ipqp_newiter(d))
break;
753 d->
task = IPQP_FACTOR;
754 d->
next = IPQP_PREPARE;
758 if (d->
status == IPQP_FACTOR_ERROR)
break;
759 casadi_ipqp_predictor_prepare(d);
760 d->
task = IPQP_SOLVE;
761 d->
next = IPQP_PREDICTOR;
765 if (d->
status == IPQP_SOLVE_ERROR)
break;
766 casadi_ipqp_predictor(d);
767 d->
task = IPQP_SOLVE;
768 d->
next = IPQP_CORRECTOR;
772 if (d->
status == IPQP_SOLVE_ERROR)
break;
773 casadi_ipqp_corrector(d);
775 d->
next = IPQP_RESIDUAL;
781 d->
next = IPQP_RESET;
787 const char* casadi_ipqp_return_status(casadi_ipqp_flag_t status) {
789 case IPQP_SUCCESS:
return "success";
790 case IPQP_MAX_ITER:
return "Maximum number of iterations reached";
791 case IPQP_NO_SEARCH_DIR:
return "Failed to calculate search direction";
792 case IPQP_MV_ERROR:
return "Matrix-vector evaluation error";
793 case IPQP_FACTOR_ERROR:
return "Linear solver factorization error";
794 case IPQP_SOLVE_ERROR:
return "Linear solver solution error";
795 case IPQP_PROGRESS_ERROR:
return "Printing error";
801 template<
typename T1>
806 casadi_copy(d->
z, p->
nx, x);
807 casadi_copy(d->
lam, p->
nx, lam_x);
808 casadi_copy(d->
lam + p->
nx, p->
na, lam_a);
812 template<
typename T1>
814 #ifdef CASADI_SNPRINTF
817 flag = CASADI_SNPRINTF(buf, buf_sz,
"%5s %9s %9s %5s %9s %5s "
819 "Iter",
"mu",
"|pr|",
"con",
"|du|",
"var",
"|co|",
"con",
823 d->
status = IPQP_PROGRESS_ERROR;
827 if (buf_sz) buf[0] =
'\0';
834 template<
typename T1>
836 #ifdef CASADI_SNPRINTF
839 flag = CASADI_SNPRINTF(buf, buf_sz,
840 "%5d %9.2g %9.2g %5d %9.2g %5d %9.2g %5d %9.2g ",
841 static_cast<int>(d->
iter), d->
mu,
842 d->
pr,
static_cast<int>(d->
ipr),
843 d->
du,
static_cast<int>(d->
idu),
844 d->
co,
static_cast<int>(d->
ico),
848 d->
status = IPQP_PROGRESS_ERROR;
856 flag = CASADI_SNPRINTF(buf, buf_sz,
"%s", d->
msg);
859 d->
status = IPQP_PROGRESS_ERROR;
864 if (buf_sz) buf[0] =
'\0';
const casadi_ipqp_prob< T1 > * prob
casadi_ipqp_flag_t status