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;
197 template<
typename T1>
199 const T1* lbx,
const T1* ubx,
const T1* lba,
const T1* uba) {
205 casadi_copy(lbx, p->
nx, d->
lbz);
206 casadi_copy(lba, p->
na, d->
lbz + p->
nx);
207 casadi_copy(ubx, p->
nx, d->
ubz);
208 casadi_copy(uba, p->
na, d->
ubz + p->
nx);
212 template<
typename T1>
214 const T1* x0,
const T1* lam_x0,
const T1* lam_a0) {
218 casadi_copy(x0, p->
nx, d->
z);
219 casadi_fill(d->
z + p->
nx, p->
na, 0.);
220 casadi_copy(lam_x0, p->
nx, d->
lam);
221 casadi_copy(lam_a0, p->
na, d->
lam + p->
nx);
227 template<
typename T1>
238 for (k = p->
nx; k < p->nz; ++k) d->
z[k] = 0;
240 for (k = 0; k < p->
nz; ++k) {
241 if (d->
lbz[k] > -p->
inf) {
244 mid = .5 * (d->
lbz[k] + d->
ubz[k]);
247 d->
z[k] = fmin(fmax(d->
z[k], d->
lbz[k] + margin), mid);
248 }
else if (d->
z[k] > mid) {
249 d->
z[k] = fmax(fmin(d->
z[k], d->
ubz[k] - margin), mid);
258 d->
z[k] = fmax(d->
z[k], d->
lbz[k] + margin);
265 d->
z[k] = fmin(d->
z[k], d->
ubz[k] - margin);
272 casadi_clear(d->
rz, p->
nz);
281 template<
typename T1>
287 for (k = 0; k < p->
nx; ++k) {
297 for (; k < p->
nz; ++k) {
301 }
else if (d->
ubz[k] <= d->
lbz[k] + p->
dmin) {
310 for (k = 0; k < p->
nz; ++k) {
317 d->
S[k] = fmin(1., std::sqrt(1. / d->
D[k]));
318 d->
D[k] = fmin(1., d->
D[k]);
324 template<
typename T1>
336 d->
status = IPQP_MAX_ITER;
348 template<
typename T1>
355 casadi_axpy(p->
nx, 1., d->
g, d->
rz);
356 for (k = 0; k < p->
nx; ++k) {
359 d->
lam[k] = -d->
rz[k];
363 d->
rz[k] += d->
lam[k];
369 for (k = p->
nx; k < p->nz; ++k) {
376 if (d->
rz[k] + d->
pr < d->
lbz[k]) {
379 }
else if (d->
rz[k] - d->
pr > d->
ubz[k]) {
388 for (k = 0; k < p->
nx; ++k) {
389 if (fabs(d->
rz[k]) > d->
du) {
390 d->
du = fabs(d->
rz[k]);
395 casadi_axpy(p->
na, -1., d->
z + p->
nx, d->
rz + p->
nx);
397 for (k = 0; k < p->
nz; ++k) {
412 for (k = 0; k < p->
nz; ++k) {
416 bdiff = d->
z[k] - d->
lbz[k];
420 viol = bdiff * fmax(-d->
lam[k], 0.);
433 bdiff = d->
ubz[k] - d->
z[k];
437 viol = bdiff * fmax(d->
lam[k], 0.);
453 template<
typename T1>
463 for (k=0; k<p->
nx; ++k) d->
dz[k] += d->
rz[k];
465 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] = d->
dz[k];
467 for (k=p->
nx; k<p->nz; ++k) {
472 d->
dz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
473 d->
dz[k] += d->
rz[k];
477 for (k=0; k<p->
nz; ++k) d->
dz[k] *= -d->
S[k];
482 for (k=0; k<p->
nx; ++k) d->
dlam[k] = d->
rlam[k];
488 template<
typename T1>
492 casadi_int k, blocking_k;
501 for (k=0; k<p->
nz; ++k) {
502 if (d->
dz[k] < 0 && d->
lbz[k] > -p->
inf) {
503 if ((test = (d->
lbz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
506 flag = IPQP_PRIMAL | IPQP_LOWER;
509 if (d->
dz[k] > 0 && d->
ubz[k] < p->
inf) {
510 if ((test = (d->
ubz[k] - d->
z[k]) / d->
dz[k]) < *alpha) {
513 flag = IPQP_PRIMAL | IPQP_UPPER;
518 for (k=0; k<p->
nz; ++k) {
523 flag = IPQP_DUAL | IPQP_LOWER;
530 flag = IPQP_DUAL | IPQP_UPPER;
535 if (ind) *ind = blocking_k;
540 template<
typename T1>
547 for (k=0; k<p->
nz; ++k) d->
dz[k] *= d->
S[k];
549 for (k=p->
nx; k<p->nz; ++k) {
552 d->
dlam[k] = d->
dz[k] = 0;
554 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
dz[k] - d->
dlam[k]);
560 for (k=0; k<p->
nz; ++k) {
564 for (k=0; k<p->
nz; ++k) {
571 (
void)casadi_ipqp_maxstep(d, &alpha, 0);
573 sigma = casadi_ipqp_sigma(d, alpha);
575 casadi_ipqp_corrector_prepare(d, -sigma * d->
mu);
581 template<
typename T1>
587 for (k=0; k<p->
nz; ++k) d->
z[k] += alpha_pr * d->
dz[k];
589 for (k=0; k<p->
nz; ++k) d->
lam[k] += alpha_du * d->
dlam[k];
595 template<
typename T1>
602 if (d->
n_con == 0)
return 0;
605 for (k = 0; k < p->
nz; ++k) {
609 * (d->
z[k] - d->
lbz[k] + alpha * d->
dz[k]);
614 * (d->
ubz[k] - d->
z[k] - alpha * d->
dz[k]);
623 template<
typename T1>
628 if (d->
n_con == 0)
return 0;
630 sigma = casadi_ipqp_mu(d, alpha);
633 sigma *= sigma * sigma;
638 template<
typename T1>
647 for (k=0; k<p->
nz; ++k)
651 for (k=p->
nx; k<p->nz; ++k) {
654 d->
rlam[k] = d->
rz[k] = 0;
657 d->
rz[k] *= d->
D[k] / (d->
S[k] * d->
S[k]);
661 for (k=0; k<p->
nz; ++k) d->
rz[k] *= -d->
S[k];
665 template<
typename T1>
668 T1 t, mu_test, primal_slack, primal_step, dual_slack, dual_step, max_tau;
673 for (k=0; k<p->
nz; ++k) d->
rz[k] *= d->
S[k];
675 for (k=p->
nx; k<p->nz; ++k) {
678 d->
rlam[k] = d->
rz[k] = 0;
680 t = d->
D[k] / (d->
S[k] * d->
S[k]) * (d->
rz[k] - d->
rlam[k]);
686 for (k=0; k<p->
nz; ++k) d->
dz[k] += d->
rz[k];
687 for (k=p->
nx; k<p->nz; ++k) d->
dlam[k] += d->
rlam[k];
689 for (k=0; k<p->
nz; ++k) {
692 if (k<p->nx) d->
dlam[k] -= t;
695 for (k=0; k<p->
nz; ++k) {
698 if (k<p->nx) d->
dlam[k] += t;
701 flag = casadi_ipqp_maxstep(d, &max_tau, &k);
703 if (flag == IPQP_NONE) {
708 mu_test = casadi_ipqp_mu(d, max_tau);
710 if (flag & IPQP_UPPER) {
711 primal_slack = d->
ubz[k] - d->
z[k];
712 primal_step = -d->
dz[k];
716 primal_slack = d->
z[k] - d->
lbz[k];
717 primal_step = d->
dz[k];
722 if (flag & IPQP_PRIMAL) {
723 d->
tau = (0.01 * mu_test / (dual_slack + max_tau * dual_step)
724 - primal_slack) / primal_step;
726 d->
tau = (0.01 * mu_test / (primal_slack + max_tau * primal_step)
727 - dual_slack) / dual_step;
729 d->
tau = fmax(d->
tau, 0.99 * max_tau);
732 casadi_ipqp_step(d, d->
tau, d->
tau);
734 casadi_clear(d->
rz, p->
nz);
738 template<
typename T1>
742 casadi_ipqp_reset(d);
744 d->
next = IPQP_RESIDUAL;
748 if (d->
status == IPQP_MV_ERROR)
break;
749 casadi_ipqp_residual(d);
750 d->
task = IPQP_PROGRESS;
751 d->
next = IPQP_NEWITER;
755 if (d->
status == IPQP_PROGRESS_ERROR)
break;
756 if (casadi_ipqp_newiter(d))
break;
757 d->
task = IPQP_FACTOR;
758 d->
next = IPQP_PREPARE;
762 if (d->
status == IPQP_FACTOR_ERROR)
break;
763 casadi_ipqp_predictor_prepare(d);
764 d->
task = IPQP_SOLVE;
765 d->
next = IPQP_PREDICTOR;
769 if (d->
status == IPQP_SOLVE_ERROR)
break;
770 casadi_ipqp_predictor(d);
771 d->
task = IPQP_SOLVE;
772 d->
next = IPQP_CORRECTOR;
776 if (d->
status == IPQP_SOLVE_ERROR)
break;
777 casadi_ipqp_corrector(d);
779 d->
next = IPQP_RESIDUAL;
785 d->
next = IPQP_RESET;
791 const char* casadi_ipqp_return_status(casadi_ipqp_flag_t status) {
793 case IPQP_SUCCESS:
return "success";
794 case IPQP_MAX_ITER:
return "Maximum number of iterations reached";
795 case IPQP_NO_SEARCH_DIR:
return "Failed to calculate search direction";
796 case IPQP_MV_ERROR:
return "Matrix-vector evaluation error";
797 case IPQP_FACTOR_ERROR:
return "Linear solver factorization error";
798 case IPQP_SOLVE_ERROR:
return "Linear solver solution error";
799 case IPQP_PROGRESS_ERROR:
return "Printing error";
805 template<
typename T1>
810 casadi_copy(d->
z, p->
nx, x);
811 casadi_copy(d->
lam, p->
nx, lam_x);
812 casadi_copy(d->
lam + p->
nx, p->
na, lam_a);
816 template<
typename T1>
818 #ifdef CASADI_SNPRINTF
821 flag = CASADI_SNPRINTF(buf, buf_sz,
"%5s %9s %9s %5s %9s %5s "
823 "Iter",
"mu",
"|pr|",
"con",
"|du|",
"var",
"|co|",
"con",
827 d->
status = IPQP_PROGRESS_ERROR;
831 if (buf_sz) buf[0] =
'\0';
838 template<
typename T1>
840 #ifdef CASADI_SNPRINTF
843 flag = CASADI_SNPRINTF(buf, buf_sz,
844 "%5d %9.2g %9.2g %5d %9.2g %5d %9.2g %5d %9.2g ",
845 static_cast<int>(d->
iter), d->
mu,
846 d->
pr,
static_cast<int>(d->
ipr),
847 d->
du,
static_cast<int>(d->
idu),
848 d->
co,
static_cast<int>(d->
ico),
852 d->
status = IPQP_PROGRESS_ERROR;
860 flag = CASADI_SNPRINTF(buf, buf_sz,
"%s", d->
msg);
863 d->
status = IPQP_PROGRESS_ERROR;
868 if (buf_sz) buf[0] =
'\0';
const long double alpha[8][8]
const casadi_ipqp_prob< T1 > * prob
casadi_ipqp_flag_t status