24 m_J.setZero(nVars, nVars);
26 R.resize(nVars, nVars);
28 r.resize(nIneqCon + nEqCon);
29 u.resize(nIneqCon + nEqCon);
33 A.resize(nIneqCon + nEqCon);
37 u_old.resize(nIneqCon + nEqCon);
38 A_old.resize(nIneqCon + nEqCon);
40 #ifdef OPTIMIZE_ADD_CONSTRAINT 46 size_t &iq,
double &R_norm) {
47 size_t nVars = J.rows();
48 #ifdef EIQGUADPROG_TRACE_SOLVER 49 std::cerr <<
"Add constraint " << iq <<
'/';
52 double cc, ss, h, t1, t2, xny;
54 #ifdef OPTIMIZE_ADD_CONSTRAINT 55 Eigen::Vector2d cc_ss;
62 for (j = d.size() - 1; j >= iq + 1; j--) {
72 h = utils::distance(cc, ss);
73 if (h == 0.0)
continue;
83 xny = ss / (1.0 + cc);
86 #ifdef OPTIMIZE_ADD_CONSTRAINT // the optimized code is actually slower than 91 J.col(j - 1).noalias() = J.middleCols<2>(j - 1) * cc_ss;
92 J.col(j) = xny * (T1 + J.col(j - 1)) - J.col(j);
95 for (k = 0; k < nVars; k++) {
98 J(k, j - 1) = t1 * cc + t2 * ss;
99 J(k, j) = xny * (t1 + J(k, j - 1)) - t2;
108 R.col(iq - 1).head(iq) = d.head(iq);
109 #ifdef EIQGUADPROG_TRACE_SOLVER 110 std::cerr << iq << std::endl;
113 if (std::abs(
d(iq - 1)) <= std::numeric_limits<double>::epsilon() * R_norm)
116 R_norm = std::max<double>(R_norm, std::abs(
d(iq - 1)));
123 size_t nVars = R.rows();
124 #ifdef EIQGUADPROG_TRACE_SOLVER 125 std::cerr <<
"Delete constraint " << l <<
' ' << iq;
129 double cc, ss, h, xny, t1, t2;
132 for (i = nEqCon; i < iq; i++)
133 if (
A(i) == static_cast<VectorXi::Scalar>(l)) {
139 for (i = qq; i < iq - 1; i++) {
142 R.col(i) = R.col(i + 1);
149 for (j = 0; j < iq; j++)
R(j, iq - 1) = 0.0;
152 #ifdef EIQGUADPROG_TRACE_SOLVER 153 std::cerr <<
'/' << iq << std::endl;
158 for (j = qq; j < iq; j++) {
161 h = utils::distance(cc, ss);
162 if (h == 0.0)
continue;
173 xny = ss / (1.0 + cc);
174 for (k = j + 1; k < iq; k++) {
177 R(j, k) = t1 * cc + t2 * ss;
178 R(j + 1, k) = xny * (t1 +
R(j, k)) - t2;
180 for (k = 0; k < nVars; k++) {
183 J(k, j) = t1 * cc + t2 * ss;
184 J(k, j + 1) = xny * (J(k, j) + t1) - t2;
192 const size_t nVars = g0.size();
193 const size_t nEqCon = ce0.size();
194 const size_t nIneqCon = ci0.size();
197 reset(nVars, nEqCon, nIneqCon);
199 assert(static_cast<size_t>(Hess.rows()) ==
m_nVars &&
200 static_cast<size_t>(Hess.cols()) ==
m_nVars);
201 assert(static_cast<size_t>(g0.size()) ==
m_nVars);
202 assert(static_cast<size_t>(CE.rows()) ==
m_nEqCon &&
203 static_cast<size_t>(CE.cols()) ==
m_nVars);
204 assert(static_cast<size_t>(ce0.size()) ==
m_nEqCon);
205 assert(static_cast<size_t>(CI.rows()) ==
m_nIneqCon &&
206 static_cast<size_t>(CI.cols()) ==
m_nVars);
207 assert(static_cast<size_t>(ci0.size()) ==
m_nIneqCon);
217 const double inf = std::numeric_limits<double>::infinity();
239 R.setZero(nVars, nVars);
247 m_J.setIdentity(nVars, nVars);
248 #ifdef OPTIMIZE_HESSIAN_INVERSE 257 #ifdef EIQGUADPROG_TRACE_SOLVER 258 utils::print_matrix(
"m_J",
m_J);
271 x =
m_J * (
m_J.transpose() * g0);
273 #ifdef OPTIMIZE_UNCONSTR_MINIM 275 chol_.solveInPlace(x);
284 #ifdef EIQGUADPROG_TRACE_SOLVER 285 std::cerr <<
"Unconstrained solution: " <<
f_value << std::endl;
286 utils::print_vector(
"x", x);
294 for (i = 0; i < nEqCon; i++) {
301 #ifdef EIQGUADPROG_TRACE_SOLVER 302 utils::print_matrix(
"R",
R);
303 utils::print_vector(
"z",
z);
304 utils::print_vector(
"r",
r);
305 utils::print_vector(
"d",
d);
312 if (std::abs(
z.dot(
z)) > std::numeric_limits<double>::epsilon())
314 t2 = (-
np.dot(x) - ce0(i)) /
z.dot(
np);
320 u.head(iq) -= t2 *
r.head(iq);
324 A(i) =
static_cast<VectorXi::Scalar
>(-i - 1);
337 for (i = 0; i < nIneqCon; i++) iai(i) = static_cast<VectorXi::Scalar>(i);
339 #ifdef USE_WARM_START 342 for (i = nEqCon; i <
q; i++) {
343 iai(i - nEqCon) = -1;
354 if (std::abs(
z.dot(
z)) >
355 std::numeric_limits<double>::epsilon())
356 t2 = (-
np.dot(x) - ci0(ip)) /
z.dot(
np);
364 u.head(iq) -= t2 *
r.head(iq);
371 std::cerr <<
"[WARM START] Constraints are linearly dependent\n";
388 #ifdef EIQGUADPROG_TRACE_SOLVER 389 utils::print_vector(
"x", x);
392 for (i = nEqCon; i < iq; i++) {
402 #ifdef OPTIMIZE_STEP_1_2 404 s.noalias() += CI * x;
406 psi = (
s.cwiseMin(VectorXd::Zero(nIneqCon))).sum();
409 for (i = 0; i < nIneqCon; i++) {
411 s(i) = CI.row(i).dot(x) + ci0(i);
412 psi += std::min(0.0,
s(i));
416 #ifdef EIQGUADPROG_TRACE_SOLVER 417 utils::print_vector(
"s",
s);
422 if (std::abs(psi) <= static_cast<double>(nIneqCon) *
423 std::numeric_limits<double>::epsilon() * c1 * c2 *
433 u_old.head(iq) =
u.head(iq);
434 A_old.head(iq) =
A.head(iq);
441 for (i = 0; i < nIneqCon; i++) {
458 A(iq) =
static_cast<VectorXi::Scalar
>(ip);
462 #ifdef EIQGUADPROG_TRACE_SOLVER 463 std::cerr <<
"Trying with constraint " << ip << std::endl;
464 utils::print_vector(
"np",
np);
483 #ifdef EIQGUADPROG_TRACE_SOLVER 484 std::cerr <<
"Step direction z" << std::endl;
485 utils::print_vector(
"z",
z);
486 utils::print_vector(
"r",
r);
487 utils::print_vector(
"u",
u);
488 utils::print_vector(
"d",
d);
489 utils::print_vector(
"A",
A);
501 for (k = nEqCon; k < iq; k++) {
503 if (
r(k) > 0.0 && ((tmp =
u(k) /
r(k)) < t1)) {
510 if (std::abs(
z.dot(
z)) > std::numeric_limits<double>::epsilon())
512 t2 = -
s(ip) /
z.dot(
np);
517 t = std::min(t1, t2);
518 #ifdef EIQGUADPROG_TRACE_SOLVER 519 std::cerr <<
"Step sizes: " << t <<
" (t1 = " << t1 <<
", t2 = " << t2
536 u.head(iq) -= t *
r.head(iq);
538 iai(l) =
static_cast<VectorXi::Scalar
>(l);
540 #ifdef EIQGUADPROG_TRACE_SOLVER 541 std::cerr <<
" in dual space: " <<
f_value << std::endl;
542 utils::print_vector(
"x", x);
543 utils::print_vector(
"z",
z);
544 utils::print_vector(
"A",
A);
555 u.head(iq) -= t *
r.head(iq);
558 #ifdef EIQGUADPROG_TRACE_SOLVER 559 std::cerr <<
" in both spaces: " <<
f_value << std::endl;
560 utils::print_vector(
"x", x);
561 utils::print_vector(
"u",
u);
562 utils::print_vector(
"r",
r);
563 utils::print_vector(
"A",
A);
567 #ifdef EIQGUADPROG_TRACE_SOLVER 568 std::cerr <<
"Full step has taken " << t << std::endl;
569 utils::print_vector(
"x", x);
576 #ifdef EIQGUADPROG_TRACE_SOLVER 577 utils::print_matrix(
"R",
R);
578 utils::print_vector(
"A",
A);
580 for (i = 0; i < nIneqCon; i++) iai(i) = static_cast<VectorXi::Scalar>(i);
581 for (i = 0; i < iq; i++) {
591 #ifdef EIQGUADPROG_TRACE_SOLVER 592 utils::print_matrix(
"R",
R);
593 utils::print_vector(
"A",
A);
600 iai(l) =
static_cast<VectorXi::Scalar
>(l);
602 s(ip) = CI.row(ip).dot(x) + ci0(ip);
604 #ifdef EIQGUADPROG_TRACE_SOLVER 605 std::cerr <<
"Partial step has taken " << t << std::endl;
606 utils::print_vector(
"x", x);
607 utils::print_matrix(
"R",
R);
608 utils::print_vector(
"A",
A);
609 utils::print_vector(
"s",
s);
Eigen::LLT< MatrixXd, Eigen::Lower > chol_
current value of cost function
virtual ~EiquadprogFast()
#define EIQUADPROG_FAST_CHOLESKY_DECOMPOSITION
EiquadprogFast_status solve_quadprog(const MatrixXd &Hess, const VectorXd &g0, const MatrixXd &CE, const VectorXd &ce0, const MatrixXd &CI, const VectorXd &ci0, VectorXd &x)
bool is_inverse_provided_
#define EIQUADPROG_FAST_ADD_EQ_CONSTR_1
#define EIQUADPROG_FAST_ADD_EQ_CONSTR_2
void delete_constraint(MatrixXd &R, MatrixXd &J, VectorXi &A, VectorXd &u, size_t nEqCon, size_t &iq, size_t l)
#define EIQUADPROG_FAST_STEP_1_UNCONSTR_MINIM
VectorXd z
step direction in primal space
void reset(size_t dim_qp, size_t num_eq, size_t num_ineq)
#define EIQUADPROG_FAST_STEP_1_2
void update_z(VectorXd &z, const MatrixXd &J, const VectorXd &d, size_t iq)
VectorXd np
current constraint normal
int iter
number of active-set iterations
#define STOP_PROFILER_EIQUADPROG_FAST(x)
#define EIQUADPROG_FAST_STEP_2C
#define DEBUG_STREAM(msg)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW EiquadprogFast()
#define START_PROFILER_EIQUADPROG_FAST(x)
bool add_constraint(MatrixXd &R, MatrixXd &J, VectorXd &d, size_t &iq, double &R_norm)
void update_r(const MatrixXd &R, VectorXd &r, const VectorXd &d, size_t iq)
#define EIQUADPROG_FAST_STEP_1
#define EIQUADPROG_FAST_ADD_EQ_CONSTR
VectorXd r
infeasibility multipliers, i.e. negative step direction in dual space
void compute_d(VectorXd &d, const MatrixXd &J, const VectorXd &np)
#define EIQUADPROG_FAST_STEP_2
#define EIQUADPROG_FAST_CHOLESKY_INVERSE
#define EIQUADPROG_FAST_STEP_2A
#define EIQUADPROG_FAST_STEP_2B
double f_value
max number of active-set iterations
VectorXd u
Lagrange multipliers.