roadrunner  2.6.0
Fast simulator for SBML models
EulerIntegrator.h
1 /*
2  * EulerIntegrator.h
3  *
4  * Created on: Dec 17, 2014
5  * Author: andy
6  */
7 
8 #ifndef EULERINTEGRATOR_H_
9 #define EULERINTEGRATOR_H_
10 
11 #include "Integrator.h"
12 #include "rrExecutableModel.h"
13 #include "rrRoadRunnerOptions.h"
14 
15 #include <string>
16 #include <stdexcept>
17 #include <sstream>
18 #include <iostream>
19 
20 namespace rr {
21  using std::string;
22  using std::invalid_argument;
23  using std::stringstream;
24 
47  class EulerIntegrator : public Integrator {
48  public:
49 
50  using Integrator::Integrator;
51 
66  : Integrator(m),
67  eventStatus(std::vector<unsigned char>(m->getNumEvents(), false)),
68  previousEventStatus(std::vector<unsigned char>(m->getNumEvents(), false)) {
70 
71  mModel = m;
72  exampleParameter1 = 3.14;
73  exampleParameter2 = "hello";
74  rrLog(Logger::LOG_WARNING) << "Euler integrator is inaccurate";
75  //std::cerr << "Number of event triggers: " << m->getEventTriggers(0, 0, 0) << std::endl;
76 
77  if (mModel) {
78  // calling the getStateVector with a NULL argument returns
79  // the size of teh state std::vector.
80  stateVectorSize = mModel->getStateVector(NULL);
81  rateBuffer = new double[stateVectorSize];
82  stateBufferBegin = new double[stateVectorSize];
83  stateBufferEnd = new double[stateVectorSize];
84  } else {
85  rateBuffer = NULL;
86  stateBufferBegin = NULL;
87  stateBufferEnd = NULL;
88  }
89  }
90 
94  ~EulerIntegrator() override {
95  if (mModel) {
96  delete[] rateBuffer;
97  delete[] stateBufferBegin;
98  delete[] stateBufferEnd;
99  rateBuffer = nullptr;
100  stateBufferBegin = nullptr;
101  stateBufferEnd = nullptr;
102  }
103  };
104 
114  virtual double integrate(double t0, double h) override {
115  int internal_steps = getValue("subdivision_steps");
116  if (mModel == (rr::ExecutableModel *) NULL) return 0;
117 
118  double finalTimeEnd;
119 
120  h /= internal_steps;
121  for (int subdiv = 0; subdiv < internal_steps; ++subdiv) {
122  // evaluate and copy the rate of change of the state std::vector
123  // rate into the local buffer. If the 2nd argument is NULL,
124  // the current mModel state is used to evaluate the
125  // state std::vector rate.
126  mModel->getStateVectorRate(t0, NULL, rateBuffer);
127 
128  // copy the current state std::vector into a local buffer
129  mModel->getStateVector(stateBufferBegin);
130 
131  // perform the Euler integration step, i.e.
132  // y_{n+1} = y_{n} + h * y'_{n}
133  for (int i = 0; i < stateVectorSize; ++i) {
134  stateBufferEnd[i] = stateBufferBegin[i] + h * rateBuffer[i];
135  }
136 
137  // set the mModel state to the newly calculated state
138  mModel->setStateVector(stateBufferEnd);
139 
140  // update the mModel time to the new time
141  double timeEnd = t0 + h;
142  mModel->setTime(timeEnd);
143 
144  // if we have a client, notify them that we have taken
145  // a time step
146  if (listener) {
147  listener->onTimeStep(this, mModel, timeEnd);
148  }
149 
150  // events
151  bool triggered = false;
152 
153  mModel->getEventTriggers(eventStatus.size(), NULL, eventStatus.size() ? &eventStatus[0] : NULL);
154  for (int k_ = 0; k_ < eventStatus.size(); ++k_) {
155  if (eventStatus.at(k_)) {
156  triggered = true;
157  //std::cerr << "Triggered" << std::endl;
158  }
159  }
160 
161  if (triggered) {
162  // applyEvents takes the list of events which were previously triggered
163  //std::cerr << "An event was triggered at " << t0 << std::endl;
164  applyEvents(timeEnd, previousEventStatus);
165  }
166 
167  if (!eventStatus.empty()) {
168  previousEventStatus = eventStatus;
169  }
170 
171  finalTimeEnd = timeEnd;
172  }
173 
174  return finalTimeEnd;
175  }
176 
177  void applyEvents(double timeEnd, std::vector<unsigned char> &previousEventStatus) {
178  //std::cerr << "Size of previous events: " << previousEventStatus.size() << std::endl;
179  // If we pass in the events including the ones just triggered, they won't be applied, so use previousEventStatus
180  mModel->applyEvents(timeEnd, previousEventStatus.size() == 0 ? NULL : &previousEventStatus[0],
181  stateBufferEnd, NULL);
182  // AHu: jk I think that mModel->applyEvents does update the mode's state std::vector
183  // The previous statement loaded the result into the final stateBufferEnd, so now update the mModel's state std::vector
184  //mModel->setStateVector(stateBufferEnd);
185  }
186 
190  virtual void restart(double t0) override {}
191 
196  virtual void setListener(IntegratorListenerPtr p) override {
197  listener = p;
198  }
199 
203  virtual IntegratorListenerPtr getListener() override {
204  return listener;
205  }
206 
210  virtual std::string toString() const override {
211  std::stringstream ss;
212  ss << "< roadrunner.EulerIntegrator() " << std::endl;
213  ss << "{ 'this' : " << (void *) this << std::endl;
214  ss << "'exampleParameter1' : " << exampleParameter1 << std::endl;
215  ss << "'exampleParameter2' : " << exampleParameter2 << std::endl;
216  ss << "}>";
217  return ss.str();
218  }
219 
223  virtual std::string toRepr() const override {
224  std::stringstream ss;
225  ss << "< roadrunner.EulerIntegrator() { 'this' : "
226  << (void *) this << " }>";
227  return ss.str();
228  }
229 
233  std::string getName() const override {
234  return "euler";
235  }
236 
242  std::string getDescription() const override {
243  return "The Euler method is one of the simplest approaches to "
244  "solving a first order ODE. Given the rate of change of "
245  "function f at time t, it computes the new value of f as "
246  "f(t+h) = f(t) + h*f'(t), where h is the time step. "
247  "Euler's method is rarely used in practice due to poor "
248  "numerical robustness.";
249  }
250 
256  std::string getHint() const override {
257  return "A simple Euler integrator";
258  }
259 
260  Solver *construct(ExecutableModel *executableModel) const override {
261  return new EulerIntegrator(executableModel);
262  }
263 
268  IntegrationMethod getIntegrationMethod() const override {
269  return Integrator::Deterministic;
270  }
271 
278  virtual void setItem(const std::string &key, const rr::Setting &value) {
279  if (key == "exampleParameter1") {
280  exampleParameter1 = value.get<double>();
281  return;
282  }
283 
284  if (key == "exampleParameter2") {
285  // Ahu: Why is this cast here, and is this a static or dynamic cast?
286  exampleParameter2 = value.get<std::string>();
287  return;
288  }
289 
290  // they did not give a valid key, so throw an exception.
291  throw std::invalid_argument("Error, attempt to set invalid key: " + key);
292  }
293 
300  virtual Setting getItem(const std::string &key) const {
301  if (key == "exampleParameter1") {
302  return Setting(exampleParameter1);
303  }
304 
305  if (key == "exampleParameter2") {
306  return Setting(exampleParameter2);
307  }
308 
309  // they did not give a valid key, so throw an exception.
310  throw std::invalid_argument("Error, attempt to read invalid key: " + key);
311  }
312 
316  virtual bool hasKey(const std::string &key) const {
317  if (key == "exampleParameter1" || key == "exampleParameter2") {
318  return true;
319  } else {
320  return false;
321  }
322  }
323 
328  virtual int deleteItem(const std::string &key) {
329  throw std::invalid_argument(
330  "Error, the EulerIntegrator does not support deleting keys");
331  }
332 
336  virtual std::vector<std::string> getKeys() const {
337  std::vector<std::string> keys;
338  keys.push_back("exampleParameter1");
339  keys.push_back("exampleParameter2");
340  return keys;
341  }
342 
343  void resetSettings() override {
345 
346  // Set default integrator settings.
347  addSetting("subdivision_steps", Setting(1),
348  "Subdivision Steps",
349  "The number of subdivisions of the Euler step size (int).",
350  "(int) For each point, up to this many extra steps will be taken as smaller steps within each step, although their values are not saved");
351  }
352 
353  private:
357  double exampleParameter1;
358 
362  std::string exampleParameter2;
363 
368  double *rateBuffer, *stateBufferBegin, *stateBufferEnd;
369 
373  int stateVectorSize;
374 
375  std::vector<unsigned char> eventStatus;
376  std::vector<unsigned char> previousEventStatus;
377 
387  IntegratorListenerPtr listener;
388  };
389 
390 
391  // ** Registration *********************************************************
392 
393 
394 } /* namespace rr */
395 
396 #endif /* EULERINTEGRATOR_H_ */
RoadRunner's Gillespie SSA integrator.
An example class intended to show how to create an Integrator.
Definition: EulerIntegrator.h:47
std::string getName() const override
get the name of this integrator
Definition: EulerIntegrator.h:233
virtual void setItem(const std::string &key, const rr::Setting &value)
sets the value for a key.
Definition: EulerIntegrator.h:278
virtual Setting getItem(const std::string &key) const
Get a value.
Definition: EulerIntegrator.h:300
Solver * construct(ExecutableModel *executableModel) const override
Constructs a new Solver of a given type.
Definition: EulerIntegrator.h:260
void resetSettings() override
Reset all settings to their respective default values.
Definition: EulerIntegrator.h:343
virtual int deleteItem(const std::string &key)
remove a value, this example class does not support deleting keys, so just raise an exception if some...
Definition: EulerIntegrator.h:328
virtual bool hasKey(const std::string &key) const
is there a key matching this name.
Definition: EulerIntegrator.h:316
virtual IntegratorListenerPtr getListener() override
get the integrator listener
Definition: EulerIntegrator.h:203
virtual double integrate(double t0, double h) override
integrates the model from t0 to t0 + hstep
Definition: EulerIntegrator.h:114
std::string getDescription() const override
Get the description for this integrator.
Definition: EulerIntegrator.h:242
virtual void setListener(IntegratorListenerPtr p) override
Clients may register a listener to listen for sbml events and time step events.
Definition: EulerIntegrator.h:196
virtual std::vector< std::string > getKeys() const
list of keys in this object.
Definition: EulerIntegrator.h:336
virtual std::string toString() const override
get a description of this object, compatable with python str
Definition: EulerIntegrator.h:210
virtual void restart(double t0) override
This simple integrator has nothing to reset, so do nothing here.
Definition: EulerIntegrator.h:190
IntegrationMethod getIntegrationMethod() const override
Always deterministic for Euler.
Definition: EulerIntegrator.h:268
std::string getHint() const override
Get the hint for this integrator.
Definition: EulerIntegrator.h:256
virtual std::string toRepr() const override
get a short descriptions of this object, compatable with python repr.
Definition: EulerIntegrator.h:223
~EulerIntegrator() override
delete any memory we allocated
Definition: EulerIntegrator.h:94
EulerIntegrator(ExecutableModel *m)
Creates a new EulerIntegrator.
Definition: EulerIntegrator.h:65
Base class for all code generation systems; allows compiling and evaluating the model.
Definition: rrExecutableModel.h:118
virtual void getStateVectorRate(double time, const double *y, double *dydt=0)=0
the state std::vector y is the rate rule values and floating species concentrations concatenated.
virtual int setStateVector(const double *stateVector)=0
sets the internal model state to the provided packed state std::vector.
virtual int getEventTriggers(size_t len, const int *indx, unsigned char *values)=0
get the event status, false if the even is not triggered, true if it is.
virtual int getStateVector(double *stateVector)=0
The state std::vector is a std::vector of elements that are defined by differential equations (rate r...
virtual int applyEvents(double timeEnd, const unsigned char *previousEventStatus, const double *initialState, double *finalState)=0
Itterate through all of the current and pending events and apply them.
Integrator is an abstract base class that provides an interface to specific integrator class implemen...
Definition: Integrator.h:60
Store a roadrunner option (or setting) as a Variant type.
Definition: Setting.h:78
SettingType get()
return the value held by this Setting as a type SettingType.
Definition: Setting.h:197
Base class for all integrators and steady state solvers.
Definition: Solver.h:39
virtual void resetSettings()
Reset all settings to their respective default values.
Definition: Solver.cpp:67
virtual Setting getValue(const std::string &key) const
Get the value of an integrator setting.
Definition: Solver.cpp:104
ExecutableModel * mModel
non-owning pointer to model
Definition: Solver.h:208
Base class for all code generators in RoadRunner.