BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/RealRep.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines