YPetri
YPetri
is a domain model and a simulator of dynamical systems. It was inspired by the problems from the field of modelling of biochemical pathways, but on purpose, YPetri is not specific to biochemistry. As a matter of separation of concerns, YPetri caters solely to the two main concerns of modelling, model specification and simulation, excelling in the first one. YPetri implements a novel universal Petri net type, that integrating discrete/continous, deterministic/stochastic, timed/timeless and stoichiometric/nonstoichiometric dichotomies commonly seen in extended Petri nets. YPetri allows specification of any kind of dynamical system whatsoever.
Usage
YPetri
provides a domain specific language (DSL) that can be loaded by:
require 'y_petri'
include YPetri
(As a matter of terminology, DSLs used in modelling are sometimes termed domain specific modelling languages (DSMLs). This term is popular especially in engineering.) Petri net places can now be created:
A = Place()
B = Place()
places.names
A.marking = 2
B.marking = 5
And transitions:
A2B = Transition stoichiometry: { A: -1, B: 1 }
A2B.stoichiometry
A2B.s
A2B.arcs.names
A2B.timeless?
A2B.enabled?
Explanation of the keywords: arcs, enabled are standard Petri net terms,
stoichiometry means arcs with the amount of tokens to add / take from the
connected places when the transition fires, timeless means that firing of
the transition is not defined in time.
We can now play the token game:
places.map &:marking
A2B.fire!
places.map &:marking
A2B.fire!
places.map &:marking
Advanced usage
A Petri net is mostly used as a wiring diagram of some real-world system. Such
Petri net can then be used to generate its simulation -- represented by
YPetri::Simulation
class. A Petri net consisting of only timed transitions
can be used to generate (implicitly or explicitly) a system of ordinary
differential equations (ODE). A simulation generated from such Petri net can
then be used to solve (eg.) the initial value problem by numeric methods:
require 'y_petri'
include YPetri
A = Place default_marking: 0.5
B = Place default_marking: 0.5
A_pump = Transition s: { A: -1 }, rate: proc { 0.005 }
B_decay = Transition s: { B: -1 }, rate: 0.05
net
run!
Simulation can now be accessed through simulation
DSL method:
simulation
simulation.settings
print_recording
If you have gnuplot
gem installed properly, you can view plots:
plot_state
plot_flux
Gillespie method
To try out another simulation method, Gillespie algorithm, open a fresh session
and type:
require 'y_petri'
require 'sy'
require 'mathn'
include YPetri
A = Place m!: 10
B = Place m!: 10
AB = Place m!: 0
AB_association = Transition s: { A: -1, B: -1, AB: 1 }, rate: 0.1
AB_dissociation = Transition s: { AB: -1, A: 1, B: 1 }, rate: 0.1
A2B = Transition s: { A: -1, B: 1 }, rate: 0.05
B2A = Transition s: { A: 1, B: -1 }, rate: 0.07
set_step 1
set_target_time 50
set_sampling 1
set_simulation_method :gillespie
run!
print_recording
Again, you can visualize the results using gnuplot
gem:
plot_state
So much for the demo for now! Thanks for trying YPetri!
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
)
- Commit your changes (
git commit -am 'Added some feature'
)
- Push to the branch (
git push origin my-new-feature
)
- Create new Pull Request
core_ext/array/