浏览代码

Use state for QSS

Eric Ramat 5 年之前
父节点
当前提交
dae5ed4bcc

+ 6 - 4
src/tests/dtss/tests.cpp

@@ -38,6 +38,7 @@ using namespace artis::common;
 
 TEST_CASE("dtss/only_one", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::dtss::Coordinator<
                     DoubleTime,
@@ -45,10 +46,10 @@ TEST_CASE("dtss/only_one", "run")
                     OnlyOneGraphManager,
                     artis::dtss::Parameters<DoubleTime>,
                     artis::common::NoParameters>
-    > rc(0, 10, "root", artis::dtss::Parameters<DoubleTime>(1), artis::common::NoParameters());
+    > rc(context, "root", artis::dtss::Parameters<DoubleTime>(1), artis::common::NoParameters());
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a").
@@ -67,18 +68,19 @@ TEST_CASE("dtss/only_one", "run")
 
 TEST_CASE("dtss/two", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::dtss::Coordinator<
                     DoubleTime,
                     Policy,
                     TwoGraphManager,
                     artis::dtss::Parameters<DoubleTime> >
-    > rc(0, 10, "root",
+    > rc(context, "root",
             artis::dtss::Parameters<DoubleTime>(1),
             artis::common::NoParameters());
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<
             DoubleTime > ::trace().elements().

+ 3 - 2
src/tests/mixed/tests.cpp

@@ -38,15 +38,16 @@ using namespace artis::common;
 
 TEST_CASE("mixed/hierachical", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 100);
     artis::common::RootCoordinator<
             DoubleTime,
             artis::pdevs::Coordinator<
                     DoubleTime,
                     RootGraphManager>
-    > rc(0, 100, "root");
+    > rc(context, "root");
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").

+ 11 - 8
src/tests/mpi/main.cpp

@@ -60,6 +60,7 @@ void example_simple(int argc, char* argv[])
 //        parameters.ranks.push_back(7);
 //        parameters.ranks.push_back(8);
 
+        artis::common::context::Context<artis::common::DoubleTime> context(0, 1000);
         artis::common::RootCoordinator<
                 DoubleTime,
                 artis::pdevs::Coordinator<
@@ -67,11 +68,11 @@ void example_simple(int argc, char* argv[])
                         artis::tests::mpi::RootGraphManager,
                         artis::common::NoParameters,
                         artis::tests::mpi::RootGraphManagerParameters>
-        > rc(0, 1000, "root", artis::common::NoParameters(), parameters);
+        > rc(context, "root", artis::common::NoParameters(), parameters);
 
         steady_clock::time_point t1 = steady_clock::now();
 
-        rc.run();
+        rc.run(context);
 
         steady_clock::time_point t2 = steady_clock::now();
 
@@ -118,6 +119,7 @@ void example_simple_local()
 //    parameters.ranks.push_back(7);
 //    parameters.ranks.push_back(8);
 
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 1000);
     artis::common::RootCoordinator<
             DoubleTime,
             artis::pdevs::Coordinator<
@@ -125,11 +127,11 @@ void example_simple_local()
                     artis::tests::mpi::RootLocalGraphManager,
                     artis::common::NoParameters,
                     artis::tests::mpi::RootGraphManagerParameters>
-    > rc(0, 1000, "root", artis::common::NoParameters(), parameters);
+    > rc(context, "root", artis::common::NoParameters(), parameters);
 
     steady_clock::time_point t1 = steady_clock::now();
 
-    rc.run();
+    rc.run(context);
 
     steady_clock::time_point t2 = steady_clock::now();
 
@@ -151,6 +153,7 @@ void example_simple_multithreading()
 //    parameters.ranks.push_back(7);
 //    parameters.ranks.push_back(8);
 
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 1000);
     artis::common::RootCoordinator<
             DoubleTime,
             artis::pdevs::multithreading::Coordinator<
@@ -158,11 +161,11 @@ void example_simple_multithreading()
                     artis::tests::mpi::RootMultithreadingGraphManager,
                     artis::common::NoParameters,
                     artis::tests::mpi::RootGraphManagerParameters>
-    > rc(0, 1000, "root", artis::common::NoParameters(), parameters);
+    > rc(context, "root", artis::common::NoParameters(), parameters);
 
     steady_clock::time_point t1 = steady_clock::now();
 
-    rc.run();
+    rc.run(context);
 
     steady_clock::time_point t2 = steady_clock::now();
 
@@ -194,7 +197,7 @@ void example_simple_multithreading()
 //                        artis::tests::mpi::GridGraphManagerParameters>
 //        > rc(0, 20, "root", artis::common::NoParameters(), parameters);
 //
-//        rc.run();
+//        rc.run(context);
 //    } else {
 //        std::stringstream ss;
 //        unsigned int x = (world.rank() - 1) % SUB_GRID_NUMBER;
@@ -258,7 +261,7 @@ void example_simple_multithreading()
 
 //         steady_clock::time_point t1 = steady_clock::now();
 
-//         rc.run();
+//         rc.run(context);
 
 //         steady_clock::time_point t2 = steady_clock::now();
 

+ 5 - 3
src/tests/multithreading/lifegame/main.cpp

@@ -30,6 +30,7 @@
 #include <tests/multithreading/lifegame/models.hpp>
 
 #include <chrono>
+#include <iostream>
 
 using namespace artis::common;
 using namespace std::chrono;
@@ -144,19 +145,20 @@ double lifegame_monothreading()
     });
     GridGraphManagerParameters graph_parameters({5, 5});
 
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::pdevs::Coordinator<
                     DoubleTime,
                     FlatGraphManager,
                     CellParameters,
                     GridGraphManagerParameters>
