// ******************** FlopCpp ********************************************** // File: MP_expression.cpp // $Id$ // Author: Tim Helge Hultberg (thh@mat.ua.pt) // Copyright (C) 2003 Tim Helge Hultberg // All Rights Reserved. //**************************************************************************** #include #include "MP_expression.hpp" #include "MP_constant.hpp" #include "MP_boolean.hpp" #include "MP_constraint.hpp" #include "MP_set.hpp" #include "MP_variable.hpp" #include "MP_model.hpp" #include namespace flopc { VariableRef::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) : V(v),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) { offset = v->offset; } double VariableRef::level() const { return V->M->Solver->getColSolution()[V->offset + V->f(V->S1->evaluate(), V->S2->evaluate(), V->S3->evaluate(), V->S4->evaluate(), V->S5->evaluate())]; } int VariableRef::getColumn() const { int i1 = V->S1->check(I1->evaluate()); int i2 = V->S2->check(I2->evaluate()); int i3 = V->S3->check(I3->evaluate()); int i4 = V->S4->check(I4->evaluate()); int i5 = V->S5->check(I5->evaluate()); if (i1==outOfBound || i2==outOfBound || i3==outOfBound || i4==outOfBound || i5==outOfBound) { return outOfBound; } else { return V->offset + V->f(i1,i2,i3,i4,i5); } } void VariableRef::generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { f.setMultiplicator(multiplicators,m); f.setTerminalExpression(this); domain.forall(&f); } class Expression_constant : public TerminalExpression, public MP { friend class MP_expression; private: Expression_constant(const Constant& c) : C(c) {} double level() const { return C->evaluate(); } double getValue() const { return C->evaluate(); } int getColumn() const { return -1; } int getStage() const { return C->getStage(); //NB to be changed } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { f.setMultiplicator(multiplicators,m); f.setTerminalExpression(this); domain.forall(&f); } void insertVariables(set& v) const {} Constant C; }; class Expression_operator : public MP_expression_base, public MP { protected: Expression_operator(const MP_expression& e1, const MP_expression& e2) : left(e1),right(e2) {} void insertVariables(set& v) const { left->insertVariables(v); right->insertVariables(v); } MP_expression left,right; }; class Expression_plus : public Expression_operator { friend MP_expression operator+(const MP_expression& e1, const MP_expression& e2); friend MP_expression operator+(const MP_expression& e1, const Constant& e2); friend MP_expression operator+(const Constant& e1, const MP_expression& e2); private: Expression_plus(const MP_expression& e1, const MP_expression& e2) : Expression_operator(e1,e2) {} double level() const { return left->level()+right->level(); } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { left->generate(domain, multiplicators, f, m); right->generate(domain, multiplicators, f, m); } }; class Expression_minus : public Expression_operator { friend MP_expression operator-(const MP_expression& e1, const MP_expression& e2); friend MP_expression operator-(const MP_expression& e1, const Constant& e2); friend MP_expression operator-(const Constant& e1, const MP_expression& e2); private: Expression_minus(const MP_expression& e1, const MP_expression& e2) : Expression_operator(e1,e2) {} double level() const { return left->level()-right->level(); } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { left->generate(domain, multiplicators, f, m); right->generate(domain, multiplicators, f, -m); } }; class Expression_mult : public MP_expression_base, MP { friend MP_expression operator*(const Constant& e1, const MP_expression& e2); friend MP_expression operator*(const MP_expression& e1, const Constant& e2); private: Expression_mult(const Constant& e1, const MP_expression& e2) : left(e1), right(e2) {} double level() const { return left->evaluate()*right->level(); } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { multiplicators.push_back(left); right->generate(domain, multiplicators, f, m); } void insertVariables(set& v) const { right->insertVariables(v); } Constant left; MP_expression right; }; class Expression_div : public MP_expression_base, MP { friend MP_expression operator/(const MP_expression& e1, const Constant& e2); private: Expression_div(const MP_expression& e, const Constant& c) : left(e), right(c) {} double level() const { return left->level()/right->evaluate(); } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { multiplicators.push_back(1/right); left->generate(domain, multiplicators, f, m); } void insertVariables(set& v) const { left->insertVariables(v); } MP_expression left; Constant right; }; class Expression_sum : public MP_expression_base, public MP { friend MP_expression sum(const MP_domain& d, const MP_expression& e); private: Expression_sum(const MP_domain& d, const MP_expression& e) : D(d), exp(e) {} double level() const { SumFunctor SF(exp); D.forall(SF); return SF.the_sum; } void generate(const MP_domain& domain, vector multiplicators, MP::GenerateFunctor& f, double m) const { // The order, D*domain (NOT domain*D), is important for efficiency! exp->generate(D*domain, multiplicators, f, m); } void insertVariables(set& v) const { exp->insertVariables(v); } class SumFunctor : public Functor { public: SumFunctor(MP_expression exp) : E(exp), the_sum(0) {} void operator()() const { the_sum += E->level(); } MP_expression E; mutable double the_sum; }; MP_domain D; MP_expression exp; }; MP_expression operator+(const MP_expression& e1, const MP_expression& e2) { return new Expression_plus(e1, e2); } MP_expression operator+(const MP_expression& e1, const Constant& e2) { return new Expression_plus(e1, e2); } MP_expression operator+(const Constant& e1, const MP_expression& e2) { return new Expression_plus(e1, e2); } MP_expression operator-(const MP_expression& e1, const MP_expression& e2) { return new Expression_minus(e1, e2); } MP_expression operator-(const MP_expression& e1, const Constant& e2) { return new Expression_minus(e1, e2); } MP_expression operator-(const Constant& e1, const MP_expression& e2) { return new Expression_minus(e1, e2); } MP_expression operator*(const Constant& e1, const MP_expression& e2) { return new Expression_mult(e1, e2); } MP_expression operator*(const MP_expression& e1, const Constant& e2) { return new Expression_mult(e2, e1); } MP_expression operator/(const MP_expression& e1, const Constant& e2) { return new Expression_div(e1, e2); } MP_expression sum(const MP_domain& d, const MP_expression& e) { return new Expression_sum(d, e); } } // End of namespace flopc using namespace flopc; MP_expression::MP_expression(const Constant &c) : Handle(new Expression_constant(c)) {} MP_expression::MP_expression(const VariableRef &v) : Handle(const_cast(&v)) {} bool MP::CoefLess::operator() (const MP::Coef& a, const MP::Coef& b) const { if (a.col < b.col) { return true; } else if (a.col == b.col && a.row < b.row) { return true; } else { return false; } } void MP::GenerateFunctor::operator()() const { double multiplicator = M; int stage = 0; for (unsigned int i=0; ievaluate(); if (multiplicators[i]->getStage() > stage) { stage = multiplicators[i]->getStage(); } } int rowNumber = -1; if (R != 0) { rowNumber = R->row_number(); } if (rowNumber != outOfBound) { int colNumber = C->getColumn(); if ( colNumber != outOfBound ) { double val = multiplicator*C->getValue(); int tstage = C->getStage(); if (tstage > stage) { stage = tstage; } // if (val != 0) { Coefs.push_back(MP::Coef(colNumber, rowNumber, val, stage)); //} } } }