31 template <
typename SCALAR >
32 LpExpr& LpExpr::operator=(
const SCALAR& rhs) {
41 template <
typename T >
42 LpExpr& LpExpr::operator+=(
const T& rhs) {
43 if (ileft__ || iright__)
44 GUM_ERROR(OperationNotAllowed,
45 "expr::operator+= (expr) : <= present on one side of expr");
47 if (!imiddle__) imiddle__ =
true;
54 template <
typename T >
55 LpExpr& LpExpr::operator-=(
const T& rhs) {
56 if (ileft__ || iright__)
57 GUM_ERROR(OperationNotAllowed,
58 "expr::operator-= (rhs) : <= present in one of expr");
60 if (!imiddle__) imiddle__ =
true;
67 template <
typename SCALAR >
68 void LpExpr::addSide__(
const SCALAR& from) {
72 }
else if (!imiddle__) {
75 }
else if (!iright__) {
79 GUM_ERROR(OperationNotAllowed,
80 "LpExpr::setSide ( const LpCol & from " 81 ") : too many <= ; no free side");
87 template <
typename GUM_SCALAR >
88 LpInterface< GUM_SCALAR >::LpInterface() {
91 GUM_CONSTRUCTOR(LpInterface);
94 template <
typename GUM_SCALAR >
95 LpInterface< GUM_SCALAR >::LpInterface(
96 const LpInterface< GUM_SCALAR >& from) :
98 positivity__(from.positivity__), sumIsOne__(from.sumIsOne__) {
99 rows__.resize(from.rows__.size());
101 for (
unsigned int i = 0, end = from.rows__.size(); i < end; i++)
102 rows__[i] =
new LpRow(*from.rows__[i]);
104 GUM_CONS_CPY(LpInterface);
107 template <
typename GUM_SCALAR >
108 LpInterface< GUM_SCALAR >::LpInterface(LpInterface< GUM_SCALAR >&& from) :
109 positivity__(from.positivity__), sumIsOne__(from.sumIsOne__) {
110 rows__.swap(from.rows__);
111 cols__.swap(from.cols__);
112 GUM_CONS_CPY(LpInterface);
115 template <
typename GUM_SCALAR >
116 LpInterface< GUM_SCALAR >::~LpInterface() {
117 for (
const auto row: rows__)
120 GUM_DESTRUCTOR(LpInterface);
123 template <
typename GUM_SCALAR >
124 LpInterface< GUM_SCALAR >& LpInterface< GUM_SCALAR >::operator=(
125 const LpInterface< GUM_SCALAR >& from) {
127 for (
const auto& row: rows__)
131 rows__.shrink_to_fit();
133 rows__.resize(from.rows__.size());
135 for (
unsigned int i = 0, end = from.rows__.size(); i < end; i++)
136 rows__[i] =
new LpRow(*from.rows__[i]);
138 cols__ = from.cols__;
139 positivity__ = from.positivity__;
140 sumIsOne__ = from.sumIsOne__;
145 template <
typename GUM_SCALAR >
146 LpInterface< GUM_SCALAR >&
147 LpInterface< GUM_SCALAR >::operator=(LpInterface< GUM_SCALAR >&& from) {
148 rows__.swap(from.rows__);
149 cols__.swap(from.cols__);
151 positivity__ = from.positivity__;
152 sumIsOne__ = from.sumIsOne__;
157 template <
typename T >
158 std::ostream& operator<<(std::ostream& out,
const LpInterface< T >& lpi) {
159 out << lpi.toString();
163 template <
typename GUM_SCALAR >
164 LpCol LpInterface< GUM_SCALAR >::addCol() {
165 LpCol col((
unsigned int)cols__.size());
167 cols__.push_back(col);
172 template <
typename GUM_SCALAR >
174 LpInterface< GUM_SCALAR >::addCols(
const unsigned int& cols) {
176 GUM_ERROR(OperationNotAllowed,
177 "LpInterface::addCols ( cols ) : cols " 178 "needs must be equal or greater than 1 : " 181 for (
unsigned int i = 0; i < cols; i++) {
182 cols__.push_back(LpCol((
unsigned int)cols__.size()));
188 template <
typename GUM_SCALAR >
189 void LpInterface< GUM_SCALAR >::addRow(
const LpExpr& expr) {
190 if (!expr.ileft__ && !expr.iright__)
191 GUM_ERROR(OperationNotAllowed,
192 "addRow ( const LpExpr & expr ) : expr : " 193 << expr.toString() <<
"is not an inequality.");
195 if ((expr.ileft__ && !expr.iright__) || (!expr.ileft__ && expr.iright__)) {
196 rows__.push_back(
new LpRow(expr, cols__));
198 LpExpr lexpr(expr,
true,
true,
false);
199 LpExpr rexpr(expr,
false,
true,
true);
202 new LpRow(std::move(lexpr),
205 new LpRow(std::move(rexpr),
210 template <
typename GUM_SCALAR >
211 void LpInterface< GUM_SCALAR >::addRow(LpExpr&& expr) {
212 if (!expr.ileft__ && !expr.iright__)
213 GUM_ERROR(OperationNotAllowed,
214 "addRow ( const LpExpr & expr ) : expr : " 215 << expr.toString() <<
"is not an inequality.");
217 if ((expr.ileft__ && !expr.iright__) || (!expr.ileft__ && expr.iright__)) {
218 rows__.push_back(
new LpRow(std::move(expr), cols__));
220 LpExpr lexpr(std::move(expr),
true,
true,
false);
223 LpExpr rexpr(std::move(expr),
false,
false,
true);
227 *rexpr.mCoeffs__ = *lexpr.mCoeffs__;
228 rexpr.mValue__ = lexpr.mValue__;
229 rexpr.imiddle__ =
true;
232 new LpRow(std::move(lexpr),
235 new LpRow(std::move(rexpr),
240 template <
typename GUM_SCALAR >
241 void LpInterface< GUM_SCALAR >::addPositivity() {
242 if (positivity__)
return;
244 for (
const auto& col: cols__)
250 template <
typename GUM_SCALAR >
251 void LpInterface< GUM_SCALAR >::addSumIsOne() {
252 if (sumIsOne__)
return;
256 for (
const auto& col: cols__)
259 addRow(1 <= std::move(expr) <= 1);
264 template <
typename GUM_SCALAR >
265 void LpInterface< GUM_SCALAR >::addProba() {
266 if (positivity__ && sumIsOne__) {
268 }
else if (positivity__ && !sumIsOne__) {
271 }
else if (!positivity__ && sumIsOne__) {
281 for (
const auto& col: cols__) {
286 addRow(1 <= std::move(expr) <= 1);
292 template <
typename GUM_SCALAR >
293 std::vector< std::vector< GUM_SCALAR > > LpInterface< GUM_SCALAR >::solve() {
294 LRSWrapper< GUM_SCALAR > lrs;
296 lrs.setUpH((
unsigned int)cols__.size());
298 std::vector< std::vector< GUM_SCALAR > > lrsMatrix;
300 for (
const auto& row: rows__) {
301 std::vector< GUM_SCALAR > expandedRow(cols__.size() + 1, 0);
303 expandedRow[0] = row->cste__;
305 for (
const auto& elt: *row->coeffs__)
306 expandedRow[elt.first.id() + 1] = elt.second;
308 lrsMatrix.push_back(expandedRow);
311 lrs.fillMatrix(lrsMatrix);
315 return lrs.getOutput();
318 template <
typename GUM_SCALAR >
319 std::vector< LpCol > LpInterface< GUM_SCALAR >::getCols()
const {
323 template <
typename GUM_SCALAR >
324 std::string LpInterface< GUM_SCALAR >::toString()
const {
325 std::ostringstream s;
327 s << std::endl << std::endl <<
"Variables : " << std::endl;
329 for (
const auto& col: cols__)
330 s <<
" " << col.toString();
334 for (
const auto& row: rows__)
335 s << std::endl << row->toString();
337 s << std::endl << std::endl;
342 template <
typename GUM_SCALAR >
343 void LpInterface< GUM_SCALAR >::clear() {
344 for (
const auto& row: rows__)
348 rows__.shrink_to_fit();
354 cols__.shrink_to_fit();
356 positivity__ =
false;
360 template <
typename GUM_SCALAR >
361 void LpInterface< GUM_SCALAR >::clearRows() {
362 for (
const auto& row: rows__)
366 rows__.shrink_to_fit();
368 positivity__ =
false;
373 template <
typename T2 >
374 LpExpr operator+(LpExpr&& lhs,
const T2& rhs) {
375 LpExpr expr = std::move(lhs);
381 template <
typename T2 >
382 LpExpr operator+(
const LpExpr& lhs,
const T2& rhs) {
389 template <
typename T1, forbidden_type< T1, LpExpr > >
390 LpExpr operator+(
const T1& lhs, LpExpr&& rhs) {
391 LpExpr expr = std::move(rhs);
398 template <
typename T1, forbidden_type< T1, LpExpr > >
399 LpExpr operator+(
const T1& lhs, LpExpr& rhs) {
406 template <
typename T2, forbidden_type< T2, LpExpr > >
407 LpExpr operator+(
const LpCol& lhs,
const T2& rhs) {
415 template <
typename T1,
416 forbidden_type< T1, LpExpr >,
417 forbidden_type< T1, LpCol > >
418 LpExpr operator+(
const T1& lhs,
const LpCol& rhs) {
427 template <
typename T2 >
428 LpExpr operator-(LpExpr&& lhs,
const T2& rhs) {
429 LpExpr expr = std::move(lhs);
435 template <
typename T2 >
436 LpExpr operator-(
const LpExpr& lhs,
const T2& rhs) {
443 template <
typename T1, forbidden_type< T1, LpExpr > >
444 LpExpr operator-(
const T1& lhs, LpExpr&& rhs) {
446 expr += std::move(rhs);
453 template <
typename T1, forbidden_type< T1, LpExpr > >
454 LpExpr operator-(
const T1& lhs, LpExpr& rhs) {
462 template <
typename T2, forbidden_type< T2, LpExpr > >
463 LpExpr operator-(
const LpCol& lhs,
const T2& rhs) {
471 template <
typename T1,
472 forbidden_type< T1, LpExpr >,
473 forbidden_type< T1, LpCol > >
474 LpExpr operator-(
const T1& lhs,
const LpCol& rhs) {
483 template <
typename SCALAR >
484 INLINE LpExpr LpExpr::multiply(
const SCALAR& lhs,
const LpCol& rhs) {
486 expr.mCoeffs__->insert(rhs, lhs);
487 expr.imiddle__ =
true;
491 template <
typename SCALAR >
492 LpExpr operator*(
const SCALAR& lhs,
const LpCol& rhs) {
493 return LpExpr::multiply(lhs, rhs);
496 template <
typename SCALAR >
497 LpExpr operator*(
const LpCol& lhs,
const SCALAR& rhs) {
498 return LpExpr::multiply(rhs, lhs);
502 template <
typename T1,
typename T2 >
503 INLINE LpExpr LpExpr::lessThan(T1&& lhs, T2&& rhs) {
505 expr.addSide__(std::forward< T1 >(lhs));
506 expr.addSide__(std::forward< T2 >(rhs));
511 template <
typename T2 >
512 LpExpr operator<=(
const LpExpr& lhs, T2&& rhs) {
513 return LpExpr::lessThan(lhs, std::forward< T2 >(rhs));
516 template <
typename T2 >
517 LpExpr operator<=(
const LpCol& lhs, T2&& rhs) {
518 return LpExpr::lessThan(lhs, std::forward< T2 >(rhs));
521 template <
typename T1,
522 forbidden_type< T1, LpExpr& >,
523 forbidden_type< T1, LpCol& > >
524 LpExpr operator<=(T1&& lhs,
const LpExpr& rhs) {
525 return LpExpr::lessThan(std::forward< T1 >(lhs), rhs);
528 template <
typename T1,
529 forbidden_type< T1, LpExpr& >,
530 forbidden_type< T1, LpCol& > >
531 LpExpr operator<=(T1&& lhs,
const LpCol& rhs) {
532 return LpExpr::lessThan(std::forward< T1 >(lhs), rhs);
536 template <
typename T2 >
537 LpExpr operator<=(LpExpr&& lhs, T2&& rhs) {
538 return LpExpr::lessThan(std::move(lhs), std::forward< T2 >(rhs));
541 template <
typename T2 >
542 LpExpr operator<=(LpCol&& lhs, T2&& rhs) {
543 return LpExpr::lessThan(std::move(lhs), std::forward< T2 >(rhs));
546 template <
typename T1,
547 forbidden_type< T1, LpExpr >,
548 forbidden_type< T1, LpCol > >
549 LpExpr operator<=(T1&& lhs, LpExpr&& rhs) {
550 return LpExpr::lessThan(std::forward< T1 >(lhs), std::move(rhs));
553 template <
typename T1,
554 forbidden_type< T1, LpExpr >,
555 forbidden_type< T1, LpCol > >
556 LpExpr operator<=(T1&& lhs, LpCol&& rhs) {
557 return LpExpr::lessThan(std::forward< T1 >(lhs), std::move(rhs));