NEST main@caf0ae8
 
Loading...
Searching...
No Matches
nest_time.h
Go to the documentation of this file.
1/*
2 * nest_time.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef NEST_TIME_H
24#define NEST_TIME_H
25
26// C++ includes:
27#include <cassert>
28#include <cfloat>
29#include <cmath>
30#include <cstdlib>
31#include <iostream>
32#include <limits>
33#include <string>
34
35// Includes from libnestutil:
36#include "numerics.h"
37
38// Includes from nestkernel:
39#include "nest_types.h"
40
41namespace nest
42{
43class Time;
44}
45
46std::ostream& operator<<( std::ostream&, const nest::Time& );
47
48namespace nest
49{
112// Function to use internally
114
115// This is just to map llabs => abs
116template < class N >
117inline N
118time_abs( const N n )
119{
120 return std::abs( n );
121}
122
123template <>
124inline long long
125time_abs( long long n )
126{
127 return llabs( n );
128}
129
131// Time class = tic_t
133
134class Time
135{
136 // tic_t: tics in a step, signed long or long long
137 // delay: steps, signed long
138 // double: milliseconds (double!)
139 friend class TimeConverter;
140
142 // Range: Limits & conversion factors for different types
144
145protected:
146 struct Range
147 {
149 static double TICS_PER_STEP_INV;
151
152 static double TICS_PER_MS;
153 static double MS_PER_TIC;
154 static double STEPS_PER_MS;
155 static double MS_PER_STEP;
156
158 static const double TICS_PER_MS_DEFAULT;
159
160 static const long INF_MARGIN = 8;
161 };
162
163public:
164 static tic_t compute_max();
165
167 // The data: longest integer for tics
169
170protected:
172
174 // Friend declaration for units and binary operators
176
177 friend struct step;
178 friend struct tic;
179 friend struct ms;
180 friend struct ms_stamp;
181
182 friend bool operator==( const Time& t1, const Time& t2 );
183 friend bool operator!=( const Time& t1, const Time& t2 );
184 friend bool operator<( const Time& t1, const Time& t2 );
185 friend bool operator>( const Time& t1, const Time& t2 );
186 friend bool operator<=( const Time& t1, const Time& t2 );
187 friend bool operator>=( const Time& t1, const Time& t2 );
188 friend Time operator+( const Time& t1, const Time& t2 );
189 friend Time operator-( const Time& t1, const Time& t2 );
190 friend Time operator*( const long factor, const Time& t );
191 friend Time operator*( const Time& t, long factor );
192 friend std::ostream&( ::operator<< )( std::ostream&, const Time& );
193
195 // Limits for time, including infinity definitions
197
198protected:
199 struct Limit
200 {
202 long steps;
203 double ms;
204
205 Limit( tic_t tics, long steps, double ms )
206 : tics( tics )
207 , steps( steps )
208 , ms( ms )
209 {
210 }
211 Limit( const tic_t& );
212 };
216
217 // max is never larger than tics/INF_MARGIN, and we can use INF_MARGIN
218 // to minimize range checks on +/- operations
219 static struct LimitPosInf
220 {
221 static const tic_t tics = tic_t_max / Range::INF_MARGIN + 1;
222 static const long steps = delay_max;
223#define LIM_POS_INF_ms DBL_MAX // because C++ bites
225
226 static struct LimitNegInf
227 {
228 static const tic_t tics = -tic_t_max / Range::INF_MARGIN - 1;
229 static const long steps = -delay_max;
230#define LIM_NEG_INF_ms ( -DBL_MAX ) // c++ bites
232
234 // Unit class for constructors
236
237public:
238 struct tic
239 {
241 explicit tic( tic_t t )
242 : t( t ) {};
243 };
244
245 struct step
246 {
247 long t;
248 explicit step( long t )
249 : t( t )
250 {
251 }
252 };
253
254 struct ms
255 {
256 double t;
257 explicit ms( double t )
258 : t( t )
259 {
260 }
261 };
262
263 struct ms_stamp
264 {
265 double t;
266 explicit ms_stamp( double t )
267 : t( t )
268 {
269 }
270 };
271
273 // Constructors
275
276protected:
278 : tics( tics )
279 {
280 // This doesn't check ranges.
281 // Ergo: LIM_MAX.tics >= tics >= LIM_MIN.tics or tics == LIM_POS_INF.tics or LIM_NEG_INF.tics
282 }
283
284public:
286 : tics( 0 ) {};
287
289 : tics( ( time_abs( t.t ) < LIM_MAX.tics ) ? t.t
290 : ( t.t < 0 ) ? LIM_NEG_INF.tics
291 : LIM_POS_INF.tics )
292 {
293 }
294
296 : tics( ( time_abs( t.t ) < LIM_MAX.steps ) ? t.t * Range::TICS_PER_STEP
297 : ( t.t < 0 ) ? LIM_NEG_INF.tics
298 : LIM_POS_INF.tics )
299 {
300 }
301
302 Time( ms t )
303 : tics( ( time_abs( t.t ) < LIM_MAX.ms ) ? static_cast< tic_t >( t.t * Range::TICS_PER_MS + 0.5 )
304 : ( t.t < 0 ) ? LIM_NEG_INF.tics
305 : LIM_POS_INF.tics )
306 {
307 }
308
309 static tic_t fromstamp( ms_stamp );
311 : tics( fromstamp( t ) )
312 {
313 }
314
316 // Resolution: set tics per ms, steps per ms
318
319 static void set_resolution( double tics_per_ms );
320 static void set_resolution( double tics_per_ms, double ms_per_step );
321 static void reset_resolution();
322 static void reset_to_defaults();
323
324 static Time
326 {
327 return Time( Range::TICS_PER_STEP );
328 }
329
330 static bool
335
337 // Common zero-ary or unary operations
339
340 void
342 {
343 tics = 0;
344 }
345
346 void
348 {
350 range();
351 }
352
353 Time
354 succ() const
355 {
356 return tic( tics + Range::TICS_PER_STEP );
357 } // check range
358 Time
359 pred() const
360 {
361 return tic( tics - Range::TICS_PER_STEP );
362 } // check range
363
365 // Subtypes of Time (bool tests)
367
368 bool
369 is_finite() const
370 {
371 return tics != LIM_POS_INF.tics and tics != LIM_NEG_INF.tics;
372 }
373
374 bool
376 {
377 // Currently tics can never become smaller than LIM_NEG_INF.tics. However, if
378 // LIM_NEG_INF.tics represent negative infinity, any smaller
379 // value cannot be larger and thus must be infinity as well. to be on the safe side
380 // we use less-or-equal instead of just equal.
381 return tics <= LIM_NEG_INF.tics;
382 }
383 bool
385 {
386 return tics >= LIM_POS_INF.tics; // see comment for is_neg_inf()
387 }
388
389 bool
391 {
392 return ( tics % Range::TICS_PER_STEP ) == 0;
393 }
394 bool
395 is_step() const
396 {
397 return tics > 0 and is_grid_time();
398 }
399
400 bool
401 is_multiple_of( const Time& divisor ) const
402 {
403 assert( divisor.tics > 0 );
404 return ( tics % divisor.tics ) == 0;
405 }
406
408 // Singleton'ish types
410
411 static Time
413 {
414 return Time( LIM_MAX.tics );
415 }
416 static Time
418 {
419 return Time( LIM_MIN.tics );
420 }
421 static double
423 {
424 return Range::MS_PER_TIC;
425 }
426 static Time
428 {
429 return Time( LIM_NEG_INF.tics );
430 }
431 static Time
433 {
434 return Time( LIM_POS_INF.tics );
435 }
436
438 // Overflow checks & recalibrate after resolution setting
440
441 void
443 {
444 if ( time_abs( tics ) < LIM_MAX.tics )
445 {
446 return;
447 }
449 }
450
451 void
453 {
454 range();
455 }
456
458 // Unary operators
460
461 Time&
462 operator+=( const Time& t )
463 {
464 tics += t.tics;
465 range();
466 return *this;
467 }
468
470 // Convert to external units
472
473 tic_t
474 get_tics() const
475 {
476 return tics;
477 }
478 static tic_t
480 {
482 }
483 static double
485 {
486 return Range::TICS_PER_MS;
487 }
488
489 double
490 get_ms() const
491 {
492 if ( is_pos_inf() )
493 {
494 return LIM_POS_INF_ms;
495 }
496 if ( is_neg_inf() )
497 {
498 return LIM_NEG_INF_ms;
499 }
500 return Range::MS_PER_TIC * tics;
501 }
502
503 long
504 get_steps() const
505 {
506 if ( is_pos_inf() )
507 {
508 return LIM_POS_INF.steps;
509 }
510 if ( is_neg_inf() )
511 {
512 return LIM_NEG_INF.steps;
513 }
514
515 // round tics up to nearest step
516 // by adding TICS_PER_STEP-1 before division
518 }
519
528 static double
529 delay_steps_to_ms( long steps )
530 {
531 return steps * Range::MS_PER_STEP;
532 }
533
534 static long
536 {
537 return ld_round( ms * Range::STEPS_PER_MS );
538 }
539};
540
542// Non-class definitions
544
545// Needs to be outside the class to get internal linkage to
546// maybe make the zero visible for optimization.
548
550// Binary operators
552
553inline bool
554operator==( const Time& t1, const Time& t2 )
555{
556 return t1.tics == t2.tics;
557}
558
559inline bool
560operator!=( const Time& t1, const Time& t2 )
561{
562 return t1.tics != t2.tics;
563}
564
565inline bool
566operator<( const Time& t1, const Time& t2 )
567{
568 return t1.tics < t2.tics;
569}
570
571inline bool
572operator>( const Time& t1, const Time& t2 )
573{
574 return t1.tics > t2.tics;
575}
576
577inline bool
578operator<=( const Time& t1, const Time& t2 )
579{
580 return t1.tics <= t2.tics;
581}
582
583inline bool
584operator>=( const Time& t1, const Time& t2 )
585{
586 return t1.tics >= t2.tics;
587}
588
589inline Time
590operator+( const Time& t1, const Time& t2 )
591{
592 return Time::tic( t1.tics + t2.tics ); // check range
593}
594
595inline Time
596operator-( const Time& t1, const Time& t2 )
597{
598 return Time::tic( t1.tics - t2.tics ); // check range
599}
600
601inline Time
602operator*( const long factor, const Time& t )
603{
604 const tic_t n = factor * t.tics;
605 // if no overflow:
606 if ( t.tics == 0 or n / t.tics == factor )
607 {
608 return Time::tic( n ); // check range
609 }
610 if ( ( t.tics > 0 and factor > 0 ) or ( t.tics < 0 and factor < 0 ) )
611 {
612 return Time( Time::LIM_POS_INF.tics );
613 }
614 else
615 {
616 return Time( Time::LIM_NEG_INF.tics );
617 }
618}
619
620inline Time
621operator*( const Time& t, long factor )
622{
623 return factor * t;
624}
625} // namespace
626
627std::ostream& operator<<( std::ostream&, const nest::Time& );
628
629
630#endif
Class to convert times from one representation to another.
Definition nest_timeconverter.h:42
Definition nest_time.h:135
friend Time operator-(const Time &t1, const Time &t2)
Definition nest_time.h:596
bool is_step() const
Definition nest_time.h:395
friend bool operator<=(const Time &t1, const Time &t2)
Definition nest_time.h:578
void set_to_zero()
Definition nest_time.h:341
Time(step t)
Definition nest_time.h:295
friend bool operator>=(const Time &t1, const Time &t2)
Definition nest_time.h:584
void calibrate()
Definition nest_time.h:452
Time & operator+=(const Time &t)
Definition nest_time.h:462
static double get_tics_per_ms()
Definition nest_time.h:484
Time()
Definition nest_time.h:285
friend bool operator==(const Time &t1, const Time &t2)
Definition nest_time.h:554
static double delay_steps_to_ms(long steps)
Convert between delays given in steps and milliseconds.
Definition nest_time.h:529
bool is_finite() const
Definition nest_time.h:369
bool is_pos_inf() const
Definition nest_time.h:384
Time(tic t)
Definition nest_time.h:288
static bool resolution_is_default()
Definition nest_time.h:331
bool is_neg_inf() const
Definition nest_time.h:375
static void reset_to_defaults()
Definition nest_time.cpp:147
static struct nest::Time::LimitNegInf LIM_NEG_INF
Time(ms t)
Definition nest_time.h:302
static Time get_resolution()
Definition nest_time.h:325
static tic_t compute_max()
Definition nest_time.cpp:55
friend bool operator>(const Time &t1, const Time &t2)
Definition nest_time.h:572
tic_t tics
Definition nest_time.h:171
static void reset_resolution()
Definition nest_time.cpp:111
Time succ() const
Definition nest_time.h:354
static void set_resolution(double tics_per_ms)
Definition nest_time.cpp:85
static Limit LIM_MAX
Definition nest_time.h:213
Time(ms_stamp t)
Definition nest_time.h:310
tic_t get_tics() const
Definition nest_time.h:474
static long delay_ms_to_steps(double ms)
Definition nest_time.h:535
static Time min()
Definition nest_time.h:417
Time(tic_t tics)
Definition nest_time.h:277
static tic_t fromstamp(ms_stamp)
Definition nest_time.cpp:123
long get_steps() const
Definition nest_time.h:504
friend bool operator<(const Time &t1, const Time &t2)
Definition nest_time.h:566
static Time pos_inf()
Definition nest_time.h:432
Time pred() const
Definition nest_time.h:359
static Time neg_inf()
Definition nest_time.h:427
Time::Limit limit(const tic_t &)
static tic_t get_tics_per_step()
Definition nest_time.h:479
void range()
Definition nest_time.h:442
friend Time operator*(const long factor, const Time &t)
Definition nest_time.h:602
static struct nest::Time::LimitPosInf LIM_POS_INF
friend Time operator+(const Time &t1, const Time &t2)
Definition nest_time.h:590
bool is_multiple_of(const Time &divisor) const
Definition nest_time.h:401
static Time max()
Definition nest_time.h:412
static Limit LIM_MIN
Definition nest_time.h:214
static double get_ms_per_tic()
Definition nest_time.h:422
bool is_grid_time() const
Definition nest_time.h:390
friend bool operator!=(const Time &t1, const Time &t2)
Definition nest_time.h:560
void advance()
Definition nest_time.h:347
double get_ms() const
Definition nest_time.h:490
const std::string N("N")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
const Time TimeZero
Definition nest_time.h:547
Time operator-(const Time &t1, const Time &t2)
Definition nest_time.h:596
N time_abs(const N n)
Class to handle simulation time and realtime.
Definition nest_time.h:118
Time operator*(const long factor, const Time &t)
Definition nest_time.h:602
bool operator<=(const Time &t1, const Time &t2)
Definition nest_time.h:578
long long tic_t
Type for Time tics.
Definition nest_types.h:103
bool operator<(const histentry_extended &he, double t)
Definition histentry.h:67
Time operator+(const Time &t1, const Time &t2)
Definition nest_time.h:590
constexpr tic_t tic_t_max
Definition nest_types.h:104
bool operator>(const Time &t1, const Time &t2)
Definition nest_time.h:572
bool operator==(const Time &t1, const Time &t2)
Definition nest_time.h:554
bool operator>=(const Time &t1, const Time &t2)
Definition nest_time.h:584
constexpr long delay_max
Definition nest_types.h:147
bool operator!=(const Time &t1, const Time &t2)
Definition nest_time.h:560
#define LIM_POS_INF_ms
Definition nest_time.h:223
#define LIM_NEG_INF_ms
Definition nest_time.h:230
std::ostream & operator<<(std::ostream &, const nest::Time &)
Definition nest_time.cpp:163
long ld_round(double x)
Round to nearest int, rounding midpoints upwards.
Definition numerics.cpp:41
Definition nest_time.h:227
static const tic_t tics
Definition nest_time.h:228
static const long steps
Definition nest_time.h:229
Definition nest_time.h:220
static const tic_t tics
Definition nest_time.h:221
static const long steps
Definition nest_time.h:222
Definition nest_time.h:200
double ms
Definition nest_time.h:203
tic_t tics
Definition nest_time.h:201
long steps
Definition nest_time.h:202
Limit(tic_t tics, long steps, double ms)
Definition nest_time.h:205
Definition nest_time.h:147
static const long INF_MARGIN
Definition nest_time.h:160
static const double TICS_PER_MS_DEFAULT
Definition nest_time.h:158
static tic_t TICS_PER_STEP
Definition nest_time.h:148
static const tic_t TICS_PER_STEP_DEFAULT
Definition nest_time.h:157
static double TICS_PER_MS
Definition nest_time.h:152
static double STEPS_PER_MS
Definition nest_time.h:154
static double TICS_PER_STEP_INV
Definition nest_time.h:149
static double MS_PER_STEP
Definition nest_time.h:155
static tic_t TICS_PER_STEP_RND
Definition nest_time.h:150
static double MS_PER_TIC
Definition nest_time.h:153
Definition nest_time.h:264
double t
Definition nest_time.h:265
ms_stamp(double t)
Definition nest_time.h:266
Definition nest_time.h:255
double t
Definition nest_time.h:256
ms(double t)
Definition nest_time.h:257
Definition nest_time.h:246
step(long t)
Definition nest_time.h:248
long t
Definition nest_time.h:247
Definition nest_time.h:239
tic_t t
Definition nest_time.h:240
tic(tic_t t)
Definition nest_time.h:241