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: RealRep.h 00019 * Synopsis: 00020 * Internal Representation for Real 00021 * 00022 * Written by 00023 * Koji Ouchi <ouchi@simulation.nyu.edu> 00024 * Chee Yap <yap@cs.nyu.edu> 00025 * Chen Li <chenli@cs.nyu.edu> 00026 * Zilin Du <zilin@cs.nyu.edu> 00027 * Sylvain Pion <pion@cs.nyu.edu> 00028 * 00029 * WWW URL: http://cs.nyu.edu/exact/ 00030 * Email: exact@cs.nyu.edu 00031 * 00032 * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/RealRep.h $ 00033 * $Id: RealRep.h 28567 2006-02-16 14:30:13Z lsaboret $ 00034 ***************************************************************************/ 00035 #ifndef _CORE_REALREP_H_ 00036 #define _CORE_REALREP_H_ 00037 #include "BigFloat.h" 00038 00039 CORE_BEGIN_NAMESPACE 00040 00041 class Real; 00042 00043 class RealRep { 00044 public: 00045 extLong mostSignificantBit; 00046 public: 00047 RealRep() : refCount(1) {} 00048 virtual ~RealRep() {} 00049 virtual int ID() const = 0; 00050 00051 virtual long longValue() const = 0; 00052 virtual double doubleValue() const = 0; 00053 virtual BigInt BigIntValue() const = 0; 00054 virtual BigRat BigRatValue() const = 0; 00055 virtual BigFloat BigFloatValue() const = 0; 00056 00057 virtual BigFloat approx(const extLong&, const extLong&) const = 0; 00058 virtual Real operator-() const = 0; 00059 00060 virtual bool isExact() const = 0; 00061 virtual int sgn() const = 0; 00062 virtual bool isZeroIn() const = 0; 00063 00064 virtual BigFloat sqrt(const extLong&) const = 0; 00065 virtual BigFloat sqrt(const extLong&, const BigFloat&) const = 0; 00066 00067 virtual void ULV_E(extLong &, extLong&, extLong&, 00068 extLong&, extLong&, extLong&) const = 0; 00069 virtual extLong flrLgErr() const = 0; 00070 virtual extLong clLgErr() const = 0; 00071 virtual unsigned long degree() const = 0; 00072 virtual unsigned long length() const = 0; 00073 virtual unsigned long height() const = 0; 00074 00075 virtual std::string toString(long prec, bool sci) const = 0; 00076 virtual std::ostream& operator<<(std::ostream& o) const = 0; 00077 public: 00078 void incRef() { 00079 ++refCount; 00080 } 00081 void decRef() { 00082 if (--refCount == 0) 00083 delete this; 00084 } 00085 int getRefCount() const { 00086 return refCount; 00087 } 00088 private: 00089 int refCount; 00090 };//realRep class 00091 00092 template <class T> 00093 class Realbase_for : public RealRep { 00094 public: 00095 CORE_MEMORY(Realbase_for) 00096 Realbase_for(const T& k); 00097 ~Realbase_for() {} 00098 int ID() const; 00099 00100 long longValue() const { 00101 return ker.longValue(); 00102 } 00103 double doubleValue() const { 00104 return ker.doubleValue(); 00105 } 00106 BigInt BigIntValue() const { 00107 return BigInt(ker); 00108 } 00109 BigRat BigRatValue() const { 00110 return BigRat(ker); 00111 } 00112 BigFloat BigFloatValue() const { 00113 return BigFloat(ker); 00114 } 00115 00116 BigFloat approx(const extLong&, const extLong&) const; 00117 Real operator-() const; 00118 00119 bool isExact() const { 00120 return true; 00121 } 00122 int sgn() const { 00123 return ker > 0.0 ? 1 : ( ker == 0.0 ? 0 : -1); 00124 } 00125 bool isZeroIn() const { 00126 return ker == 0.0; 00127 } 00128 00129 BigFloat sqrt(const extLong&) const; 00130 BigFloat sqrt(const extLong&, const BigFloat&) const; 00131 00132 void ULV_E(extLong &, extLong&, extLong&, extLong&, extLong&, extLong&) const; 00133 extLong flrLgErr() const { 00134 return CORE_negInfty; 00135 } 00136 extLong clLgErr() const { 00137 return CORE_negInfty; 00138 } 00139 unsigned long degree() const { 00140 return 1; 00141 } 00142 unsigned long length() const; 00143 unsigned long height() const; 00144 00145 std::string toString(long, bool) const { 00146 std::stringstream st; 00147 st << ker; 00148 return st.str(); 00149 } 00150 std::ostream& operator<<(std::ostream& o) const { 00151 return o << ker; 00152 } 00153 private: 00154 T ker; 00155 };//Realbase_for class 00156 00157 typedef Realbase_for<long> RealLong; 00158 typedef Realbase_for<double> RealDouble; 00159 typedef Realbase_for<BigInt> RealBigInt; 00160 typedef Realbase_for<BigRat> RealBigRat; 00161 typedef Realbase_for<BigFloat> RealBigFloat; 00162 00163 enum { REAL_LONG, REAL_DOUBLE, REAL_BIGINT, REAL_BIGRAT, REAL_BIGFLOAT }; 00164 00165 // constructors 00166 template<> 00167 inline RealLong::Realbase_for(const long& l) : ker(l) { 00168 mostSignificantBit = (ker != 0 ) ? extLong(flrLg(ker)) : CORE_negInfty; 00169 } 00170 template<> 00171 inline RealDouble::Realbase_for(const double& d) : ker(d) { 00172 mostSignificantBit = BigFloat(ker).MSB(); 00173 } 00174 template<> 00175 inline RealBigInt::Realbase_for(const BigInt& l) : ker(l) { 00176 mostSignificantBit = (sign(ker)) ? extLong(floorLg(ker)) : CORE_negInfty; 00177 } 00178 template<> 00179 inline RealBigRat::Realbase_for(const BigRat& l) : ker(l) { 00180 mostSignificantBit = BigFloat(ker).MSB(); 00181 } 00182 template<> 00183 inline RealBigFloat::Realbase_for(const BigFloat& l) : ker(l) { 00184 mostSignificantBit = ker.MSB(); 00185 } 00186 00187 // ID() 00188 template<> 00189 inline int RealLong::ID() const { 00190 return REAL_LONG; 00191 } 00192 template<> 00193 inline int RealDouble::ID() const { 00194 return REAL_DOUBLE; 00195 } 00196 template<> 00197 inline int RealBigInt::ID() const { 00198 return REAL_BIGINT; 00199 } 00200 template<> 00201 inline int RealBigRat::ID() const { 00202 return REAL_BIGRAT; 00203 } 00204 template<> 00205 inline int RealBigFloat::ID() const { 00206 return REAL_BIGFLOAT; 00207 } 00208 00209 // cast functions 00210 template<> 00211 inline long RealLong::longValue() const { 00212 return ker; 00213 } 00214 template<> 00215 inline long RealDouble::longValue() const { 00216 return static_cast<long>(ker); 00217 } 00218 template<> 00219 inline double RealLong::doubleValue() const { 00220 return static_cast<double>(ker); 00221 } 00222 template<> 00223 inline double RealDouble::doubleValue() const { 00224 return ker; 00225 } 00226 template<> 00227 inline BigInt RealBigInt::BigIntValue() const { 00228 return ker; 00229 } 00230 template<> 00231 inline BigInt RealBigRat::BigIntValue() const { 00232 return ker.BigIntValue(); 00233 } 00234 template<> 00235 inline BigInt RealBigFloat::BigIntValue() const { 00236 return ker.BigIntValue(); 00237 } 00238 template<> 00239 inline BigRat RealBigRat::BigRatValue() const { 00240 return ker; 00241 } 00242 template<> 00243 inline BigRat RealBigFloat::BigRatValue() const { 00244 return ker.BigRatValue(); 00245 } 00246 template<> 00247 inline BigFloat RealBigFloat::BigFloatValue() const { 00248 return ker; 00249 } 00250 00251 // isExact() 00252 template<> 00253 inline bool RealBigFloat::isExact() const { 00254 return ker.isExact(); 00255 } 00256 00257 // sign() 00258 template<> 00259 inline int RealBigInt::sgn() const { 00260 return sign(ker); 00261 } 00262 template<> 00263 inline int RealBigRat::sgn() const { 00264 return sign(ker); 00265 } 00266 template<> 00267 inline int RealBigFloat::sgn() const { 00268 return ker.sign(); 00269 } 00270 00271 // isZeroIn() 00272 template<> 00273 inline bool RealBigInt::isZeroIn() const { 00274 return sign(ker) == 0; 00275 } 00276 template<> 00277 inline bool RealBigRat::isZeroIn() const { 00278 return sign(ker) == 0; 00279 } 00280 template<> 00281 inline bool RealBigFloat::isZeroIn() const { 00282 return ker.isZeroIn(); 00283 } 00284 00285 // approx 00286 template <class T> 00287 inline BigFloat Realbase_for<T>::approx(const extLong& r, const extLong& a) const { 00288 BigFloat x; 00289 x.approx(ker, r, a); 00290 return x; 00291 } 00292 template <> 00293 inline BigFloat RealLong::approx(const extLong& r, const extLong& a) const { 00294 BigFloat x; 00295 x.approx(BigInt(ker), r, a); 00296 return x; 00297 } 00298 template <> 00299 inline BigFloat RealDouble::approx(const extLong& r, const extLong& a) const { 00300 BigFloat x; 00301 x.approx(BigRat(ker), r, a); 00302 return x; 00303 } 00304 00305 // sqrt 00306 template <class T> 00307 inline BigFloat Realbase_for<T>::sqrt(const extLong& a) const { 00308 return BigFloat(ker).sqrt(a); 00309 } 00310 template <class T> 00311 inline BigFloat Realbase_for<T>::sqrt(const extLong& a, const BigFloat& A) const { 00312 return BigFloat(ker).sqrt(a, A); 00313 } 00314 00315 // ULV_E() 00316 template<> 00317 inline void RealLong::ULV_E(extLong &up, extLong &lp, extLong &v2p, 00318 extLong &v2m, extLong &v5p, extLong &v5m) const { 00319 // TODO : extract the power of 5. 00320 up = lp = v2p = v2m = v5p = v5m = EXTLONG_ZERO; 00321 if (ker == 0) 00322 return; 00323 00324 // Extract the power of 2. 00325 unsigned long exp = 0; 00326 unsigned long tmp_ker = ker; 00327 while ((tmp_ker&1) != 0) { 00328 tmp_ker = tmp_ker/2; 00329 ++exp; 00330 } 00331 up = clLg(tmp_ker); 00332 lp = 0; 00333 v2p = exp; 00334 } 00335 template<> 00336 inline void RealDouble::ULV_E(extLong &up, extLong &lp, extLong &v2p, 00337 extLong &v2m, extLong &v5p, extLong &v5m) const { 00338 // TODO : can probably be made faster using frexp() or such. 00339 // TODO : extract the power of 5. 00340 BigRat R = BigRat(ker); 00341 up = ceilLg(numerator(R)); 00342 v2m = ceilLg(denominator(R)); 00343 lp = v2p = v5m = v5p = EXTLONG_ZERO; 00344 } 00345 template<> 00346 inline void RealBigInt::ULV_E(extLong &up, extLong &lp, extLong &v2p, 00347 extLong &v2m, extLong &v5p, extLong &v5m) const { 00348 up = lp = v2p = v2m = v5p = v5m = EXTLONG_ZERO; 00349 if (ker == 0) 00350 return; 00351 00352 // Extract power of 5. 00353 int exp5; 00354 BigInt remainder5; 00355 getKaryExpo(ker, remainder5, exp5, 5); 00356 v5p = exp5; 00357 // Extract power of 2. 00358 int exp2 = getBinExpo(remainder5); 00359 up = ceilLg(remainder5) - exp2; 00360 v2p = exp2; 00361 } 00362 template<> 00363 inline void RealBigRat::ULV_E(extLong &up, extLong &lp, extLong &v2p, 00364 extLong &v2m, extLong &v5p, extLong &v5m) const { 00365 up = lp = v2p = v2m = v5p = v5m = EXTLONG_ZERO; 00366 if (ker == 0) 00367 return; 00368 00369 // Extract power of 5. 00370 int exp5; 00371 BigInt num5, den5; 00372 getKaryExpo(numerator(ker), num5, exp5, 5); 00373 if (exp5 != 0) { 00374 v5p = exp5; 00375 den5 = denominator(ker); 00376 } else { 00377 getKaryExpo(denominator(ker), den5, exp5, 5); 00378 v5m = exp5; 00379 } 00380 00381 // Now we work with num5/den5. 00382 int exp2 = getBinExpo(num5); 00383 if (exp2 != 0) { 00384 v2p = exp2; 00385 } else { 00386 exp2 = getBinExpo(den5); 00387 v2m = exp2; 00388 } 00389 00390 up = ceilLg(num5) - v2p; 00391 lp = ceilLg(den5) - v2m; 00392 } 00393 template<> 00394 inline void RealBigFloat::ULV_E(extLong &up, extLong &lp, extLong &v2p, 00395 extLong &v2m, extLong &v5p, extLong &v5m) const { 00396 // TODO : extract power of 5. 00397 up = lp = v2p = v2m = v5p = v5m = EXTLONG_ZERO; 00398 BigRat R = ker.BigRatValue(); 00399 up = ceilLg(numerator(R)); 00400 v2m = ceilLg(denominator(R)); 00401 } 00402 00403 // flrLgErr && clLgErr 00404 template<> 00405 inline extLong RealBigFloat::flrLgErr() const { 00406 return ker.flrLgErr(); 00407 } 00408 template<> 00409 inline extLong RealBigFloat::clLgErr() const { 00410 return ker.clLgErr(); 00411 } 00412 00413 // height && length 00414 template<> 00415 inline unsigned long RealLong::length() const { 00416 return clLg(1+ core_abs(ker)); 00417 } // length is (log_2(1+ker^2)) /2. 00418 00419 template<> 00420 inline unsigned long RealLong::height() const { 00421 return clLg(core_max(1L, core_abs(ker))); 00422 } // height is max{1, |ker|} 00423 00424 template<> 00425 inline unsigned long RealDouble::length() const { 00426 BigRat R = BigRat(ker); 00427 long ln = 1 + ceilLg(numerator(R)); 00428 long ld = 1 + ceilLg(denominator(R)); 00429 return (ln>ld) ? ln : ld; 00430 } 00431 00432 template<> 00433 inline unsigned long RealDouble::height() const { 00434 BigRat R = BigRat(ker); 00435 long ln = ceilLg(numerator(R)); 00436 long ld = ceilLg(denominator(R)); 00437 return (ln>ld) ? ln : ld; 00438 } 00439 template<> 00440 inline unsigned long RealBigInt::length() const { 00441 return ceilLg(1 + abs(ker)); 00442 } 00443 00444 template<> 00445 inline unsigned long RealBigInt::height() const { 00446 BigInt r(abs(ker)); 00447 if (r<1) 00448 r = 1; 00449 return ceilLg(r); 00450 } 00451 00452 template<> 00453 inline unsigned long RealBigFloat::length() const { 00454 // Chen Li: A bug fixed. 00455 // The statement in the older version with the bug was: 00456 // BigRat R = BigRat(ker); 00457 // The BigRat(BigFloat) actually is a 00458 // conversion operator (defined in BigFloat.h), _NOT_ 00459 // an ordinary class constructor! The C++ language 00460 // specify that an intialization is not an assignment 00461 // but a constructor operation! 00462 // Considering that BigRat(BigFloat) is a conversion 00463 // operator not really a constructor. The programmer's 00464 // intent is obvious to do an assignment. 00465 // However, the g++ seems to be confused by the above 00466 // initialization. 00467 BigRat R = ker.BigRatValue(); 00468 long ln = 1 + ceilLg(numerator(R)); 00469 long ld = 1 + ceilLg(denominator(R)); 00470 return ( ln > ld ) ? ln : ld; 00471 } 00472 00473 template<> 00474 inline unsigned long RealBigFloat::height() const { 00475 // Chen Li: A bug fixed. The old statement with the bug was: 00476 // BigRat R = BigRat(ker); 00477 // Detailed reasons see above (in RealBigFloat::length()! 00478 BigRat R = ker.BigRatValue(); 00479 long ln = ceilLg(numerator(R)); 00480 long ld = ceilLg(denominator(R)); 00481 return ( ln > ld ) ? ln : ld; 00482 } 00483 00484 template<> 00485 inline unsigned long RealBigRat::length() const { 00486 long ln = 1 + ceilLg(numerator(ker)); 00487 long ld = 1 + ceilLg(denominator(ker)); 00488 return ( ln > ld ) ? ln : ld; 00489 } 00490 00491 template<> 00492 inline unsigned long RealBigRat::height() const { 00493 long ln = ceilLg(numerator(ker)); 00494 long ld = ceilLg(denominator(ker)); 00495 return (ln > ld ) ? ln : ld; 00496 } 00497 00498 // toString() 00499 template<> 00500 inline std::string RealBigInt::toString(long, bool) const { 00501 return ker.get_str(); 00502 } 00503 template<> 00504 inline std::string RealBigRat::toString(long, bool) const { 00505 return ker.get_str(); 00506 } 00507 template<> 00508 inline std::string RealBigFloat::toString(long prec, bool sci) const { 00509 return ker.toString(prec, sci); 00510 } 00511 00512 CORE_END_NAMESPACE 00513 #endif // _CORE_REALREP_H_ 00514