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, public Functor {
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 void operator()() const {
00228 double temp = exp->evaluate();
00229 if (temp > the_max) {
00230 the_max = temp;
00231 }
00232 }
00233 double evaluate() const {
00234 the_max = DBL_MIN;
00235 d.Forall(this);
00236 return the_max;
00237 }
00238
00239 MP_domain d;
00240 Constant exp;
00241 mutable double the_max;
00242 };
00243
00244 class Constant_min : public Constant_base, public Functor {
00245 friend Constant minimum(const MP_domain& i, const Constant& e);
00246 private:
00247 Constant_min(const MP_domain& i, const Constant& e) : d(i), exp(e) {};
00248 void operator()() const {
00249 double temp = exp->evaluate();
00250 if (temp < the_min) {
00251 the_min = temp;
00252 }
00253 }
00254 double evaluate() const {
00255 the_min = DBL_MAX;
00256 d.Forall(this);
00257 return the_min;
00258 }
00259
00260 MP_domain d;
00261 Constant exp;
00262 mutable double the_min;
00263 };
00264
00265 class Constant_sum : public Constant_base, public Functor {
00266 friend Constant sum(const MP_domain& i, const Constant& e);
00267 private:
00268 Constant_sum(const MP_domain& i, const Constant& e) : d(i), exp(e) {};
00269 void operator()() const {
00270 the_sum += exp->evaluate();
00271 }
00272 double evaluate() const {
00273 the_sum = 0;
00274 d.Forall(this);
00275 return the_sum;
00276 }
00277
00278 MP_domain d;
00279 Constant exp;
00280 mutable double the_sum;
00281 };
00282
00283 class Constant_product : public Constant_base, public Functor {
00284 friend Constant product(const MP_domain& i, const Constant& e);
00285 private:
00286 Constant_product(const MP_domain& i, const Constant& e) : d(i), exp(e) {};
00287 void operator()() const {
00288 the_product *= exp->evaluate();
00289 }
00290 double evaluate() const {
00291 the_product = 1;
00292 d.Forall(this);
00293 return the_product;
00294 }
00295
00296 MP_domain d;
00297 Constant exp;
00298 mutable double the_product;
00299 };
00300
00301 Constant maximum(const MP_domain& i, const Constant& e) {
00302 return new Constant_max(i,e);
00303 }
00304 Constant minimum(const MP_domain& i, const Constant& e) {
00305 return new Constant_min(i,e);
00306 }
00307 Constant sum(const MP_domain& i, const Constant& e) {
00308 return new Constant_sum(i,e);
00309 }
00310 Constant product(const MP_domain& i, const Constant& e) {
00311 return new Constant_product(i,e);
00312 }
00313
00314 Constant::Constant(const DataRef& d) :
00315 Handle<Constant_base*>(const_cast<DataRef*>(&d)) {}
00316
00317 Constant::Constant(const MP_index_exp& i) :
00318 Handle<Constant_base*>(new Constant_index(i)){}
00319
00320 Constant::Constant(double d) :
00321 Handle<Constant_base*>(new Constant_double(d)) {}
00322
00323 Constant::Constant(int d) :
00324 Handle<Constant_base*>(new Constant_double(d)) {}
00325
00326 }
00327