-    > rc(0, 10, "root", parameters, graph_parameters);
+    > rc(context, "root", parameters, graph_parameters);
 
     rc.attachView("Matrix", new ::View());
 
     steady_clock::time_point t1 = steady_clock::now();
 
-    rc.run();
+    rc.run(context);
 
     steady_clock::time_point t2 = steady_clock::now();
 
@@ -179,7 +181,7 @@ double lifegame_multithreading()
 
     steady_clock::time_point t1 = steady_clock::now();
 
-//    rc.run();
+//    rc.run(context);
 
     steady_clock::time_point t2 = steady_clock::now();
 

+ 1 - 3
src/tests/pdevs/CMakeLists.txt

@@ -13,6 +13,4 @@ TARGET_LINK_LIBRARIES(pdevs-tests
 
 ADD_EXECUTABLE(pdevs-main graph_manager.hpp models.hpp main.cpp)
 
-TARGET_LINK_LIBRARIES(pdevs-main
-        ${Boost_SYSTEM_LIBRARY}
-        ${Boost_TIMER_LIBRARY})
+TARGET_LINK_LIBRARIES(pdevs-main ${Boost_LIBRARIES})

+ 12 - 2
src/tests/pdevs/main.cpp

@@ -29,16 +29,26 @@
 
 #include <artis-star/common/RootCoordinator.hpp>
 
+#include <fstream>
+#include <boost/archive/binary_oarchive.hpp>
+
 using namespace artis::tests::pdevs;
 
 int main()
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10000);
     artis::common::RootCoordinator<
             artis::common::DoubleTime, artis::pdevs::Coordinator<
                     artis::common::DoubleTime,
                     OnlyOneGraphManager<ThreeStateModel> >
-    > rc(0, 10000, "root", artis::common::NoParameters(), artis::common::NoParameters());
+    > rc(context, "root", artis::common::NoParameters(), artis::common::NoParameters());
+
+    rc.run(context);
+    rc.save(context);
+
+    std::ofstream os("state");
+    boost::archive::binary_oarchive oa(os);
 
-    rc.run();
+    oa << context;
     return 0;
 }

+ 66 - 27
src/tests/pdevs/models.hpp

@@ -33,6 +33,7 @@
 #include <artis-star/kernel/pdevs/Dynamics.hpp>
 
 #include <chrono>
+#include <iostream>
 
 #define DELAY 100
 
@@ -80,7 +81,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_INT);
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_INT);
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
@@ -93,7 +95,8 @@ namespace artis {
                     }
                 }
 
-                void dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
+                void
+                dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
                         const common::Bag<common::DoubleTime>& msgs) override
                 {
 
@@ -104,7 +107,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_EXT)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_EXT)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
@@ -112,7 +116,8 @@ namespace artis {
                     _phase = SEND;
                 }
 
-                void dconf(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
+                void dconf(typename common::DoubleTime::type t,
+                        typename common::DoubleTime::type /* e */,
                         const common::Bag<common::DoubleTime>& msgs) override
                 {
 
@@ -123,14 +128,16 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_CONF)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_CONF)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
                 }
 
-                typename common::DoubleTime::type start(typename common::DoubleTime::type t) override
+                typename common::DoubleTime::type
+                start(typename common::DoubleTime::type t) override
                 {
 
 #ifndef WITH_TRACE
@@ -139,7 +146,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::START);
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::START);
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
@@ -147,7 +155,8 @@ namespace artis {
                     return 0;
                 }
 
