Building a simulation engine
Introducing the stochadex project
The building blocks of simulations that we have discussed can now be pieced together to form a complete simulation engine.
The stochadex project is an actual simulation engine written in Go which is based on these basic conceptual building blocks.
Armed with the fundamentals, we can now describe how this simulation engine was built in specific detail, supported by the appropriate system diagrams.
Interfaces and data types
The fundamental data types in the stochadex simulation engine are Go types which can be configured as Settings (pure data) or Implementations (code which implements the provided interfaces).
For example, we have the Iteration interface, which is based directly on the State Partition Iteration we discussed in the previous post.
The Iteration interface can be used to implement any simulation in practice. To illustrate this point, we can show how the internal logic may be implemented to recreate some well-known stochastic processes.
Example: Wiener process
For example, the Wiener process has some very simple logic.
Example: Itô’s lemma
It is well-known (especially by those in finance) that Itô’s lemma can be used to adapt the model formulae for a Wiener process after a mathematical function (a.k.a. transformation) has been applied to it.
We can demonstrate that the Iteration interface can support this kind of transformation as well, through some more complicated logic.
Example: Time-Inhomogeneous Poisson process
What about event-based processes?
The Time-Inhomogeneous Poisson process, is an example of an event-based process which counts the cumulative number of events in Time, while its event rate varies.
The Iteration interface can support this too.
Example: Hawkes process
Let’s give one more example.
The Hawkes process couples the history of events to the current event rate. One may therefore categorise this process as ‘non-Markovian’.
This means that the Hawkes process needs a memory of the State Partition History in order to calculate its Next State Values. Based on everything we have already built and discussed, the Iteration interface obviously supports this quite easily.
Serial dependency graphs and modularity
Multiple Iterations can run within the stochadex for each step in Time. In order to construct serial dependency graphs between them, we can utilise upstream-downstream Iteration relationships.
Structuring groups of Iterations in this way can increase modularity. For example, the Time-Inhomogeneous Poisson process can be implemented serially.
Simulation loop and embedded simulation runs
The Simulation Run loop coordinates the serial relationships between Iterations while maximising concurrency in execution of each Iteration per step in Time.
Given that this loop always runs for any stochadex simulation, it is sufficient to describe any simulation uniquely through the dependency diagram between its Iterations.
Having designed the Simulation Run loop, are now finally able to implement Embedded Simulation Runs.
As a reminder; Embedded Simulation Runs are Iterations which perform entire Simulation Runs from start to end for every Timestep. Their presence can make the diagrams a little more complex, but even more flexible.
The Iteration interface can support these as well.