00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <float.h>
00010 #include <cmath>
00011 #include <sstream>
00012 #include "MP_constant.hpp"
00013 #include "MP_data.hpp"
00014 #include "MP_domain.hpp"
00015 #include "MP_index.hpp"
00016
00017 namespace flopc {
00018
00019 class Constant_index : public Constant_base {
00020 friend class Constant;
00021 private:
00022 Constant_index(const MP_index_exp& i) : I(i) {}
00023 double evaluate() const {
00024 return I->evaluate();
00025 }
00026 const MP_index_exp I;
00027 };
00028
00029 class Constant_double : public Constant_base {
00030 friend class Constant;
00031 private:
00032 Constant_double(double d) : D(d) {}
00033 double evaluate() const {
00034 return D;
00035 }
00036 double D;
00037 };
00038
00039 class Constant_abs : public Constant_base {
00040 friend Constant abs(const Constant& c);
00041 private:
00042 Constant_abs(const Constant& c) : C(c) {}
00043 double evaluate() const {
00044 return fabs(C->evaluate());
00045 }
00046 Constant C;
00047 };
00048 Constant abs(const Constant& c) {
00049 return new Constant_abs(c);
00050 }
00051
00052 class Constant_pos : public Constant_base {
00053 friend Constant pos(const Constant& c);
00054 private:
00055 Constant_pos(const Constant& c) : C(c) {}
00056 double evaluate() const {
00057 double temp = C->evaluate();
00058 if (temp>0) {
00059 return temp;
00060 } else {
00061 return 0.0;
00062 }
00063 }
00064 Constant C;
00065 };
00066 Constant pos(const Constant& c) {
00067 return new Constant_pos(c);
00068 }
00069
00070 class Constant_ceil : public Constant_base {
00071 friend Constant ceil(const Constant& c);
00072 private:
00073 Constant_ceil(const Constant& c) : C(c) {}
00074 double evaluate() const {
00075 return std::ceil(C->evaluate());
00076 }
00077 Constant C;
00078 };
00079 Constant ceil(const Constant& c) {
00080 return new Constant_ceil(c);
00081 }
00082
00083 class Constant_floor : public Constant_base {
00084 friend Constant floor(const Constant& c);
00085 private:
00086 Constant_floor(const Constant& c) : C(c) {}
00087 double evaluate() const {
00088 return std::floor(C->evaluate());
00089 }
00090 Constant C;
00091 };
00092 Constant floor(const Constant& c) {
00093 return new Constant_floor(c);
00094 }
00095
00096 class Constant_exp : public Constant_base {
00097 protected:
00098 Constant_exp(const Constant& i, const Constant& j) : left(i),right(j) {}
00099 Constant left, right;
00100 };
00101
00102 class Constant_min_2 : public Constant_exp {
00103 friend Constant minimum(const Constant& a, const Constant& b);
00104 private:
00105 Constant_min_2(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00106 double evaluate() const {
00107 return std::min(left->evaluate(),right->evaluate());
00108 }
00109 };
00110
00111 Constant minimum(const Constant& a, const Constant& b) {
00112 return new Constant_min_2(a,b);
00113 }
00114
00115 class Constant_max_2 : public Constant_exp {
00116 friend Constant maximum(const Constant& a, const Constant& b);
00117 private:
00118 Constant_max_2(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00119 double evaluate() const {
00120 return std::max(left->evaluate(),right->evaluate());
00121 }
00122 };
00123
00124 Constant maximum(const Constant& a, const Constant& b) {
00125 return new Constant_max_2(a,b);
00126 }
00127
00128 class Constant_plus : public Constant_exp {
00129 friend Constant operator+(const Constant& a, const Constant& b);
00130 friend Constant operator+(MP_index& a, MP_index& b);
00131 private:
00132 Constant_plus(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00133 double evaluate() const {
00134 return left->evaluate()+right->evaluate();
00135 }
00136 };
00137
00138 Constant operator+(const Constant& a, const Constant& b) {
00139 return new Constant_plus(a,b);
00140 }
00141 Constant operator+(MP_index& a, MP_index& b) {
00142 return new Constant_plus(Constant(a),Constant(b));
00143 }
00144
00145 class Constant_minus : public Constant_exp {
00146 friend Constant operator-(const Constant& a, const Constant& b);
00147 friend Constant operator-(MP_index& a, MP_index& b);
00148 private:
00149 Constant_minus(const Constant& i, const Constant& j): Constant_exp(i,j) {}
00150 double evaluate() const {
00151 return left->evaluate()-right->evaluate();
00152 }
00153 };
00154
00155 Constant operator-(const Constant& a, const Constant& b) {
00156 return new Constant_minus(a,b);
00157 }
00158
00159 Constant operator-(MP_index& a, MP_index& b) {
00160 return new Constant_minus(Constant(a),Constant(b));
00161 }
00162
00163
00164 class Constant_unary_minus : public Constant_base {
00165 friend Constant operator-(const Constant& a);
00166 private:
00167 Constant_unary_minus(const Constant& i) : left(i) {}
00168 double evaluate() const {
00169 return -left->evaluate();
00170 }
00171 Constant left;
00172 };
00173 Constant operator-(const Constant& a) {
00174 return new Constant_unary_minus(a);
00175 }
00176
00177 class Constant_mult : public Constant_exp {
00178 friend Constant operator*(const Constant& a, const Constant& b);
00179 private:
00180 Constant_mult(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00181 double evaluate() const {
00182 return left->evaluate()*right->evaluate();
00183 }
00184 };
00185
00186 Constant operator*(const Constant& a, const Constant& b) {
00187 return new Constant_mult(a,b);
00188 }
00189
00190 class Constant_div : public Constant_exp {
00191 friend Constant operator/(const Constant& a, const Constant& b);
00192 private:
00193 Constant_div(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00194 double evaluate() const {
00195 return left->evaluate()/right->evaluate();
00196 }
00197 };
00198
00199 Constant operator/(const Constant& a, const Constant& b) {
00200 return new Constant_div(a,b);
00201 }
00202
00203 class Constant_if : public Constant_exp {
00204 friend Constant mpif(const MP_boolean& c, const Constant& a, const Constant& b);
00205 private:
00206 Constant_if(const MP_boolean b, const Constant& i, const Constant& j) : Constant_exp(i,j), B(b) {}
00207 double evaluate() const {
00208 if (B->evaluate()==true) {
00209 return left->evaluate();
00210 } else {
00211 return right->evaluate();
00212 }
00213 }
00214
00215 MP_boolean B;
00216 };
00217
00218 Constant mpif(const MP_boolean& c, const Constant& a, const Constant& b) {
00219 return new Constant_if(c,a,b);
00220 }
00221
00222
00223 class Constant_max : public Constant_base {
00224 friend Constant maximum(const MP_domain& i, const Constant& e);
00225 private:
00226 Constant_max(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00227 double evaluate() const {
00228 MaxFunctor MF(exp);
00229 d.forall(MF);
00230 return MF.the_max;
00231 }
00232 class MaxFunctor : public Functor {
00233 public:
00234 MaxFunctor(Constant exp) : C(exp), the_max(DBL_MIN) {}
00235 void operator()() const {
00236 double temp = C->evaluate();
00237 if (temp > the_max) {
00238 the_max = temp;
00239 }
00240 }
00241 Constant C;
00242 mutable double the_max;
00243 };
00244
00245 MP_domain d;
00246 Constant exp;
00247 };
00248
00249 class Constant_min : public Constant_base, public Functor {
00250 friend Constant minimum(const MP_domain& i, const Constant& e);
00251 private:
00252 Constant_min(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00253 void operator()() const {
00254 double temp = exp->evaluate();
00255 if (temp < the_min) {
00256 the_min = temp;
00257 }
00258 }
00259 double evaluate() const {
00260 the_min = DBL_MAX;
00261 d.forall(this);
00262 return the_min;
00263 }
00264
00265 MP_domain d;
00266 Constant exp;
00267 mutable double the_min;
00268 };
00269
00270 class Constant_sum : public Constant_base, public Functor {
00271 friend Constant sum(const MP_domain& i, const Constant& e);
00272 private:
00273 Constant_sum(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00274 void operator()() const {
00275 the_sum += exp->evaluate();
00276 }
00277 double evaluate() const {
00278 the_sum = 0;
00279 d.forall(this);
00280 return the_sum;
00281 }
00282
00283 MP_domain d;
00284 Constant exp;
00285 mutable double the_sum;
00286 };
00287
00288 class Constant_product : public Constant_base, public Functor {
00289 friend Constant product(const MP_domain& i, const Constant& e);
00290 private:
00291 Constant_product(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00292 void operator()() const {
00293 the_product *= exp->evaluate();
00294 }
00295 double evaluate() const {
00296 the_product = 1;
00297 d.forall(this);
00298 return the_product;
00299 }
00300
00301 MP_domain d;
00302 Constant exp;
00303 mutable double the_product;
00304 };
00305
00306 Constant maximum(const MP_domain& i, const Constant& e) {
00307 return new Constant_max(i,e);
00308 }
00309 Constant minimum(const MP_domain& i, const Constant& e) {
00310 return new Constant_min(i,e);
00311 }
00312 Constant sum(const MP_domain& i, const Constant& e) {
00313 return new Constant_sum(i,e);
00314 }
00315 Constant product(const MP_domain& i, const Constant& e) {
00316 return new Constant_product(i,e);
00317 }
00318
00319 Constant::Constant(const DataRef& d) :
00320 Handle<Constant_base*>(const_cast<DataRef*>(&d)) {}
00321
00322 Constant::Constant(const MP_index_exp& i) :
00323 Handle<Constant_base*>(new Constant_index(i)){}
00324
00325 Constant::Constant(double d) :
00326 Handle<Constant_base*>(new Constant_double(d)) {}
00327
00328 Constant::Constant(int d) :
00329 Handle<Constant_base*>(new Constant_double(d)) {}
00330
00331 }
00332