models.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /**
  2. * @file tests/qss/models.hpp
  3. * @author The ARTIS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * ARTIS - the multimodeling and simulation environment
  8. * This file is a part of the ARTIS environment
  9. *
  10. * Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #ifndef TESTS_QSS_MODELS_HPP
  26. #define TESTS_QSS_MODELS_HPP
  27. #include <artis-star/common/time/DoubleTime.hpp>
  28. #include <artis-star/common/utils/Trace.hpp>
  29. #include <artis-star/kernel/qss/Derivative.hpp>
  30. #include <artis-star/kernel/qss/MultiDerivative.hpp>
  31. #include <artis-star/kernel/dtss/Dynamics.hpp>
  32. namespace artis {
  33. namespace tests {
  34. namespace qss {
  35. class Constant : public artis::qss::Derivative<common::DoubleTime, Constant>
  36. {
  37. public:
  38. Constant(const std::string &name,
  39. const artis::pdevs::Context<common::DoubleTime,
  40. Constant,
  41. artis::common::NoParameters> &context)
  42. :
  43. artis::qss::Derivative<common::DoubleTime, Constant>(name,
  44. context)
  45. {}
  46. ~Constant() override = default;
  47. double compute() const override
  48. { return 0.5; }
  49. };
  50. struct ParabolaParameters
  51. {
  52. double alpha;
  53. };
  54. class Parabola
  55. : public artis::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters>
  56. {
  57. public:
  58. Parabola(const std::string &name,
  59. const artis::pdevs::Context<common::DoubleTime, Parabola, ParabolaParameters> &context)
  60. :
  61. artis::qss::Derivative<common::DoubleTime, Parabola, ParabolaParameters>(
  62. name,
  63. context), _alpha(context.parameters().alpha)
  64. {
  65. internal("X", &Parabola::_x);
  66. }
  67. ~Parabola() override = default;
  68. double compute() const override
  69. { return _alpha * _x; }
  70. private:
  71. double _alpha;
  72. double _x;
  73. };
  74. struct PreyPredatorParameters
  75. {
  76. double a;
  77. double b;
  78. double d;
  79. double e;
  80. };
  81. class Predator
  82. : public artis::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters>
  83. {
  84. public:
  85. unsigned int IN_X;
  86. Predator(const std::string &name,
  87. const artis::pdevs::Context<common::DoubleTime,
  88. Predator,
  89. PreyPredatorParameters> &context)
  90. :
  91. artis::qss::Derivative<common::DoubleTime, Predator, PreyPredatorParameters>(
  92. name,
  93. context), _b(context.parameters().b), _d(context.parameters().d),
  94. _e(context.parameters().e)
  95. {
  96. internal("Y", &Predator::_y);
  97. IN_X = external("X", &Predator::_x);
  98. }
  99. ~Predator() override = default;
  100. double compute() const override
  101. { return _b * _d * _x * _y - _e * _y; }
  102. private:
  103. // parameters
  104. double _b;
  105. double _d;
  106. double _e;
  107. // state
  108. double _x;
  109. double _y;
  110. };
  111. class Prey
  112. : public artis::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters>
  113. {
  114. public:
  115. unsigned int IN_Y;
  116. Prey(const std::string &name,
  117. const artis::pdevs::Context<common::DoubleTime, Prey, PreyPredatorParameters> &context)
  118. :
  119. artis::qss::Derivative<common::DoubleTime, Prey, PreyPredatorParameters>(
  120. name,
  121. context), _a(context.parameters().a), _b(context.parameters().b)
  122. {
  123. internal("X", &Prey::_x);
  124. IN_Y = external("Y", &Prey::_y);
  125. }
  126. ~Prey() override = default;
  127. double compute() const override
  128. { return _a * _x - _b * _y * _x; }
  129. private:
  130. // parameters
  131. double _a;
  132. double _b;
  133. // state
  134. double _x;
  135. double _y;
  136. };
  137. struct SmartGardenerParameters
  138. {
  139. double threshold;
  140. double prey_proportion;
  141. double predator_proportion;
  142. double delay;
  143. };
  144. class SmartGardener
  145. : public artis::pdevs::Dynamics<common::DoubleTime, SmartGardener, SmartGardenerParameters>
  146. {
  147. public:
  148. enum inputs
  149. {
  150. IN_X, IN_Y
  151. };
  152. enum outputs
  153. {
  154. OUT_X, OUT_Y
  155. };
  156. SmartGardener(const std::string &name,
  157. const artis::pdevs::Context<common::DoubleTime,
  158. SmartGardener,
  159. SmartGardenerParameters> &context)
  160. :
  161. artis::pdevs::Dynamics<common::DoubleTime, SmartGardener, SmartGardenerParameters>(
  162. name, context),
  163. _threshold(context.parameters().threshold),
  164. _prey_proportion(context.parameters().prey_proportion),
  165. _predator_proportion(context.parameters().predator_proportion),
  166. _delay(context.parameters().delay)
  167. {
  168. input_ports({{IN_X, "in_x"},
  169. {IN_Y, "in_y"}});
  170. output_ports({{OUT_X, "out_x"},
  171. {OUT_Y, "out_y"}});
  172. }
  173. ~SmartGardener() override = default;
  174. void dint(const typename common::DoubleTime::type & /* t */) override
  175. {
  176. switch (_phase) {
  177. case INIT:_phase = IDLE;
  178. _sigma = _delay;
  179. break;
  180. case IDLE:
  181. if (_prey_amount > _threshold) {
  182. _phase = PEST;
  183. } else {
  184. _phase = IDLE;
  185. _sigma = _delay;
  186. }
  187. break;
  188. case PEST:_phase = IDLE;
  189. _sigma = _delay;
  190. break;
  191. }
  192. }
  193. void
  194. dext(const typename common::DoubleTime::type & /* t */,
  195. const typename common::DoubleTime::type &e,
  196. const common::Bag<common::DoubleTime> &bag) override
  197. {
  198. std::for_each(bag.begin(), bag.end(),
  199. [this](const common::ExternalEvent<common::DoubleTime> &event) {
  200. artis::qss::IntegratorData data;
  201. event.data()(data);
  202. if (event.on_port(IN_X)) {
  203. _prey_amount = data.value;
  204. } else if (event.on_port(IN_Y)) {
  205. _predator_amount = data.value;
  206. }
  207. });
  208. _sigma -= e;
  209. }
  210. void
  211. start(const typename common::DoubleTime::type & /* t */) override
  212. { _phase = INIT; }
  213. typename common::DoubleTime::type
  214. ta(const typename common::DoubleTime::type & /* t */) const override
  215. {
  216. switch (_phase) {
  217. case INIT:return 0.0;
  218. case IDLE:return _sigma;
  219. case PEST:return 0.0;
  220. }
  221. return common::DoubleTime::infinity;
  222. }
  223. common::Bag<common::DoubleTime>
  224. lambda(const typename common::DoubleTime::type & /* t */) const override
  225. {
  226. common::Bag<common::DoubleTime> bag;
  227. if (_phase == PEST) {
  228. artis::qss::IntegratorData data = {_prey_amount * _prey_proportion};
  229. bag.push_back(common::ExternalEvent<common::DoubleTime>(OUT_X, data));
  230. data = {_predator_amount * _predator_proportion};
  231. bag.push_back(common::ExternalEvent<common::DoubleTime>(OUT_Y, data));
  232. }
  233. return bag;
  234. }
  235. private:
  236. enum Phase
  237. {
  238. INIT, IDLE, PEST
  239. };
  240. // parameters
  241. double _threshold;
  242. double _prey_proportion;
  243. double _predator_proportion;
  244. double _delay;
  245. // state
  246. Phase _phase;
  247. common::DoubleTime::type _sigma;
  248. double _prey_amount;
  249. double _predator_amount;
  250. };
  251. struct DiscretePreyPredatorParameters
  252. {
  253. artis::common::DoubleTime::type time_step;
  254. double init_value;
  255. double a;
  256. double b;
  257. double d;
  258. double e;
  259. };
  260. class DiscretePredator
  261. : public artis::dtss::Dynamics<artis::common::DoubleTime,
  262. DiscretePredator,
  263. DiscretePreyPredatorParameters>
  264. {
  265. public:
  266. enum inputs
  267. {
  268. RESET, IN_X, IN_Y
  269. };
  270. enum outputs
  271. {
  272. OUT
  273. };
  274. enum vars
  275. {
  276. VALUE
  277. };
  278. DiscretePredator(const std::string &name,
  279. const artis::dtss::Context<artis::common::DoubleTime,
  280. DiscretePredator,
  281. DiscretePreyPredatorParameters> &context)
  282. :
  283. artis::dtss::Dynamics<artis::common::DoubleTime,
  284. DiscretePredator,
  285. DiscretePreyPredatorParameters>(
  286. name, context), _init_value(context.parameters().init_value),
  287. _b(context.parameters().b), _d(context.parameters().d),
  288. _e(context.parameters().e)
  289. {
  290. input_ports({{RESET, "reset"},
  291. {IN_X, "in_x"},
  292. {IN_Y, "in_y"}});
  293. output_ports({{OUT, "out"}});
  294. observables({{VALUE, "value"}});
  295. }
  296. ~DiscretePredator() override = default;
  297. void transition(const artis::common::Bag<artis::common::DoubleTime> &bag,
  298. const artis::common::DoubleTime::type & /* t */) override
  299. {
  300. std::for_each(bag.begin(), bag.end(),
  301. [this](const artis::common::ExternalEvent<artis::common::DoubleTime> &event) {
  302. if (event.on_port(IN_X)) {
  303. artis::qss::IntegratorData data;
  304. event.data()(data);
  305. _x = data.value;
  306. } else if (event.on_port(RESET)) {
  307. // TODO
  308. }
  309. });
  310. _y += (_b * _d * _x * _y - _e * _y) * time_step();
  311. }
  312. void start(const artis::common::DoubleTime::type & /* t */) override
  313. {
  314. _y = _init_value;
  315. }
  316. artis::common::Bag<artis::common::DoubleTime>
  317. lambda(const artis::common::DoubleTime::type & /* t */) const override
  318. {
  319. artis::common::Bag<artis::common::DoubleTime> msgs;
  320. artis::qss::IntegratorData data = {_y};
  321. msgs.push_back(
  322. artis::common::ExternalEvent<artis::common::DoubleTime>(OUT, data));
  323. return msgs;
  324. }
  325. artis::common::Value observe(const artis::common::DoubleTime::type & /* t */,
  326. unsigned int index) const override
  327. {
  328. if (index == VALUE) {
  329. return (double) _y;
  330. }
  331. return artis::common::Value();
  332. }
  333. private:
  334. // parameters
  335. double _init_value;
  336. double _b;
  337. double _d;
  338. double _e;
  339. // state
  340. double _x;
  341. double _y;
  342. };
  343. class PreyPredator
  344. : public artis::qss::MultiDerivative<common::DoubleTime, PreyPredator, PreyPredatorParameters>
  345. {
  346. public:
  347. PreyPredator(const std::string &name,
  348. const artis::pdevs::Context<common::DoubleTime, PreyPredator,
  349. PreyPredatorParameters> &context)
  350. :
  351. artis::qss::MultiDerivative<common::DoubleTime, PreyPredator, PreyPredatorParameters>(
  352. name, context),
  353. _a(context.parameters().a), _b(context.parameters().b),
  354. _d(context.parameters().d), _e(context.parameters().e)
  355. {
  356. internal("X", &PreyPredator::_x);
  357. internal("Y", &PreyPredator::_y);
  358. }
  359. ~PreyPredator() override = default;
  360. std::vector<double> compute() override
  361. {
  362. return {_a * _x - _b * _y * _x,
  363. _b * _d * _x * _y - _e * _y};
  364. }
  365. private:
  366. // parameters
  367. double _a;
  368. double _b;
  369. double _d;
  370. double _e;
  371. // state
  372. double _x;
  373. double _y;
  374. };
  375. }
  376. }
  377. } // namespace artis tests qss
  378. #endif