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