BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/CORE/Filter.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: Filter.h
00019  * Synopsis:
00020  *      This is a simple filtered floating point number,
00021  *      represented by the main class, FilterFp.
00022  *      based on the Burnikel-Funke-Schirra (BFS) filter scheme.
00023  *      We do not use IEEE exception mechanism here.
00024  *      It is used by the Expr class.
00025  * 
00026  * Written by 
00027  *       Zilin Du <zilin@cs.nyu.edu>
00028  *       Chee Yap <yap@cs.nyu.edu>
00029  *
00030  * WWW URL: http://cs.nyu.edu/exact/
00031  * Email: exact@cs.nyu.edu
00032  *
00033  * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/Filter.h $
00034  * $Id: Filter.h 45042 2008-08-20 11:14:00Z spion $
00035  ***************************************************************************/
00036 
00037 #ifndef _CORE_FILTER_H_
00038 #define _CORE_FILTER_H_
00039 
00040 #include <CGAL/config.h>
00041 #include <CGAL/CORE/Real.h>
00042 #include <cmath>
00043 
00044 #if !defined CGAL_CFG_NO_CPP0X_ISFINITE
00045   #define finite(x)     std::isfinite(x)
00046 #elif defined (_MSC_VER) || defined (__MINGW32__) // add support for MinGW
00047   #define finite(x)     _finite(x)
00048   #define ilogb(x)      (int)_logb(x)
00049 #endif
00050 
00051 #if defined(sun) || defined(__sun)
00052   #include <ieeefp.h>
00053 #endif
00054 
00055 CORE_BEGIN_NAMESPACE
00056 
00057 const int POWTWO_26 = (1 << 26);  
00058 
00062 class filteredFp {
00063   double fpVal;         // approximate double value for some "real value"
00064   double maxAbs;        // if (|fpVal| > maxAbs * ind * 2^{-53}) then
00065   int ind;              // sign of value is sign(fpVal).  Else, don't know.
00066   // REFERENCE: Burnikel, Funke, Schirra (BFS) filter
00067   // Chee: in isOK(), you used the test "|fpVal| >= maxAbs * ind * 2^{-53}" 
00068   // which seems to be correct (i.e., not |fpVal| > maxAbs * ind * 2^{-53})
00069 public:
00071 
00072 
00073   filteredFp (double val = 0.0)
00074       : fpVal(val), maxAbs(core_abs(val)), ind(0) {}
00076   filteredFp (double val, double m, int i)
00077       : fpVal(val), maxAbs(m), ind(i) {}
00078 
00080 
00082   filteredFp (const Real & value) : fpVal(0.0), maxAbs(0.0), ind(0) {
00083     if (value != CORE_REAL_ZERO) {
00084       ind = 1;
00085       fpVal = value.doubleValue();
00086       if (value.MSB() <= -1075)
00087         maxAbs = 1;
00088       else      
00089         maxAbs = core_abs(fpVal); // NaN are propagated correctly by core_abs.
00090     }
00091   }
00093 
00095 
00096 
00097   double getValue() const {
00098     return fpVal;
00099   }
00101   bool isOK() const {
00102     return (fpFilterFlag  && // To disable filter
00103             finite(fpVal) && // Test for infinite and NaNs
00104             (core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
00105   }
00107 
00109   int sign() const {
00110 #ifdef CORE_DEBUG
00111     assert(isOK());
00112 #endif
00113     if (fpVal == 0.0)
00114       return 0;
00115     else
00116       return fpVal > 0.0 ? 1: -1;
00117   }
00119 
00122   extLong lMSB() const {
00123     return extLong(ilogb(core_abs(fpVal)-maxAbs*ind*CORE_EPS));
00124   }
00126   extLong uMSB() const {
00127     return extLong(ilogb(core_abs(fpVal)+maxAbs*ind*CORE_EPS));
00128   }
00130 
00132 
00133 
00134   filteredFp operator -() const {
00135     return filteredFp(-fpVal, maxAbs, ind);
00136   }
00138   filteredFp operator+ (const filteredFp& x) const {
00139     return filteredFp(fpVal+x.fpVal, maxAbs+x.maxAbs, 1+core_max(ind, x.ind));
00140   }
00142   filteredFp operator- (const filteredFp& x) const {
00143     return filteredFp(fpVal-x.fpVal, maxAbs+x.maxAbs, 1+core_max(ind, x.ind));
00144   }
00146   filteredFp operator* (const filteredFp& x) const {
00147     return filteredFp(fpVal*x.fpVal, maxAbs*x.maxAbs+DBL_MIN, 1+ind+x.ind);
00148   }
00150   filteredFp operator/ (const filteredFp& x) const {
00151     if (x.fpVal == 0.0)
00152       core_error("possible zero divisor!", __FILE__, __LINE__, false);
00153     double xxx = core_abs(x.fpVal) / x.maxAbs - (x.ind+1)*CORE_EPS + DBL_MIN;
00154     if (xxx > 0) {
00155       double val =  fpVal / x.fpVal;
00156       double maxVal = ( core_abs(val) + maxAbs / x.maxAbs) / xxx + DBL_MIN;
00157       return filteredFp(val, maxVal, 1 + core_max(ind, x.ind + 1));
00158     } else
00159       return filteredFp(getDoubleInfty(), 0.0, 0);
00160   }
00162   filteredFp sqrt () const {
00163     if (fpVal < 0.0)
00164       core_error("possible negative sqrt!", __FILE__, __LINE__, false);
00165     if (fpVal > 0.0) {
00166       double val = std::sqrt(fpVal);
00167       return filteredFp(val,  ( maxAbs / fpVal ) * val, 1 + ind);
00168     } else
00169       return filteredFp(0.0, std::sqrt(maxAbs) * POWTWO_26, 1 + ind);
00170   }
00171 
00173   void dump (std::ostream&os) const {
00174     os << "Filter=[fpVal=" << fpVal << ",maxAbs=" << maxAbs << ",ind=" << ind << "]";
00175   }
00176 
00178   static double getDoubleInfty() {
00179     static double d = DBL_MAX;
00180     return 2*d;
00181   }
00183 }; //filteredFp class
00184 
00185 inline std::ostream & operator<< (std::ostream & os, const filteredFp& fp) {
00186   fp.dump(os);
00187   return os;
00188 }
00189 
00190 CORE_END_NAMESPACE
00191 #endif // _CORE_FILTER_H_
00192 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines