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,
"expr::operator+= (expr) : <= present on one side of expr")
46 if (!_imiddle_) _imiddle_ =
true;
53 template <
typename T >
54 LpExpr& LpExpr::operator-=(
const T& rhs) {
55 if (_ileft_ || _iright_)
56 GUM_ERROR(OperationNotAllowed,
"expr::operator-= (rhs) : <= present in one of expr")
58 if (!_imiddle_) _imiddle_ =
true;
65 template <
typename SCALAR >
66 void LpExpr::_addSide_(
const SCALAR& from) {
70 }
else if (!_imiddle_) {
73 }
else if (!_iright_) {
77 GUM_ERROR(OperationNotAllowed,
78 "LpExpr::setSide ( const LpCol & from " 79 ") : too many <= ; no free side");
85 template <
typename GUM_SCALAR >
86 LpInterface< GUM_SCALAR >::LpInterface() {
89 GUM_CONSTRUCTOR(LpInterface);
92 template <
typename GUM_SCALAR >
93 LpInterface< GUM_SCALAR >::LpInterface(
const LpInterface< GUM_SCALAR >& from) :
94 _cols_(from._cols_), _positivity_(from._positivity_), _sumIsOne_(from._sumIsOne_) {
95 _rows_.resize(from._rows_.size());
97 for (
unsigned int i = 0, end = from._rows_.size(); i < end; i++)
98 _rows_[i] =
new LpRow(*from._rows_[i]);
100 GUM_CONS_CPY(LpInterface);
103 template <
typename GUM_SCALAR >
104 LpInterface< GUM_SCALAR >::LpInterface(LpInterface< GUM_SCALAR >&& from) :
105 _positivity_(from._positivity_), _sumIsOne_(from._sumIsOne_) {
106 _rows_.swap(from._rows_);
107 _cols_.swap(from._cols_);
108 GUM_CONS_CPY(LpInterface);
111 template <
typename GUM_SCALAR >
112 LpInterface< GUM_SCALAR >::~LpInterface() {
113 for (
const auto row: _rows_)
116 GUM_DESTRUCTOR(LpInterface);
119 template <
typename GUM_SCALAR >
120 LpInterface< GUM_SCALAR >&
121 LpInterface< GUM_SCALAR >::operator=(
const LpInterface< GUM_SCALAR >& from) {
123 for (
const auto& row: _rows_)
127 _rows_.shrink_to_fit();
129 _rows_.resize(from._rows_.size());
131 for (
unsigned int i = 0, end = from._rows_.size(); i < end; i++)
132 _rows_[i] =
new LpRow(*from._rows_[i]);
134 _cols_ = from._cols_;
135 _positivity_ = from._positivity_;
136 _sumIsOne_ = from._sumIsOne_;
141 template <
typename GUM_SCALAR >
142 LpInterface< GUM_SCALAR >&
143 LpInterface< GUM_SCALAR >::operator=(LpInterface< GUM_SCALAR >&& from) {
144 _rows_.swap(from._rows_);
145 _cols_.swap(from._cols_);
147 _positivity_ = from._positivity_;
148 _sumIsOne_ = from._sumIsOne_;
153 template <
typename T >
154 std::ostream& operator<<(std::ostream& out,
const LpInterface< T >& lpi) {
155 out << lpi.toString();
159 template <
typename GUM_SCALAR >
160 LpCol LpInterface< GUM_SCALAR >::addCol() {
161 LpCol col((
unsigned int)_cols_.size());
163 _cols_.push_back(col);
168 template <
typename GUM_SCALAR >
169 std::vector< LpCol > LpInterface< GUM_SCALAR >::addCols(
const unsigned int& cols) {
171 GUM_ERROR(OperationNotAllowed,
172 "LpInterface::addCols ( cols ) : cols " 173 "needs must be equal or greater than 1 : " 176 for (
unsigned int i = 0; i < cols; i++) {
177 _cols_.push_back(LpCol((
unsigned int)_cols_.size()));
183 template <
typename GUM_SCALAR >
184 void LpInterface< GUM_SCALAR >::addRow(
const LpExpr& expr) {
185 if (!expr._ileft_ && !expr._iright_)
186 GUM_ERROR(OperationNotAllowed,
187 "addRow ( const LpExpr & expr ) : expr : " << expr.toString()
188 <<
"is not an inequality.");
190 if ((expr._ileft_ && !expr._iright_) || (!expr._ileft_ && expr._iright_)) {
191 _rows_.push_back(
new LpRow(expr, _cols_));
193 LpExpr lexpr(expr,
true,
true,
false);
194 LpExpr rexpr(expr,
false,
true,
true);
196 _rows_.push_back(
new LpRow(std::move(lexpr),
198 _rows_.push_back(
new LpRow(std::move(rexpr),
203 template <
typename GUM_SCALAR >
204 void LpInterface< GUM_SCALAR >::addRow(LpExpr&& expr) {
205 if (!expr._ileft_ && !expr._iright_)
206 GUM_ERROR(OperationNotAllowed,
207 "addRow ( const LpExpr & expr ) : expr : " << expr.toString()
208 <<
"is not an inequality.");
210 if ((expr._ileft_ && !expr._iright_) || (!expr._ileft_ && expr._iright_)) {
211 _rows_.push_back(
new LpRow(std::move(expr), _cols_));
213 LpExpr lexpr(std::move(expr),
true,
true,
false);
216 LpExpr rexpr(std::move(expr),
false,
false,
true);
220 *rexpr._mCoeffs_ = *lexpr._mCoeffs_;
221 rexpr._mValue_ = lexpr._mValue_;
222 rexpr._imiddle_ =
true;
224 _rows_.push_back(
new LpRow(std::move(lexpr),
226 _rows_.push_back(
new LpRow(std::move(rexpr),
231 template <
typename GUM_SCALAR >
232 void LpInterface< GUM_SCALAR >::addPositivity() {
233 if (_positivity_)
return;
235 for (
const auto& col: _cols_)
241 template <
typename GUM_SCALAR >
242 void LpInterface< GUM_SCALAR >::addSumIsOne() {
243 if (_sumIsOne_)
return;
247 for (
const auto& col: _cols_)
250 addRow(1 <= std::move(expr) <= 1);
255 template <
typename GUM_SCALAR >
256 void LpInterface< GUM_SCALAR >::addProba() {
257 if (_positivity_ && _sumIsOne_) {
259 }
else if (_positivity_ && !_sumIsOne_) {
262 }
else if (!_positivity_ && _sumIsOne_) {
272 for (
const auto& col: _cols_) {
277 addRow(1 <= std::move(expr) <= 1);
283 template <
typename GUM_SCALAR >
284 std::vector< std::vector< GUM_SCALAR > > LpInterface< GUM_SCALAR >::solve() {
285 LRSWrapper< GUM_SCALAR > lrs;
287 lrs.setUpH((
unsigned int)_cols_.size());
289 std::vector< std::vector< GUM_SCALAR > > lrsMatrix;
291 for (
const auto& row: _rows_) {
292 std::vector< GUM_SCALAR > expandedRow(_cols_.size() + 1, 0);
294 expandedRow[0] = row->_cste_;
296 for (
const auto& elt: *row->_coeffs_)
297 expandedRow[elt.first.id() + 1] = elt.second;
299 lrsMatrix.push_back(expandedRow);
302 lrs.fillMatrix(lrsMatrix);
306 return lrs.getOutput();
309 template <
typename GUM_SCALAR >
310 std::vector< LpCol > LpInterface< GUM_SCALAR >::getCols()
const {
314 template <
typename GUM_SCALAR >
315 std::string LpInterface< GUM_SCALAR >::toString()
const {
316 std::ostringstream s;
318 s << std::endl << std::endl <<
"Variables : " << std::endl;
320 for (
const auto& col: _cols_)
321 s <<
" " << col.toString();
325 for (
const auto& row: _rows_)
326 s << std::endl << row->toString();
328 s << std::endl << std::endl;
333 template <
typename GUM_SCALAR >
334 void LpInterface< GUM_SCALAR >::clear() {
335 for (
const auto& row: _rows_)
339 _rows_.shrink_to_fit();
345 _cols_.shrink_to_fit();
347 _positivity_ =
false;
351 template <
typename GUM_SCALAR >
352 void LpInterface< GUM_SCALAR >::clearRows() {
353 for (
const auto& row: _rows_)
357 _rows_.shrink_to_fit();
359 _positivity_ =
false;
364 template <
typename T2 >
365 LpExpr operator+(LpExpr&& lhs,
const T2& rhs) {
366 LpExpr expr = std::move(lhs);
372 template <
typename T2 >
373 LpExpr operator+(
const LpExpr& lhs,
const T2& rhs) {
380 template <
typename T1, forbidden_type< T1, LpExpr > >
381 LpExpr operator+(
const T1& lhs, LpExpr&& rhs) {
382 LpExpr expr = std::move(rhs);
389 template <
typename T1, forbidden_type< T1, LpExpr > >
390 LpExpr operator+(
const T1& lhs, LpExpr& rhs) {
397 template <
typename T2, forbidden_type< T2, LpExpr > >
398 LpExpr operator+(
const LpCol& lhs,
const T2& rhs) {
406 template <
typename T1, forbidden_type< T1, LpExpr >, forbidden_type< T1, LpCol > >
407 LpExpr operator+(
const T1& lhs,
const LpCol& rhs) {
416 template <
typename T2 >
417 LpExpr operator-(LpExpr&& lhs,
const T2& rhs) {
418 LpExpr expr = std::move(lhs);
424 template <
typename T2 >
425 LpExpr operator-(
const LpExpr& lhs,
const T2& rhs) {
432 template <
typename T1, forbidden_type< T1, LpExpr > >
433 LpExpr operator-(
const T1& lhs, LpExpr&& rhs) {
435 expr += std::move(rhs);
442 template <
typename T1, forbidden_type< T1, LpExpr > >
443 LpExpr operator-(
const T1& lhs, LpExpr& rhs) {
451 template <
typename T2, forbidden_type< T2, LpExpr > >
452 LpExpr operator-(
const LpCol& lhs,
const T2& rhs) {
460 template <
typename T1, forbidden_type< T1, LpExpr >, forbidden_type< T1, LpCol > >
461 LpExpr operator-(
const T1& lhs,
const LpCol& rhs) {
470 template <
typename SCALAR >
471 INLINE LpExpr LpExpr::multiply(
const SCALAR& lhs,
const LpCol& rhs) {
473 expr._mCoeffs_->insert(rhs, lhs);
474 expr._imiddle_ =
true;
478 template <
typename SCALAR >
479 LpExpr operator*(
const SCALAR& lhs,
const LpCol& rhs) {
480 return LpExpr::multiply(lhs, rhs);
483 template <
typename SCALAR >
484 LpExpr operator*(
const LpCol& lhs,
const SCALAR& rhs) {
485 return LpExpr::multiply(rhs, lhs);
489 template <
typename T1,
typename T2 >
490 INLINE LpExpr LpExpr::lessThan(T1&& lhs, T2&& rhs) {
492 expr._addSide_(std::forward< T1 >(lhs));
493 expr._addSide_(std::forward< T2 >(rhs));
498 template <
typename T2 >
499 LpExpr operator<=(
const LpExpr& lhs, T2&& rhs) {
500 return LpExpr::lessThan(lhs, std::forward< T2 >(rhs));
503 template <
typename T2 >
504 LpExpr operator<=(
const LpCol& lhs, T2&& rhs) {
505 return LpExpr::lessThan(lhs, std::forward< T2 >(rhs));
508 template <
typename T1, forbidden_type< T1, LpExpr& >, forbidden_type< T1, LpCol& > >
509 LpExpr operator<=(T1&& lhs,
const LpExpr& rhs) {
510 return LpExpr::lessThan(std::forward< T1 >(lhs), rhs);
513 template <
typename T1, forbidden_type< T1, LpExpr& >, forbidden_type< T1, LpCol& > >
514 LpExpr operator<=(T1&& lhs,
const LpCol& rhs) {
515 return LpExpr::lessThan(std::forward< T1 >(lhs), rhs);
519 template <
typename T2 >
520 LpExpr operator<=(LpExpr&& lhs, T2&& rhs) {
521 return LpExpr::lessThan(std::move(lhs), std::forward< T2 >(rhs));
524 template <
typename T2 >
525 LpExpr operator<=(LpCol&& lhs, T2&& rhs) {
526 return LpExpr::lessThan(std::move(lhs), std::forward< T2 >(rhs));
529 template <
typename T1, forbidden_type< T1, LpExpr >, forbidden_type< T1, LpCol > >
530 LpExpr operator<=(T1&& lhs, LpExpr&& rhs) {
531 return LpExpr::lessThan(std::forward< T1 >(lhs), std::move(rhs));
534 template <
typename T1, forbidden_type< T1, LpExpr >, forbidden_type< T1, LpCol > >
535 LpExpr operator<=(T1&& lhs, LpCol&& rhs) {
536 return LpExpr::lessThan(std::forward< T1 >(lhs), std::move(rhs));