Browse Source

Add timed observations

Eric Ramat 1 year ago
parent
commit
98b4bfd151

+ 6 - 4
src/artis-star/common/RootCoordinator.hpp

@@ -92,12 +92,12 @@ namespace artis {
                     _tn = _root.start(_tn);
                 }
                 while (_tn <= _t_max) {
-                    typename Time::type new_tn;
+                    typename Time::type next_tn;
 
                     _root.output(_tn);
-                    new_tn = _root.transition(_tn);
-                    _observer.observe(_tn);
-                    _tn = new_tn;
+                    next_tn = _root.transition(_tn);
+                    _observer.observe(_tn, _t_max < next_tn ? _t_max : next_tn);
+                    _tn = next_tn;
                 }
             }
 
@@ -107,6 +107,8 @@ namespace artis {
                 context.saved();
             }
 
+            void switch_to_timed_observer(double step) { _observer.switch_to_timed_observer(step); }
+
             std::string to_string() const
             {
                 std::ostringstream ss;

+ 29 - 2
src/artis-star/common/observer/Observer.hpp

@@ -42,6 +42,7 @@ namespace artis {
 
             Observer(const common::Model<Time>* model)
                     :
+                    _step(0),
                     _model(model) { }
 
             virtual ~Observer()
@@ -69,12 +70,38 @@ namespace artis {
                 return v;
             }
 
-            const View<Time>& view(const std::string& name) const { return *_views.find(name)->second; }
+            const View<Time>& view(const std::string& name) const
+            {
+                return *_views.find(name)->second;
+            }
 
             const Views& views() const { return _views; }
 
             void init() { }
 
+            void observe(double t, double next_t)
+            {
+                if (_step == 0) {
+                    observe(t);
+                } else {
+                    double time = std::ceil(t / _step) * _step;
+
+                    while (time < next_t) {
+                        observe(time);
+                        time += _step;
+                    }
+                }
+            }
+
+            void switch_to_timed_observer(double step)
+            {
+
+                assert(step > 0);
+
+                _step = step;
+            }
+
+        private:
             void observe(double t)
             {
                 for (typename Views::iterator it = _views.begin(); it != _views.end();
@@ -83,7 +110,7 @@ namespace artis {
                 }
             }
 
-        private:
+            double _step;
             const common::Model<Time>* _model;
             Views _views;
         };