All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
expressions.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //=======================================================================
16 #ifndef PAAL_EXPRESSIONS_HPP
17 #define PAAL_EXPRESSIONS_HPP
18 
19 #include "paal/lp/ids.hpp"
20 #include "paal/utils/floating.hpp"
21 #include "paal/utils/functors.hpp"
24 
25 #include <boost/range/adaptor/transformed.hpp>
26 #include <boost/range/algorithm/count_if.hpp>
27 
28 #include <functional>
29 #include <unordered_map>
30 
31 namespace paal {
32 namespace lp {
33 
34 namespace {
35 struct linear_expression_traits {
36  static const utils::compare<double> CMP;
37 };
38 
39 const utils::compare<double> linear_expression_traits::CMP = utils::compare<double>();
40 }
41 
46  typedef std::unordered_map<col_id, double> Elements;
47  typedef Elements::const_iterator ExprIter;
48 
49  public:
52 
54  linear_expression(col_id col, double coef = 1.) {
55  m_coefs.emplace(col, coef);
56  }
57 
60  join_expression(expr, utils::plus{});
61  return *this;
62  }
63 
66  join_expression(expr, utils::minus{});
67  return *this;
68  }
69 
72  for (auto &elem : m_coefs) {
73  elem.second *= val;
74  }
75  return *this;
76  }
77 
79  linear_expression &operator/=(double val) { return operator*=(1. / val); }
80 
82  double get_coefficient(col_id col) const {
83  auto elem = m_coefs.find(col);
84  if (elem != m_coefs.end()) {
85  return elem->second;
86  } else {
87  return 0.;
88  }
89  }
90 
92  const Elements &get_elements() const { return m_coefs; }
93 
95  int non_zeros() const {
96  return boost::count_if(m_coefs, [](std::pair<col_id, double> x) {
97  return !linear_expression_traits::CMP.e(x.second, 0);
98  });
99  }
100 
101  private:
102  template <typename Operation>
103  void join_expression(const linear_expression &expr, Operation op) {
104  for (auto new_elem : expr.m_coefs) {
105  auto elem = m_coefs.find(new_elem.first);
106  if (elem == m_coefs.end()) {
107  new_elem.second = op(0., new_elem.second);
108  m_coefs.insert(new_elem);
109  } else {
110  elem->second = op(elem->second, new_elem.second);
111  }
112  }
113  }
114 
115  Elements m_coefs;
116 };
117 
118 namespace detail {
119 inline std::string col_id_to_string(col_id col) {
120  return " x_" + std::to_string(col.get());
121 }
122 
123 template <typename Stream, typename PrintCol>
124 void print_expression(Stream &o, const linear_expression &expr,
125  PrintCol print_col) {
126  print_collection(o, expr.get_elements() |
127  boost::adaptors::transformed(
128  [&](std::pair<col_id, double> col_and_val) {
129  return pretty_to_string(col_and_val.second) +
130  print_col(col_and_val.first);
131  }),
132  " + ");
133 }
134 };
135 
137 template <typename Stream>
138 Stream &operator<<(Stream &o, const linear_expression &expr) {
139  detail::print_expression(o, expr, detail::col_id_to_string);
140  return o;
141 }
142 
145  const linear_expression &expr_right) {
146  expr_left += expr_right;
147  return expr_left;
148 }
149 
152  const linear_expression &expr_right) {
153  expr_left -= expr_right;
154  return expr_left;
155 }
156 
159  expr *= val;
160  return expr;
161 }
162 
164 inline linear_expression operator*(double val, const linear_expression &expr) {
165  return expr * val;
166 }
167 
170  expr /= val;
171  return expr;
172 }
173 
176  return expr * (-1.);
177 }
178 
179 } // lp
180 } // paal
181 
182 #endif // PAAL_EXPRESSIONS_HPP
linear_expression operator-(linear_expression expr_left, const linear_expression &expr_right)
linear_expression - linear_expression operator.
linear_expression()
Constructor.
Definition: expressions.hpp:51
linear_expression & operator+=(const linear_expression &expr)
Addition operator.
Definition: expressions.hpp:59
const Elements & get_elements() const
Returns the iterator range of the elements in the expression.
Definition: expressions.hpp:92
linear_expression operator*(linear_expression expr, double val)
linear_expression * double operator.
std::string pretty_to_string(double x, double epsilon=1e-9)
pretty_to_string prints double which is close to int as int
void print_collection(Stream &o, Range &&r, const std::string &del)
prints collection with delimiters without trailing delimiter
linear_expression operator+(linear_expression expr_left, const linear_expression &expr_right)
linear_expression + linear_expression operator.
linear_expression & operator-=(const linear_expression &expr)
Subtraction operator.
Definition: expressions.hpp:65
linear_expression operator/(linear_expression expr, double val)
linear_expression / double operator.
linear_expression(col_id col, double coef=1.)
Constructor.
Definition: expressions.hpp:54
linear_expression & operator*=(double val)
Multiplication by a constant operator.
Definition: expressions.hpp:71
This file contains set of simple useful functors or functor adapters.
double get_coefficient(col_id col) const
Returns the coefficient for a given column.
Definition: expressions.hpp:82
int non_zeros() const
Returns the size (number of nonzero coefficients) of the expression.
Definition: expressions.hpp:95
Stream & operator<<(Stream &o, const single_bounded_expression< LowerBoundTag, BoundDirection > &expr)
operator&lt;&lt; for Lower Bound
Definition: constraints.hpp:94
linear_expression & operator/=(double val)
Division by a constant operator.
Definition: expressions.hpp:79