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 
53 class sd_time
54 {
55  public:
56  // Creates the identify (0,0)
57  sd_time():t(0.0),k(0){}
58  // Create a time (t,k)
59  sd_time(double t, int k):t(t),k(k){}
60  sd_time(const sd_time& other):t(other.t),k(other.k){}
61  double real() const { return t; }
62  double integer() const { return k; }
63  const sd_time& operator=(const sd_time& other)
64  {
65  t = other.t;
66  k = other.k;
67  return *this;
68  }
70  bool operator==(const sd_time& t2) const
71  {
72  return (t == t2.t && k == t2.k);
73  }
75  bool operator!=(const sd_time& t2) const
76  {
77  return !(*this == t2);
78  }
80  bool operator<(const sd_time& t2) const
81  {
82  return (t < t2.t || (t == t2.t && k < t2.k));
83  }
84  bool operator<=(const sd_time& t2) const
85  {
86  return (*this == t2 || *this < t2);
87  }
88  bool operator>(const sd_time& t2) const
89  {
90  return !(*this <= t2);
91  }
92  bool operator>=(const sd_time& t2) const
93  {
94  return !(*this < t2);
95  }
97  sd_time operator+(const sd_time& t2) const
98  {
99  sd_time result(*this);
100  result += t2;
101  return result;
102  }
103  const sd_time& operator+=(const sd_time& t2)
104  {
105  if (t2.t == 0.0) k += t2.k;
106  else { t += t2.t; k = t2.k; }
107  return *this;
108  }
109  sd_time operator-(const sd_time& t2) const
110  {
111  sd_time result(*this);
112  result -= t2;
113  return result;
114  }
115  const sd_time& operator-=(const sd_time& t2)
116  {
117  if (t == t2.t) { t = 0.0; k -= t2.k; }
118  else t -= t2.t;
119  return *this;
120  }
121  friend std::ostream& operator<<(std::ostream& out, const sd_time& t)
122  {
123  out << "(" << t.t << "," << t.k << ")";
124  return out;
125  }
126  private:
127  double t; int k;
128 };
129 
143 inline int fcmp(double x1, double x2, double epsilon)
144 {
145  int exponent;
146  double delta;
147  double difference;
148 
149  /* Get exponent(max(fabs(x1), fabs(x2))) and store it in exponent. */
150 
151  /* If neither x1 nor x2 is 0, */
152  /* this is equivalent to max(exponent(x1), exponent(x2)). */
153 
154  /* If either x1 or x2 is 0, its exponent returned by frexp would be 0, */
155  /* which is much larger than the exponents of numbers close to 0 in */
156  /* magnitude. But the exponent of 0 should be less than any number */
157  /* whose magnitude is greater than 0. */
158 
159  /* So we only want to set exponent to 0 if both x1 and */
160  /* x2 are 0. Hence, the following works for all x1 and x2. */
161 
162  frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
163 
164  /* Do the comparison. */
165 
166  /* delta = epsilon * pow(2, exponent) */
167 
168  /* Form a neighborhood around x2 of size delta in either direction. */
169  /* If x1 is within this delta neighborhood of x2, x1 == x2. */
170  /* Otherwise x1 > x2 or x1 < x2, depending on which side of */
171  /* the neighborhood x1 is on. */
172 
173  delta = ldexp(epsilon, exponent);
174 
175  difference = x1 - x2;
176 
177  if (difference > delta)
178  return 1; /* x1 > x2 */
179  else if (difference < -delta)
180  return -1; /* x1 < x2 */
181  else /* -delta <= difference <= delta */
182  return 0; /* x1 == x2 */
183 }
184 
192 class double_fcmp {
193 
194 private:
195  double d;
196 
197 public:
202  static double epsilon;
203 
204  double_fcmp(double rhs = 0)
205  : d(rhs) { }
206 
207  const double_fcmp& operator=(const double_fcmp& rhs)
208  {
209  d = rhs.d;
210  return *this;
211  }
212  const double_fcmp& operator=(double rhs)
213  {
214  d = rhs;
215  return *this;
216  }
217  operator double()
218  {
219  return d;
220  }
221  bool operator<(double rhs) const
222  {
223  return (fcmp(d, rhs, epsilon) < 0);
224  }
225  bool operator<(const double_fcmp& rhs) const
226  {
227  return (fcmp(d, rhs.d, epsilon) < 0);
228  }
229  bool operator<=(const double_fcmp& rhs) const
230  {
231  return (fcmp(d, rhs.d, epsilon) <= 0);
232  }
233  bool operator>(const double_fcmp& rhs) const
234  {
235  return (fcmp(d, rhs.d, epsilon) > 0);
236  }
237  bool operator>=(const double_fcmp& rhs) const
238  {
239  return (fcmp(d, rhs.d, epsilon) >= 0);
240  }
241  bool operator==(double rhs) const
242  {
243  return (fcmp(d, rhs, epsilon) == 0);
244  }
245  bool operator==(const double_fcmp& rhs) const
246  {
247  return (fcmp(d, rhs.d, epsilon) == 0);
248  }
249 };
250 
251 } // end namespace
252 
253 template <> inline float adevs_inf() {
254  return std::numeric_limits<float>::max(); }
255 template <> inline long double adevs_inf() {
256  return std::numeric_limits<long double>::max(); }
257 template <> inline double adevs_inf() {
258  return std::numeric_limits<double>::max(); }
259 template <> inline int adevs_inf() {
260  return std::numeric_limits<int>::max(); }
261 template <> inline long adevs_inf() {
262  return std::numeric_limits<long>::max(); }
263 template <> inline adevs::double_fcmp adevs_inf() {
264  return std::numeric_limits<double>::max(); }
265 template <> inline adevs::sd_time adevs_inf() {
266  return adevs::sd_time(std::numeric_limits<float>::max(),std::numeric_limits<int>::max()); }
267 
268 template <> inline float adevs_zero() { return 0.0f; }
269 template <> inline long double adevs_zero() { return 0.0L; }
270 template <> inline double adevs_zero() { return 0.0; }
271 template <> inline int adevs_zero() { return 0; }
272 template <> inline long adevs_zero() { return 0; }
273 template <> inline adevs::double_fcmp adevs_zero() { return 0.0; }
274 template <> inline adevs::sd_time adevs_zero() { return adevs::sd_time(); }
275 
276 template <> inline float adevs_sentinel() { return -1.0f; }
277 template <> inline long double adevs_sentinel() { return -1.0L; }
278 template <> inline double adevs_sentinel() { return -1.0; }
279 template <> inline int adevs_sentinel() { return -1; }
280 template <> inline long adevs_sentinel() { return -1; }
281 template <> inline adevs::double_fcmp adevs_sentinel() { return -1.0; }
282 template <> inline adevs::sd_time adevs_sentinel() { return adevs::sd_time(-1.0,0); }
283 
284 template <> inline float adevs_epsilon() { return 0.0f; }
285 template <> inline long double adevs_epsilon() { return 0.0L; }
286 template <> inline double adevs_epsilon() { return 0.0; }
287 template <> inline int adevs_epsilon() { return 0; }
288 template <> inline long adevs_epsilon() { return 0; }
289 template <> inline adevs::double_fcmp adevs_epsilon() { return 0.0; }
290 template <> inline adevs::sd_time adevs_epsilon() { return adevs::sd_time(0.0,1); }
291 
292 #endif
bool operator==(const sd_time &t2) const
Equivalence.
Definition: adevs_time.h:70
bool operator<(const sd_time &t2) const
Order by t then by c.
Definition: adevs_time.h:80
Definition: adevs_time.h:192
Definition: adevs_fmi.h:57
static double epsilon
Definition: adevs_time.h:202
int fcmp(double x1, double x2, double epsilon)
Definition: adevs_time.h:143
bool operator!=(const sd_time &t2) const
Not equal.
Definition: adevs_time.h:75
sd_time operator+(const sd_time &t2) const
Add and subtract.
Definition: adevs_time.h:97
Definition: adevs_time.h:53