adevs
adevs_time.h
1 
31 #ifndef __adevs_time_h_
32 #define __adevs_time_h_
33 #include <cfloat>
34 #include <iostream>
35 #include <cmath>
36 #include <limits>
37 
39 template <class T> inline T adevs_inf();
41 template <class T> inline T adevs_zero();
43 template <class T> inline T adevs_sentinel();
45 template <class T> inline T adevs_epsilon();
46 
47 namespace adevs
48 {
49 
55 template<class T = double> struct Time
56 {
57  T t;
58  unsigned int c;
60  static adevs::Time<T> Inf() { return Time<T>(adevs_inf<T>(),0); }
62  Time(T t = adevs_zero<T>(), unsigned int c = 0):t(t),c(c){}
64  Time(const Time& t2):t(t2.t),c(t2.c){}
66  const Time& operator=(const Time& t2)
67  {
68  t = t2.t;
69  c = t2.c;
70  return *this;
71  }
73  bool operator<(T t2) const { return t < t2; }
78  const Time& operator=(T t2)
79  {
80  t = t2;
81  c = 0;
82  return *this;
83  }
85  Time operator+(const Time& t2) const
86  {
87  if (t2.t == 0) return Time(t,t2.c+c);
88  else return Time(t+t2.t,0);
89  }
91  const Time& operator+=(const Time& t2)
92  {
93  *this = *this+t2;
94  return *this;
95  }
97  T operator-(T t2) const
98  {
99  return t-t2;
100  }
102  bool operator==(const Time& t2) const
103  {
104  return (t == t2.t && c == t2.c);
105  }
107  bool operator!=(const Time& t2) const
108  {
109  return !(*this == t2);
110  }
112  bool operator<(const Time& t2) const
113  {
114  return (t < t2.t || (t == t2.t && c < t2.c));
115  }
116  bool operator<=(const Time& t2) const
117  {
118  return (*this == t2 || *this < t2);
119  }
120  bool operator>(const Time& t2) const
121  {
122  return !(*this <= t2);
123  }
124  bool operator>=(const Time& t2) const
125  {
126  return !(*this < t2);
127  }
128 };
129 
133 class sd_time
134 {
135  public:
136  // Creates the identify (0,0)
137  sd_time():t(0.0),k(0){}
138  // Create a time (t,k)
139  sd_time(double t, int k):t(t),k(k){}
140  sd_time(const sd_time& other):t(other.t),k(other.k){}
141  double real() const { return t; }
142  double integer() const { return k; }
143  const sd_time& operator=(const sd_time& other)
144  {
145  t = other.t;
146  k = other.k;
147  return *this;
148  }
150  bool operator==(const sd_time& t2) const
151  {
152  return (t == t2.t && k == t2.k);
153  }
155  bool operator!=(const sd_time& t2) const
156  {
157  return !(*this == t2);
158  }
160  bool operator<(const sd_time& t2) const
161  {
162  return (t < t2.t || (t == t2.t && k < t2.k));
163  }
164  bool operator<=(const sd_time& t2) const
165  {
166  return (*this == t2 || *this < t2);
167  }
168  bool operator>(const sd_time& t2) const
169  {
170  return !(*this <= t2);
171  }
172  bool operator>=(const sd_time& t2) const
173  {
174  return !(*this < t2);
175  }
177  sd_time operator+(const sd_time& t2) const
178  {
179  sd_time result(*this);
180  result += t2;
181  return result;
182  }
183  const sd_time& operator+=(const sd_time& t2)
184  {
185  if (t2.t == 0.0) k += t2.k;
186  else { t += t2.t; k = t2.k; }
187  return *this;
188  }
189  sd_time operator-(const sd_time& t2) const
190  {
191  sd_time result(*this);
192  result -= t2;
193  return result;
194  }
195  const sd_time& operator-=(const sd_time& t2)
196  {
197  if (t == t2.t) { t = 0.0; k -= t2.k; }
198  else t -= t2.t;
199  return *this;
200  }
201  friend std::ostream& operator<<(std::ostream& out, const sd_time& t)
202  {
203  out << "(" << t.t << "," << t.k << ")";
204  return out;
205  }
206  private:
207  double t; int k;
208 };
209 
210 
224 inline int fcmp(double x1, double x2, double epsilon)
225 {
226  int exponent;
227  double delta;
228  double difference;
229 
230  /* Get exponent(max(fabs(x1), fabs(x2))) and store it in exponent. */
231 
232  /* If neither x1 nor x2 is 0, */
233  /* this is equivalent to max(exponent(x1), exponent(x2)). */
234 
235  /* If either x1 or x2 is 0, its exponent returned by frexp would be 0, */
236  /* which is much larger than the exponents of numbers close to 0 in */
237  /* magnitude. But the exponent of 0 should be less than any number */
238  /* whose magnitude is greater than 0. */
239 
240  /* So we only want to set exponent to 0 if both x1 and */
241  /* x2 are 0. Hence, the following works for all x1 and x2. */
242 
243  frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
244 
245  /* Do the comparison. */
246 
247  /* delta = epsilon * pow(2, exponent) */
248 
249  /* Form a neighborhood around x2 of size delta in either direction. */
250  /* If x1 is within this delta neighborhood of x2, x1 == x2. */
251  /* Otherwise x1 > x2 or x1 < x2, depending on which side of */
252  /* the neighborhood x1 is on. */
253 
254  delta = ldexp(epsilon, exponent);
255 
256  difference = x1 - x2;
257 
258  if (difference > delta)
259  return 1; /* x1 > x2 */
260  else if (difference < -delta)
261  return -1; /* x1 < x2 */
262  else /* -delta <= difference <= delta */
263  return 0; /* x1 == x2 */
264 }
265 
273 class double_fcmp {
274 
275 private:
276  double d;
277 
278 public:
283  static double epsilon;
284 
285  double_fcmp(double rhs = 0)
286  : d(rhs) { }
287 
288  const double_fcmp& operator=(const double_fcmp& rhs)
289  {
290  d = rhs.d;
291  return *this;
292  }
293  const double_fcmp& operator=(double rhs)
294  {
295  d = rhs;
296  return *this;
297  }
298  operator double()
299  {
300  return d;
301  }
302  bool operator<(double rhs) const
303  {
304  return (fcmp(d, rhs, epsilon) < 0);
305  }
306  bool operator<(const double_fcmp& rhs) const
307  {
308  return (fcmp(d, rhs.d, epsilon) < 0);
309  }
310  bool operator<=(const double_fcmp& rhs) const
311  {
312  return (fcmp(d, rhs.d, epsilon) <= 0);
313  }
314  bool operator>(const double_fcmp& rhs) const
315  {
316  return (fcmp(d, rhs.d, epsilon) > 0);
317  }
318  bool operator>=(const double_fcmp& rhs) const
319  {
320  return (fcmp(d, rhs.d, epsilon) >= 0);
321  }
322  bool operator==(double rhs) const
323  {
324  return (fcmp(d, rhs, epsilon) == 0);
325  }
326  bool operator==(const double_fcmp& rhs) const
327  {
328  return (fcmp(d, rhs.d, epsilon) == 0);
329  }
330 };
331 
332 } // end namespace
333 
334 template <> inline long double adevs_inf() {
335  return std::numeric_limits<long double>::max(); }
336 template <> inline double adevs_inf() {
337  return std::numeric_limits<double>::max(); }
338 template <> inline int adevs_inf() {
339  return std::numeric_limits<int>::max(); }
340 template <> inline long adevs_inf() {
341  return std::numeric_limits<long>::max(); }
342 template <> inline adevs::double_fcmp adevs_inf() {
343  return std::numeric_limits<double>::max(); }
344 template <> inline adevs::sd_time adevs_inf() {
345  return adevs::sd_time(std::numeric_limits<float>::max(),std::numeric_limits<int>::max()); }
346 
347 template <> inline long double adevs_zero() { return 0.0L; }
348 template <> inline double adevs_zero() { return 0.0; }
349 template <> inline int adevs_zero() { return 0; }
350 template <> inline long adevs_zero() { return 0; }
351 template <> inline adevs::double_fcmp adevs_zero() { return 0.0; }
352 template <> inline adevs::sd_time adevs_zero() { return adevs::sd_time(); }
353 
354 template <> inline long double adevs_sentinel() { return -1.0L; }
355 template <> inline double adevs_sentinel() { return -1.0; }
356 template <> inline int adevs_sentinel() { return -1; }
357 template <> inline long adevs_sentinel() { return -1; }
358 template <> inline adevs::double_fcmp adevs_sentinel() { return -1.0; }
359 template <> inline adevs::sd_time adevs_sentinel() { return adevs::sd_time(-1.0,0); }
360 
361 template <> inline long double adevs_epsilon() { return 0.0L; }
362 template <> inline double adevs_epsilon() { return 0.0; }
363 template <> inline int adevs_epsilon() { return 0; }
364 template <> inline long adevs_epsilon() { return 0; }
365 template <> inline adevs::double_fcmp adevs_epsilon() { return 0.0; }
366 template <> inline adevs::sd_time adevs_epsilon() { return adevs::sd_time(0.0,1); }
367 
368 template<class T>
369 std::ostream& operator<<(std::ostream& strm, const adevs::Time<T>& t);
370 
371 #endif
bool operator==(const sd_time &t2) const
Equivalence.
Definition: adevs_time.h:150
static adevs::Time< T > Inf()
Value for infinity.
Definition: adevs_time.h:60
const Time & operator=(T t2)
Definition: adevs_time.h:78
bool operator<(const sd_time &t2) const
Order by t then by c.
Definition: adevs_time.h:160
Time(const Time &t2)
Copy constructor.
Definition: adevs_time.h:64
const Time & operator=(const Time &t2)
Assignment operator.
Definition: adevs_time.h:66
bool operator==(const Time &t2) const
Equivalence.
Definition: adevs_time.h:102
Definition: adevs_time.h:273
Definition: adevs_time.h:55
Time operator+(const Time &t2) const
Advance operator (this is not commutative or associative!)
Definition: adevs_time.h:85
T operator-(T t2) const
Subtract a real number (used to get the elapsed time)
Definition: adevs_time.h:97
bool operator<(T t2) const
Comparing with a T compares the real field.
Definition: adevs_time.h:73
Definition: adevs_fmi.h:56
bool operator<(const Time &t2) const
Order by t then by c.
Definition: adevs_time.h:112
static double epsilon
Definition: adevs_time.h:283
const Time & operator+=(const Time &t2)
Advance and assign.
Definition: adevs_time.h:91
int fcmp(double x1, double x2, double epsilon)
Definition: adevs_time.h:224
bool operator!=(const sd_time &t2) const
Not equal.
Definition: adevs_time.h:155
bool operator!=(const Time &t2) const
Not equal.
Definition: adevs_time.h:107
Time(T t=adevs_zero< T >(), unsigned int c=0)
Constructor. Default time is (0,0).
Definition: adevs_time.h:62
sd_time operator+(const sd_time &t2) const
Add and subtract.
Definition: adevs_time.h:177
Definition: adevs_time.h:133