00001 /*!@file Util/SimTime.H */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/SimTime.H $ 00035 // $Id: SimTime.H 13293 2010-04-23 22:50:48Z dberg $ 00036 // 00037 00038 #ifndef UTIL_SIMTIME_H_DEFINED 00039 #define UTIL_SIMTIME_H_DEFINED 00040 00041 #include "Util/Types.H" // for int64 00042 00043 #include <limits> 00044 #include <string> 00045 00046 #ifdef MAX 00047 #undef MAX 00048 #endif 00049 00050 //! Encapsulated representation of simulation time 00051 /*! Basic arithmetic operators are supported. The idea is to not rely 00052 on a particular representation, but currently we are using a 00053 64-bit signed integer to represent the number of microseconds or 00054 nanoseconds. 00055 00056 With this representation, the possible range of values is 00057 -2^(-63)/10^9 seconds = -9.2e+9 seconds, to 2^(63)/10^9 seconds = 00058 9.2e+9 seconds. So, roughly: 33 bits are used to represent the 00059 integer portion, 30 bits to represent the fractional portion, and 00060 1 bit for the sign. That means that this representation has a 00061 somewhat larger range of values than does the standard 32+32 bit 00062 'struct timeval' from <sys/time.h>, which uses 32 bits for the 00063 integral portion, and 32 bits for the fractional portion (of which 00064 12 bits are wasted since the fractional portion represents 00065 microseconds and so only 20 bits are needed to get up to 10^6). 00066 00067 In order to avoid losing precision, you should avoid calling 00068 secs() or msecs() etc. and doing math on the results; instead, do 00069 math using SimTime's builtin operators, and only convert to secs() 00070 or msecs() when absolutely necessary (e.g., to display the time to 00071 the user). */ 00072 class SimTime 00073 { 00074 public: 00075 //! Default constructor; initialize to time=0 00076 SimTime() : nseconds(0) {} 00077 00078 //! Pseudo-constructor; returns time=0 00079 static SimTime ZERO() { return SimTime(0LL); } 00080 00081 //! Pseudo-constructor; builds the largest representable time 00082 static SimTime MAX() { return SimTime(std::numeric_limits<int64>::max()); } 00083 00084 //! Pseudo-constructor; returns time=s seconds 00085 static SimTime SECS(double s) { return SimTime(int64(1000000000LL*s)); } 00086 00087 //! Pseudo-constructor; returns time=ms milliseconds 00088 static SimTime MSECS(double ms) { return SimTime(int64(1000000LL*ms)); } 00089 00090 //! Pseudo-constructor; returns time=us microseconds 00091 static SimTime USECS(double us) { return SimTime(int64(1000LL*us)); } 00092 00093 //! Pseudo-constructor; returns time=ns nanoseconds 00094 static SimTime NSECS(int64 ns) { return SimTime(ns); } 00095 00096 //! Pseudo-constructor; returns time=1/hz seconds 00097 static SimTime HERTZ(double hz) { return SimTime::SECS(1.0/hz); } 00098 00099 //! Return a delta-t close to timestep for traversing the given interval 00100 static SimTime computeDeltaT(const SimTime& interval, 00101 const SimTime& timestep) 00102 { 00103 int64 nsteps = interval.nseconds / timestep.nseconds; 00104 if (nsteps <= 0) nsteps = 1; 00105 return SimTime(interval.nseconds / nsteps); 00106 } 00107 00108 //! Convert to string 00109 /*! If with_suffix==true, then write a suffix after the number 00110 indicating the units (i.e., 's', 'ms', 'us'). If 00111 with_suffix==false, the no suffix is written and the number will 00112 represent the number of seconds. */ 00113 std::string toString(bool with_suffix=false) const; 00114 00115 //! Convert from string 00116 /*! If default_suffix=null, then a valid suffix must be present to 00117 indicate the units represented by the number. If 00118 default_suffix==non-null, then that suffix will be used if the 00119 string itself doesn't contain a units suffix. */ 00120 static SimTime fromString(const std::string& s, 00121 const char* default_suffix = 0); 00122 00123 //! Return the number of seconds represented 00124 double secs() const 00125 { return double(this->nseconds) / 1000000000LL; } 00126 00127 //! Return the number of milliseconds represented 00128 double msecs() const 00129 { return double(this->nseconds) / 1000000LL; } 00130 00131 //! Return the number of microseconds represented 00132 double usecs() const 00133 { return double(this->nseconds) / 1000LL; } 00134 00135 //! Return the number of nanoseconds represented 00136 int64 nsecs() const 00137 { return this->nseconds; } 00138 00139 //! Return the rate (inverse seconds) represented 00140 double hertz() const 00141 { 00142 return (this->nseconds == 0LL) ? 00143 0.0 : 00144 1000000000LL / double(this->nseconds); 00145 } 00146 00147 //! Return true if the time represented is non-zero 00148 bool nonzero() const 00149 { return this->nseconds != 0; } 00150 00151 //! Plus-equals 00152 SimTime& operator+=(const SimTime& step) 00153 { this->nseconds += step.nseconds; return *this; } 00154 00155 //! result=time1+time2 00156 SimTime operator+(const SimTime& that) const 00157 { return SimTime(this->nseconds + that.nseconds); } 00158 00159 //! result=time1-time2 00160 SimTime operator-(const SimTime& that) const 00161 { return SimTime(this->nseconds - that.nseconds); } 00162 00163 00164 //! result=time*factor 00165 SimTime operator*(const double x) const 00166 { return SimTime(int64(this->nseconds * x)); } 00167 00168 //! result=time*factor 00169 SimTime operator*(const int x) const 00170 { return SimTime(this->nseconds * x); } 00171 00172 //! result=time*factor 00173 SimTime operator*(const int64 x) const 00174 { return SimTime(this->nseconds * x); } 00175 00176 00177 //! compare time1<time2 00178 bool operator<(const SimTime& that) const 00179 { return this->nseconds < that.nseconds; } 00180 00181 //! compare time1<=time2 00182 bool operator<=(const SimTime& that) const 00183 { return this->nseconds <= that.nseconds; } 00184 00185 //! compare time1>time2 00186 bool operator>(const SimTime& that) const 00187 { return this->nseconds > that.nseconds; } 00188 00189 //! compare time1>=time2 00190 bool operator>=(const SimTime& that) const 00191 { return this->nseconds >= that.nseconds; } 00192 00193 //! compare time1==time2 00194 bool operator==(const SimTime& that) const 00195 { return this->nseconds == that.nseconds; } 00196 00197 //! compare time1!=time2 00198 bool operator!=(const SimTime& that) const 00199 { return this->nseconds != that.nseconds; } 00200 00201 private: 00202 // this constructor is private since public users should call one of 00203 // pseudo-constructors SimTime::SECS() or SimTime::MSECS() so that 00204 // it is always clear at the point of the call which units are being 00205 // used (i.e. either seconds or milliseconds) 00206 explicit SimTime(int64 ns) : nseconds(ns) {} 00207 00208 int64 nseconds; 00209 }; 00210 00211 //! SimTime overload: format is floating-point number of seconds 00212 inline std::string convertToString(const SimTime& val) 00213 { 00214 // pass false so that we don't get a units suffix 00215 return val.toString(false); 00216 } 00217 00218 //! SimTime overload: format is floating-point number of seconds; 00219 inline void convertFromString(const std::string& str, SimTime& val) 00220 { 00221 // pass "s" to specify that the default units are seconds 00222 val = SimTime::fromString(str, "s"); 00223 } 00224 00225 // ###################################################################### 00226 // ###################################################################### 00227 // additional inline free functions for SimTime 00228 // ###################################################################### 00229 // ###################################################################### 00230 00231 // ###################################################################### 00232 inline SimTime operator*(const double x, const SimTime& t) 00233 { return t * x; } 00234 00235 // ###################################################################### 00236 inline SimTime operator*(const int x, const SimTime& t) 00237 { return t * x; } 00238 00239 // ###################################################################### 00240 inline SimTime operator*(const int64 x, const SimTime& t) 00241 { return t * x; } 00242 00243 // ###################################################################### 00244 /* So things look consistent in everyone's emacs... */ 00245 /* Local Variables: */ 00246 /* indent-tabs-mode: nil */ 00247 /* End: */ 00248 00249 #endif // UTIL_SIMTIME_H_DEFINED