00001 /************************************************************************* 00002 00003 Copyright Rice University, 2004, 2005, 2006. 00004 All rights reserved. 00005 00006 Permission is hereby granted, free of charge, to any person obtaining a 00007 copy of this software and associated documentation files (the "Software"), 00008 to deal in the Software without restriction, including without limitation 00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell 00010 copies of the Software, and to permit persons to whom the Software is 00011 furnished to do so, provided that the above copyright notice(s) and this 00012 permission notice appear in all copies of the Software and that both the 00013 above copyright notice(s) and this permission notice appear in supporting 00014 documentation. 00015 00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY 00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS 00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL 00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 00024 THIS SOFTWARE. 00025 00026 Except as contained in this notice, the name of a copyright holder shall 00027 not be used in advertising or otherwise to promote the sale, use or other 00028 dealings in this Software without prior written authorization of the 00029 copyright holder. 00030 00031 **************************************************************************/ 00032 00033 #ifndef __RVL_UTILITY__ 00034 #define __RVL_UTILITY__ 00035 00036 #include "except.hh" 00037 00043 //#define RVL_OPERATOR_NEW_ENABLED 00044 00047 extern "C" { 00048 #include "rngs.h" 00049 } 00050 00054 template<class real> 00055 inline static int numeric_precision() { return 0; } 00056 00057 template<> 00058 inline int numeric_precision<float>() { return 1; } 00059 00060 template<> 00061 inline int numeric_precision<double>() { return 2; } 00062 00063 namespace RVL { 00064 00084 template<class Scalar> 00085 struct ScalarFieldTraits { 00086 typedef Scalar ScalarType; 00087 typedef Scalar AbsType; 00088 static inline Scalar Zero(); 00089 static inline Scalar One(); 00090 static inline Scalar AbsZero(); 00091 static inline Scalar AbsOne(); 00092 }; 00093 00094 template<> 00095 struct ScalarFieldTraits<bool> { 00096 typedef bool ScalarType; 00097 typedef bool AbsType; 00098 static inline int Zero() { return false; } 00099 static inline int One() { return true; } 00100 static inline int AbsZero() { return false; } 00101 static inline int AbsOne() { return true; } 00102 }; 00103 00104 template<> 00105 struct ScalarFieldTraits<int> { 00106 typedef int ScalarType; 00107 typedef int AbsType; 00108 static inline int Zero() { return 0; } 00109 static inline int One() { return 1; } 00110 static inline int AbsZero() { return 0; } 00111 static inline int AbsOne() { return 1; } 00112 }; 00113 00114 template<> 00115 struct ScalarFieldTraits<long> { 00116 typedef long ScalarType; 00117 typedef long AbsType; 00118 static inline long Zero() { return 0; } 00119 static inline long One() { return 1; } 00120 static inline long AbsZero() { return 0; } 00121 static inline long AbsOne() { return 1; } 00122 }; 00123 00124 template<> 00125 struct ScalarFieldTraits<unsigned int> { 00126 typedef unsigned int ScalarType; 00127 typedef unsigned int AbsType; 00128 static inline unsigned int Zero() { return 0; } 00129 static inline unsigned int One() { return 1; } 00130 static inline unsigned int AbsZero() { return 0; } 00131 static inline unsigned int AbsOne() { return 1; } 00132 }; 00133 00134 template<> 00135 struct ScalarFieldTraits<unsigned long> { 00136 typedef unsigned long ScalarType; 00137 typedef unsigned long AbsType; 00138 static inline unsigned long Zero() { return 0; } 00139 static inline unsigned long One() { return 1; } 00140 static inline unsigned long AbsZero() { return 0; } 00141 static inline unsigned long AbsOne() { return 1; } 00142 }; 00143 00144 00145 template<> 00146 struct ScalarFieldTraits<float> { 00147 typedef float ScalarType; 00148 typedef float AbsType; 00149 static inline float Zero() { return 0.0; } 00150 static inline float One() { return 1.0; } 00151 static inline float AbsZero() { return 0.0; } 00152 static inline float AbsOne() { return 1.0; } 00153 }; 00154 00155 template<> 00156 struct ScalarFieldTraits<double> { 00157 typedef double ScalarType; 00158 typedef double AbsType; 00159 static inline double Zero() { return 0.0; } 00160 static inline double One() { return 1.0; } 00161 static inline double AbsZero() { return 0.0; } 00162 static inline double AbsOne() { return 1.0; } 00163 }; 00164 00165 template<class T> 00166 struct ScalarFieldTraits<std::complex<T> > { 00167 typedef complex<T> ScalarType; 00168 typedef T AbsType; 00169 static inline complex<T> Zero() { 00170 return complex<T>(ScalarFieldTraits<T>::Zero()); 00171 } 00172 static inline complex<T> One() { 00173 return complex<T>(ScalarFieldTraits<T>::One()); 00174 } 00175 static inline T AbsZero() { return ScalarFieldTraits<T>::Zero(); } 00176 static inline T AbsOne() { return ScalarFieldTraits<T>::One(); } 00177 }; 00178 00183 static inline float conj(float x) { return x; } 00184 static inline double conj(double x) { return x; } 00185 static inline std::complex<float> conj(std::complex<float> x) { return std::conj(x); } 00186 static inline std::complex<double> conj(std::complex<double> x) { return std::conj(x); } 00187 00194 template<typename Scalar> 00195 void testRealOnly() { 00196 typename ScalarFieldTraits<Scalar>::AbsType a; 00197 Scalar b = ScalarFieldTraits<Scalar>::One(); 00198 a=b; 00199 b=a; 00200 } 00201 00211 template<class real> 00212 inline int ProtectedDivision(real a, real b, real & quot, 00213 real tol = ScalarFieldTraits<real>::AbsZero() ) { 00214 typedef typename ScalarFieldTraits<real>::AbsType absreal; 00215 absreal fb = abs(b); 00216 absreal fa = abs(a); 00217 if (tol == ScalarFieldTraits<real>::AbsZero()) { 00218 if( fb < abs(ScalarFieldTraits<real>::One()) ) { 00219 if( fa < fb*std::numeric_limits<absreal>::max() ) { 00220 quot = a/b; 00221 return 0; 00222 } else { 00223 return 1; 00224 } 00225 } else { // fb > 1.0 00226 if( fa > fb*numeric_limits<absreal>::min() ) { 00227 quot = a/b; 00228 return 0; 00229 } else { 00230 quot = ScalarFieldTraits<real>::Zero(); 00231 // return 2; 00232 return 0; 00233 } 00234 } 00235 } else if( fb > fa*abs(tol) ) { 00236 quot = a/b; 00237 return 0; 00238 } 00239 else 00240 return 3; 00241 } 00242 00245 class Writeable { 00246 00247 public: 00248 00250 virtual ostream & write(ostream & str) const = 0; 00251 00252 virtual ~Writeable() {}; 00253 00255 void write(RVLException & e) const { 00256 std::ostringstream ss; 00257 this->write(ss); 00258 e<<ss.str(); 00259 } 00260 }; 00261 00264 template<typename T> 00265 class Oracle: public Writeable { 00266 00267 public: 00268 00270 virtual bool isFeasible(T const &) const = 0; 00271 00272 }; 00273 00276 template<typename T> 00277 class Factory: public Writeable { 00278 00279 public: 00280 00281 Factory() {} 00282 Factory(Factory<T> const &) {} 00283 virtual ~Factory() {} 00284 00286 virtual T * build() const = 0; 00287 00288 }; 00289 00290 00291 } 00292 00293 #endif