00001 /** 00002 \file Robots/LoBot/util/LoMath.H 00003 \brief Math functions. 00004 */ 00005 00006 // //////////////////////////////////////////////////////////////////// // 00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00008 // by the University of Southern California (USC) and the iLab at USC. // 00009 // See http://iLab.usc.edu for information about this project. // 00010 // //////////////////////////////////////////////////////////////////// // 00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00013 // in Visual Environments, and Applications'' by Christof Koch and // 00014 // Laurent Itti, California Institute of Technology, 2001 (patent // 00015 // pending; application number 09/912,225 filed July 23, 2001; see // 00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00017 // //////////////////////////////////////////////////////////////////// // 00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00019 // // 00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00021 // redistribute it and/or modify it under the terms of the GNU General // 00022 // Public License as published by the Free Software Foundation; either // 00023 // version 2 of the License, or (at your option) any later version. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00028 // PURPOSE. See the GNU General Public License for more details. // 00029 // // 00030 // You should have received a copy of the GNU General Public License // 00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00033 // Boston, MA 02111-1307 USA. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // 00036 // Primary maintainer for this file: mviswana usc edu 00037 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/util/LoMath.H $ 00038 // $Id: LoMath.H 13628 2010-06-28 23:48:02Z mviswana $ 00039 // 00040 00041 #ifndef LOBOT_MATH_UTILITIES_DOT_H 00042 #define LOBOT_MATH_UTILITIES_DOT_H 00043 00044 //------------------------------ HEADERS -------------------------------- 00045 00046 // lobot headers 00047 #include "Robots/LoBot/util/range.hh" 00048 00049 // Standard C++ headers 00050 #include <algorithm> 00051 #include <limits> 00052 00053 // Standard C headers 00054 #include <math.h> 00055 00056 //----------------------------- NAMESPACE ------------------------------- 00057 00058 namespace lobot { 00059 00060 //---------------------------- BASIC STUFF ------------------------------ 00061 00062 /// The sign of a number 00063 template<typename T> 00064 int sign(T t) 00065 { 00066 return (t < 0) ? -1 : +1 ; 00067 } 00068 00069 /// The sign of a number: -1 for -ve, 0 for zero, +1 for +ve 00070 template<typename T> 00071 int sign0(T t) 00072 { 00073 if (t < 0) 00074 return -1 ; 00075 if (t > 0) 00076 return +1 ; 00077 return 0 ; 00078 } 00079 00080 /// Absolute value for different numeric types 00081 template<typename T> 00082 T abs(T t) 00083 { 00084 return (t < 0) ? -t : t ; 00085 } 00086 00087 /// Square of a number 00088 template<typename T> 00089 inline T sqr(T t) 00090 { 00091 return t * t ; 00092 } 00093 00094 /// Return the next power of two >= given number 00095 int next_power_of_two(int n) ; 00096 00097 //-------------------------- FLOATING POINT ----------------------------- 00098 00099 /// Check if a floating point number is near zero 00100 inline bool is_zero(float t) 00101 { 00102 return t > -std::numeric_limits<float>::epsilon() 00103 && t < std::numeric_limits<float>::epsilon() ; 00104 } 00105 00106 /// Check if a double precision floating point number is near zero 00107 inline bool is_zero(double t) 00108 { 00109 return t > -std::numeric_limits<double>::epsilon() 00110 && t < std::numeric_limits<double>::epsilon() ; 00111 } 00112 00113 /// Round a floating-point number to the nearest integer 00114 int round(float t) ; 00115 00116 //----------------------------- CLAMPING -------------------------------- 00117 00118 /// Clamp a given value to the specified range 00119 template<typename T> 00120 T clamp(T value, T min, T max) 00121 { 00122 if (value < min) 00123 return min ; 00124 if (value > max) 00125 return max ; 00126 return value ; 00127 } 00128 00129 /// Clamp a given value to the specified range 00130 template<typename T> 00131 inline T clamp(T value, const range<T>& R) 00132 { 00133 return clamp(value, R.min(), R.max()) ; 00134 } 00135 00136 /// Clamp the input range's min and max to the bounds range's min and max 00137 template<typename T> 00138 inline range<T> clamp(const range<T>& input, const range<T>& bounds) 00139 { 00140 return range<T>(std::max(input.min(), bounds.min()), 00141 std::min(input.max(), bounds.max())) ; 00142 } 00143 00144 //------------------------------ ANGLES --------------------------------- 00145 00146 /// Clamp an angle (specified in degrees) to lie in [0, 360] 00147 float clamp_angle(float angle) ; 00148 00149 /// Returns the quadrant to which the given angle belongs. 00150 inline int quadrant(float angle) 00151 { 00152 return static_cast<int>(clamp_angle(angle)/90) + 1 ; 00153 } 00154 00155 // Returns the octant to which the given angle belongs. 00156 // 00157 // NOTE: Octants are counted starting at one (not zero). Octant #1 goes 00158 // from zero to 44 degrees; octant #2 from 45 to 89 degrees; so on and so 00159 // forth. 00160 inline int octant(float angle) 00161 { 00162 return static_cast<int>(clamp_angle(angle)/45) + 1 ; 00163 } 00164 00165 //-------------------------- RANDOM NUMBERS ----------------------------- 00166 00167 /// Return a random integer in the specified range. 00168 /// 00169 /// NOTE: The range is inclusive, i.e., this function will return a 00170 /// number in the range [min, max]. 00171 int random(int min, int max) ; 00172 00173 /// Return a random float in the specified range. 00174 /// 00175 /// NOTE: The range is inclusive, i.e., this function will return a 00176 /// number in the range [min, max]. 00177 float randomf(float min, float max) ; 00178 00179 //------------------------------- TRIG ---------------------------------- 00180 00181 /// Trig functions for degrees rather than radians 00182 //@{ 00183 00184 // Sine 00185 inline float sin(float angle) 00186 { 00187 return sinf(angle * 0.01745329f) ; // angle * PI/180 00188 } 00189 00190 inline double sin(double angle) 00191 { 00192 return ::sin(angle * 0.0174532925199432) ; // angle * PI/180 00193 } 00194 00195 inline float sin(int angle) 00196 { 00197 return sin(static_cast<float>(angle)) ; 00198 } 00199 00200 // Cosine 00201 inline float cos(float angle) 00202 { 00203 return cosf(angle * 0.01745329f) ; // angle * PI/180 00204 } 00205 00206 inline double cos(double angle) 00207 { 00208 return ::cos(angle * 0.0174532925199432) ; // angle * PI/180 00209 } 00210 00211 inline float cos(int angle) 00212 { 00213 return cos(static_cast<float>(angle)) ; 00214 } 00215 00216 // Inverse sine 00217 inline float asin(float x) 00218 { 00219 return asinf(x) * 57.29577976f ; // 180/PI 00220 } 00221 00222 inline double asin(double x) 00223 { 00224 return ::asin(x) * 57.2957795130823215 ; // 180/PI 00225 } 00226 00227 inline float asin(int x) 00228 { 00229 return asin(static_cast<float>(x)) ; 00230 } 00231 00232 // Inverse cosine 00233 inline float acos(float x) 00234 { 00235 return acosf(x) * 57.29577976f ; // 180/PI 00236 } 00237 00238 inline double acos(double x) 00239 { 00240 return ::acos(x) * 57.2957795130823215 ; // 180/PI 00241 } 00242 00243 inline float acos(int x) 00244 { 00245 return acos(static_cast<float>(x)) ; 00246 } 00247 00248 // Inverse tangent 00249 inline float atan(float x) 00250 { 00251 return atanf(x) * 57.29577976f ; // 180/PI 00252 } 00253 00254 inline double atan(double x) 00255 { 00256 return ::atan(x) * 57.2957795130823215 ; // 180/PI 00257 } 00258 00259 inline float atan(int x) 00260 { 00261 return atan(static_cast<float>(x)) ; 00262 } 00263 00264 // Inverse tangent considering signs of both components 00265 inline float atan(float y, float x) 00266 { 00267 return atan2f(y, x) * 57.29577976f ; // 180/PI 00268 } 00269 00270 inline double atan(double y, double x) 00271 { 00272 return ::atan2(y, x) * 57.2957795130823215 ; // 180/PI 00273 } 00274 00275 inline float atan(int y, int x) 00276 { 00277 return atan(static_cast<float>(y), static_cast<float>(x)) ; 00278 } 00279 //@} 00280 00281 //---------------------------- LOG AND EXP ------------------------------ 00282 00283 /// Log functions for base 10 00284 //@{ 00285 inline float log(float n) 00286 { 00287 return log10f(n) ; 00288 } 00289 00290 inline double log(double n) 00291 { 00292 return log10(n) ; 00293 } 00294 //@} 00295 00296 /// Natural logarithms 00297 //@{ 00298 inline float ln(float n) 00299 { 00300 return logf(n) ; 00301 } 00302 00303 inline double ln(double n) 00304 { 00305 return ::log(n) ; 00306 } 00307 //@} 00308 00309 /// Exponential functions 00310 //@{ 00311 inline float exp(float n) 00312 { 00313 return expf(n) ; 00314 } 00315 00316 inline double exp(double n) 00317 { 00318 return ::exp(n) ; 00319 } 00320 //@} 00321 00322 /// These functions convert from normal [0,1] probabilities to log-odds 00323 /// and vice versa. 00324 //@{ 00325 float prob_to_log_odds(float p) ; 00326 float log_odds_to_prob(float log_odds) ; 00327 //@} 00328 00329 //--------------------------- MISCELLANEOUS ----------------------------- 00330 00331 /// A function to evaluate the Gaussian 00332 float gaussian(float x, float mu, float sigma) ; 00333 00334 /// A function object to perform Gaussian weighting 00335 //@{ 00336 template<typename T = float> 00337 class gaussian_weight { 00338 T mean ; 00339 T two_sigma_sqr, sqrt_2pi_sigma ; 00340 public: 00341 gaussian_weight(T mean, T sigma) ; 00342 T operator()(T x, T w) const { 00343 return w * exp(-sqr(x - mean)/two_sigma_sqr)/sqrt_2pi_sigma ; 00344 } 00345 } ; 00346 00347 template<typename T> 00348 gaussian_weight<T>::gaussian_weight(T m, T sigma) 00349 : mean(m), 00350 two_sigma_sqr(2 * sqr(sigma)), 00351 sqrt_2pi_sigma(T(2.5066282746310004) * sigma) 00352 {} 00353 //@} 00354 00355 /// This function returns a random number sampled from a triangular 00356 /// distribution centered at sigma. 00357 float sample_tri(float sigma) ; 00358 00359 //----------------------------------------------------------------------- 00360 00361 } // end of namespace encapsulating this file's definitions 00362 00363 #endif 00364 00365 /* So things look consistent in everyone's emacs... */ 00366 /* Local Variables: */ 00367 /* indent-tabs-mode: nil */ 00368 /* End: */