BWAPI
|
00001 /**************************************************************************** 00002 * Core Library Version 1.7, August 2004 00003 * Copyright (c) 1995-2004 Exact Computation Project 00004 * All rights reserved. 00005 * 00006 * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may 00007 * redistribute it under the terms of the Q Public License version 1.0. 00008 * See the file LICENSE.QPL distributed with CORE. 00009 * 00010 * Licensees holding a valid commercial license may use this file in 00011 * accordance with the commercial license agreement provided with the 00012 * software. 00013 * 00014 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00015 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00016 * 00017 * 00018 * File: Expr.h 00019 * Synopsis: a class of Expression in Level 3 00020 * 00021 * Written by 00022 * Koji Ouchi <ouchi@simulation.nyu.edu> 00023 * Chee Yap <yap@cs.nyu.edu> 00024 * Igor Pechtchanski <pechtcha@cs.nyu.edu> 00025 * Vijay Karamcheti <vijayk@cs.nyu.edu> 00026 * Chen Li <chenli@cs.nyu.edu> 00027 * Zilin Du <zilin@cs.nyu.edu> 00028 * Sylvain Pion <pion@cs.nyu.edu> 00029 * Vikram Sharma<sharma@cs.nyu.edu> 00030 * 00031 * WWW URL: http://cs.nyu.edu/exact/ 00032 * Email: exact@cs.nyu.edu 00033 * 00034 * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/Expr.h $ 00035 * $Id: Expr.h 37555 2007-03-27 11:33:02Z afabri $ 00036 ***************************************************************************/ 00037 00038 #ifndef _CORE_EXPR_H_ 00039 #define _CORE_EXPR_H_ 00040 00041 #include <CGAL/CORE/ExprRep.h> 00042 00043 CORE_BEGIN_NAMESPACE 00044 00047 typedef RCImpl<ExprRep> RCExpr; 00048 class Expr : public RCExpr { 00049 public: 00051 00052 00053 Expr() : RCExpr(new ConstDoubleRep()) {} 00055 Expr(int i) : RCExpr(new ConstDoubleRep(i)) {} 00057 Expr(short i) : RCExpr(new ConstDoubleRep(i)) {} 00059 Expr(unsigned int ui) : RCExpr(new ConstDoubleRep(ui)) {} 00060 00062 Expr(long l) : RCExpr(new ConstRealRep(Real(l))) {} 00064 Expr(unsigned long ul) : RCExpr(new ConstRealRep(Real(ul))) {} 00065 00067 00075 Expr(float f) : RCExpr(NULL) { // check for valid numbers 00076 // (i.e., not infinite and not NaN) 00077 if (!finite(f)) { 00078 std::cerr << " ERROR : constructed an invalid float! " << std::endl; 00079 if (AbortFlag) 00080 abort(); 00081 InvalidFlag = -1; 00082 } 00083 rep = new ConstDoubleRep(f); 00084 } 00086 Expr(double d) : RCExpr(NULL) { // check for valid numbers 00087 // (i.e., not infinite and not NaN) 00088 if (!finite(d)) { 00089 std::cerr << " ERROR : constructed an invalid double! " << std::endl; 00090 if (AbortFlag) 00091 abort(); 00092 InvalidFlag = -2; 00093 } 00094 rep = new ConstDoubleRep(d); 00095 } 00096 00098 Expr(const BigInt& I) : RCExpr(new ConstRealRep(Real(I))) {} 00100 Expr(const BigRat& R) : RCExpr(new ConstRealRep(Real(R))) {} 00101 00103 Expr(const BigFloat& F) : RCExpr(new ConstRealRep(Real(F))) {} 00104 00106 00112 Expr(const char *s, const extLong& p = defInputDigits) 00113 : RCExpr(new ConstRealRep(Real(s, p))) {} 00114 00116 Expr(const std::string& s, const extLong& p = defInputDigits) 00117 : RCExpr(new ConstRealRep(Real(s, p))) {} 00118 00120 Expr(const Real &r) : RCExpr(new ConstRealRep(r)) {} 00121 00123 00124 template <class NT> 00125 Expr(const Polynomial<NT>& p, int n = 0) 00126 : RCExpr(new ConstPolyRep<NT>(p, n)) {} 00127 00129 template <class NT> 00130 Expr(const Polynomial<NT>& p, const BFInterval& I) 00131 : RCExpr(new ConstPolyRep<NT>(p, I)) {} 00132 00134 Expr(ExprRep* p) : RCExpr(p) {} 00136 00138 00139 00140 Expr(const Expr& rhs) : RCExpr(rhs) { 00141 rep->incRef(); 00142 } 00143 00145 Expr& operator=(const Expr& rhs) { 00146 if (this != &rhs) { 00147 rep->decRef(); 00148 rep = rhs.rep; 00149 rep->incRef(); 00150 } 00151 return *this; 00152 } 00154 ~Expr() { 00155 rep->decRef(); 00156 } 00158 00160 00161 00162 Expr& operator+=(const Expr& e) { 00163 *this = new AddRep(rep, e.rep); 00164 return *this; 00165 } 00167 Expr& operator-=(const Expr& e) { 00168 *this = new SubRep(rep, e.rep); 00169 return *this; 00170 } 00172 Expr& operator*=(const Expr& e) { 00173 *this = new MultRep(rep, e.rep); 00174 return *this; 00175 } 00177 Expr& operator/=(const Expr& e) { 00178 if ((e.rep)->getSign() == 0) { 00179 std::cerr << " ERROR : division by zero ! " << std::endl; 00180 if (AbortFlag) 00181 abort(); 00182 InvalidFlag = -3; 00183 } 00184 *this = new DivRep(rep, e.rep); 00185 return *this; 00186 } 00188 00190 00191 00192 Expr operator+() const { 00193 return Expr(*this); 00194 } 00196 Expr operator-() const { 00197 return Expr(new NegRep(rep)); 00198 } 00200 Expr& operator++() { 00201 *this += 1; 00202 return *this; 00203 } 00205 Expr operator++(int) { 00206 Expr t(*this); 00207 *this += 1; 00208 return t; 00209 } 00211 Expr& operator--() { 00212 *this -= 1; 00213 return *this; 00214 } 00216 Expr operator--(int) { 00217 Expr t(*this); 00218 *this -= 1; 00219 return t; 00220 } 00222 00224 00225 00226 void fromString(const char* s, const extLong& prec = defInputDigits) { 00227 *this = Expr(s, prec); 00228 } 00230 00231 std::string toString(long prec=defOutputDigits, bool sci=false) const { 00232 return rep->toString(prec, sci); 00233 } 00235 // 00236 00238 00239 00240 int intValue() const { 00241 return approx(64, 1024).intValue(); 00242 } 00244 long longValue() const { 00245 return approx(64, 1024).longValue(); 00246 } 00248 float floatValue() const { 00249 return approx(53, 1024).floatValue(); 00250 } 00252 00255 double doubleValue() const { 00256 return approx(53, 1024).doubleValue(); 00257 } 00259 00261 void doubleInterval(double & lb, double & ub) const; 00263 BigInt BigIntValue() const { 00264 return rep->BigIntValue(); 00265 } 00267 BigRat BigRatValue() const { 00268 return rep->BigRatValue(); 00269 } 00271 00272 BigFloat BigFloatValue() const { 00273 return rep->BigFloatValue(); 00274 } 00276 00278 00279 00280 00283 const Real & approx(const extLong& relPrec = defRelPrec, 00284 const extLong& absPrec = defAbsPrec) const { 00285 return rep->getAppValue(relPrec, absPrec); 00286 } 00288 00290 00291 //CONSTANTS: 00293 static const Expr& getZero(); 00295 static const Expr& getOne(); 00296 00298 static bool hasExactDivision() { 00299 return true; 00300 } 00301 00303 int sign() const { 00304 return rep->getSign(); 00305 } 00307 bool isZero() const { 00308 return sign() == 0; 00309 } 00311 Expr abs() const { 00312 return (sign() >= 0) ? +(*this) : -(*this); 00313 } 00314 00316 int cmp(const Expr& e) const { 00317 return rep == e.rep ? 0 : SubRep(rep, e.rep).getSign(); 00318 } 00319 00321 ExprRep* Rep() const { 00322 return rep; 00323 } 00325 long getExponent() const { 00326 return BigFloatValue().exp(); 00327 } 00329 BigInt getMantissa() const { 00330 return BigFloatValue().m(); 00331 } 00333 00334 public: 00336 00337 00338 void debug(int mode = TREE_MODE, int level = DETAIL_LEVEL, 00339 int depthLimit = INT_MAX) const; 00341 00342 enum {LIST_MODE, TREE_MODE, SIMPLE_LEVEL, DETAIL_LEVEL}; 00343 };// class Expr 00344 00345 #define CORE_EXPR_ZERO Expr::getZero() 00346 00348 inline std::ostream& operator<<(std::ostream& o, const Expr& e) { 00349 o << *(const_cast<ExprRep*>(&e.getRep())); 00350 return o; 00351 } 00353 inline std::istream& operator>>(std::istream& i, Expr& e) { 00354 Real rVal; 00355 i >> rVal; // precision is = defInputDigits 00356 if (i) 00357 e = rVal; // only assign when reading is successful. 00358 return i; 00359 } 00360 00362 BigInt floor(const Expr&, Expr&); 00364 Expr pow(const Expr&, unsigned long); 00365 00367 inline Expr operator+(const Expr& e1, const Expr& e2) { 00368 return Expr(new AddRep(e1.Rep(), e2.Rep())); 00369 } 00371 inline Expr operator-(const Expr& e1, const Expr& e2) { 00372 return Expr(new SubRep(e1.Rep(), e2.Rep())); 00373 } 00375 inline Expr operator*(const Expr& e1, const Expr& e2) { 00376 return Expr(new MultRep(e1.Rep(), e2.Rep())); 00377 } 00379 inline Expr operator/(const Expr& e1, const Expr& e2) { 00380 if (e2.sign() == 0) { 00381 std::cerr << " ERROR : division by zero ! " << std::endl; 00382 if (AbortFlag) 00383 abort(); 00384 InvalidFlag = -4; 00385 } 00386 return Expr(new DivRep(e1.Rep(), e2.Rep())); 00387 } 00389 inline Expr operator%(const Expr& e1, const Expr& e2) { 00390 Expr result; 00391 floor(e1/e2, result); 00392 return result; 00393 } 00394 00396 00398 inline bool operator==(const Expr& e1, const Expr& e2) { 00399 return e1.cmp(e2) == 0; 00400 } 00402 inline bool operator!=(const Expr& e1, const Expr& e2) { 00403 return e1.cmp(e2) != 0; 00404 } 00406 inline bool operator< (const Expr& e1, const Expr& e2) { 00407 return e1.cmp(e2) < 0; 00408 } 00410 inline bool operator<=(const Expr& e1, const Expr& e2) { 00411 return e1.cmp(e2) <= 0; 00412 } 00414 inline bool operator> (const Expr& e1, const Expr& e2) { 00415 return e1.cmp(e2) > 0; 00416 } 00418 inline bool operator>=(const Expr& e1, const Expr& e2) { 00419 return e1.cmp(e2) >= 0; 00420 } 00421 00423 inline int sign(const Expr& e) { 00424 return e.sign(); 00425 } 00427 inline bool isZero(const Expr& e) { 00428 return e.isZero(); 00429 } 00431 00435 inline int cmp(const Expr& e1, const Expr& e2) { 00436 return e1.cmp(e2); 00437 } 00439 inline Expr abs(const Expr& x) { 00440 return x.abs(); 00441 } 00443 inline Expr fabs(const Expr& x) { 00444 return abs(x); 00445 } 00447 inline BigInt floor(const Expr& e) { 00448 Expr tmp; 00449 return floor(e, tmp); 00450 } 00452 inline BigInt ceil(const Expr& e) { 00453 return -floor(-e); 00454 } 00456 inline long floorLg(const Expr& e) { 00457 Expr tmp; 00458 return floorLg(floor(e)); 00459 } 00461 inline long ceilLg(const Expr& e) { 00462 Expr tmp; 00463 return ceilLg(ceil(e)); 00464 } 00466 inline Expr power(const Expr& e, unsigned long p) { 00467 return pow(e, p); 00468 } 00469 00471 00473 // NOTE: The name "isDivisible" is not consistent 00474 // with the analogous "divisible" predicate in BigInt! 00475 inline bool isDivisible(const Expr& e1, const Expr& e2) { 00476 Expr result; 00477 floor(e1/e2, result); 00478 return (result.sign() == 0); 00479 } 00480 00482 inline Expr sqrt(const Expr& e) { 00483 if (e.sign() < 0) { 00484 std::cerr << " ERROR : sqrt of negative value ! " << std::endl; 00485 if (AbortFlag) 00486 abort(); 00487 InvalidFlag = -5; 00488 } 00489 return Expr(new SqrtRep(e.Rep())); 00490 } 00491 00492 //Following two have been added to make NT=Expr work for Polynomial<NT> 00494 inline Expr gcd(const Expr& /*a*/, const Expr& /*b*/) { 00495 return Expr(1); 00496 } 00497 inline Expr div_exact(const Expr& x, const Expr& y) { 00498 return x/y - x%y; 00499 } 00500 00502 template <class NT> 00503 inline Expr rootOf(const Polynomial<NT>& p, int n = 0) { 00504 return Expr(p, n); 00505 } 00506 00508 template <class NT> 00509 inline Expr rootOf(const Polynomial<NT>& p, const BFInterval& I) { 00510 return Expr(p, I); 00511 } 00513 template <class NT> 00514 inline Expr rootOf(const Polynomial<NT>& p, const BigFloat& x, 00515 const BigFloat& y) { 00516 return Expr(p, BFInterval(x, y) ); 00517 } 00519 template <class NT> 00520 inline Expr rootOf(const Polynomial<NT>& p, double x, double y) { 00521 return Expr(p, BFInterval(BigFloat(x), BigFloat(y)) ); 00522 } 00524 template <class NT> 00525 inline Expr rootOf(const Polynomial<NT>& p, int x, int y) { 00526 return Expr(p, BFInterval(BigFloat(x), BigFloat(y)) ); 00527 } 00528 00530 00532 template <class NT> 00533 inline Expr radical(const NT& n, int m) { 00534 assert(n>=0 && m>=1); 00535 if (n == 0 || n == 1 || m == 1) 00536 return Expr(n); 00537 Polynomial<NT> Q(m); 00538 Q.setCoeff(0, -n); 00539 Q.setCoeff(m, 1); 00540 return Expr(Q, 0); 00541 } 00542 00543 // We include this file here and not from inside Poly.h, 00544 // because otherwise VC++.net2003 can't compile Expr.cpp 00545 #include <CGAL/CORE/poly/Poly.tcc> 00546 00547 CORE_END_NAMESPACE 00548 #endif // _CORE_EXPR_H_