00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <sstream>
00010 #include "MP_expression.hpp"
00011 #include "MP_constant.hpp"
00012 #include "MP_boolean.hpp"
00013 #include "MP_constraint.hpp"
00014 #include "MP_set.hpp"
00015 #include "MP_variable.hpp"
00016 #include "MP_model.hpp"
00017 #include <OsiSolverInterface.hpp>
00018
00019 namespace flopc {
00020
00021 VariableRef::VariableRef(MP_variable* v,
00022 const MP_index_exp& i1,
00023 const MP_index_exp& i2,
00024 const MP_index_exp& i3,
00025 const MP_index_exp& i4,
00026 const MP_index_exp& i5) :
00027 V(v),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {
00028 offset = v->offset;
00029 }
00030
00031 double VariableRef::level() const {
00032 return V->M->Solver->getColSolution()[V->offset +
00033 V->f(V->S1->evaluate(),
00034 V->S2->evaluate(),
00035 V->S3->evaluate(),
00036 V->S4->evaluate(),
00037 V->S5->evaluate())];
00038 }
00039
00040 int VariableRef::getColumn() const {
00041 int i1 = V->S1->check(I1->evaluate());
00042 int i2 = V->S2->check(I2->evaluate());
00043 int i3 = V->S3->check(I3->evaluate());
00044 int i4 = V->S4->check(I4->evaluate());
00045 int i5 = V->S5->check(I5->evaluate());
00046
00047 if (i1==outOfBound || i2==outOfBound || i3==outOfBound ||
00048 i4==outOfBound || i5==outOfBound) {
00049 return outOfBound;
00050 } else {
00051 return V->offset + V->f(i1,i2,i3,i4,i5);
00052 }
00053 }
00054
00055 void VariableRef::generate(const MP_domain& domain,
00056 vector<Constant > multiplicators,
00057 MP::GenerateFunctor& f,
00058 double m) const {
00059 f.setMultiplicator(multiplicators,m);
00060 f.setTerminalExpression(this);
00061 domain.forall(&f);
00062 }
00063
00064 class Expression_constant : public TerminalExpression, public MP {
00065 friend class MP_expression;
00066 private:
00067 Expression_constant(const Constant& c) : C(c) {}
00068 double level() const {
00069 return C->evaluate();
00070 }
00071 double getValue() const {
00072 return C->evaluate();
00073 }
00074 int getColumn() const {
00075 return -1;
00076 }
00077 int getStage() const {
00078 return C->getStage();
00079 }
00080 void generate(const MP_domain& domain,
00081 vector<Constant> multiplicators,
00082 MP::GenerateFunctor& f,
00083 double m) const {
00084 f.setMultiplicator(multiplicators,m);
00085 f.setTerminalExpression(this);
00086 domain.forall(&f);
00087 }
00088 void insertVariables(set<MP_variable*>& v) const {}
00089
00090 Constant C;
00091 };
00092
00093
00094 class Expression_operator : public MP_expression_base, public MP {
00095 protected:
00096 Expression_operator(const MP_expression& e1, const MP_expression& e2) :
00097 left(e1),right(e2) {}
00098
00099 void insertVariables(set<MP_variable*>& v) const {
00100 left->insertVariables(v);
00101 right->insertVariables(v);
00102 }
00103
00104 MP_expression left,right;
00105 };
00106
00107 class Expression_plus : public Expression_operator {
00108 friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2);
00109 friend MP_expression operator+(const MP_expression& e1, const Constant& e2);
00110 friend MP_expression operator+(const Constant& e1, const MP_expression& e2);
00111 private:
00112 Expression_plus(const MP_expression& e1, const MP_expression& e2) :
00113 Expression_operator(e1,e2) {}
00114 double level() const {
00115 return left->level()+right->level();
00116 }
00117 void generate(const MP_domain& domain,
00118 vector<Constant> multiplicators,
00119 MP::GenerateFunctor& f,
00120 double m) const {
00121 left->generate(domain, multiplicators, f, m);
00122 right->generate(domain, multiplicators, f, m);
00123 }
00124 };
00125
00126 class Expression_minus : public Expression_operator {
00127 friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2);
00128 friend MP_expression operator-(const MP_expression& e1, const Constant& e2);
00129 friend MP_expression operator-(const Constant& e1, const MP_expression& e2);
00130 private:
00131 Expression_minus(const MP_expression& e1, const MP_expression& e2) :
00132 Expression_operator(e1,e2) {}
00133 double level() const {
00134 return left->level()-right->level();
00135 }
00136 void generate(const MP_domain& domain,
00137 vector<Constant> multiplicators,
00138 MP::GenerateFunctor& f,
00139 double m) const {
00140 left->generate(domain, multiplicators, f, m);
00141 right->generate(domain, multiplicators, f, -m);
00142 }
00143 };
00144
00145 class Expression_mult : public MP_expression_base, MP {
00146 friend MP_expression operator*(const Constant& e1, const MP_expression& e2);
00147 friend MP_expression operator*(const MP_expression& e1, const Constant& e2);
00148
00149 private:
00150 Expression_mult(const Constant& e1, const MP_expression& e2) :
00151 left(e1), right(e2) {}
00152 double level() const {
00153 return left->evaluate()*right->level();
00154 }
00155 void generate(const MP_domain& domain,
00156 vector<Constant> multiplicators,
00157 MP::GenerateFunctor& f,
00158 double m) const {
00159 multiplicators.push_back(left);
00160 right->generate(domain, multiplicators, f, m);
00161 }
00162 void insertVariables(set<MP_variable*>& v) const {
00163 right->insertVariables(v);
00164 }
00165 Constant left;
00166 MP_expression right;
00167 };
00168
00169 class Expression_div : public MP_expression_base, MP {
00170 friend MP_expression operator/(const MP_expression& e1, const Constant& e2);
00171 private:
00172 Expression_div(const MP_expression& e, const Constant& c) :
00173 left(e), right(c) {}
00174 double level() const {
00175 return left->level()/right->evaluate();
00176 }
00177 void generate(const MP_domain& domain,
00178 vector<Constant> multiplicators,
00179 MP::GenerateFunctor& f,
00180 double m) const {
00181 multiplicators.push_back(1/right);
00182 left->generate(domain, multiplicators, f, m);
00183 }
00184 void insertVariables(set<MP_variable*>& v) const {
00185 left->insertVariables(v);
00186 }
00187 MP_expression left;
00188 Constant right;
00189 };
00190
00191 class Expression_sum : public MP_expression_base, public MP {
00192 friend MP_expression sum(const MP_domain& d, const MP_expression& e);
00193 private:
00194 Expression_sum(const MP_domain& d, const MP_expression& e) : D(d), exp(e) {}
00195
00196 double level() const {
00197 SumFunctor SF(exp);
00198 D.forall(SF);
00199 return SF.the_sum;
00200 }
00201 void generate(const MP_domain& domain,
00202 vector<Constant> multiplicators,
00203 MP::GenerateFunctor& f,
00204 double m) const {
00205
00206 exp->generate(D*domain, multiplicators, f, m);
00207 }
00208 void insertVariables(set<MP_variable*>& v) const {
00209 exp->insertVariables(v);
00210 }
00211
00212 class SumFunctor : public Functor {
00213 public:
00214 SumFunctor(MP_expression exp) : E(exp), the_sum(0) {}
00215 void operator()() const {
00216 the_sum += E->level();
00217 }
00218 MP_expression E;
00219 mutable double the_sum;
00220 };
00221
00222 MP_domain D;
00223 MP_expression exp;
00224 };
00225
00226
00227 MP_expression operator+(const MP_expression& e1, const MP_expression& e2) {
00228 return new Expression_plus(e1, e2);
00229 }
00230 MP_expression operator+(const MP_expression& e1, const Constant& e2) {
00231 return new Expression_plus(e1, e2);
00232 }
00233 MP_expression operator+(const Constant& e1, const MP_expression& e2) {
00234 return new Expression_plus(e1, e2);
00235 }
00236
00237 MP_expression operator-(const MP_expression& e1, const MP_expression& e2) {
00238 return new Expression_minus(e1, e2);
00239 }
00240 MP_expression operator-(const MP_expression& e1, const Constant& e2) {
00241 return new Expression_minus(e1, e2);
00242 }
00243 MP_expression operator-(const Constant& e1, const MP_expression& e2) {
00244 return new Expression_minus(e1, e2);
00245 }
00246
00247 MP_expression operator*(const Constant& e1, const MP_expression& e2) {
00248 return new Expression_mult(e1, e2);
00249 }
00250 MP_expression operator*(const MP_expression& e1, const Constant& e2) {
00251 return new Expression_mult(e2, e1);
00252 }
00253
00254 MP_expression operator/(const MP_expression& e1, const Constant& e2) {
00255 return new Expression_div(e1, e2);
00256 }
00257
00258 MP_expression sum(const MP_domain& d, const MP_expression& e) {
00259 return new Expression_sum(d, e);
00260 }
00261
00262 }
00263
00264 using namespace flopc;
00265
00266
00267 MP_expression::MP_expression(const Constant &c) :
00268 Handle<MP_expression_base*>(new Expression_constant(c)) {}
00269
00270 MP_expression::MP_expression(const VariableRef &v) :
00271 Handle<MP_expression_base*>(const_cast<VariableRef*>(&v)) {}
00272
00273
00274 bool MP::CoefLess::operator() (const MP::Coef& a, const MP::Coef& b) const {
00275 if (a.col < b.col) {
00276 return true;
00277 } else if (a.col == b.col && a.row < b.row) {
00278 return true;
00279 } else {
00280 return false;
00281 }
00282 }
00283
00284 void MP::GenerateFunctor::operator()() const {
00285 double multiplicator = M;
00286 int stage = 0;
00287 for (unsigned int i=0; i<multiplicators.size(); i++) {
00288 multiplicator *= multiplicators[i]->evaluate();
00289 if (multiplicators[i]->getStage() > stage) {
00290 stage = multiplicators[i]->getStage();
00291 }
00292 }
00293 int rowNumber = -1;
00294 if (R != 0) {
00295 rowNumber = R->row_number();
00296 }
00297 if (rowNumber != outOfBound) {
00298 int colNumber = C->getColumn();
00299 if ( colNumber != outOfBound ) {
00300 double val = multiplicator*C->getValue();
00301 int tstage = C->getStage();
00302 if (tstage > stage) {
00303 stage = tstage;
00304 }
00305
00306 Coefs.push_back(MP::Coef(colNumber, rowNumber, val, stage));
00307
00308 }
00309 }
00310 }