eiquadprog-rt.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 
20 
21 #include <Eigen/Core>
22 #include <boost/test/unit_test.hpp>
23 #include <iostream>
24 
25 using namespace eiquadprog::solvers;
26 
34 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
35 
36 // min ||x||^2
37 
38 BOOST_AUTO_TEST_CASE(test_unbiased) {
40 
42  Q.setZero();
43  Q(0, 0) = 1.0;
44  Q(1, 1) = 1.0;
45 
47  C.setZero();
48 
50 
51  RtVectorX<0>::d Beq;
52 
53  RtMatrixX<0, 2>::d Aineq;
54 
55  RtVectorX<0>::d Bineq;
56 
58 
59  RtVectorX<2>::d solution;
60  solution.setZero();
61 
62  double val = 0.0;
63 
65 
66  RtEiquadprog_status status =
67  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
68 
69  BOOST_CHECK_EQUAL(status, expected);
70 
71  BOOST_CHECK_CLOSE(qp.getObjValue(), val, 1e-6);
72 
73  BOOST_CHECK(x.isApprox(solution));
74 }
75 
76 // min ||x-x_0||^2, x_0 = (1 1)^T
77 
78 BOOST_AUTO_TEST_CASE(test_biased) {
80 
82  Q.setZero();
83  Q(0, 0) = 1.0;
84  Q(1, 1) = 1.0;
85 
87  C(0) = -1.;
88  C(1) = -1.;
89 
91 
92  RtVectorX<0>::d Beq;
93 
94  RtMatrixX<0, 2>::d Aineq;
95 
96  RtVectorX<0>::d Bineq;
97 
99 
100  RtVectorX<2>::d solution;
101  solution(0) = 1.;
102  solution(1) = 1.;
103 
104  double val = -1.;
105 
107 
108  RtEiquadprog_status status =
109  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
110 
111  BOOST_CHECK_EQUAL(status, expected);
112 
113  BOOST_CHECK_CLOSE(qp.getObjValue(), val, 1e-6);
114 
115  BOOST_CHECK(x.isApprox(solution));
116 }
117 
118 // min ||x||^2
119 // s.t.
120 // x[1] = 1 - x[0]
121 
122 BOOST_AUTO_TEST_CASE(test_equality_constraints) {
124 
126  Q.setZero();
127  Q(0, 0) = 1.0;
128  Q(1, 1) = 1.0;
129 
130  RtVectorX<2>::d C;
131  C.setZero();
132 
133  RtMatrixX<1, 2>::d Aeq;
134  Aeq(0, 0) = 1.;
135  Aeq(0, 1) = 1.;
136 
137  RtVectorX<1>::d Beq;
138  Beq(0) = -1.;
139 
140  RtMatrixX<0, 2>::d Aineq;
141 
142  RtVectorX<0>::d Bineq;
143 
144  RtVectorX<2>::d x;
145 
146  RtVectorX<2>::d solution;
147  solution(0) = 0.5;
148  solution(1) = 0.5;
149 
150  double val = 0.25;
151 
153 
154  RtEiquadprog_status status =
155  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
156 
157  BOOST_CHECK_EQUAL(status, expected);
158 
159  BOOST_CHECK_CLOSE(qp.getObjValue(), val, 1e-6);
160 
161  BOOST_CHECK(x.isApprox(solution));
162 }
163 
164 // min ||x||^2
165 // s.t.
166 // x[i] >= 1
167 
168 BOOST_AUTO_TEST_CASE(test_inequality_constraints) {
170 
172  Q.setZero();
173  Q(0, 0) = 1.0;
174  Q(1, 1) = 1.0;
175 
176  RtVectorX<2>::d C;
177  C.setZero();
178 
179  RtMatrixX<0, 2>::d Aeq;
180 
181  RtVectorX<0>::d Beq(0);
182 
183  RtMatrixX<2, 2>::d Aineq;
184  Aineq.setZero();
185  Aineq(0, 0) = 1.;
186  Aineq(1, 1) = 1.;
187 
188  RtVectorX<2>::d Bineq;
189  Bineq(0) = -1.;
190  Bineq(1) = -1.;
191 
192  RtVectorX<2>::d x;
193 
194  RtVectorX<2>::d solution;
195  solution(0) = 1.;
196  solution(1) = 1.;
197 
198  double val = 1.;
199 
201 
202  RtEiquadprog_status status =
203  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
204 
205  BOOST_CHECK_EQUAL(status, expected);
206 
207  BOOST_CHECK_CLOSE(qp.getObjValue(), val, 1e-6);
208 
209  BOOST_CHECK(x.isApprox(solution));
210 }
211 
212 // min ||x-x_0||^2, x_0 = (1 1)^T
213 // s.t.
214 // x[1] = 5 - x[0]
215 // x[1] >= 3
216 
219 
221  Q.setZero();
222  Q(0, 0) = 1.0;
223  Q(1, 1) = 1.0;
224 
225  RtVectorX<2>::d C;
226  C(0) = -1.;
227  C(1) = -1.;
228 
229  RtMatrixX<1, 2>::d Aeq;
230  Aeq(0, 0) = 1.;
231  Aeq(0, 1) = 1.;
232 
233  RtVectorX<1>::d Beq;
234  Beq(0) = -5.;
235 
236  RtMatrixX<1, 2>::d Aineq;
237  Aineq.setZero();
238  Aineq(0, 1) = 1.;
239 
240  RtVectorX<1>::d Bineq;
241  Bineq(0) = -3.;
242 
243  RtVectorX<2>::d x;
244 
245  RtVectorX<2>::d solution;
246  solution(0) = 2.;
247  solution(1) = 3.;
248 
249  double val = 1.5;
250 
252 
253  RtEiquadprog_status status =
254  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
255 
256  BOOST_CHECK_EQUAL(status, expected);
257 
258  BOOST_CHECK_CLOSE(qp.getObjValue(), val, 1e-6);
259 
260  BOOST_CHECK(x.isApprox(solution));
261 }
262 
263 // min ||x||^2
264 // s.t.
265 // x[0] = 1
266 // x[0] = -1
267 
268 BOOST_AUTO_TEST_CASE(test_unfeasible_equalities) {
270 
272  Q.setZero();
273  Q(0, 0) = 1.0;
274  Q(1, 1) = 1.0;
275 
276  RtVectorX<2>::d C;
277  C.setZero();
278 
279  RtMatrixX<2, 2>::d Aeq;
280  Aeq.setZero();
281  Aeq(0, 0) = 1.;
282  Aeq(1, 0) = 1.;
283 
284  RtVectorX<2>::d Beq;
285  Beq(0) = -1.;
286  Beq(1) = 1.;
287 
288  RtMatrixX<0, 2>::d Aineq;
289 
290  RtVectorX<0>::d Bineq;
291 
292  RtVectorX<2>::d x;
293 
295 
296  RtEiquadprog_status status =
297  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
298 
299  BOOST_CHECK_EQUAL(status, expected);
300 }
301 
302 // min ||x||^2
303 // s.t.
304 // x[0] >= 1
305 // x[0] <= -1
306 //
307 // correctly fails, but returns wrong error code
308 
309 BOOST_AUTO_TEST_CASE(test_unfeasible_inequalities) {
311 
313  Q.setZero();
314  Q(0, 0) = 1.0;
315  Q(1, 1) = 1.0;
316 
317  RtVectorX<2>::d C;
318  C.setZero();
319 
320  RtMatrixX<0, 2>::d Aeq;
321 
322  RtVectorX<0>::d Beq;
323 
324  RtMatrixX<2, 2>::d Aineq;
325  Aineq.setZero();
326  Aineq(0, 0) = 1.;
327  Aineq(1, 0) = -1.;
328 
329  RtVectorX<2>::d Bineq;
330  Bineq(0) = -1;
331  Bineq(1) = -1;
332 
333  RtVectorX<2>::d x;
334 
336 
337  RtEiquadprog_status status =
338  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
339 
340  BOOST_WARN_EQUAL(status, expected);
341  BOOST_CHECK(status != RT_EIQUADPROG_OPTIMAL);
342 }
343 
344 // min ||x-x_0||^2, x_0 = (1 1)^T
345 // s.t.
346 // x[1] = 1 - x[0]
347 // x[0] <= 0
348 // x[1] <= 0
349 //
350 // correctly fails, but returns wrong error code
351 
352 BOOST_AUTO_TEST_CASE(test_unfeasible_constraints) {
354 
356  Q.setZero();
357  Q(0, 0) = 1.0;
358  Q(1, 1) = 1.0;
359 
360  RtVectorX<2>::d C;
361  C(0) = -1.;
362  C(1) = -1.;
363 
364  RtMatrixX<1, 2>::d Aeq;
365  Aeq(0, 0) = 1.;
366  Aeq(0, 1) = 1.;
367 
368  RtVectorX<1>::d Beq;
369  Beq(0) = -1.;
370 
371  RtMatrixX<2, 2>::d Aineq;
372  Aineq.setZero();
373  Aineq(0, 0) = -1.;
374  Aineq(1, 1) = -1.;
375 
376  RtVectorX<2>::d Bineq;
377  Bineq.setZero();
378 
379  RtVectorX<2>::d x;
380 
382 
383  RtEiquadprog_status status =
384  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
385 
386  BOOST_WARN_EQUAL(status, expected);
387  BOOST_CHECK(status != RT_EIQUADPROG_OPTIMAL);
388 }
389 
390 // min -||x||^2
391 // DOES NOT WORK!
392 
393 BOOST_AUTO_TEST_CASE(test_unbounded) {
395 
397  Q.setZero();
398  Q(0, 0) = -1.0;
399  Q(1, 1) = -1.0;
400 
401  RtVectorX<2>::d C;
402  C.setZero();
403 
404  RtMatrixX<0, 2>::d Aeq;
405 
406  RtVectorX<0>::d Beq;
407 
408  RtMatrixX<0, 2>::d Aineq;
409 
410  RtVectorX<0>::d Bineq;
411 
412  RtVectorX<2>::d x;
413 
415 
416  RtEiquadprog_status status =
417  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
418 
419  BOOST_WARN_EQUAL(status, expected);
420  BOOST_WARN(status != RT_EIQUADPROG_OPTIMAL); // SHOULD pass!
421 }
422 
423 // min -||x||^2
424 // s.t.
425 // 0<= x[0] <= 1
426 // 0<= x[1] <= 1
427 // DOES NOT WORK!
428 
429 BOOST_AUTO_TEST_CASE(test_nonconvex) {
431 
433  Q.setZero();
434  Q(0, 0) = -1.0;
435  Q(1, 1) = -1.0;
436 
437  RtVectorX<2>::d C;
438  C.setZero();
439 
440  RtMatrixX<0, 2>::d Aeq;
441 
442  RtVectorX<0>::d Beq;
443 
444  RtMatrixX<4, 2>::d Aineq(4, 2);
445  Aineq.setZero();
446  Aineq(0, 0) = 1.;
447  Aineq(1, 0) = -1.;
448  Aineq(2, 1) = 1.;
449  Aineq(3, 1) = -1.;
450 
451  RtVectorX<4>::d Bineq;
452  Bineq(0) = 0.;
453  Bineq(1) = 1.;
454  Bineq(2) = 0.;
455  Bineq(3) = 1.;
456 
457  RtVectorX<2>::d x;
458 
459  RtVectorX<2>::d solution;
460  solution(0) = 1.;
461  solution(1) = 1.;
462 
463  double val = -1.;
464 
466 
467  RtEiquadprog_status status =
468  qp.solve_quadprog(Q, C, Aeq, Beq, Aineq, Bineq, x);
469 
470  BOOST_CHECK_EQUAL(status, expected);
471 
472  BOOST_WARN_CLOSE(qp.getObjValue(), val, 1e-6);
473 
474  BOOST_WARN(x.isApprox(solution));
475 }
476 
477 BOOST_AUTO_TEST_SUITE_END()
eiquadprog::solvers::RtEiquadprog
Definition: eiquadprog-rt.hpp:89
eiquadprog-rt.hpp
eiquadprog::solvers::RT_EIQUADPROG_REDUNDANT_EQUALITIES
@ RT_EIQUADPROG_REDUNDANT_EQUALITIES
Definition: eiquadprog-rt.hpp:85
eiquadprog::solvers::RtEiquadprog::solve_quadprog
RtEiquadprog_status solve_quadprog(const typename RtMatrixX< nVars, nVars >::d &Hess, const typename RtVectorX< nVars >::d &g0, const typename RtMatrixX< nEqCon, nVars >::d &CE, const typename RtVectorX< nEqCon >::d &ce0, const typename RtMatrixX< nIneqCon, nVars >::d &CI, const typename RtVectorX< nIneqCon >::d &ci0, typename RtVectorX< nVars >::d &x)
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_unbiased)
Definition: eiquadprog-rt.cpp:38
eiquadprog::solvers::RT_EIQUADPROG_INFEASIBLE
@ RT_EIQUADPROG_INFEASIBLE
Definition: eiquadprog-rt.hpp:82
eiquadprog::solvers::RT_EIQUADPROG_OPTIMAL
@ RT_EIQUADPROG_OPTIMAL
Definition: eiquadprog-rt.hpp:81
RtMatrixX::d
Eigen::Matrix< double, Rows, Cols > d
Definition: eiquadprog-rt.hpp:64
eiquadprog::solvers::RT_EIQUADPROG_UNBOUNDED
@ RT_EIQUADPROG_UNBOUNDED
Definition: eiquadprog-rt.hpp:83
eiquadprog::solvers::RtEiquadprog::getObjValue
double getObjValue() const
Definition: eiquadprog-rt.hpp:118
eiquadprog::solvers
Definition: eiquadprog-fast.hpp:65
eiquadprog::solvers::RtEiquadprog_status
RtEiquadprog_status
Definition: eiquadprog-rt.hpp:80
RtVectorX::d
Eigen::Matrix< double, Rows, 1 > d
Definition: eiquadprog-rt.hpp:69


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