FLOPC++
MP_expression.cpp
Go to the documentation of this file.
1 // ******************** FlopCpp **********************************************
2 // File: MP_expression.cpp
3 // $Id$
4 // Author: Tim Helge Hultberg (thh@mat.ua.pt)
5 // Copyright (C) 2003 Tim Helge Hultberg
6 // All Rights Reserved.
7 //****************************************************************************
8 
9 #include <sstream>
10 #include "MP_expression.hpp"
11 #include "MP_constant.hpp"
12 #include "MP_boolean.hpp"
13 #include "MP_constraint.hpp"
14 #include "MP_set.hpp"
15 #include "MP_variable.hpp"
16 #include "MP_model.hpp"
17 #include <OsiSolverInterface.hpp>
18 
19 namespace flopc {
20 
22  const MP_index_exp& i1,
23  const MP_index_exp& i2,
24  const MP_index_exp& i3,
25  const MP_index_exp& i4,
26  const MP_index_exp& i5) :
27  V(v),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {
28  offset = v->offset;
29  }
30 
31  double VariableRef::level() const {
32  return V->M->Solver->getColSolution()[V->offset +
33  V->f(V->S1->evaluate(),
34  V->S2->evaluate(),
35  V->S3->evaluate(),
36  V->S4->evaluate(),
37  V->S5->evaluate())];
38  }
39 
40  int VariableRef::getColumn() const {
41  int i1 = V->S1->check(I1->evaluate());
42  int i2 = V->S2->check(I2->evaluate());
43  int i3 = V->S3->check(I3->evaluate());
44  int i4 = V->S4->check(I4->evaluate());
45  int i5 = V->S5->check(I5->evaluate());
46 
47  if (i1==outOfBound || i2==outOfBound || i3==outOfBound ||
48  i4==outOfBound || i5==outOfBound) {
49  return outOfBound;
50  } else {
51  return V->offset + V->f(i1,i2,i3,i4,i5);
52  }
53  }
54 
55  void VariableRef::generate(const MP_domain& domain,
56  vector<Constant > multiplicators,
58  double m) const {
59  f.setMultiplicator(multiplicators,m);
60  f.setTerminalExpression(this);
61  domain.forall(&f);
62  }
63 
64  class Expression_constant : public TerminalExpression, public MP {
65  friend class MP_expression;
66  private:
67  Expression_constant(const Constant& c) : C(c) {}
68  double level() const {
69  return C->evaluate();
70  }
71  double getValue() const {
72  return C->evaluate();
73  }
74  int getColumn() const {
75  return -1;
76  }
77  int getStage() const {
78  return C->getStage(); //NB to be changed
79  }
80  void generate(const MP_domain& domain,
81  vector<Constant> multiplicators,
83  double m) const {
84  f.setMultiplicator(multiplicators,m);
85  f.setTerminalExpression(this);
86  domain.forall(&f);
87  }
88  void insertVariables(set<MP_variable*>& v) const {}
89 
91  };
92 
93 
94  class Expression_operator : public MP_expression_base, public MP {
95  protected:
97  left(e1),right(e2) {}
98 
99  void insertVariables(set<MP_variable*>& v) const {
100  left->insertVariables(v);
101  right->insertVariables(v);
102  }
103 
105  };
106 
108  friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2);
109  friend MP_expression operator+(const MP_expression& e1, const Constant& e2);
110  friend MP_expression operator+(const Constant& e1, const MP_expression& e2);
111  private:
112  Expression_plus(const MP_expression& e1, const MP_expression& e2) :
113  Expression_operator(e1,e2) {}
114  double level() const {
115  return left->level()+right->level();
116  }
117  void generate(const MP_domain& domain,
118  vector<Constant> multiplicators,
120  double m) const {
121  left->generate(domain, multiplicators, f, m);
122  right->generate(domain, multiplicators, f, m);
123  }
124  };
125 
127  friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2);
128  friend MP_expression operator-(const MP_expression& e1, const Constant& e2);
129  friend MP_expression operator-(const Constant& e1, const MP_expression& e2);
130  private:
132  Expression_operator(e1,e2) {}
133  double level() const {
134  return left->level()-right->level();
135  }
136  void generate(const MP_domain& domain,
137  vector<Constant> multiplicators,
139  double m) const {
140  left->generate(domain, multiplicators, f, m);
141  right->generate(domain, multiplicators, f, -m);
142  }
143  };
144 
146  friend MP_expression operator*(const Constant& e1, const MP_expression& e2);
147  friend MP_expression operator*(const MP_expression& e1, const Constant& e2);
148 
149  private:
150  Expression_mult(const Constant& e1, const MP_expression& e2) :
151  left(e1), right(e2) {}
152  double level() const {
153  return left->evaluate()*right->level();
154  }
155  void generate(const MP_domain& domain,
156  vector<Constant> multiplicators,
158  double m) const {
159  multiplicators.push_back(left);
160  right->generate(domain, multiplicators, f, m);
161  }
162  void insertVariables(set<MP_variable*>& v) const {
163  right->insertVariables(v);
164  }
167  };
168 
170  friend MP_expression operator/(const MP_expression& e1, const Constant& e2);
171  private:
172  Expression_div(const MP_expression& e, const Constant& c) :
173  left(e), right(c) {}
174  double level() const {
175  return left->level()/right->evaluate();
176  }
177  void generate(const MP_domain& domain,
178  vector<Constant> multiplicators,
180  double m) const {
181  multiplicators.push_back(1/right);
182  left->generate(domain, multiplicators, f, m);
183  }
184  void insertVariables(set<MP_variable*>& v) const {
185  left->insertVariables(v);
186  }
189  };
190 
191  class Expression_sum : public MP_expression_base, public MP {
192  friend MP_expression sum(const MP_domain& d, const MP_expression& e);
193  private:
194  Expression_sum(const MP_domain& d, const MP_expression& e) : D(d), exp(e) {}
195 
196  double level() const {
197  SumFunctor SF(exp);
198  D.forall(SF);
199  return SF.the_sum;
200  }
201  void generate(const MP_domain& domain,
202  vector<Constant> multiplicators,
204  double m) const {
205  // The order, D*domain (NOT domain*D), is important for efficiency!
206  exp->generate(D*domain, multiplicators, f, m);
207  }
208  void insertVariables(set<MP_variable*>& v) const {
209  exp->insertVariables(v);
210  }
211 
212  class SumFunctor : public Functor {
213  public:
214  SumFunctor(MP_expression exp) : E(exp), the_sum(0) {}
215  void operator()() const {
216  the_sum += E->level();
217  }
219  mutable double the_sum;
220  };
221 
224  };
225 
226 
228  return new Expression_plus(e1, e2);
229  }
231  return new Expression_plus(e1, e2);
232  }
234  return new Expression_plus(e1, e2);
235  }
236 
238  return new Expression_minus(e1, e2);
239  }
241  return new Expression_minus(e1, e2);
242  }
244  return new Expression_minus(e1, e2);
245  }
246 
248  return new Expression_mult(e1, e2);
249  }
251  return new Expression_mult(e2, e1);
252  }
253 
255  return new Expression_div(e1, e2);
256  }
257 
258  MP_expression sum(const MP_domain& d, const MP_expression& e) {
259  return new Expression_sum(d, e);
260  }
261 
262 } // End of namespace flopc
263 
264 using namespace flopc;
265 
266 
269 
271  Handle<MP_expression_base*>(const_cast<VariableRef*>(&v)) {}
272 
273 
274 bool MP::CoefLess::operator() (const MP::Coef& a, const MP::Coef& b) const {
275  if (a.col < b.col) {
276  return true;
277  } else if (a.col == b.col && a.row < b.row) {
278  return true;
279  } else {
280  return false;
281  }
282 }
283 
285  double multiplicator = M;
286  int stage = 0;
287  for (unsigned int i=0; i<multiplicators.size(); i++) {
288  multiplicator *= multiplicators[i]->evaluate();
289  if (multiplicators[i]->getStage() > stage) {
290  stage = multiplicators[i]->getStage();
291  }
292  }
293  int rowNumber = -1;
294  if (R != 0) {
295  rowNumber = R->row_number();
296  }
297  if (rowNumber != outOfBound) {
298  int colNumber = C->getColumn();
299  if ( colNumber != outOfBound ) {
300  double val = multiplicator*C->getValue();
301  int tstage = C->getStage();
302  if (tstage > stage) {
303  stage = tstage;
304  }
305  // if (val != 0) {
306  Coefs.push_back(MP::Coef(colNumber, rowNumber, val, stage));
307  //}
308  }
309  }
310 }
const MP_index_exp I2
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
void insertVariables(set< MP_variable *> &v) const
void setMultiplicator(vector< Constant > &mults, double m)
void insertVariables(set< MP_variable *> &v) const
Expression_operator(const MP_expression &e1, const MP_expression &e2)
const MP_index_exp I3
Symbolic representation of a linear expression.This is one of the main public interface classes...
Constant operator/(const Constant &a, const Constant &b)
Returns the quotient of two constants.This is used in the formation of an expression.
VariableRef(MP_variable *v, const MP_index_exp &i1, const MP_index_exp &i2, const MP_index_exp &i3, const MP_index_exp &i4, const MP_index_exp &i5)
void insertVariables(set< MP_variable *> &v) const
Expression_constant(const Constant &c)
void setTerminalExpression(const TerminalExpression *c)
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
Expression_mult(const Constant &e1, const MP_expression &e2)
Expression_sum(const MP_domain &d, const MP_expression &e)
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
void insertVariables(set< MP_variable *> &v) const
const MP_set_base * S1
Definition: MP_variable.hpp:84
Utility for doing reference counted pointers.
Constant operator+(const Constant &a, const Constant &b)
Returns the sum of two constants.This is used in the formation of an expression.
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
const MP_index_exp I4
Representation of an expression involving an index.This is one of the main public interface classes...
Definition: MP_index.hpp:141
const MP_set_base * S5
Definition: MP_variable.hpp:84
The base class for all expressions.
void forall(const Functor *op) const
Special conditional operation on the domain.
Definition: MP_domain.cpp:88
const int outOfBound
Distinct return value on conditions where an index goes out of bounds.
Constant operator-(const Constant &a, const Constant &b)
Returns the difference of two constants.This is used in the formation of an expression.
All flopc++ code is contained within the flopc namespace.
Definition: flopc.cpp:11
OsiSolverInterface * Solver
Definition: MP_model.hpp:251
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
const MP_set_base * S2
Definition: MP_variable.hpp:84
Expression_minus(const MP_expression &e1, const MP_expression &e2)
Range over which some other constuct is defined.This is one of the main public interface classes...
Definition: MP_domain.hpp:61
int getColumn() const
int f(int i1=0, int i2=0, int i3=0, int i4=0, int i5=0) const
Symantic representation of a variable.This is one of the main public interface classes. It should be directly declared by clients of the FlopC++. The parametersof construction are MP_set s which specify the indexes over which the variable is defined.
Definition: MP_variable.hpp:35
Function object. Often used.
const MP_index_exp I5
Reference counted class for all "constant" types of data.
Definition: MP_constant.hpp:49
double level() const
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
const MP_index_exp I1
const MP_set_base * S3
Definition: MP_variable.hpp:84
Constant operator*(const Constant &a, const Constant &b)
Returns the product of two constants.This is used in the formation of an expression.
void generate(const MP_domain &domain, vector< Constant > multiplicators, MP::GenerateFunctor &f, double m) const
Expression_div(const MP_expression &e, const Constant &c)
int check(int i) const
Definition: MP_set.hpp:38
bool operator()(const MP::Coef &a, const MP::Coef &b) const
Constant sum(const MP_domain &i, const Constant &e)
Returns the sum of two constants.
The base class for all expressions.
const MP_set_base * S4
Definition: MP_variable.hpp:84
void insertVariables(set< MP_variable *> &v) const
int evaluate() const
Definition: MP_index.hpp:59
Expression_plus(const MP_expression &e1, const MP_expression &e2)