15 #ifndef CORE_BEHAVIOR_REGULATORY_NETWORK_H_
16 #define CORE_BEHAVIOR_REGULATORY_NETWORK_H_
23 #include "boost/numeric/odeint.hpp"
24 #include "boost/phoenix/core.hpp"
25 #include "boost/phoenix/operator.hpp"
29 typedef boost::numeric::ublas::vector<double> b_vector_t;
30 typedef boost::numeric::ublas::matrix<double> b_matrix_t;
35 enum class ODE_solver { Euler, Rosenbrock, RungeKutta };
37 class RegulatoryNetwork :
public Behavior {
41 RegulatoryNetwork() { AlwaysCopyToNew(); }
44 real_t dt,
int n_dt,
const std::vector<real_t>& x, ODE_solver m,
45 const std::function<
void(
const b_vector_t&, b_vector_t&,
real_t, Agent*)>&
47 const std::function<
void(
const b_vector_t&, b_matrix_t&,
real_t,
48 b_vector_t&, Agent*)>& jacob,
49 const std::function<
void(
const b_vector_t&,
real_t, Agent*)>& out) {
54 time_subdivision_ = n_dt;
62 virtual ~RegulatoryNetwork() =
default;
64 void Initialize(
const NewAgentEvent& event)
override {
65 Base::Initialize(event);
68 dynamic_cast<RegulatoryNetwork*
>(event.existing_behavior)) {
70 current_time_ = other->current_time_;
71 current_species_ = other->current_species_;
72 previous_species_ = other->previous_species_;
75 time_step_ = other->time_step_;
76 time_subdivision_ = other->time_subdivision_;
80 jacob_ = other->jacob_;
82 method_ = other->method_;
85 Log::Fatal(
"RegulatoryNetwork::EventConstructor",
86 "other was not of type RegulatoryNetwork");
91 const size_t GetNumberOfSpecies()
const {
return current_species_.size(); }
92 const b_vector_t& GetSpecies()
const {
return current_species_; }
93 const real_t& GetSpecie(
size_t i)
const {
return current_species_[i]; }
96 void Run(Agent* agent)
override {
99 previous_species_ = current_species_;
101 auto ode_rhs_ = [&](
const b_vector_t& x, b_vector_t& dxdt,
real_t t) {
102 rhs_(x, dxdt, t, agent);
104 auto ode_jacob_ = [&](
const b_vector_t& x, b_matrix_t& jac,
real_t t,
105 b_vector_t& dfdt) { jacob_(x, jac, t, dfdt, agent); };
108 if (ODE_solver::Euler == method_) {
110 const real_t dt = time_step_ / time_subdivision_;
113 for (
int i = 0; i < time_subdivision_; i++) {
114 const real_t t = current_time_ + dt * (1 + i);
117 b_vector_t dxdt(current_species_.size());
118 ode_rhs_(current_species_, dxdt, t);
121 current_species_ += dxdt * dt;
123 }
else if (ODE_solver::Rosenbrock == method_) {
124 typedef boost::numeric::odeint::rosenbrock4<double> ode_int;
128 boost::numeric::odeint::make_dense_output<ode_int>(1e-6, 1e-6);
131 integrate_const(stepper, std::make_pair(ode_rhs_, ode_jacob_),
132 current_species_, current_time_,
133 (current_time_ + time_step_),
134 (time_step_ / time_subdivision_));
135 }
else if (ODE_solver::RungeKutta == method_) {
136 typedef boost::numeric::odeint::runge_kutta_dopri5<b_vector_t> ode_int;
140 boost::numeric::odeint::make_dense_output<ode_int>(1e-6, 1e-6);
143 integrate_const(stepper, ode_rhs_, current_species_, current_time_,
144 (current_time_ + time_step_),
145 (time_step_ / time_subdivision_));
148 "invalid type of ODE solution method indicated");
152 current_time_ += time_step_;
155 out_(current_species_, current_time_, agent);
158 "this behavior is supported only with \"boost\" installed");
163 #ifndef __ROOTCLING__
164 void SetInitialSpecies(
const std::vector<real_t>& x) {
165 const size_t n_species = x.size();
167 current_species_.resize(n_species);
168 previous_species_.resize(n_species);
169 for (
size_t i = 0; i < n_species; i++)
170 current_species_[i] = previous_species_[i] = x[i];
176 real_t current_time_ = 0.0;
179 int time_subdivision_ = 100;
180 #ifndef __ROOTCLING__
182 b_vector_t current_species_ = {};
184 b_vector_t previous_species_ = {};
189 #ifndef __ROOTCLING__
190 std::function<void(
const b_vector_t&, b_vector_t&,
real_t, Agent*)> rhs_;
191 std::function<void(
const b_vector_t&, b_matrix_t&,
real_t, b_vector_t&,
194 std::function<void(
const b_vector_t&,
real_t, Agent*)> out_;
#define BDM_BEHAVIOR_HEADER(class_name, base_class, class_version_id)
Inserts boilerplate code for behaviors with state.
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.