10 const VectorXd &ce0,
const MatrixXd &CI,
11 const VectorXd &ci0, VectorXd &x, VectorXi &activeSet,
12 size_t &activeSetSize) {
13 Eigen::DenseIndex p = CE.cols();
14 Eigen::DenseIndex m = CI.cols();
23 const VectorXd &ce0,
const MatrixXd &CI,
24 const VectorXd &ci0, VectorXd &x, VectorXd &y,
25 VectorXi &activeSet,
size_t &activeSetSize) {
26 LLT<MatrixXd, Lower> chol(G.cols());
34 return solve_quadprog(chol, c1, g0, CE, ce0, CI, ci0, x, y, activeSet,
39 const MatrixXd &CE,
const VectorXd &ce0,
40 const MatrixXd &CI,
const VectorXd &ci0, VectorXd &x,
41 VectorXi &activeSet,
size_t &activeSetSize) {
42 Eigen::DenseIndex p = CE.cols();
43 Eigen::DenseIndex m = CI.cols();
47 return solve_quadprog(chol, c1, g0, CE, ce0, CI, ci0, x, y, activeSet,
57 const MatrixXd &CE,
const VectorXd &ce0,
58 const MatrixXd &CI,
const VectorXd &ci0, VectorXd &x,
59 VectorXd &u, VectorXi &A,
size_t &q) {
65 MatrixXd R(g0.size(), g0.size()), J(g0.size(), g0.size());
67 VectorXd s(m + p), z(n), r(m + p), d(n), np(n);
68 VectorXd x_old(n), u_old(m + p);
69 double f_value, psi, c2, sum, ss, R_norm;
70 const double inf = std::numeric_limits<double>::infinity();
75 if (
static_cast<size_t>(A.size()) != m + p) A.resize(m + p);
76 VectorXi A_old(m + p), iai(m + p), iaexcl(m + p);
98 chol.matrixU().solveInPlace(J);
100 #ifdef EIQGUADPROG_TRACE_SOLVER
101 utils::print_matrix(
"J", J);
112 chol.solveInPlace(x);
114 f_value = 0.5 * g0.dot(x);
115 #ifdef EIQGUADPROG_TRACE_SOLVER
116 std::cerr <<
"Unconstrained solution: " << f_value << std::endl;
117 utils::print_vector(
"x", x);
122 for (i = 0; i < me; i++) {
127 #ifdef EIQGUADPROG_TRACE_SOLVER
128 utils::print_matrix(
"R", R);
129 utils::print_vector(
"z", z);
130 utils::print_vector(
"r", r);
131 utils::print_vector(
"d", d);
137 if (std::abs(z.dot(z)) >
138 std::numeric_limits<double>::epsilon())
139 t2 = (-np.dot(x) - ce0(i)) / z.dot(np);
145 u.head(iq) -= t2 * r.head(iq);
148 f_value += 0.5 * (t2 * t2) * z.dot(np);
149 A(i) =
static_cast<VectorXi::Scalar
>(-i - 1);
159 for (i = 0; i < mi; i++) iai(i) = static_cast<VectorXi::Scalar>(i);
163 #ifdef EIQGUADPROG_TRACE_SOLVER
164 utils::print_vector(
"x", x);
167 for (i = me; i < iq; i++) {
176 for (i = 0; i < mi; i++) {
178 sum = CI.col(i).dot(x) + ci0(i);
180 psi += std::min(0.0, sum);
182 #ifdef EIQGUADPROG_TRACE_SOLVER
183 utils::print_vector(
"s", s);
186 if (std::abs(psi) <=
static_cast<double>(mi) *
187 std::numeric_limits<double>::epsilon() * c1 * c2 *
195 u_old.head(iq) = u.head(iq);
196 A_old.head(iq) = A.head(iq);
200 for (i = 0; i < mi; i++) {
201 if (s(i) < ss && iai(i) != -1 && iaexcl(i)) {
216 A(iq) =
static_cast<VectorXi::Scalar
>(ip);
218 #ifdef EIQGUADPROG_TRACE_SOLVER
219 std::cerr <<
"Trying with constraint " << ip << std::endl;
220 utils::print_vector(
"np", np);
231 #ifdef EIQGUADPROG_TRACE_SOLVER
232 std::cerr <<
"Step direction z" << std::endl;
233 utils::print_vector(
"z", z);
234 utils::print_vector(
"r", r);
235 utils::print_vector(
"u", u);
236 utils::print_vector(
"d", d);
237 utils::print_vector(
"A", A);
246 for (k = me; k < iq; k++) {
248 if (r(k) > 0.0 && ((tmp = u(k) / r(k)) < t1)) {
255 if (std::abs(z.dot(z)) >
256 std::numeric_limits<double>::epsilon())
257 t2 = -s(ip) / z.dot(np);
262 t = std::min(t1, t2);
263 #ifdef EIQGUADPROG_TRACE_SOLVER
264 std::cerr <<
"Step sizes: " << t <<
" (t1 = " << t1 <<
", t2 = " << t2
280 u.head(iq) -= t * r.head(iq);
282 iai(l) =
static_cast<VectorXi::Scalar
>(l);
284 #ifdef EIQGUADPROG_TRACE_SOLVER
285 std::cerr <<
" in dual space: " << f_value << std::endl;
286 utils::print_vector(
"x", x);
287 utils::print_vector(
"z", z);
288 utils::print_vector(
"A", A);
297 f_value += t * z.dot(np) * (0.5 * t + u(iq));
299 u.head(iq) -= t * r.head(iq);
301 #ifdef EIQGUADPROG_TRACE_SOLVER
302 std::cerr <<
" in both spaces: " << f_value << std::endl;
303 utils::print_vector(
"x", x);
304 utils::print_vector(
"u", u);
305 utils::print_vector(
"r", r);
306 utils::print_vector(
"A", A);
310 #ifdef EIQGUADPROG_TRACE_SOLVER
311 std::cerr <<
"Full step has taken " << t << std::endl;
312 utils::print_vector(
"x", x);
319 #ifdef EIQGUADPROG_TRACE_SOLVER
320 utils::print_matrix(
"R", R);
321 utils::print_vector(
"A", A);
323 for (i = 0; i < m; i++) iai(i) = static_cast<VectorXi::Scalar>(i);
324 for (i = 0; i < iq; i++) {
333 #ifdef EIQGUADPROG_TRACE_SOLVER
334 utils::print_matrix(
"R", R);
335 utils::print_vector(
"A", A);
341 #ifdef EIQGUADPROG_TRACE_SOLVER
342 std::cerr <<
"Partial step has taken " << t << std::endl;
343 utils::print_vector(
"x", x);
346 iai(l) =
static_cast<VectorXi::Scalar
>(l);
348 #ifdef EIQGUADPROG_TRACE_SOLVER
349 utils::print_matrix(
"R", R);
350 utils::print_vector(
"A", A);
353 s(ip) = CI.col(ip).dot(x) + ci0(ip);
355 #ifdef EIQGUADPROG_TRACE_SOLVER
356 utils::print_vector(
"s", s);
364 #ifdef EIQGUADPROG_TRACE_SOLVER
365 std::cerr <<
"Add constraint " << iq <<
'/';
368 double cc, ss, h, t1, t2, xny;
374 for (j = n - 1; j >= iq + 1; j--) {
385 h = utils::distance(cc, ss);
386 if (h == 0.0)
continue;
396 xny = ss / (1.0 + cc);
397 for (k = 0; k < n; k++) {
400 J(k, j - 1) = t1 * cc + t2 * ss;
401 J(k, j) = xny * (t1 + J(k, j - 1)) - t2;
409 R.col(iq - 1).head(iq) = d.head(iq);
410 #ifdef EIQGUADPROG_TRACE_SOLVER
411 std::cerr << iq << std::endl;
414 if (std::abs(d(iq - 1)) <= std::numeric_limits<double>::epsilon() * R_norm)
417 R_norm = std::max<double>(R_norm, std::abs(d(iq - 1)));
422 size_t p,
size_t &iq,
size_t l) {
424 #ifdef EIQGUADPROG_TRACE_SOLVER
425 std::cerr <<
"Delete constraint " << l <<
' ' << iq;
427 size_t i, j, k, qq = 0;
428 double cc, ss, h, xny, t1, t2;
431 for (i = p; i < iq; i++)
432 if (
static_cast<size_t>(A(i)) == l) {
438 for (i = qq; i < iq - 1; i++) {
441 R.col(i) = R.col(i + 1);
448 for (j = 0; j < iq; j++) R(j, iq - 1) = 0.0;
451 #ifdef EIQGUADPROG_TRACE_SOLVER
452 std::cerr <<
'/' << iq << std::endl;
457 for (j = qq; j < iq; j++) {
460 h = utils::distance(cc, ss);
461 if (h == 0.0)
continue;
472 xny = ss / (1.0 + cc);
473 for (k = j + 1; k < iq; k++) {
476 R(j, k) = t1 * cc + t2 * ss;
477 R(j + 1, k) = xny * (t1 + R(j, k)) - t2;
479 for (k = 0; k < n; k++) {
482 J(k, j) = t1 * cc + t2 * ss;
483 J(k, j + 1) = xny * (J(k, j) + t1) - t2;