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

LoUtils.H

Go to the documentation of this file.
00001 /**
00002    \file Robots/LoBot/misc/LoUtils.H
00003 
00004    \brief Various utility functions/classes.
00005 */
00006 
00007 // //////////////////////////////////////////////////////////////////// //
00008 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00009 // by the University of Southern California (USC) and the iLab at USC.  //
00010 // See http://iLab.usc.edu for information about this project.          //
00011 // //////////////////////////////////////////////////////////////////// //
00012 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00013 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00014 // in Visual Environments, and Applications'' by Christof Koch and      //
00015 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00016 // pending; application number 09/912,225 filed July 23, 2001; see      //
00017 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00018 // //////////////////////////////////////////////////////////////////// //
00019 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00020 //                                                                      //
00021 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00022 // redistribute it and/or modify it under the terms of the GNU General  //
00023 // Public License as published by the Free Software Foundation; either  //
00024 // version 2 of the License, or (at your option) any later version.     //
00025 //                                                                      //
00026 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00027 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00028 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00029 // PURPOSE.  See the GNU General Public License for more details.       //
00030 //                                                                      //
00031 // You should have received a copy of the GNU General Public License    //
00032 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00033 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00034 // Boston, MA 02111-1307 USA.                                           //
00035 // //////////////////////////////////////////////////////////////////// //
00036 //
00037 // Primary maintainer for this file: Manu Viswanathan <mviswana at usc dot edu>
00038 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/misc/LoUtils.H $
00039 // $Id: LoUtils.H 12039 2009-11-17 05:36:44Z mviswana $
00040 //
00041 
00042 #ifndef LOBOT_UTILITIES_DOT_H
00043 #define LOBOT_UTILITIES_DOT_H
00044 
00045 //------------------------------ HEADERS --------------------------------
00046 
00047 // lobot headers
00048 #include "Robots/LoBot/misc/range.hh"
00049 
00050 // INVT utilities
00051 #include "Util/log.H"
00052 
00053 // Standard C++ headers
00054 #include <sstream>
00055 #include <ostream>
00056 #include <string>
00057 #include <algorithm>
00058 #include <list>
00059 #include <vector>
00060 #include <functional>
00061 #include <iterator>
00062 #include <limits>
00063 #include <utility>
00064 
00065 // Standard C headers
00066 #include <math.h>
00067 
00068 //----------------------------- NAMESPACE -------------------------------
00069 
00070 namespace lobot {
00071 
00072 //------------------------- NUMERIC FUNCTIONS ---------------------------
00073 
00074 /// The sign of a number
00075 template<typename T>
00076 inline int sign(const T& t)
00077 {
00078    return (t < 0) ? -1 : +1 ;
00079 }
00080 
00081 /// Absolute value for different numeric types
00082 template<typename T>
00083 inline T abs(const T& t)
00084 {
00085    return (t < 0) ? -t : t ;
00086 }
00087 
00088 /// Clamp a given value to the specified range
00089 template<typename T>
00090 T clamp(const T& value, const T& min, const T& max)
00091 {
00092    if (value < min)
00093       return min ;
00094    if (value > max)
00095       return max ;
00096    return value ;
00097 }
00098 
00099 /// Quick helper to clamp a given value to the specified range
00100 template<typename T>
00101 inline T clamp(const T& value, const range<T>& range)
00102 {
00103    return clamp(value, range.min(), range.max()) ;
00104 }
00105 
00106 /// Quick helper to clamp a given angle to lie within 0 and 360 degrees
00107 template<typename T>
00108 T clamp_angle(const T& angle)
00109 {
00110    T A = angle - 360 * static_cast<int>(angle/360) ;
00111    return (A < 0) ? 360 + A : A ;
00112 }
00113 
00114 /// Check if a floating-point number is near zero
00115 template<typename T>
00116 bool is_zero(const T& t)
00117 {
00118    return t > -std::numeric_limits<T>::epsilon()
00119        && t <  std::numeric_limits<T>::epsilon() ;
00120 }
00121 
00122 /// Round a floating-point number to the nearest integer
00123 template<typename T>
00124 int round(const T& t)
00125 {
00126    return static_cast<int>(t + T(0.5)) ;
00127 }
00128 
00129 /// Force the supplied number to be an odd number
00130 template<typename T>
00131 T force_odd(const T& t)
00132 {
00133    return t | 1 ;
00134 }
00135 
00136 /// Force the supplied number to be an even number
00137 template<typename T>
00138 T force_even(const T& t)
00139 {
00140    return t & T(~1) ;
00141 }
00142 
00143 /// Stuff two 16-bit ints into a long
00144 inline unsigned long make_long(int a, int b)
00145 {
00146    return (a << 16) | b ;
00147 }
00148 
00149 /// Extract the lower 16 bits of a long
00150 inline int loword(unsigned long L)
00151 {
00152    return static_cast<int>(L & 0xFFFF) ;
00153 }
00154 
00155 /// Extract the higher 16 bits of a long
00156 inline int hiword(unsigned long L)
00157 {
00158    return loword(L >> 16) ;
00159 }
00160 
00161 /// Trig functions for degrees rather than radians
00162 //@{
00163 inline float sin(float angle)
00164 {
00165    return sinf(angle * 0.01745329f) ; // angle * PI/180
00166 }
00167 
00168 inline float cos(float angle)
00169 {
00170    return cosf(angle * 0.01745329f) ; // angle * PI/180
00171 }
00172 
00173 inline double sin(double angle)
00174 {
00175    return ::sin(angle * 0.0174532925199432) ; // angle * PI/180
00176 }
00177 
00178 inline double cos(double angle)
00179 {
00180    return ::cos(angle * 0.0174532925199432) ; // angle * PI/180
00181 }
00182 //@}
00183 
00184 /// Log functions for base 10
00185 //@{
00186 inline float log(float n)
00187 {
00188    return log10f(n) ;
00189 }
00190 
00191 inline double log(double n)
00192 {
00193    return log10(n) ;
00194 }
00195 //@}
00196 
00197 /// Exponential functions
00198 //@{
00199 inline float exp(float n)
00200 {
00201    return expf(n) ;
00202 }
00203 
00204 inline double exp(double n)
00205 {
00206    return ::exp(n) ;
00207 }
00208 //@}
00209 
00210 //------------------------ STRING MANIPULATION --------------------------
00211 
00212 /// Convenient (but perhaps not the most efficient) helper to convert
00213 /// various data types to strings.
00214 ///
00215 /// DEVNOTE: Works as long as type T defines an operator << that writes
00216 /// to an ostream.
00217 template<typename T>
00218 std::string to_string(const T& t)
00219 {
00220    std::ostringstream str ;
00221    str << t ;
00222    return str.str() ;
00223 }
00224 
00225 /// Read from string. As above, works as long as type T defines an
00226 /// operator >> that reads from an istream.
00227 template<typename T>
00228 T from_string(const std::string& s, const T& defval = T())
00229 {
00230    T t(defval) ;
00231    std::istringstream str(s) ;
00232    str >> t ;
00233    return t ;
00234 }
00235 
00236 /// from_string() specialization for strings. If the client wants a
00237 /// string from the input string, we just return the input string. If we
00238 /// were to apply the default version of this template function, we would
00239 /// end up parsing the input string as a whitespace separated string
00240 /// stream and only return the first string from this stream.
00241 template<>
00242 std::string from_string(const std::string& s, const std::string&)
00243 {
00244    return s ;
00245 }
00246 
00247 /// Converts a whitespace separated string of T into a vector of T
00248 template<typename T>
00249 std::vector<T> string_to_vector(const std::string& s)
00250 {
00251    std::istringstream str(s) ;
00252    return std::vector<T>(std::istream_iterator<T>(str),
00253                          std::istream_iterator<T>()) ;
00254 }
00255 
00256 /// Converts a whitespace separated string of T into a list of T
00257 template<typename T>
00258 std::list<T> string_to_list(const std::string& s)
00259 {
00260    std::istringstream str(s) ;
00261    return std::list<T>(std::istream_iterator<T>(str),
00262                        std::istream_iterator<T>()) ;
00263 }
00264 
00265 /// String case conversion
00266 //@{
00267 std::string upstring(std::string) ;
00268 std::string downstring(std::string) ;
00269 //@}
00270 
00271 //---------------------------- STL HELPERS ------------------------------
00272 
00273 /// Pointer deletion (useful in conjunction with STL algorithms and
00274 /// containers).
00275 ///
00276 /// WARNING: P must be a pointer type (e.g., int* rather than int).
00277 template<typename P> void delete_ptr(P p) {delete p ;}
00278 
00279 /// Pointer deletion when the pointer is part of an std::pair
00280 //@{
00281 template<typename P> void delete_first (P& p) {delete p.first ;}
00282 template<typename P> void delete_second(P& p) {delete p.second ;}
00283 //@}
00284 
00285 /// Functions to retrieve the individual elements of a pair.
00286 //@{
00287 template<typename P>
00288 typename P::first_type  get_first(const P& p)  {return p.first ;}
00289 
00290 template<typename P>
00291 typename P::second_type get_second(const P& p) {return p.second ;}
00292 //@}
00293 
00294 /// Releasing an STL container of pointers using a specific delete
00295 /// function (useful in cases of std::maps).
00296 ///
00297 /// C: container type
00298 /// D: delete function object type
00299 ///
00300 /// WARNING: C *must* be an STL container or *must* provide an equivalent
00301 /// begin/end iterator interface.
00302 ///
00303 /// This function would typically be used to clean-up maps. For example,
00304 /// an std::map<int, int*>. In this case, we cannot use delete_ptr<int*>
00305 /// directly because the map iterators point to std::pair objects whose
00306 /// first member is the key (int in this case) and whose second member is
00307 /// the value (int* in this case).
00308 ///
00309 /// Thus, we need to supply an appropriate delete function. In this case,
00310 /// that function would be delete_second<std::pair<int, int*>>.
00311 template<typename C, typename D>
00312 void purge_container(C& c, D delete_fn)
00313 {
00314    std::for_each(c.begin(), c.end(), delete_fn) ;
00315 }
00316 
00317 /// Releasing an STL container of pointers using the delete_ptr function.
00318 /// C: container type
00319 ///
00320 /// WARNING: C *must* be an STL container or provide an equivalent
00321 /// begin/end iterator interface and value_type typedef.
00322 ///
00323 /// This function would typically be used to clean-up a containers such as
00324 /// std::vector<int*> or other such containers of pointers. In this case,
00325 /// value_type would be int*.
00326 template<typename C>
00327 void purge_container(C& c)
00328 {
00329    typedef typename C::value_type P ;
00330    purge_container(c, delete_ptr<P>) ;
00331 }
00332 
00333 /// The STL already provides canned function objects for relational
00334 /// operators. These two are for the min and max functions. They can be
00335 /// used in conjunction with binders to quickly write calls to
00336 /// std::transform(), etc. without having to create custom function
00337 /// objects.
00338 //@{
00339 template<typename T>
00340 struct min : std::binary_function<T, T, T> {
00341    T operator()(const T& a, const T& b) const {
00342       return std::min(a, b) ;
00343    }
00344 } ;
00345 
00346 template<typename T>
00347 struct max : std::binary_function<T, T, T> {
00348    T operator()(const T& a, const T& b) const {
00349       return std::max(a, b) ;
00350    }
00351 } ;
00352 //@}
00353 
00354 /// This function object is meant to be used in conjunction with the
00355 /// std::accumulate algorithm and returns the sum of the squares of the
00356 /// sequence to which the accumulate algorithm is applied.
00357 template<typename T>
00358 struct sum_of_squares : std::binary_function<T, T, T> {
00359    T operator()(const T& a, const T& b) const {
00360       return T(a + b*b) ;
00361    }
00362 } ;
00363 
00364 /// This function object is a predicate that returns true if the number
00365 /// passed to its function call operator is out of the specified range.
00366 template<typename T>
00367 class out_of_range : public std::unary_function<T, bool> {
00368    range<T> m_range ;
00369 public:
00370    out_of_range(const range<T>& R) : m_range(R) {}
00371    bool operator()(const T& t) const {return ! m_range.in(t) ;}
00372 } ;
00373 
00374 /// Quick helper to connect whatever is in the supplied container to the
00375 /// specified target object using push_back(). (Thus, the target object
00376 /// must supply a push_back() method and other necessary STL glue to make
00377 /// this work.)
00378 template<typename C, typename T>
00379 static void connect(const C& container, T& target)
00380 {
00381    std::copy(container.begin(), container.end(), std::back_inserter(target)) ;
00382 }
00383 
00384 //-------------------------- OPENGL HELPERS -----------------------------
00385 
00386 /// Draw a text label in a GLUT window.
00387 void draw_label(float x, float y, const char* label) ;
00388 
00389 //--------------------------- DEBUG SUPPORT -----------------------------
00390 
00391 /// Debugging support: dump an STL container using LERROR
00392 ///
00393 /// DEVNOTE: Mostly suitable for small containers, e.g., vector of 10
00394 /// numbers or something like that.
00395 template<typename container>
00396 void dump(const container& C, const std::string& caller,
00397           const std::string& container_name = "container")
00398 {
00399    std::ostringstream str ;
00400    std::copy(C.begin(), C.end(),
00401              std::ostream_iterator<typename container::value_type>(str, " ")) ;
00402    LERROR("from %s ==> %s[0x%lx]: size = %d, contents = %s",
00403           caller.c_str(), container_name.c_str(),
00404           reinterpret_cast<long int>(&C), static_cast<int>(C.size()),
00405           str.str().c_str()) ;
00406 }
00407 
00408 /// Dump an array of type T given pointers to its first and last elements
00409 template<typename T>
00410 void dump(const T* begin, const T* end, const std::string& caller,
00411           const std::string& container_name = "array")
00412 {
00413    std::vector<T> vec(begin, end) ;
00414    dump(vec, caller, container_name) ;
00415 }
00416 
00417 /// Function object to dump an std::pair to the given output stream
00418 template<typename T1, typename T2>
00419 class dump_pair {
00420    std::ostream& os ;
00421 public:
00422    dump_pair(std::ostream& s) : os(s) {}
00423    void operator()(const std::pair<T1, T2>& p) const {
00424       os << '[' << p.first << ' ' << p.second << "] " ;
00425    }
00426 } ;
00427 
00428 /// The earlier version of the dump() function for dumping containers
00429 /// will only work with containers of built-in/standard types such as
00430 /// vector<int>, list<float>, etc. because it uses std::ostream_iterator,
00431 /// which, annoyingly enough, doesn't work with user-defined types.
00432 /// Therefore, the earlier dump() function won't dump std::map containers
00433 /// (because their value type is an std::pair).
00434 ///
00435 /// We work around this problem by providing this overloaded version of
00436 /// dump() especially for std::maps.
00437 template<typename key_type, typename value_type>
00438 void dump(const std::map<key_type, value_type>& C,
00439           const std::string& caller,
00440           const std::string& container_name = "container")
00441 {
00442    std::ostringstream str ;
00443    std::for_each(C.begin(), C.end(),
00444                  dump_pair<key_type, value_type>(str)) ;
00445    LERROR("from %s ==> %s[0x%lx]: size = %d, contents = %s",
00446           caller.c_str(), container_name.c_str(),
00447           reinterpret_cast<long int>(&C), static_cast<int>(C.size()),
00448           str.str().c_str()) ;
00449 }
00450 
00451 //-----------------------------------------------------------------------
00452 
00453 } // end of namespace encapsulating this file's definitions
00454 
00455 #endif
00456 
00457 /* So things look consistent in everyone's emacs... */
00458 /* Local Variables: */
00459 /* indent-tabs-mode: nil */
00460 /* End: */

Generated on Mon Nov 23 15:47:01 2009 for iLab Neuromorphic Vision Toolkit by  doxygen 1.4.4