-                typename common::DoubleTime::type ta(typename common::DoubleTime::type t) const override
+                typename common::DoubleTime::type
+                ta(typename common::DoubleTime::type t) const override
                 {
 
 #ifndef WITH_TRACE
@@ -167,7 +176,8 @@ namespace artis {
                     }
                 }
 
-                common::Bag<common::DoubleTime> lambda(typename common::DoubleTime::type t) const override
+                common::Bag<common::DoubleTime>
+                lambda(typename common::DoubleTime::type t) const override
                 {
 #ifndef WITH_TRACE
                     (void)t;
@@ -175,12 +185,14 @@ namespace artis {
                     common::Bag<common::DoubleTime> msgs;
 
                     if (_phase == SEND) {
-                        msgs.push_back(artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
+                        msgs.push_back(
+                                artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
                     }
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::LAMBDA)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::LAMBDA)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
@@ -227,7 +239,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_INT);
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_INT);
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
@@ -236,7 +249,8 @@ namespace artis {
                     }
                 }
 
-                void dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
+                void
+                dext(typename common::DoubleTime::type t, typename common::DoubleTime::type /* e */,
                         const common::Bag<common::DoubleTime>& msgs) override
                 {
 
@@ -247,7 +261,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_EXT)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_EXT)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
@@ -269,14 +284,16 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::DELTA_CONF)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::DELTA_CONF)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
                 }
 
-                typename common::DoubleTime::type start(typename common::DoubleTime::type t) override
+                typename common::DoubleTime::type
+                start(typename common::DoubleTime::type t) override
                 {
 
 #ifndef WITH_TRACE
@@ -285,7 +302,8 @@ namespace artis {
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::START);
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::START);
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
 
