eiquadprog-basic.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2019 CNRS
3 //
4 // This file is part of eiquadprog.
5 //
6 // eiquadprog is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 //(at your option) any later version.
10 
11 // eiquadprog is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with eiquadprog. If not, see <https://www.gnu.org/licenses/>.
18 
19 #include <Eigen/Core>
20 #include <boost/test/unit_test.hpp>
21 #include <iostream>
22 
24 
25 // The problem is in the form:
26 // min 0.5 * x G x + g0 x
27 // s.t.
28 // CE^T x + ce0 = 0
29 // CI^T x + ci0 >= 0
30 // The matrix and vectors dimensions are as follows:
31 // G: n * n
32 // g0: n
33 // CE: n * p
34 // ce0: p
35 // CI: n * m
36 // ci0: m
37 // x: n
38 
39 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
40 
41 // min ||x||^2
42 
43 BOOST_AUTO_TEST_CASE(test_unbiased) {
44  Eigen::MatrixXd Q(2, 2);
45  Q.setZero();
46  Q(0, 0) = 1.0;
47  Q(1, 1) = 1.0;
48 
49  Eigen::VectorXd C(2);
50  C.setZero();
51 
52  Eigen::MatrixXd Aeq(2, 0);
53 
54  Eigen::VectorXd Beq(0);
55 
56  Eigen::MatrixXd Aineq(2, 0);
57 
58  Eigen::VectorXd Bineq(0);
59 
60  Eigen::VectorXd x(2);
61  Eigen::VectorXi activeSet(0);
62  size_t activeSetSize;
63 
64  Eigen::VectorXd solution(2);
65  solution.setZero();
66 
67  double val = 0.0;
68 
69  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
70  x, activeSet, activeSetSize);
71 
72  BOOST_CHECK_CLOSE(out, val, 1e-6);
73 
74  BOOST_CHECK(x.isApprox(solution));
75 }
76 
77 // min ||x-x_0||^2, x_0 = (1 1)^T
78 
79 BOOST_AUTO_TEST_CASE(test_biased) {
80  Eigen::MatrixXd Q(2, 2);
81  Q.setZero();
82  Q(0, 0) = 1.0;
83  Q(1, 1) = 1.0;
84 
85  Eigen::VectorXd C(2);
86  C(0) = -1.;
87  C(1) = -1.;
88 
89  Eigen::MatrixXd Aeq(2, 0);
90 
91  Eigen::VectorXd Beq(0);
92 
93  Eigen::MatrixXd Aineq(2, 0);
94 
95  Eigen::VectorXd Bineq(0);
96 
97  Eigen::VectorXd x(2);
98  Eigen::VectorXi activeSet(0);
99  size_t activeSetSize;
100 
101  Eigen::VectorXd solution(2);
102  solution(0) = 1.;
103  solution(1) = 1.;
104 
105  double val = -1.;
106 
107  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
108  x, activeSet, activeSetSize);
109 
110  BOOST_CHECK_CLOSE(out, val, 1e-6);
111 
112  BOOST_CHECK(x.isApprox(solution));
113 }
114 
115 // min ||x||^2
116 // s.t.
117 // x[1] = 1 - x[0]
118 
119 BOOST_AUTO_TEST_CASE(test_equality_constraints) {
120  Eigen::MatrixXd Q(2, 2);
121  Q.setZero();
122  Q(0, 0) = 1.0;
123  Q(1, 1) = 1.0;
124 
125  Eigen::VectorXd C(2);
126  C.setZero();
127 
128  Eigen::MatrixXd Aeq(2, 1);
129  Aeq(0, 0) = 1.;
130  Aeq(1, 0) = 1.;
131 
132  Eigen::VectorXd Beq(1);
133  Beq(0) = -1.;
134 
135  Eigen::MatrixXd Aineq(2, 0);
136 
137  Eigen::VectorXd Bineq(0);
138 
139  Eigen::VectorXd x(2);
140  Eigen::VectorXi activeSet(1);
141  size_t activeSetSize;
142 
143  Eigen::VectorXd solution(2);
144  solution(0) = 0.5;
145  solution(1) = 0.5;
146 
147  double val = 0.25;
148 
149  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
150  x, activeSet, activeSetSize);
151 
152  BOOST_CHECK_CLOSE(out, val, 1e-6);
153 
154  BOOST_CHECK(x.isApprox(solution));
155 }
156 
157 // min ||x||^2
158 // s.t.
159 // x[i] >= 1
160 
161 BOOST_AUTO_TEST_CASE(test_inequality_constraints) {
162  Eigen::MatrixXd Q(2, 2);
163  Q.setZero();
164  Q(0, 0) = 1.0;
165  Q(1, 1) = 1.0;
166 
167  Eigen::VectorXd C(2);
168  C.setZero();
169 
170  Eigen::MatrixXd Aeq(2, 0);
171 
172  Eigen::VectorXd Beq(0);
173 
174  Eigen::MatrixXd Aineq(2, 2);
175  Aineq.setZero();
176  Aineq(0, 0) = 1.;
177  Aineq(1, 1) = 1.;
178 
179  Eigen::VectorXd Bineq(2);
180  Bineq(0) = -1.;
181  Bineq(1) = -1.;
182 
183  Eigen::VectorXd x(2);
184  Eigen::VectorXi activeSet(2);
185  size_t activeSetSize;
186 
187  Eigen::VectorXd solution(2);
188  solution(0) = 1.;
189  solution(1) = 1.;
190 
191  double val = 1.;
192 
193  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
194  x, activeSet, activeSetSize);
195 
196  BOOST_CHECK_CLOSE(out, val, 1e-6);
197 
198  BOOST_CHECK(x.isApprox(solution));
199 }
200 
201 // min ||x-x_0||^2, x_0 = (1 1)^T
202 // s.t.
203 // x[1] = 5 - x[0]
204 // x[1] >= 3
205 
207  Eigen::MatrixXd Q(2, 2);
208  Q.setZero();
209  Q(0, 0) = 1.0;
210  Q(1, 1) = 1.0;
211 
212  Eigen::VectorXd C(2);
213  C(0) = -1.;
214  C(1) = -1.;
215 
216  Eigen::MatrixXd Aeq(2, 1);
217  Aeq(0, 0) = 1.;
218  Aeq(1, 0) = 1.;
219 
220  Eigen::VectorXd Beq(1);
221  Beq(0) = -5.;
222 
223  Eigen::MatrixXd Aineq(2, 1);
224  Aineq.setZero();
225  Aineq(1, 0) = 1.;
226 
227  Eigen::VectorXd Bineq(1);
228  Bineq(0) = -3.;
229 
230  Eigen::VectorXd x(2);
231  Eigen::VectorXi activeSet(2);
232  size_t activeSetSize;
233 
234  Eigen::VectorXd solution(2);
235  solution(0) = 2.;
236  solution(1) = 3.;
237 
238  double val = 1.5;
239 
240  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
241  x, activeSet, activeSetSize);
242 
243  BOOST_CHECK_CLOSE(out, val, 1e-6);
244 
245  BOOST_CHECK(x.isApprox(solution));
246 }
247 
248 // min ||x||^2
249 // s.t.
250 // x[0] = 1
251 // x[0] = -1
252 // DOES NOT WORK!
253 
254 BOOST_AUTO_TEST_CASE(test_unfeasible_equalities) {
255  Eigen::MatrixXd Q(2, 2);
256  Q.setZero();
257  Q(0, 0) = 1.0;
258  Q(1, 1) = 1.0;
259 
260  Eigen::VectorXd C(2);
261  C.setZero();
262 
263  Eigen::MatrixXd Aeq(2, 2);
264  Aeq.setZero();
265  Aeq(0, 0) = 1.;
266  Aeq(0, 1) = 1.;
267 
268  Eigen::VectorXd Beq(2);
269  Beq(0) = -1.;
270  Beq(1) = 1.;
271 
272  Eigen::MatrixXd Aineq(2, 0);
273 
274  Eigen::VectorXd Bineq(0);
275 
276  Eigen::VectorXd x(2);
277  Eigen::VectorXi activeSet(2);
278  size_t activeSetSize;
279 
280  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
281  x, activeSet, activeSetSize);
282 
283  // DOES NOT WORK!?
284  BOOST_WARN(std::isinf(out));
285 }
286 
287 // min ||x||^2
288 // s.t.
289 // x[0] >= 1
290 // x[0] <= -1
291 
292 BOOST_AUTO_TEST_CASE(test_unfeasible_inequalities) {
293  Eigen::MatrixXd Q(2, 2);
294  Q.setZero();
295  Q(0, 0) = 1.0;
296  Q(1, 1) = 1.0;
297 
298  Eigen::VectorXd C(2);
299  C.setZero();
300 
301  Eigen::MatrixXd Aeq(2, 0);
302 
303  Eigen::VectorXd Beq(0);
304 
305  Eigen::MatrixXd Aineq(2, 2);
306  Aineq.setZero();
307  Aineq(0, 0) = 1.;
308  Aineq(0, 1) = -1.;
309 
310  Eigen::VectorXd Bineq(2);
311  Bineq(0) = -1;
312  Bineq(1) = -1;
313 
314  Eigen::VectorXd x(2);
315  Eigen::VectorXi activeSet(2);
316  size_t activeSetSize;
317 
318  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
319  x, activeSet, activeSetSize);
320 
321  BOOST_CHECK(std::isinf(out));
322 }
323 
324 // min ||x-x_0||^2, x_0 = (1 1)^T
325 // s.t.
326 // x[1] = 1 - x[0]
327 // x[0] <= 0
328 // x[1] <= 0
329 
330 BOOST_AUTO_TEST_CASE(test_unfeasible_constraints) {
331  Eigen::MatrixXd Q(2, 2);
332  Q.setZero();
333  Q(0, 0) = 1.0;
334  Q(1, 1) = 1.0;
335 
336  Eigen::VectorXd C(2);
337  C(0) = -1.;
338  C(1) = -1.;
339 
340  Eigen::MatrixXd Aeq(2, 1);
341  Aeq(0, 0) = 1.;
342  Aeq(1, 0) = 1.;
343 
344  Eigen::VectorXd Beq(1);
345  Beq(0) = -1.;
346 
347  Eigen::MatrixXd Aineq(2, 2);
348  Aineq.setZero();
349  Aineq(0, 0) = -1.;
350  Aineq(1, 1) = -1.;
351 
352  Eigen::VectorXd Bineq(2);
353  Bineq.setZero();
354 
355  Eigen::VectorXd x(2);
356  Eigen::VectorXi activeSet(3);
357  size_t activeSetSize;
358 
359  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
360  x, activeSet, activeSetSize);
361 
362  BOOST_CHECK(std::isinf(out));
363 }
364 
365 // min -||x||^2
366 // DOES NOT WORK!
367 
368 BOOST_AUTO_TEST_CASE(test_unbounded) {
369  Eigen::MatrixXd Q(2, 2);
370  Q.setZero();
371  Q(0, 0) = -1.0;
372  Q(1, 1) = -1.0;
373 
374  Eigen::VectorXd C(2);
375  C.setZero();
376 
377  Eigen::MatrixXd Aeq(2, 0);
378 
379  Eigen::VectorXd Beq(0);
380 
381  Eigen::MatrixXd Aineq(2, 0);
382 
383  Eigen::VectorXd Bineq(0);
384 
385  Eigen::VectorXd x(2);
386  Eigen::VectorXi activeSet(0);
387  size_t activeSetSize;
388 
389  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
390  x, activeSet, activeSetSize);
391 
392  // DOES NOT WORK!?
393  BOOST_WARN(std::isinf(out));
394 }
395 
396 // min -||x||^2
397 // s.t.
398 // 0<= x[0] <= 1
399 // 0<= x[1] <= 1
400 // DOES NOT WORK!
401 
402 BOOST_AUTO_TEST_CASE(test_nonconvex) {
403  Eigen::MatrixXd Q(2, 2);
404  Q.setZero();
405  Q(0, 0) = -1.0;
406  Q(1, 1) = -1.0;
407 
408  Eigen::VectorXd C(2);
409  C.setZero();
410 
411  Eigen::MatrixXd Aeq(2, 0);
412 
413  Eigen::VectorXd Beq(0);
414 
415  Eigen::MatrixXd Aineq(2, 4);
416  Aineq.setZero();
417  Aineq(0, 0) = 1.;
418  Aineq(0, 1) = -1.;
419  Aineq(1, 2) = 1.;
420  Aineq(1, 3) = -1.;
421 
422  Eigen::VectorXd Bineq(4);
423  Bineq(0) = 0.;
424  Bineq(1) = 1.;
425  Bineq(2) = 0.;
426  Bineq(3) = 1.;
427 
428  Eigen::VectorXd x(2);
429  Eigen::VectorXi activeSet(4);
430  size_t activeSetSize;
431 
432  Eigen::VectorXd solution(2);
433  solution(0) = 1.;
434  solution(1) = 1.;
435 
436  double val = -1.;
437 
438  double out = eiquadprog::solvers::solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq,
439  x, activeSet, activeSetSize);
440 
441  // DOES NOT WORK!?
442  BOOST_WARN_CLOSE(out, val, 1e-6);
443 
444  BOOST_WARN(x.isApprox(solution));
445 }
446 
447 BOOST_AUTO_TEST_SUITE_END()
eiquadprog.hpp
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_unbiased)
Definition: eiquadprog-basic.cpp:43
eiquadprog::solvers::solve_quadprog
double solve_quadprog(Eigen::LLT< Eigen::MatrixXd, Eigen::Lower > &chol, double c1, Eigen::VectorXd &g0, const Eigen::MatrixXd &CE, const Eigen::VectorXd &ce0, const Eigen::MatrixXd &CI, const Eigen::VectorXd &ci0, Eigen::VectorXd &x, Eigen::VectorXi &A, size_t &q)


eiquadprog
Author(s): Gabriele Buondonno, Andrea Del Prete, Luca Di Gaspero, Angelo Furfaro, Benjamin Stephens, Gael Guennebaud
autogenerated on Wed May 28 2025 02:55:57