ocra-recipes
Doxygen documentation for the ocra-recipes repository
SolverUtilities.hxx
Go to the documentation of this file.
1 #ifndef _OCRA_SOLVER_UTILITIES_HXX_
2 #define _OCRA_SOLVER_UTILITIES_HXX_
3 
4 #ifdef WIN32
5 # pragma once
6 #endif
7 
8 namespace ocra
9 {
10  namespace utils
11  {
12  template<class Derived, class VectorBase>
13  inline void printLinearEquation(const MatrixBase<Derived>& A, const VectorBase& b, int space, int precision)
14  {
16  ocra_assert(b.rows()==1 || b.cols()==1);
17  double eps = 1.e-8;
18  double zero = 1.e-15;
19  ocra_assert(A.rows() == b.size());
20 
21  for (int r=0; r<A.rows(); ++r)
22  {
23  if (r%10 == 0)
24  {
25  for (int c=0; c<A.cols(); ++c)
26  {
27  if (c%10 == 0)
28  std::cout << (c/10)%10 << "-";
29  else
30  std::cout << "-";
31  for (int i=0; i<space; ++i)
32  std::cout << "-";
33  }
34  std::cout << std::endl;
35  }
36 
37  for (int c=0; c<A.cols(); ++c)
38  {
39  if (c%10 == 0)
40  std::cout << "|";
41  if (std::abs(A(r,c)) < eps)
42  {
43  if (A(r,c)>zero)
44  std::cout << std::setw(space) << "+eps";
45  else if (A(r,c)<-zero)
46  std::cout << std::setw(space) << "-eps";
47  else
48  std::cout << std::setw(space) << "0";
49  }
50  else
51  {
52  if (std::abs(A(r,c)) < 0.01)
53  std::cout << std::setw(space) << std::setprecision(precision-1) << A(r,c);
54  else
55  std::cout << std::setw(space) << std::setprecision(precision) << A(r,c);
56  }
57  if (c<A.cols()-1)
58  std::cout << ",";
59  }
60 
61  std::cout << " ";
62  if (std::abs(b[r]) < eps)
63  {
64  if (b[r]>zero)
65  std::cout << std::setw(space) << "+eps" << std::endl;
66  else if (b[r]<-zero)
67  std::cout << std::setw(space) << "-eps" << std::endl;
68  else
69  std::cout << std::setw(space) << "0" << std::endl;
70  }
71  else
72  std::cout << std::setw(space) << std::setprecision(precision) << b[r] << std::endl;
73  }
74 
75  std::cout << std::endl;
76  }
77 
78 /* uncompressedByCol
79  uncompressedByRow
80  uncompressed2d*/
81 
82  template<class Derived1, class Derived2>
83  inline void uncompressByCol(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
84  const std::vector<int>& mapping, double scale, bool reverseMapping)
85  {
86  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
87  if (reverseMapping)
89  else
91 
92  }
93 
94  // const_cast Eigen trick : http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html#TopicPlainFunctionsFailing
95  template<class Derived1, class Derived2>
96  inline void uncompressByCol(const Variable& base, const Variable& rel,
97  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
98  std::vector<int>& mapping, double scale)
99  {
100  ocra_assert(in.rows() == _out.rows());
101  ocra_assert(_out.cols() == base.getSize());
102  ocra_assert(in.cols() == rel.getSize());
103 
104  base.getRelativeMappingOf(rel, mapping);
105  if (mapping.size() != rel.getSize())
106  throw std::runtime_error("[ocra::utils::uncompressByCol] base variable does not contains relative variable" );
107 
108  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
109  uncompressByCol(in, out, mapping, scale);
110  }
111 
112  template<class Derived1, class Derived2>
113  inline void uncompressByRow(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
114  const std::vector<int>& mapping, double scale, bool reverseMapping)
115  {
116  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
117  if (reverseMapping)
119  else
120  uncompress<assign_functor, true>::uncompressByRow(in, out, mapping, scale);
121  }
122 
123  template<class Derived1, class Derived2>
124  inline void uncompressByRow(const Variable& base, const Variable& rel,
125  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
126  std::vector<int>& mapping, double scale)
127  {
128  ocra_assert(in.cols() == out.cols());
129  ocra_assert(out.cols() == base.getSize());
130  ocra_assert(in.cols() == rel.getSize());
131 
132  base.getRelativeMappingOf(rel, mapping);
133  if (mapping.size() != rel.getSize())
134  throw std::runtime_error("[ocra::utils::uncompressByRow] base variable does not contains relative variable" );
135 
136  uncompressbyRow(in, out, mapping, scale);
137  }
138 
139  template<class Derived1, class Derived2>
140  inline void uncompress2d(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
141  const std::vector<int>& mapping, double scale, bool reverseMapping)
142  {
143  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
144  if (reverseMapping)
145  uncompress<assign_functor, false>::uncompress2d(in, out, mapping, mapping, scale);
146  else
147  uncompress<assign_functor, true>::uncompress2d(in, out, mapping, mapping, scale);
148  }
149 
150  template<class Derived1, class Derived2>
151  inline void uncompress2d(const Variable& base, const Variable& rel,
152  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
153  std::vector<int>& mapping, double scale)
154  {
155  ocra_assert(out.cols() == base.getSize());
156  ocra_assert(in.cols() == rel.getSize());
157 
158  base.getRelativeMappingOf(rel, mapping);
159  if (mapping.size() != rel.getSize())
160  throw std::runtime_error("[ocra::utils::uncompress2d] base variable does not contains relative variable" );
161 
162  uncompress2d(in, out, mapping, scale);
163  }
164 
165 
166 
167 /* addCompressedByCol
168  addCompressedByRow
169  addCompressed2d*/
170 
171  template<class Derived1, class Derived2>
172  inline void addCompressedByCol(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
173  const std::vector<int>& mapping, double scale, bool reverseMapping)
174  {
175  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
176  if (reverseMapping)
177  uncompress<add_functor, false>::uncompressByCol(in, out, mapping, scale);
178  else
179  uncompress<add_functor, true>::uncompressByCol(in, out, mapping, scale);
180  }
181 
182  template<class Derived1, class Derived2>
183  inline void addCompressedByCol(const Variable& base, const Variable& rel,
184  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
185  std::vector<int>& mapping, double scale)
186  {
187  ocra_assert(in.rows() == out.rows());
188  ocra_assert(out.cols() == base.getSize());
189  ocra_assert(in.cols() == rel.getSize());
190 
191  base.getRelativeMappingOf(rel, mapping);
192  if (mapping.size() != rel.getSize())
193  throw std::runtime_error("[ocra::utils::addCompressByCol] base variable does not contains relative variable" );
194 
195  addCompressByCol(in, out, mapping, scale);
196  }
197 
198  template<class Derived1, class Derived2>
199  inline void addCompressedByRow(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
200  const std::vector<int>& mapping, double scale, bool reverseMapping)
201  {
202  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
203  if (reverseMapping)
204  uncompress<add_functor, false>::uncompressByRow(in, out, mapping, scale);
205  else
206  uncompress<add_functor, true>::uncompressByRow(in, out, mapping, scale);
207  }
208 
209  template<class Derived1, class Derived2>
210  inline void addCompressedByRow(const Variable& base, const Variable& rel,
211  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
212  std::vector<int>& mapping, double scale)
213  {
214  ocra_assert(in.cols() == out.cols());
215  ocra_assert(out.cols() == base.getSize());
216  ocra_assert(in.cols() == rel.getSize());
217 
218  base.getRelativeMappingOf(rel, mapping);
219  if (mapping.size() != rel.getSize())
220  throw std::runtime_error("[ocra::utils::addCompressedByRow] base variable does not contains relative variable" );
221 
222  addCompressedByRow(in, out, mapping, scale);
223  }
224 
225  template<class Derived1, class Derived2>
226  inline void addCompressed2d(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
227  const std::vector<int>& mapping, double scale, bool reverseMapping)
228  {
229  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
230  if (reverseMapping)
231  uncompress<add_functor, false>::uncompress2d(in, out, mapping, mapping, scale);
232  else
233  uncompress<add_functor, true>::uncompress2d(in, out, mapping, mapping, scale);
234  }
235 
236  template<class Derived1, class Derived2>
237  inline void addCompressed2d(const Variable& base, const Variable& rel,
238  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
239  std::vector<int>& mapping, double scale)
240  {
241  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
242  ocra_assert(out.cols() == base.getSize());
243  ocra_assert(in.cols() == rel.getSize());
244 
245  base.getRelativeMappingOf(rel, mapping);
246  if (mapping.size() != rel.getSize())
247  throw std::runtime_error("[ocra::utils::addCompressed2d] base variable does not contains relative variable" );
248 
249  addCompressed2d(in, out, mapping, scale);
250  }
251 
252 
253 
254 /* minCompressedByCol
255  minCompressedByRow
256  minCompressed2d*/
257 
258  template<class Derived1, class Derived2>
259  inline void minCompressedByCol(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
260  const std::vector<int>& mapping, double scale, bool reverseMapping)
261  {
262  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
263  if (reverseMapping)
264  uncompress<min_functor, false>::uncompressByCol(in, out, mapping, scale);
265  else
266  uncompress<min_functor, true>::uncompressByCol(in, out, mapping, scale);
267  }
268 
269  template<class Derived1, class Derived2>
270  inline void minCompressedByCol(const Variable& base, const Variable& rel,
271  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
272  std::vector<int>& mapping, double scale)
273  {
274  ocra_assert(in.rows() == out.rows());
275  ocra_assert(out.cols() == base.getSize());
276  ocra_assert(in.cols() == rel.getSize());
277 
278  base.getRelativeMappingOf(rel, mapping);
279  if (mapping.size() != rel.getSize())
280  throw std::runtime_error("[ocra::utils::minCompressedByCol] base variable does not contains relative variable" );
281 
282  minCompressedByCol(in, out, mapping, scale);
283  }
284 
285  template<class Derived1, class Derived2>
286  inline void minCompressedByRow(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
287  const std::vector<int>& mapping, double scale, bool reverseMapping)
288  {
289  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
290  if (reverseMapping)
291  uncompress<min_functor, false>::uncompressByRow(in, out, mapping, scale);
292  else
293  uncompress<min_functor, true>::uncompressByRow(in, out, mapping, scale);
294  }
295 
296  template<class Derived1, class Derived2>
297  inline void minCompressedByRow(const Variable& base, const Variable& rel,
298  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
299  std::vector<int>& mapping, double scale)
300  {
301  ocra_assert(in.cols() == out.cols());
302  ocra_assert(out.cols() == base.getSize());
303  ocra_assert(in.cols() == rel.getSize());
304 
305  base.getRelativeMappingOf(rel, mapping);
306  if (mapping.size() != rel.getSize())
307  throw std::runtime_error("[ocra::utils::minCompressedByRow] base variable does not contains relative variable" );
308 
309  minCompressedByRow(in, out, mapping, scale);
310  }
311 
312  template<class Derived1, class Derived2>
313  inline void minCompressed2d(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
314  const std::vector<int>& mapping, double scale, bool reverseMapping)
315  {
316  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
317  if (reverseMapping)
318  uncompress<min_functor, false>::uncompress2d(in, out, mapping, mapping, scale);
319  else
320  uncompress<min_functor, true>::uncompress2d(in, out, mapping, mapping, scale);
321  }
322 
323  template<class Derived1, class Derived2>
324  inline void minCompressed2d(const Variable& base, const Variable& rel,
325  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
326  std::vector<int>& mapping, double scale)
327  {
328  ocra_assert(out.cols() == base.getSize());
329  ocra_assert(in.cols() == rel.getSize());
330 
331  base.getRelativeMappingOf(rel, mapping);
332  if (mapping.size() != rel.getSize())
333  throw std::runtime_error("[ocra::utils::minCompressed2d] base variable does not contains relative variable" );
334 
335  minCompressed2d(in, out, mapping, scale);
336  }
337 
338 
339 /* maxCompressedByCol
340  maxCompressedByRow
341  maxCompressed2d*/
342 
343  template<class Derived1, class Derived2>
344  inline void maxCompressedByCol(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
345  const std::vector<int>& mapping, double scale, bool reverseMapping)
346  {
347  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
348  if (reverseMapping)
349  uncompress<max_functor, false>::uncompressByCol(in, out, mapping, scale);
350  else
351  uncompress<max_functor, true>::uncompressByCol(in, out, mapping, scale);
352  }
353 
354  template<class Derived1, class Derived2>
355  inline void maxCompressedByCol(const Variable& base, const Variable& rel,
356  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
357  std::vector<int>& mapping, double scale)
358  {
359  ocra_assert(in.rows() == out.rows());
360  ocra_assert(out.cols() == base.getSize());
361  ocra_assert(in.cols() == rel.getSize());
362 
363  base.getRelativeMappingOf(rel, mapping);
364  if (mapping.size() != rel.getSize())
365  throw std::runtime_error("[ocra::utils::maxCompressedByCol] base variable does not contains relative variable" );
366 
367  maxCompressedByCol(in, out, mapping, scale);
368  }
369 
370  template<class Derived1, class Derived2>
371  inline void maxCompressedByRow(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
372  const std::vector<int>& mapping, double scale, bool reverseMapping)
373  {
374  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
375  if (reverseMapping)
376  uncompress<max_functor, false>::uncompressByRow(in, out, mapping, scale);
377  else
378  uncompress<max_functor, true>::uncompressByRow(in, out, mapping, scale);
379  }
380 
381  template<class Derived1, class Derived2>
382  inline void maxCompressedByRow(const Variable& base, const Variable& rel,
383  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
384  std::vector<int>& mapping, double scale)
385  {
386  ocra_assert(in.cols() == out.cols());
387  ocra_assert(out.cols() == base.getSize());
388  ocra_assert(in.cols() == rel.getSize());
389 
390  base.getRelativeMappingOf(rel, mapping);
391  if (mapping.size() != rel.getSize())
392  throw std::runtime_error("[ocra::utils::maxCompressedByRow] base variable does not contains relative variable" );
393 
394  maxCompressedByRow(in, out, mapping, scale);
395  }
396 
397  template<class Derived1, class Derived2>
398  inline void maxCompressed2d(const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& _out,
399  const std::vector<int>& mapping, double scale, bool reverseMapping)
400  {
401  MatrixBase<Derived2>& out = const_cast<MatrixBase<Derived2>& >(_out);
402  if (reverseMapping)
403  uncompress<max_functor, false>::uncompress2d(in, out, mapping, mapping, scale);
404  else
405  uncompress<max_functor, true>::uncompress2d(in, out, mapping, mapping, scale);
406  }
407 
408  template<class Derived1, class Derived2>
409  inline void maxCompressed2d(const Variable& base, const Variable& rel,
410  const MatrixBase<Derived1>& in, MatrixBase<Derived2> const& out,
411  std::vector<int>& mapping, double scale)
412  {
413  ocra_assert(out.cols() == base.getSize());
414  ocra_assert(in.cols() == rel.getSize());
415 
416  base.getRelativeMappingOf(rel, mapping);
417  if (mapping.size() != rel.getSize())
418  throw std::runtime_error("[ocra::utils::maxCompressed2d] base variable does not contains relative variable" );
419 
420  maxCompressed2d(in, out, mapping, scale);
421  }
422 
423 
424  namespace details
425  {
426  // const_cast Eigen trick : http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html#TopicPlainFunctionsFailing
427  template<class Derived, class VectorDerived>
428  void convert_(const LinearConstraint& cstr, eConstraintType apparentType, const std::vector<int>& mapping, eConvertCase convertCase,
429  MatrixBase<Derived>& A, MatrixBase<VectorDerived> const & _b)
430  {
431  VectorXd dummy;
432  const VectorXd* v;
433  switch (apparentType)
434  {
435  case CSTR_EQUAL_B: v = &cstr.getB(); break;
436  case CSTR_LOWER_U: v = &cstr.getU(); break;
437  case CSTR_GREATER_L: v = &cstr.getL(); break;
438  default:
439  v = &dummy;
440  }
441 
442  MatrixBase<VectorDerived>& b = const_cast<MatrixBase<VectorDerived>& >(_b);
443  convert(cstr.getFunction().getA(), cstr.getFunction().getb(), *v, A, b, mapping, convertCase);
444  }
445 
446 
447  template<class DerivedIn, class VectorBaseIn1, class VectorBaseIn2, class DerivedOut, class VectorBaseOut>
448  inline void convert(const MatrixBase<DerivedIn>& M, const VectorBaseIn1& v1, const VectorBaseIn2& v2,
449  MatrixBase<DerivedOut>& A, VectorBaseOut& b,
450  const std::vector<int>& mapping,
451  details::eConvertCase convertCase)
452  {
454  ocra_assert(v1.cols()==1);
456  ocra_assert(v2.cols()==1);
457  ocra_assert(M.rows()== A.rows() && "Input and output matrices do not have the same row size");
458  ocra_assert(v1.size()== b.size() && "Input and output vectors do not have the same size");
459 
460  switch (convertCase)
461  {
462  case details::PLUS_A_PLUS_B: uncompressByCol(M, A, mapping, 1.); b = v1; break;
463  case details::PLUS_A_MINUS_B: uncompressByCol(M, A, mapping, 1.); b = -v1; break;
464  case details::PLUS_A_PLUS_BV: uncompressByCol(M, A, mapping, 1.); b = v1-v2; break;
465  case details::PLUS_A_MINUS_BV: uncompressByCol(M, A, mapping, 1.); b = v2-v1; break;
466  case details::MINUS_A_PLUS_B: uncompressByCol(M, A, mapping, -1.); b = v1; break;
467  case details::MINUS_A_MINUS_B: uncompressByCol(M, A, mapping, -1.); b = -v1; break;
468  case details::MINUS_A_PLUS_BV: uncompressByCol(M, A, mapping, -1.); b = v1-v2; break;
469  case details::MINUS_A_MINUS_BV: uncompressByCol(M, A, mapping, -1.); b = v2-v1; break;
470  default:
471  ocra_assert(false && "this should never happen");
472  }
473  }
474  } // details
475 
476 
477  template<class Derived, class VectorBase1, class VectorBase2>
478  inline void convert(const LinearConstraint& cstr, const std::vector<int>& mapping, eConstraintOutput type,
479  MatrixBase<Derived>& A, VectorBase1& b, VectorBase2& l, double infinity)
480  {
481  details::eConvertCase cvrtCase = conversion_cases[type][cstr.getType()];
482 
483  ocra_assert(cvrtCase != details::IMPOSSIBLE_CASE && "You cannot do this conversion.");
484 
485  VectorXd dummy;
486  if (cvrtCase != details::SPECIAL_CASE)
487  {
488  if (type != CSTR_DOUBLE_BOUNDS)
489  {
490  details::convert_(cstr, cstr.getType(), mapping, cvrtCase, A, b);
491  }
492  else
493  {
494  ocra_assert(infinity > 0 && "if you use this type of output (CSTR_DOUBLE_BOUNDS), please specify its value (last argument of convert())");
495  switch (cstr.getType())
496  {
497  case CSTR_LOWER_ZERO:
498  details::convert(cstr.getFunction().getA(), cstr.getFunction().getb(), dummy, A, b, mapping, cvrtCase); l.fill(-infinity);
499  break;
500  case CSTR_LOWER_U:
501  details::convert(cstr.getFunction().getA(), cstr.getFunction().getb(), cstr.getU(), A, b, mapping, cvrtCase); l.fill(-infinity);
502  break;
503  case CSTR_GREATER_ZERO:
504  details::convert(cstr.getFunction().getA(), cstr.getFunction().getb(), dummy, A, l, mapping, cvrtCase); b.fill(infinity);
505  break;
506  case CSTR_GREATER_L:
507  details::convert(cstr.getFunction().getA(), cstr.getFunction().getb(), cstr.getL(), A, l, mapping, cvrtCase); b.fill(infinity);
508  break;
509  default:
510  ocra_assert(false && "this should never happen");
511  }
512  }
513  }
514  else
515  {
516  if (type != CSTR_DOUBLE_BOUNDS)
517  {
518  int dim = cstr.getDimension();
519  ocra_assert(A.rows() == 2*dim && "Output matrix A does not have the correct number of rows");
520  ocra_assert(b.size() == 2*dim && "Output vector b does not have the correct dimension");
521  Eigen::Block<Derived> A_block_0 = A.block(0, 0, dim, A.cols());
522  Eigen::Block<Derived> A_block_dim = A.block(dim, 0, dim, A.cols());
523 
524  switch (type)
525  {
526  case CSTR_PLUS_LOWER:
527  details::convert_(cstr, CSTR_LOWER_U, mapping, details::PLUS_A_PLUS_BV, A_block_0, b.head(dim));
528  details::convert_(cstr, CSTR_GREATER_L, mapping, details::MINUS_A_MINUS_BV, A_block_dim, b.tail(dim));
529  break;
530  case CSTR_MINUS_LOWER:
531  details::convert_(cstr, CSTR_LOWER_U, mapping, details::PLUS_A_MINUS_BV, A_block_0, b.head(dim));
532  details::convert_(cstr, CSTR_GREATER_L, mapping, details::MINUS_A_PLUS_BV, A_block_dim, b.tail(dim));
533  break;
534  case CSTR_PLUS_GREATER:
535  details::convert_(cstr, CSTR_LOWER_U, mapping, details::MINUS_A_MINUS_BV, A_block_0, b.head(dim));
536  details::convert_(cstr, CSTR_GREATER_L, mapping, details::PLUS_A_PLUS_BV, A_block_dim, b.tail(dim));
537  break;
538  case CSTR_MINUS_GREATER:
539  details::convert_(cstr, CSTR_LOWER_U, mapping, details::MINUS_A_PLUS_BV, A_block_0, b.head(dim));
540  details::convert_(cstr, CSTR_GREATER_L, mapping, details::PLUS_A_MINUS_BV, A_block_dim, b.tail(dim));
541  break;
542  default:
543  ocra_assert(false && "this should never happen");
544  }
545  }
546  else
547  {
548  details::convert(cstr.getFunction().getA(), cstr.getFunction().getb(), cstr.getU(), A, b, mapping, details::PLUS_A_MINUS_BV);
549  l = cstr.getL() - cstr.getFunction().getb();
550  }
551  }
552  }
553 
554 
555  template<class VectorBase1, class VectorBase2>
556  inline void intersectBounds(const DiagonalLinearConstraint& bounds, const std::vector<int>& mapping, VectorBase1& bl, VectorBase2& bu)
557  {
559  ocra_assert(bl.rows()==1 || bl.cols()==1);
561  ocra_assert(bu.rows()==1 || bu.cols()==1);
562  ocra_assert((dynamic_cast<const BoundConstraint*>(&bounds) || dynamic_cast<const IdentityConstraint*>(&bounds)) && "bounds can only be of type BoundConstraint or IdentityConstraint");
563 
564  //TODO [done]: corriger pour les DiagonalLinearFunction avec -I (bornes inf)
565  //-> TODO: validate
566 
567  if (bounds.getDimension() == 0)
568  return;
569  if (bounds.getFunction().getA()(0,0) > 0) //i.e. A is the identity
570  {
571  switch(bounds.getType())
572  {
573  case CSTR_LOWER_ZERO: utils::minCompressedByRow( - bounds.getFunction().getb(), bu, mapping); break;
574  case CSTR_LOWER_U: utils::minCompressedByRow(bounds.getU() - bounds.getFunction().getb(), bu, mapping); break;
575  case CSTR_GREATER_ZERO: utils::maxCompressedByRow( - bounds.getFunction().getb(), bl, mapping); break;
576  case CSTR_GREATER_L: utils::maxCompressedByRow(bounds.getL() - bounds.getFunction().getb(), bl, mapping); break;
577  case CSTR_LOWER_AND_GREATER: utils::minCompressedByRow(bounds.getU() - bounds.getFunction().getb(), bu, mapping);
578  utils::maxCompressedByRow(bounds.getL() - bounds.getFunction().getb(), bl, mapping); break;
579  default:
580  ocra_assert(false && "should never happen, the constraint should be a bound constraint, hence an inequality");
581  }
582  }
583  else //i.e. A is the -I
584  {
585  switch(bounds.getType())
586  {
587  case CSTR_LOWER_ZERO: utils::maxCompressedByRow(bounds.getFunction().getb() , bl, mapping); break;
588  case CSTR_LOWER_U: utils::maxCompressedByRow(bounds.getFunction().getb() - bounds.getU(), bl, mapping); break;
589  case CSTR_GREATER_ZERO: utils::minCompressedByRow(bounds.getFunction().getb() , bu, mapping); break;
590  case CSTR_GREATER_L: utils::minCompressedByRow(bounds.getFunction().getb() - bounds.getL(), bu, mapping); break;
591  case CSTR_LOWER_AND_GREATER: utils::maxCompressedByRow(bounds.getFunction().getb() - bounds.getU(), bl, mapping);
592  utils::minCompressedByRow(bounds.getFunction().getb() - bounds.getL(), bu, mapping); break;
593  default:
594  ocra_assert(false && "should never happen, the constraint should be a bound constraint, hence an inequality");
595  }
596  }
597  }
598  }
599 }
600 
601 #endif // _OCRA_SOLVER_UTILITIES_HXX_
602 
603 // cmake:sourcegroup=Solvers
void minCompressedByCol(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
void addCompressedByCol(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
const details::eConvertCase conversion_cases[7][7]
void addCompressed2d(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
void minCompressedByRow(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
void convert_(const LinearConstraint &cstr, eConstraintType apparentType, const std::vector< int > &mapping, eConvertCase convertCase, MatrixBase< Derived > &A, MatrixBase< VectorDerived > const &_b)
void getRelativeMappingOf(const Variable &subVariable, std::vector< int > &mapping) const
Returns the indexes of a subvariable in the variable.
Definition: Variable.cpp:175
static void uncompress2d(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > &out, const std::vector< int > &mappingRow, const std::vector< int > &mappingCol, double scale)
Definition: uncompress.h:168
void uncompressByCol(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
void uncompressByRow(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
eConstraintOutput
static void uncompressByRow(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > &out, const std::vector< int > &mapping, double scale)
Definition: uncompress.h:140
Constraint class.
Definition: Constraint.h:100
void uncompress2d(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
int getSize() const
Definition: Variable.cpp:81
This class represents a variable in a mathematical sense.
Definition: Variable.h:105
void addCompressedByRow(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
void maxCompressed2d(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
virtual T & getFunction(void)
Definition: Constraint.h:156
void intersectBounds(const DiagonalLinearConstraint &bounds, const std::vector< int > &mapping, VectorBase1 &bl, VectorBase2 &bu)
void convert(const MatrixBase< DerivedIn > &M, const VectorBaseIn1 &v1, const VectorBaseIn2 &v2, MatrixBase< DerivedOut > &A, VectorBaseOut &b, const std::vector< int > &mapping, details::eConvertCase convertCase)
void maxCompressedByRow(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
void maxCompressedByCol(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)
#define ocra_assert(ocra_expression)
Definition: ocra_assert.h:45
static void uncompressByCol(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > &out, const std::vector< int > &mapping, double scale)
Definition: uncompress.h:111
#define OCRA_STATIC_ASSERT_VECTOR_OR_DYNAMIC_MATRIX(TYPE)
Definition: MathTypes.h:31
void printLinearEquation(const MatrixBase< Derived > &A, const VectorBase &b, int space=9, int precision=3)
eConstraintType
Definition: Constraint.h:49
void minCompressed2d(const MatrixBase< Derived1 > &in, MatrixBase< Derived2 > const &_out, const std::vector< int > &mapping, double scale, bool reverseMapping)