@@ -323,12 +341,14 @@ namespace artis {
                     common::Bag<common::DoubleTime> msgs;
 
                     if (_phase == SEND) {
-                        msgs.push_back(artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
+                        msgs.push_back(
+                                artis::common::ExternalEvent<common::DoubleTime>(OUT, _value));
                     }
 
 #ifdef WITH_TRACE
                     common::Trace<common::DoubleTime>::trace()
-                            << common::TraceElement<common::DoubleTime>(get_name(), t, common::LAMBDA)
+                            << common::TraceElement<common::DoubleTime>(get_name(), t,
+                                    common::LAMBDA)
                             << "messages = " << msgs.to_string();
                     common::Trace<common::DoubleTime>::trace().flush();
 #endif
@@ -364,14 +384,16 @@ namespace artis {
                     _last_time = t;
                 }
 
-                typename common::DoubleTime::type start(typename common::DoubleTime::type t) override
+                typename common::DoubleTime::type
+                start(typename common::DoubleTime::type t) override
                 {
                     _phase = S1;
                     _last_time = t;
                     return ta(t);
                 }
 
-                typename common::DoubleTime::type ta(typename common::DoubleTime::type /* t */) const override
+                typename common::DoubleTime::type
+                ta(typename common::DoubleTime::type /* t */) const override
                 {
                     if (_phase == S1) {
                         return 5;
@@ -380,7 +402,8 @@ namespace artis {
                     }
                 }
 
-                common::Bag<common::DoubleTime> lambda(typename common::DoubleTime::type t) const override
+                common::Bag<common::DoubleTime>
+                lambda(typename common::DoubleTime::type t) const override
                 {
 
                     std::cout << (t - _last_time) << std::endl;
@@ -397,17 +420,29 @@ namespace artis {
                 typename common::DoubleTime::type _last_time;
             };
 
-            class ThreeStateModel : public artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel> {
+            class ThreeStateModel
+                    : public artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel> {
             public:
                 enum outputs {
                     OUT
                 };
 
+                enum states {
+                    HEIGHTS, SPEEDS, SCALES, N, INDEX, SIGMA, LAST_TIME
+                };
+
                 ThreeStateModel(const std::string& name,
                         const artis::pdevs::Context<common::DoubleTime, ThreeStateModel, artis::common::NoParameters>& context)
                         :
                         artis::pdevs::Dynamics<common::DoubleTime, ThreeStateModel>(name, context)
                 {
+                    States(std::vector<double>,
+                            ((HEIGHTS, &ThreeStateModel::heights), (SPEEDS, &ThreeStateModel::speeds), (SCALES, &ThreeStateModel::scales)));
+                    States(unsigned int,
+                            ((N, &ThreeStateModel::n), (INDEX, &ThreeStateModel::index)));
+                    States(typename common::DoubleTime::type,
+                            ((SIGMA, &ThreeStateModel::sigma), (LAST_TIME, &ThreeStateModel::_last_time)));
+
                     output_ports({{OUT, "out"}});
                 }
 
@@ -424,7 +459,9 @@ namespace artis {
                         typename common::DoubleTime::type /* e */,
                         const common::Bag<common::DoubleTime>& msgs) override
                 {
-                    for (common::Bag<common::DoubleTime>::const_iterator it = msgs.begin(); it != msgs.end(); ++it) {
+                    for (common::Bag<common::DoubleTime>::const_iterator it = msgs.begin();
+                         it != msgs.end();
+                         ++it) {
                         ++n;
                     }
                     if (sigma == 1) {
@@ -456,7 +493,8 @@ namespace artis {
                     compute();
                 }
 
-                typename common::DoubleTime::type start(typename common::DoubleTime::type t) override
+                typename common::DoubleTime::type
+                start(typename common::DoubleTime::type t) override
                 {
                     heights = {0, 0, 0, 0, 0};
                     speeds = {0.21, 0.3, 0.7, 0.56, 0.14};
@@ -471,7 +509,8 @@ namespace artis {
                 typename common::DoubleTime::type
                 ta(typename common::DoubleTime::type /* t */) const override { return sigma; }
 
-                common::Bag<common::DoubleTime> lambda(typename common::DoubleTime::type /* t */) const override
+                common::Bag<common::DoubleTime>
+                lambda(typename common::DoubleTime::type /* t */) const override
                 {
                     common::Bag<common::DoubleTime> msgs;
 
@@ -560,13 +599,13 @@ namespace artis {
                     }
                 }
 
+                // state
                 std::vector<double> heights;
                 std::vector<double> speeds;
                 std::vector<double> scales;
                 unsigned int index;
                 unsigned int n;
                 typename common::DoubleTime::type sigma;
-
                 typename common::DoubleTime::type _last_time;
             };
 

+ 9 - 6
src/tests/pdevs/tests.cpp

@@ -38,14 +38,15 @@ using namespace artis::common;
 
 TEST_CASE("pdevs/only_one", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::pdevs::Coordinator<
                     DoubleTime,
                     OnlyOneGraphManager<A> >
-    > rc(0, 10, "root", artis::common::NoParameters(), artis::common::NoParameters());
+    > rc(context, "root", artis::common::NoParameters(), artis::common::NoParameters());
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a").
@@ -71,14 +72,15 @@ TEST_CASE("pdevs/only_one", "run")
 
 TEST_CASE("pdevs/flat", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::pdevs::Coordinator<
                     DoubleTime,
                     FlatGraphManager>
-    > rc(0, 10, "root", artis::common::NoParameters(), artis::common::NoParameters());
+    > rc(context, "root", artis::common::NoParameters(), artis::common::NoParameters());
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").
@@ -159,14 +161,15 @@ TEST_CASE("pdevs/flat", "run")
 
 TEST_CASE("pdevs/hierachical", "run")
 {
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 10);
     artis::common::RootCoordinator<
             DoubleTime, artis::pdevs::Coordinator<
                     DoubleTime,
                     RootGraphManager>
-    > rc(0, 10, "root", artis::common::NoParameters(), artis::common::NoParameters());
+    > rc(context, "root", artis::common::NoParameters(), artis::common::NoParameters());
 
     artis::common::Trace<DoubleTime>::trace().clear();
-    rc.run();
+    rc.run(context);
 
     REQUIRE(artis::common::Trace<DoubleTime>::trace().elements().
             filter_model_name("a1").

+ 8 - 4
src/tests/qss/main.cpp

@@ -29,6 +29,8 @@
 #include <artis-star/common/RootCoordinator.hpp>
 #include <artis-star/common/observer/Iterator.hpp>
 
+#include <iostream>
+
 using namespace artis::tests::qss;
 
 void test_parabola()
@@ -46,16 +48,17 @@ void test_parabola()
         }
     };
 
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 5);
     artis::common::RootCoordinator<
             artis::common::DoubleTime, artis::pdevs::Coordinator<
                     artis::common::DoubleTime,
                     OnlyOneParabolaGraphManager,
                     artis::pdevs::qss::QSSParameters<ParabolaParameters>>
-    > rc(0, 5, "root", parameters, artis::common::NoParameters());
+    > rc(context, "root", parameters, artis::common::NoParameters());
 
     rc.attachView("Value", new View());
 
-    rc.run();
+    rc.run(context);
 
     const View::Values& values = rc.observer().view("Value").get("Value");
 
@@ -89,16 +92,17 @@ void test_predator_prey()
         }
     };
 
+    artis::common::context::Context<artis::common::DoubleTime> context(0, 100);
     artis::common::RootCoordinator<
             artis::common::DoubleTime, artis::pdevs::Coordinator<
                     artis::common::DoubleTime,
                     PreyPredatorGraphManager,
                     PreyPredatorGraphManagerParameters>
-    > rc(0, 100, "root", parameters, artis::common::NoParameters());
+    > rc(context, "root", parameters, artis::common::NoParameters());
 
     rc.attachView("Value", new View());
 
-    rc.run();
+    rc.run(context);
 
     {
         artis::observer::DiscreteTimeIterator<artis::common::DoubleTime> it(

+ 53 - 12
src/tests/qss/models.hpp

@@ -53,20 +53,31 @@ namespace artis {
                 double alpha;
             };
 
-            class Parabola : public artis::pdevs::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters> {
+            class Parabola
+                    : public artis::pdevs::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters> {
             public:
+                enum states {
+                    X = IN
+                };
+
                 Parabola(const std::string& name,
                         const artis::pdevs::Context<common::DoubleTime, Parabola, ParabolaParameters>& context)
                         :
-                        artis::pdevs::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters>(name,
-                                context), _alpha(context.parameters().alpha) { }
+                        artis::pdevs::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters>(
+                                name,
+                                context), _alpha(context.parameters().alpha)
+                {
+                    States(double, ((X, &Parabola::_x)));
+                }
 
                 ~Parabola() override = default;
 
-                double compute() const override { return _alpha * input(IN); }
+                double compute() const override { return _alpha * _x; }
 
             private:
                 double _alpha;
+
+                double _x;
             };
 
             struct PreyPredatorParameters {
@@ -76,51 +87,81 @@ namespace artis {
                 double e;
             };
 
-            class Predator : public artis::pdevs::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters> {
+            class Predator
+                    : public artis::pdevs::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters> {
             public:
                 enum inputs {
                     IN_X = IN + 1
                 };
 
+                enum states {
+                    Y = IN, X
+                };
+
                 Predator(const std::string& name,
                         const artis::pdevs::Context<common::DoubleTime, Predator, PreyPredatorParameters>& context)
                         :
-                        artis::pdevs::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters>(name,
-                                context), _b(context.parameters().b), _d(context.parameters().d), _e(context.parameters().e) {
+                        artis::pdevs::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters>(
+                                name,
+                                context), _b(context.parameters().b), _d(context.parameters().d),
+                        _e(context.parameters().e)
+                {
+                    States(double, ((X, &Predator::_x), (Y, &Predator::_y)));
+
                     input_port({IN_X, "in_x"});
                 }
 
                 ~Predator() override = default;
 
-                double compute() const override { return _b * _d * input(IN_X) * input(IN) - _e * input(IN); }
+                double compute() const override { return _b * _d * _x * _y - _e * _y; }
 
             private:
+                // parameters
                 double _b;
                 double _d;
                 double _e;
+
+                // state
+                double _x;
+                double _y;
             };
 
-            class Prey : public artis::pdevs::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters> {
+            class Prey
+                    : public artis::pdevs::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters> {
             public:
                 enum inputs {
                     IN_Y = IN + 1
                 };
 
+                enum states {
+                    X = IN, Y
+                };
+
                 Prey(const std::string& name,
                         const artis::pdevs::Context<common::DoubleTime, Prey, PreyPredatorParameters>& context)
                         :
-                        artis::pdevs::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters>(name,
-                                context), _a(context.parameters().a), _b(context.parameters().b) {
+                        artis::pdevs::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters>(
+                                name,
+                                context), _a(context.parameters().a), _b(context.parameters().b)
+                {
+                    States(double,
+                            ((X, &Prey::_x), (Y, &Prey::_y)));
+
                     input_port({IN_Y, "in_y"});
                 }
 
                 ~Prey() override = default;
 
-                double compute() const override { return _a * input(IN) - _b * input(IN_Y) * input(IN); }
+                double compute() const override { return _a * _x - _b * _y * _x; }
 
             private:
+                // parameters
                 double _a;
                 double _b;
+
+                // state
+                double _x;
+                double _y;
             };
 
         }