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