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 class Constant_mult : public Constant_exp {
00164 friend Constant operator*(const Constant& a, const Constant& b);
00165 private:
00166 Constant_mult(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00167 double evaluate() const {
00168 return left->evaluate()*right->evaluate();
00169 }
00170 };
00171
00172 Constant operator*(const Constant& a, const Constant& b) {
00173 return new Constant_mult(a,b);
00174 }
00175
00176 class Constant_div : public Constant_exp {
00177 friend Constant operator/(const Constant& a, const Constant& b);
00178 private:
00179 Constant_div(const Constant& i, const Constant& j) : Constant_exp(i,j) {}
00180 double evaluate() const {
00181 return left->evaluate()/right->evaluate();
00182 }
00183 };
00184
00185 Constant operator/(const Constant& a, const Constant& b) {
00186 return new Constant_div(a,b);
00187 }
00188
00189 class Constant_max : public Constant_base, public Functor {
00190 friend Constant maximum(const MP_domain& i, const Constant& e);
00191 private:
00192 Constant_max(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00193 void operator()() const {
00194 double temp = exp->evaluate();
00195 if (temp > the_max) {
00196 the_max = temp;
00197 }
00198 }
00199 double evaluate() const {
00200 the_max = DBL_MIN;
00201 d.Forall(this);
00202 return the_max;
00203 }
00204
00205 MP_domain d;
00206 Constant exp;
00207 mutable double the_max;
00208 };
00209
00210 class Constant_min : public Constant_base, public Functor {
00211 friend Constant minimum(const MP_domain& i, const Constant& e);
00212 private:
00213 Constant_min(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00214 void operator()() const {
00215 double temp = exp->evaluate();
00216 if (temp < the_min) {
00217 the_min = temp;
00218 }
00219 }
00220 double evaluate() const {
00221 the_min = DBL_MAX;
00222 d.Forall(this);
00223 return the_min;
00224 }
00225
00226 MP_domain d;
00227 Constant exp;
00228 mutable double the_min;
00229 };
00230
00231 class Constant_sum : public Constant_base, public Functor {
00232 friend Constant sum(const MP_domain& i, const Constant& e);
00233 private:
00234 Constant_sum(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00235 void operator()() const {
00236 the_sum += exp->evaluate();
00237 }
00238 double evaluate() const {
00239 the_sum = 0;
00240 d.Forall(this);
00241 return the_sum;
00242 }
00243
00244 MP_domain d;
00245 Constant exp;
00246 mutable double the_sum;
00247 };
00248
00249 class Constant_product : public Constant_base, public Functor {
00250 friend Constant product(const MP_domain& i, const Constant& e);
00251 private:
00252 Constant_product(const MP_domain& i, const Constant& e) : d(i), exp(e) {}
00253 void operator()() const {
00254 the_product *= exp->evaluate();
00255 }
00256 double evaluate() const {
00257 the_product = 1;
00258 d.Forall(this);
00259 return the_product;
00260 }
00261
00262 MP_domain d;
00263 Constant exp;
00264 mutable double the_product;
00265 };
00266
00267 Constant maximum(const MP_domain& i, const Constant& e) {
00268 return new Constant_max(i,e);
00269 }
00270 Constant minimum(const MP_domain& i, const Constant& e) {
00271 return new Constant_min(i,e);
00272 }
00273 Constant sum(const MP_domain& i, const Constant& e) {
00274 return new Constant_sum(i,e);
00275 }
00276 Constant product(const MP_domain& i, const Constant& e) {
00277 return new Constant_product(i,e);
00278 }
00279
00280 Constant::Constant(const DataRef& d) :
00281 Handle<Constant_base*>(const_cast<DataRef*>(&d)) {}
00282
00283 Constant::Constant(const MP_index_exp& i) :
00284 Handle<Constant_base*>(new Constant_index(i)){}
00285
00286 Constant::Constant(double d) :
00287 Handle<Constant_base*>(new Constant_double(d)) {}
00288
00289 Constant::Constant(int d) :
00290 Handle<Constant_base*>(new Constant_double(d)) {}
00291
00292 }
00293
00294 using namespace flopc;
00295