FLOPC++
|
00001 // ******************** FlopCpp ********************************************** 00002 // File: MP_constant.cpp 00003 // $Id$ 00004 // Author: Tim Helge Hultberg (thh@mat.ua.pt) 00005 // Copyright (C) 2003 Tim Helge Hultberg 00006 // All Rights Reserved. 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 } // End of namespace flopc 00332