Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShFractionImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
00004 // Project administrator: Michael D. McCool
00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
00006 //          Michael D. McCool
00007 // 
00008 // This software is provided 'as-is', without any express or implied
00009 // warranty. In no event will the authors be held liable for any damages
00010 // arising from the use of this software.
00011 // 
00012 // Permission is granted to anyone to use this software for any purpose,
00013 // including commercial applications, and to alter it and redistribute it
00014 // freely, subject to the following restrictions:
00015 // 
00016 // 1. The origin of this software must not be misrepresented; you must
00017 // not claim that you wrote the original software. If you use this
00018 // software in a product, an acknowledgment in the product documentation
00019 // would be appreciated but is not required.
00020 // 
00021 // 2. Altered source versions must be plainly marked as such, and must
00022 // not be misrepresented as being the original software.
00023 // 
00024 // 3. This notice may not be removed or altered from any source
00025 // distribution.
00027 #ifndef SHFRACTIONALIMPL_HPP
00028 #define SHFRACTIONALIMPL_HPP
00029 
00030 #include <cmath>
00031 #include "ShMath.hpp"
00032 #include "ShFraction.hpp"
00033 
00034 namespace SH {
00035 
00036 #define _CompType typename ShFraction<T>::CompType 
00037 #define _LongType typename ShFraction<T>::LongType 
00038 #define _SignedLongType typename ShFraction<T>::SignedLongType 
00039 
00040 // @todo replace uses of std::fabs 
00041 
00042 template<typename T/* @todo clamp , bool Clamp */>
00043 ShFraction<T>::ShFraction()
00044 {}
00045 
00046 template<typename T/* @todo clamp , bool Clamp */>
00047 ShFraction<T>::ShFraction(double value)
00048   : m_val(clamp_val(value))
00049 {
00050 }
00051 
00052 template<typename T/* @todo clamp , bool Clamp */>
00053 ShFraction<T> ShFraction<T>::make_fraction(CompType value)
00054 {
00055   ShFraction result;
00056   result.m_val = clamp_val(value);
00057   return result; 
00058 }
00059 
00060 template<typename T/* @todo clamp , bool Clamp */>
00061 ShFraction<T> ShFraction<T>::make_fraction_signed(SignedLongType value)
00062 {
00063   ShFraction result;
00064   result.m_val = clamp_val_signed(value);
00065   return result; 
00066 }
00067 
00068 template<typename T/* @todo clamp , bool Clamp */>
00069 template<typename T2>
00070 ShFraction<T>::ShFraction(const ShFraction<T2> &other)
00071   : m_val(clamp_val(other.get_double())) 
00072 {
00073 }
00074 
00076 template<typename T/* @todo clamp , bool Clamp */>
00077 ShFraction<T>::operator double() const
00078 {
00079   return get_double(); 
00080 }
00081 
00082 template<typename T/* @todo clamp , bool Clamp */>
00083 T& ShFraction<T>::val()
00084 {
00085   return m_val;
00086 }
00087 
00088 template<typename T/* @todo clamp , bool Clamp */>
00089 T ShFraction<T>::val() const
00090 {
00091   return m_val;
00092 }
00093 
00095 template<typename T/* @todo clamp , bool Clamp */>
00096 ShFraction<T>& ShFraction<T>::operator=(double value)
00097 {
00098   m_val = clamp_val(value);
00099   return *this;
00100 }
00101 
00102 template<typename T/* @todo clamp , bool Clamp */>
00103 ShFraction<T>& ShFraction<T>::operator=(const ShFraction& other)
00104 {
00105   m_val = other.m_val;
00106   return *this;
00107 }
00108 
00109 template<typename T/* @todo clamp , bool Clamp */>
00110 ShFraction<T>& ShFraction<T>::operator+=(double value)
00111 {
00112   return operator+=(ShFraction(value));
00113 }
00114 
00115 template<typename T/* @todo clamp , bool Clamp */>
00116 ShFraction<T>& ShFraction<T>::operator+=(const ShFraction& other)
00117 {
00118   m_val = clamp_val(CompType(m_val) + CompType(other.m_val));
00119   return *this;
00120 }
00121 
00122 template<typename T/* @todo clamp , bool Clamp */>
00123 ShFraction<T>& ShFraction<T>::operator-=(double value)
00124 {
00125   return operator-=(ShFraction(value));
00126 }
00127 
00128 template<typename T/* @todo clamp , bool Clamp */>
00129 ShFraction<T>& ShFraction<T>::operator-=(const ShFraction& other)
00130 {
00131   m_val = clamp_val_signed(SignedLongType(m_val) - SignedLongType(other.m_val));
00132   return *this;
00133 }
00134 
00135 template<typename T/* @todo clamp , bool Clamp */>
00136 ShFraction<T>& ShFraction<T>::operator*=(double value)
00137 {
00138   return operator*=(ShFraction(value)); 
00139 }
00140 
00141 template<typename T/* @todo clamp , bool Clamp */>
00142 ShFraction<T>& ShFraction<T>::operator*=(const ShFraction& other)
00143 {
00144   m_val = clamp_val(CompType(m_val) * CompType(other.m_val));
00145   return *this;
00146 }
00147 
00148 template<typename T/* @todo clamp , bool Clamp */>
00149 ShFraction<T>& ShFraction<T>::operator/=(double value)
00150 {
00151   return operator/=(ShFraction(value)); 
00152 }
00153 
00154 template<typename T/* @todo clamp , bool Clamp */>
00155 ShFraction<T>& ShFraction<T>::operator/=(const ShFraction& other)
00156 {
00157   LongType numerator = LongType(m_val) << BITS;   
00158   LongType denom = LongType(other.m_val);
00159   m_val = clamp_val(numerator / denom);
00160   return (*this); 
00161 }
00162 
00163 template<typename T/* @todo clamp , bool Clamp */>
00164 ShFraction<T>& ShFraction<T>::operator%=(double value)
00165 {
00166   return operator%=(ShFraction(value));
00167 }
00168 
00169 template<typename T/* @todo clamp , bool Clamp */>
00170 ShFraction<T>& ShFraction<T>::operator%=(const ShFraction& other)
00171 {
00172   // @todo range - should need no clamping for this
00173   m_val = m_val % other.m_val;
00174   if(m_val < 0) m_val += other.m_val;
00175 }
00176 
00178 template<typename T/* @todo clamp , bool Clamp */>
00179 ShFraction<T> ShFraction<T>::operator-() const 
00180 {
00181   if(is_signed /* @todo clamp && Clamp */) return make_fraction(0); 
00182   return make_fraction(-m_val);
00183 }
00184 
00185 template<typename TT>
00186 std::ostream& operator<<(std::ostream &out, const ShFraction<TT> &value)
00187 {
00188   out << double(value);
00189   return out;
00190 }
00191 
00192 template<typename TT>
00193 std::istream& operator>>(std::istream &in, ShFraction<TT> &value)
00194 {
00195   double temp;
00196   in >> temp;
00197   value = temp;
00198   return in;
00199 }
00200 
00201 template<typename T/* @todo clamp , bool Clamp */>
00202 inline
00203 double ShFraction<T>::get_double() const
00204 {
00205   return double(m_val) / double(ONE);
00206 }
00207 
00208 template<typename T/* @todo clamp , bool Clamp */>
00209 inline
00210 T ShFraction<T>::clamp_val(double value)
00211 {
00212   double temp = value * ONE;
00213 
00214 /* @todo clamp  if(Clamp) { */
00215     temp = std::max(std::min(temp, double(MAX)), double(MIN));
00216 /* @todo clamp  } */
00217   return T(temp);
00218 }
00219 
00220 template<typename T/* @todo clamp , bool Clamp */>
00221 inline
00222 T ShFraction<T>::clamp_val(CompType value)
00223 {
00224   /* @todo clamp if(Clamp) { */
00225     value = std::max(std::min(value, CompType(MAX)), CompType(MIN));
00226   /* @todo clamp } */
00227   return T(value);
00228 }
00229 
00230 template<typename T/* @todo clamp , bool Clamp */>
00231 inline
00232 T ShFraction<T>::clamp_val_signed(SignedLongType value)
00233 {
00234   /* @todo clamp if(Clamp) { */
00235     value = std::max(std::min(value, SignedLongType(MAX)), SignedLongType(MIN));
00236   /* @todo clamp } */
00237   return T(value);
00238 }
00239 
00241 template<typename T/* @todo clamp , bool Clamp */>
00242 ShFraction<T> operator+(const ShFraction<T> &a, const ShFraction<T> &b) 
00243 {
00244   return ShFraction<T>::make_fraction(_CompType(a.m_val) + _CompType(b.m_val));
00245 }
00246 
00247 
00248 template<typename T/* @todo clamp , bool Clamp */>
00249 ShFraction<T> operator-(const ShFraction<T> &a, const ShFraction<T> &b) 
00250 {
00251   return ShFraction<T>::make_fraction_signed(
00252       _SignedLongType(a.m_val) - 
00253       _SignedLongType(b.m_val));
00254 }
00255 
00256 template<typename T/* @todo clamp , bool Clamp */>
00257 ShFraction<T> operator*(const ShFraction<T> &a, const ShFraction<T> &b) 
00258 {
00259   return ShFraction<T>::make_fraction(_CompType(a.m_val) * _CompType(b.m_val));
00260 }
00261 
00262 
00263 template<typename T/* @todo clamp , bool Clamp */>
00264 ShFraction<T> operator/(const ShFraction<T> &a, const ShFraction<T> &b) 
00265 {
00266   _LongType numerator = _LongType(a.m_val) << ShFraction<T>::BITS;   
00267   _LongType denom = _LongType(b.m_val);
00268   return ShFraction<T>::make_fraction(numerator / denom);
00269 }
00270 
00271 
00272 template<typename T/* @todo clamp , bool Clamp */>
00273 ShFraction<T> operator%(const ShFraction<T> &a, const ShFraction<T> &b) 
00274 {
00275   T temp = a.m_val % b.m_val;
00276   if(temp < 0) temp += b.m_val; 
00277   return ShFraction<T>(temp);
00278 }
00279 
00280 template<typename T/* @todo clamp , bool Clamp */>
00281 ShFraction<T> cbrt(const ShFraction<T> &a) 
00282 {
00283   return ShFraction<T>(std::pow(double(a), 1.0 / 3.0)); 
00284 }
00285 
00286 
00287 template<typename T/* @todo clamp , bool Clamp */>
00288 ShFraction<T> exp(const ShFraction<T> &a) 
00289 {
00290   return ShFraction<T>(std::exp(double(a))); 
00291 }
00292 
00293 
00294 template<typename T/* @todo clamp , bool Clamp */>
00295 ShFraction<T> exp2(const ShFraction<T> &a) 
00296 {
00297   return ShFraction<T>(std::pow(2.0, double(a))); 
00298 }
00299 
00300 
00301 template<typename T/* @todo clamp , bool Clamp */>
00302 ShFraction<T> exp10(const ShFraction<T> &a) 
00303 {
00304   return ShFraction<T>(std::pow(10.0, double(a))); 
00305 }
00306 
00307 
00308 template<typename T/* @todo clamp , bool Clamp */>
00309 ShFraction<T> log(const ShFraction<T> &a) 
00310 {
00311   return ShFraction<T>(std::log(double(a))); 
00312 }
00313 
00314 
00315 template<typename T/* @todo clamp , bool Clamp */>
00316 ShFraction<T> log2(const ShFraction<T> &a) 
00317 {
00318   return ShFraction<T>(log2f(double(a))); 
00319 }
00320 
00321 
00322 template<typename T/* @todo clamp , bool Clamp */>
00323 ShFraction<T> log10(const ShFraction<T> &a) 
00324 {
00325   return ShFraction<T>(log10f(double(a))); 
00326 }
00327 
00328 template<typename T/* @todo clamp , bool Clamp */>
00329 ShFraction<T> frac(const ShFraction<T> &a)
00330 {
00331   T result = a.m_val;
00332   if(result < 0) {
00333     result += ShFraction<T>::ONE;
00334   }
00335   return ShFraction<T>(result);
00336 }
00337 
00338 template<typename T/* @todo clamp , bool Clamp */>
00339 ShFraction<T> fmod(const ShFraction<T> &a, const ShFraction<T> &b) 
00340 {
00341   return a % b;
00342 }
00343 
00344 
00345 template<typename T/* @todo clamp , bool Clamp */>
00346 ShFraction<T> pow(const ShFraction<T> &a, const ShFraction<T> &b) 
00347 {
00348   // @todo check if this is optimal
00349   // @todo do integer special cases? - see NuS.cc
00350   return ShFraction<T>(std::pow(double(a), double(b))); 
00351 }
00352 
00353 
00354 // not a good function for fractional types...
00355 // guaranteed to overflow...DOH
00356 template<typename T/* @todo clamp , bool Clamp */>
00357 ShFraction<T> rcp(const ShFraction<T> &a) 
00358 {
00359   if(a.m_val > 0) return ShFraction<T>(ShFraction<T>::MAX);
00360   return ShFraction<T>(ShFraction<T>::MIN);
00361 }
00362 
00363 template<typename T/* @todo clamp , bool Clamp */>
00364 ShFraction<T> rsq(const ShFraction<T> &a) 
00365 {
00366   return rcp(a); // same bad behaviour 
00367 }
00368 
00369 template<typename T/* @todo clamp , bool Clamp */>
00370 ShFraction<T> sgn(const ShFraction<T> &a) 
00371 {
00372   return ShFraction<T>(a.m_val > 0 ? 1 : a.m_val == 0 ? 0 : -1); 
00373 }
00374 
00375 template<typename T/* @todo clamp , bool Clamp */>
00376 ShFraction<T> sqrt(const ShFraction<T> &a) 
00377 {
00378   return ShFraction<T>(std::sqrt(double(a)));
00379 }
00380 
00381 
00383 template<typename T/* @todo clamp , bool Clamp */>
00384 ShFraction<T> acos(const ShFraction<T> &a) 
00385 {
00386   return ShFraction<T>(std::acos(double(a)));
00387 }
00388 
00389 
00390 template<typename T/* @todo clamp , bool Clamp */>
00391 ShFraction<T> asin(const ShFraction<T> &a) 
00392 {
00393   return ShFraction<T>(std::asin(double(a)));
00394 }
00395 
00396 
00397 template<typename T/* @todo clamp , bool Clamp */>
00398 ShFraction<T> atan(const ShFraction<T> &a) 
00399 {
00400   return ShFraction<T>(std::atan(double(a)));
00401 }
00402 
00403 
00404 template<typename T/* @todo clamp , bool Clamp */>
00405 ShFraction<T> atan2(const ShFraction<T> &a, const ShFraction<T> &b) 
00406 {
00407   return ShFraction<T>(std::atan2(double(a), double(b)));
00408 }
00409 
00410 
00411 template<typename T/* @todo clamp , bool Clamp */>
00412 ShFraction<T> cos(const ShFraction<T> &a) 
00413 {
00414   return ShFraction<T>(std::cos(double(a)));
00415 }
00416 
00417 template<typename T/* @todo clamp , bool Clamp */>
00418 ShFraction<T> sin(const ShFraction<T> &a) 
00419 {
00420   return ShFraction<T>(std::sin(double(a)));
00421 }
00422 
00423 
00424 template<typename T/* @todo clamp , bool Clamp */>
00425 ShFraction<T> tan(const ShFraction<T> &a) 
00426 {
00427   return ShFraction<T>(std::tan(double(a)));
00428 }
00429 
00430 
00432 template<typename T/* @todo clamp , bool Clamp */>
00433 bool operator<(const ShFraction<T> &a, const ShFraction<T> &b) 
00434 {
00435   return (a.m_val < b.m_val);
00436 }
00437 
00438 template<typename T/* @todo clamp , bool Clamp */>
00439 bool operator<=(const ShFraction<T> &a, const ShFraction<T> &b) 
00440 {
00441   return (a.m_val <= b.m_val);
00442 }
00443 
00444 template<typename T/* @todo clamp , bool Clamp */>
00445 bool operator>(const ShFraction<T> &a, const ShFraction<T> &b) 
00446 {
00447   return (a.m_val > b.m_val);
00448 }
00449 
00450 template<typename T/* @todo clamp , bool Clamp */>
00451 bool operator>=(const ShFraction<T> &a, const ShFraction<T> &b) 
00452 {
00453   return (a.m_val >= b.m_val);
00454 }
00455 
00456 template<typename T/* @todo clamp , bool Clamp */>
00457 bool operator==(const ShFraction<T> &a, const ShFraction<T> &b) 
00458 {
00459   return (a.m_val == b.m_val);
00460 }
00461 
00462 template<typename T/* @todo clamp , bool Clamp */>
00463 bool operator!=(const ShFraction<T> &a, const ShFraction<T> &b) 
00464 {
00465   return (a.m_val != b.m_val);
00466 }
00467 
00469 template<typename T/* @todo clamp , bool Clamp */>
00470 ShFraction<T> min(const ShFraction<T> &a, const ShFraction<T> &b) 
00471 {
00472   return ShFraction<T>(std::min(a.m_val, b.m_val));
00473 }
00474 
00475 template<typename T/* @todo clamp , bool Clamp */>
00476 ShFraction<T> max(const ShFraction<T> &a, const ShFraction<T> &b) 
00477 {
00478   return ShFraction<T>(std::max(a.m_val, b.m_val));
00479 }
00480 
00481 template<typename T/* @todo clamp , bool Clamp */>
00482 ShFraction<T> floor(const ShFraction<T> &a) 
00483 {
00484 
00485   T result = 0; 
00486   if(a.m_val == ShFraction<T>::ONE) {
00487     result = ShFraction<T>::ONE;
00488   } else if(ShFraction<T>::is_signed && a.m_val < 0) {
00489     a.m_val = -ShFraction<T>::ONE;
00490   }
00491   return ShFraction<T>(result); 
00492 }
00493 
00494 template<typename T/* @todo clamp , bool Clamp */>
00495 ShFraction<T> ceil(const ShFraction<T> &a) 
00496 {
00497   T ONE = ShFraction<T>::ONE;
00498   T result = 0; 
00499   if(a.m_val > 0) {
00500     result = ONE;
00501   } else if(ShFraction<T>::is_signed && 
00502       a.m_val == -ONE) {
00503     result = -ONE;
00504   }
00505   return ShFraction<T>(result);
00506 }
00507 
00508 template<typename T/* @todo clamp , bool Clamp */>
00509 ShFraction<T> rnd(const ShFraction<T> &a) 
00510 {
00511   T ONE = ShFraction<T>::ONE;
00512   T HALF = ONE >> 1; // slightly less than half
00513   T result;
00514   if(a.m_val > HALF) {
00515     result = ONE;
00516   } else if(!ShFraction<T>::is_signed || result > -HALF) {
00517     result = 0;
00518   } else {
00519     result = -ONE;
00520   }
00521   return ShFraction<T>(result); 
00522 }
00523 
00524 template<typename T/* @todo clamp , bool Clamp */>
00525 ShFraction<T> abs(const ShFraction<T> &a) 
00526 {
00527   return ShFraction<T>(a.m_val < 0 ? -a.m_val: a.m_val);
00528 }
00529 
00531 template<typename T/* @todo clamp , bool Clamp */>
00532 ShFraction<T> cond(const ShFraction<T> &a, const ShFraction<T> &b, 
00533     const ShFraction<T> &c)
00534 {
00535   return ShFraction<T>(a.m_val > 0 ? b.m_val: c.m_val); 
00536 }
00537 
00538 template<typename T/* @todo clamp , bool Clamp */>
00539 ShFraction<T> lerp(const ShFraction<T> &a, const ShFraction<T> &b, const ShFraction<T> &c) 
00540 {
00541   T ONE = ShFraction<T>(ShFraction<T>::ONE);
00542   return a * b + (ONE - a) * c;
00543 }
00544 
00545 #undef _CompType
00546 #undef _LongType
00547 #undef _SignedLongType
00548 }
00549 
00550 #endif

Generated on Mon Jan 24 18:36:31 2005 for Sh by  doxygen 1.4.1