y_petri 2.2.4 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +675 -0
  3. data/README.md +6 -3
  4. data/Rakefile +1 -1
  5. data/lib/y_petri/agent/{petri_net_related.rb → petri_net_aspect.rb} +34 -10
  6. data/lib/y_petri/agent/{simulation_related.rb → simulation_aspect.rb} +49 -34
  7. data/lib/y_petri/agent.rb +5 -5
  8. data/lib/y_petri/core/guarded.rb +24 -0
  9. data/lib/y_petri/core/timed/euler.rb +4 -8
  10. data/lib/y_petri/core/timed/gillespie.rb +11 -17
  11. data/lib/y_petri/core/timed/methods.rb +23 -0
  12. data/lib/y_petri/core/timed/pseudo_euler.rb +10 -13
  13. data/lib/y_petri/core/timed/quasi_euler.rb +9 -8
  14. data/lib/y_petri/core/timed/runge_kutta.rb +10 -18
  15. data/lib/y_petri/core/timed.rb +6 -14
  16. data/lib/y_petri/core/timeless/methods.rb +15 -0
  17. data/lib/y_petri/core/timeless/pseudo_euler.rb +4 -8
  18. data/lib/y_petri/core/timeless.rb +9 -4
  19. data/lib/y_petri/core.rb +44 -42
  20. data/lib/y_petri/net/data_set.rb +246 -142
  21. data/lib/y_petri/net/node_access.rb +282 -0
  22. data/lib/y_petri/net/own_state.rb +14 -4
  23. data/lib/y_petri/net/state/feature/assignment.rb +123 -0
  24. data/lib/y_petri/net/state/feature/delta.rb +55 -35
  25. data/lib/y_petri/net/state/feature/firing.rb +68 -25
  26. data/lib/y_petri/net/state/feature/flux.rb +9 -2
  27. data/lib/y_petri/net/state/feature/gradient.rb +36 -19
  28. data/lib/y_petri/net/state/feature/marking.rb +10 -5
  29. data/lib/y_petri/net/state/feature.rb +105 -11
  30. data/lib/y_petri/net/state/features/record.rb +144 -99
  31. data/lib/y_petri/net/state/features.rb +327 -200
  32. data/lib/y_petri/net/state.rb +48 -82
  33. data/lib/y_petri/net/visualization.rb +1 -1
  34. data/lib/y_petri/net.rb +62 -47
  35. data/lib/y_petri/place/arcs.rb +44 -0
  36. data/lib/y_petri/place/features.rb +115 -0
  37. data/lib/y_petri/place.rb +62 -29
  38. data/lib/y_petri/simulation/dependency.rb +31 -67
  39. data/lib/y_petri/simulation/feature_set.rb +1 -1
  40. data/lib/y_petri/simulation/initial_marking/access.rb +42 -26
  41. data/lib/y_petri/simulation/marking_clamps/access.rb +22 -17
  42. data/lib/y_petri/simulation/marking_clamps.rb +0 -2
  43. data/lib/y_petri/simulation/marking_vector/access.rb +102 -40
  44. data/lib/y_petri/simulation/marking_vector.rb +35 -37
  45. data/lib/y_petri/simulation/matrix.rb +1 -1
  46. data/lib/y_petri/simulation/node_representation.rb +25 -0
  47. data/lib/y_petri/simulation/nodes/access.rb +78 -0
  48. data/lib/y_petri/simulation/{elements.rb → nodes.rb} +14 -13
  49. data/lib/y_petri/simulation/place_mapping.rb +2 -2
  50. data/lib/y_petri/simulation/place_representation.rb +8 -7
  51. data/lib/y_petri/simulation/places/access.rb +89 -70
  52. data/lib/y_petri/simulation/places/free.rb +1 -1
  53. data/lib/y_petri/simulation/places/types.rb +20 -22
  54. data/lib/y_petri/simulation/places.rb +23 -18
  55. data/lib/y_petri/simulation/recorder.rb +23 -18
  56. data/lib/y_petri/simulation/timed/recorder.rb +19 -11
  57. data/lib/y_petri/simulation/timed.rb +93 -29
  58. data/lib/y_petri/simulation/timeless/recorder.rb +11 -6
  59. data/lib/y_petri/simulation/timeless.rb +13 -3
  60. data/lib/y_petri/simulation/transition_representation/A.rb +24 -4
  61. data/lib/y_petri/simulation/transition_representation/S.rb +11 -1
  62. data/lib/y_petri/simulation/transition_representation/T.rb +1 -1
  63. data/lib/y_petri/simulation/transition_representation/Ts.rb +1 -1
  64. data/lib/y_petri/simulation/transition_representation/a.rb +1 -1
  65. data/lib/y_petri/simulation/transition_representation/s.rb +12 -1
  66. data/lib/y_petri/simulation/transition_representation/t.rb +1 -1
  67. data/lib/y_petri/simulation/transition_representation/tS.rb +1 -1
  68. data/lib/y_petri/simulation/transition_representation/ts.rb +1 -1
  69. data/lib/y_petri/simulation/transition_representation/types.rb +1 -1
  70. data/lib/y_petri/simulation/transition_representation.rb +4 -11
  71. data/lib/y_petri/simulation/transitions/A.rb +17 -2
  72. data/lib/y_petri/simulation/transitions/S.rb +1 -1
  73. data/lib/y_petri/simulation/transitions/T.rb +1 -1
  74. data/lib/y_petri/simulation/transitions/Ts.rb +6 -5
  75. data/lib/y_petri/simulation/transitions/a.rb +1 -1
  76. data/lib/y_petri/simulation/transitions/access.rb +195 -168
  77. data/lib/y_petri/simulation/transitions/s.rb +1 -1
  78. data/lib/y_petri/simulation/transitions/t.rb +1 -1
  79. data/lib/y_petri/simulation/transitions/tS.rb +1 -1
  80. data/lib/y_petri/simulation/transitions/ts.rb +1 -1
  81. data/lib/y_petri/simulation/transitions/types.rb +1 -1
  82. data/lib/y_petri/simulation/transitions.rb +5 -7
  83. data/lib/y_petri/simulation.rb +84 -90
  84. data/lib/y_petri/transition/A.rb +8 -2
  85. data/lib/y_petri/transition/T.rb +25 -2
  86. data/lib/y_petri/transition/arcs.rb +19 -3
  87. data/lib/y_petri/transition/construction_convenience.rb +11 -10
  88. data/lib/y_petri/transition/t.rb +14 -1
  89. data/lib/y_petri/transition/types.rb +6 -1
  90. data/lib/y_petri/transition.rb +9 -12
  91. data/lib/y_petri/version.rb +1 -1
  92. data/lib/y_petri/world/dependency.rb +3 -3
  93. data/lib/y_petri/world/{petri_net_related.rb → petri_net_aspect.rb} +4 -4
  94. data/lib/y_petri/world/simulation_aspect.rb +352 -0
  95. data/lib/y_petri/world.rb +4 -4
  96. data/lib/y_petri.rb +1 -1
  97. data/test/agent_test.rb +2 -1
  98. data/test/examples/demonstrator.rb +4 -1
  99. data/test/examples/demonstrator_2.rb +5 -0
  100. data/test/examples/demonstrator_4.rb +6 -5
  101. data/test/examples/example_2.rb +2 -0
  102. data/test/examples/manual_examples.rb +4 -4
  103. data/test/net_test.rb +457 -54
  104. data/test/place_test.rb +11 -7
  105. data/test/simulation_test.rb +358 -331
  106. data/test/transition_test.rb +11 -10
  107. data/test/world_test.rb +2 -0
  108. data/test/y_petri_test.rb +2 -1
  109. data/y_petri.gemspec +24 -18
  110. metadata +71 -17
  111. data/LICENSE +0 -22
  112. data/lib/y_petri/net/element_access.rb +0 -239
  113. data/lib/y_petri/simulation/element_representation.rb +0 -20
  114. data/lib/y_petri/simulation/elements/access.rb +0 -57
  115. data/lib/y_petri/transition/type.rb +0 -103
  116. data/lib/y_petri/transition/type_information.rb +0 -103
  117. data/lib/y_petri/world/simulation_related.rb +0 -176
data/README.md CHANGED
@@ -1,11 +1,14 @@
1
1
  # YPetri
2
2
 
3
- `YPetri` is a domain model and a simulator of _functional_ _Petri_ _nets_,
4
- a family of Petri nets, whose transitions have functions attached to them.
3
+ `YPetri` is a domain model and a simulator of _YPetri_ nets, a specific kind of
4
+ _Petri_ _nets_ unifying discrete/continous, deterministic/stochastic,
5
+ timed/timeless and stoichiometric/nonstoichiometric dichotomies, thus enabling
6
+ modelling and simulation of dynamic systems of any kind whatsoever.
5
7
 
6
8
  ## Usage
7
9
 
8
- `YPetri` provides a _domain_ _specific_ _language_ (DSL), that can be loaded by:
10
+ `YPetri` provides a _domain_ _specific_ _modeling_ _language_ (DSML), that can
11
+ be loaded by:
9
12
  ```ruby
10
13
  require 'y_petri'
11
14
  include YPetri
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
2
+
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Public command interface of YPetri.
3
+ # Petri net aspect of +YPetri::Agent+.
4
4
  #
5
- module YPetri::Agent::PetriNetRelated
5
+ module YPetri::Agent::PetriNetAspect
6
6
  # Net selection class.
7
7
  #
8
8
  NetSelection = Class.new YPetri::Agent::Selection
@@ -21,9 +21,9 @@ module YPetri::Agent::PetriNetRelated
21
21
  super
22
22
  end
23
23
 
24
- # Elements and selections:
24
+ # Nodes and selections:
25
25
  #
26
- delegate :place, :transition, :element,
26
+ delegate :place, :transition, :node,
27
27
  :nets, :places, :transitions,
28
28
  to: :world
29
29
 
@@ -74,17 +74,41 @@ module YPetri::Agent::PetriNetRelated
74
74
  world.Transition.send( :new, *ordered, **named, &block )
75
75
  end
76
76
 
77
+ # Place constructor: Creates a new place in the current world.
78
+ #
79
+ def Place( *ordered_args, **named_args, &block )
80
+ fail ArgumentError, "If block is given, :guard named argument " +
81
+ "must not be given!" if named_args.has? :guard if block
82
+ named_args.update( guard: block ) if block # use block as a guard
83
+ named_args.may_have :default_marking, syn!: :m!
84
+ named_args.may_have :marking, syn!: :m
85
+ world.Place.send( :new, *ordered_args, **named_args, &block )
86
+ end
87
+
88
+
89
+ # Assignment transition constructor: Creates a new assignment transition in
90
+ # the current world. Ordered arguments are collected as codomain. Domain key
91
+ # (+:domain) is optional. Assignment closure must be supplied in a block.
92
+ #
93
+ def AT( *codomain, **nn, &block )
94
+ fail ArgumentError, "Assignment transition constructor requires a block " +
95
+ "defining the assignment function!" unless block
96
+ world.Transition.send( :new,
97
+ codomain: codomain,
98
+ assignment: block,
99
+ **nn )
100
+ end
101
+
77
102
  # Timed transition constructor: Creates a new timed transition in the current
78
- # world. Rate closure has to be supplied as a block.
103
+ # world. Rate can be supplied either as +:rate+ named argument, or as a block.
104
+ # If none is supplied, rate argument defaults to 1.
79
105
  #
80
106
  def TT( *ordered, **named, &block )
81
107
  if named.has? :rate then
82
108
  fail ArgumentError, "Block must not be given if :rate named argument " +
83
109
  "is given!" if block
84
110
  else
85
- fail ArgumentError, "Timed transition constructor requires either " +
86
- "a :rate argument, or a block!" unless block
87
- named.update rate: block
111
+ named.update rate: block || 1 # default rate is 1
88
112
  end
89
113
  world.Transition.send( :new, *ordered, **named )
90
114
  end
@@ -101,7 +125,7 @@ module YPetri::Agent::PetriNetRelated
101
125
  args.update domain: nn.delete( :domain ) if nn.has? :domain
102
126
  else
103
127
  fail ArgumentError, "There must not be any ordered arguments if " +
104
- "named argument :domain is given!" unless domain.empty?
128
+ "named argument :domain is given!" if nn.has? :domain
105
129
  args.update domain: domain
106
130
  end
107
131
  args.update rate: nn.delete( :rate ) if nn.has? :rate, syn!: :rate_closure
@@ -148,4 +172,4 @@ module YPetri::Agent::PetriNetRelated
148
172
  def net_point= id
149
173
  net_point_reset id
150
174
  end
151
- end # module YPetri::Agent::PetriNetRelated
175
+ end # module YPetri::Agent::PetriNetAspect
@@ -1,9 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Agent instance methods related to simulation (initial marking collections,
4
- # clamp collections, initial marking collections, management of simulations...)
3
+ # Simulation aspect of +YPetri::Agent+: initial marking collections, clamp
4
+ # collections, initial marking collections, management of simulations...
5
5
  #
6
- module YPetri::Agent::SimulationRelated
6
+ module YPetri::Agent::SimulationAspect
7
7
  require_relative 'hash_key_pointer'
8
8
  require_relative 'selection'
9
9
 
@@ -118,9 +118,8 @@ module YPetri::Agent::SimulationRelated
118
118
  return nil
119
119
  end
120
120
 
121
- # Returns the simulation identified by the argument, or one at simulation
122
- # point, if no argument given. The simulation is identified in the same way
123
- # as for #simulation_point_to method.
121
+ # Returns the simulation identified by the argument. If no argument is given,
122
+ # returns the simulation at point.
124
123
  #
125
124
  def simulation *args
126
125
  return simulation_point.get if args.empty?
@@ -155,7 +154,7 @@ module YPetri::Agent::SimulationRelated
155
154
  end
156
155
  alias ssc simulation_settings_collection
157
156
 
158
- # FIXME: This is going to be tested
157
+ # FIXME: This is not tested yet.
159
158
 
160
159
  def clamp clamp_hash
161
160
  clamp_hash.each_pair do |place, clamp|
@@ -265,75 +264,91 @@ module YPetri::Agent::SimulationRelated
265
264
  # Plot the recording reduced into the given feature set.
266
265
  #
267
266
  def plot features
268
- ff = simulation.net.state.features( features )
267
+ ff = simulation.net.State.Features( features )
269
268
  simulation.recording.reduce_features( ff ).plot
270
269
  end
271
270
 
272
271
  # Plot system state history.
273
272
  #
274
- def plot_marking( place_ids=nil, except: [],
273
+ def plot_marking( places=nil, except: [],
275
274
  title: "State plot", ylabel: "Marking [µM]",
276
275
  **options )
277
276
  rec = simulation.recording
278
- pp = simulation.pp( place_ids ) - simulation.pp( except )
279
- rec.marking( pp ).plot( title: title, ylabel: ylabel, **options )
277
+ pp = simulation.pp( *places ) - simulation.Pp( except )
278
+ rec.Marking( pp ).plot( title: title, ylabel: ylabel, **options )
280
279
  end
281
280
  alias plot_state plot_marking
282
281
 
283
282
  # Plot flux history of TS transitions.
284
283
  #
285
- def plot_flux( transition_ids=nil, except: [],
284
+ def plot_flux( transitions=nil, except: [],
286
285
  title: "Flux plot", ylabel: "Flux [µM.s⁻¹]",
287
286
  **options )
288
287
  rec = simulation.recording
289
- tt = transition_ids.nil? ? simulation.TS_tt : transition_ids
290
- tt = simulation.TS_tt( tt )
291
- tt -= simulation.tt( except )
292
- rec.flux( tt ).plot( title: title, ylabel: ylabel, **options )
288
+ tt = simulation.TS_tt( *transitions ) - simulation.Tt( except )
289
+ rec.Flux( tt ).plot( title: title, ylabel: ylabel, **options )
293
290
  end
294
291
 
295
292
  # Plot firing history of tS transitions.
296
293
  #
297
- def plot_firing( transition_ids=nil, except: [],
294
+ def plot_firing( transitions=nil, except: [],
298
295
  title: "Firing plot", ylabel: "Firing [µM]",
299
296
  **options )
300
297
  rec = simulation.recording
301
- tt = transition_ids.nil? ? simulation.tS_tt : transition_ids
302
- tt = simulation.tS_tt( tt )
303
- tt -= simulation.tt( except )
304
- rec.firing( tt ).plot( title: title, ylabel: ylabel, **options )
298
+ tt = simulation.tS_tt( *transitions ) - simulation.Tt( except )
299
+ rec.Firing( tt ).plot( title: title, ylabel: ylabel, **options )
305
300
  end
306
301
 
307
302
  # Plot gradient history of selected places with respect to a set of T
308
303
  # transitions.
309
304
  #
310
- def plot_gradient( place_ids=nil, except: [], transitions: nil,
305
+ def plot_gradient( places=nil, except: [], transitions: nil,
311
306
  title: "Gradient plot", ylabel: "Gradient [µM.s⁻¹]",
312
307
  **options )
313
308
  rec = simulation.recording
314
- pp = simulation.pp( place_ids ) - simulation.ee( place_ids )
315
- tt = transitions.nil? ? simulation.T_tt : transitions
316
- tt = simulation.T_tt( tt )
317
- tt -= simulation.ee( except )
318
- rec.gradient( pp, transitions: tt )
309
+ pp = simulation.pp( *places ) - simulation.Nn( except )
310
+ tt = simulation.T_tt( *transitions ) - simulation.Nn( except )
311
+ rec.Gradient( pp, transitions: tt )
319
312
  .plot( title: title, ylabel: ylabel, **options )
320
313
  end
321
314
 
322
315
  # Plot delta history of selected places with respect to a set of transitions.
323
316
  #
324
- def plot_delta( place_ids=nil, except: [], transitions: nil,
317
+ def plot_delta( places=nil, except: [], transitions: nil,
325
318
  title: "Delta plot", ylabel: "Delta [µM]",
326
319
  **options )
327
320
  options.may_have :delta_time, syn!: :Δt
328
321
  rec = simulation.recording
329
- pp = simulation.pp( place_ids ) - simulation.ee( except )
330
- tt = transitions.nil? ? simulation.tt : transitions
331
- tt = simulation.tt( tt )
332
- tt -= simulation.ee( except )
333
- rec.delta( pp, transitions: tt, Δt: options[:delta_time] )
322
+ pp = simulation.pp( *places ) - simulation.Nn( except )
323
+ tt = simulation.tt( *transitions ) - simulation.Nn( except )
324
+ simulation.recording.Delta( pp, transitions: tt, Δt: options[:delta_time] )
334
325
  .plot( title: title, ylabel: ylabel, **options )
335
326
  end
336
327
 
328
+ # Save a file.
329
+ #
330
+ def save_file f, txt
331
+ File.open( f, 'w' ) { |f| f.write "txt" }
332
+ end
333
+
334
+ # Load a file
335
+ #
336
+ def load_file f
337
+ rr = []
338
+ CSV.parse( File.open( f ), headers: true ) { |row|
339
+ rr << row
340
+ }
341
+ r1 = rr.first.to_hash.with_keys { |k| eval k }.with_values { |v| eval v }
342
+ ff = world.net.State.Features( r1.keys[ 1..-1 ] )
343
+ dataset = ff.DataSet.new
344
+ rr.each { |row|
345
+ r = row.to_hash.with_keys { |k| eval k }.with_values { |v| eval v }
346
+ event = r.delete :event
347
+ dataset[ event ] = ff.r.values
348
+ }
349
+ return dataset
350
+ end
351
+
337
352
  # # Pretty print marking of the current simulation.
338
353
  # #
339
354
  # def marking
@@ -367,4 +382,4 @@ module YPetri::Agent::SimulationRelated
367
382
  # tt = transitions.nil? ? simulation.tt : transitions
368
383
  # simulation.delta( place_id, except: except, transitions: transitions )
369
384
  # end
370
- end # module YPetri::Agent::SimulationRelated
385
+ end # module YPetri::Agent::SimulationAspect
data/lib/y_petri/agent.rb CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  require_relative 'agent/selection'
4
4
  require_relative 'agent/hash_key_pointer'
5
- require_relative 'agent/petri_net_related'
6
- require_relative 'agent/simulation_related'
5
+ require_relative 'agent/petri_net_aspect'
6
+ require_relative 'agent/simulation_aspect'
7
7
 
8
- # Public command interface of YPetri.
8
+ # A dumb agent that represents and helps the user.
9
9
  #
10
10
  class YPetri::Agent
11
- PetriNetRelated # ★ means include
12
- SimulationRelated
11
+ PetriNetAspect # ★ means include
12
+ SimulationAspect
13
13
 
14
14
  attr_reader :world
15
15
 
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ # Guarded simulation mixin – not working yet.
4
+ #
5
+ module YPetri::Core::Guarded
6
+ # Guarded version of the method.
7
+ #
8
+ def increment_marking_vector( delta )
9
+ try "to update marking" do
10
+ super( note( "Δ state if tS transitions fire once",
11
+ is: Δ_if_tS_fire_once ) +
12
+ note( "Δ state if tsa transitions fire once",
13
+ is: Δ_if_tsa_fire_once ) )
14
+ end
15
+ end
16
+
17
+ # Guarded version of the method.
18
+ #
19
+ def A_all_fire!
20
+ try "to fire the assignment transitions" do
21
+ super
22
+ end
23
+ end
24
+ end # module YPetri::Core::Guarded
@@ -1,15 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Euler method.
3
+ # Euler method. Assumes that only T transitions are in the net.
4
4
  #
5
5
  module YPetri::Core::Timed::Euler
6
- # Name of this method.
7
- #
8
- def simulation_method
9
- :euler
10
- end
11
-
12
- # Computes Δ for the period of Δt.
6
+ # Computes Δ for the period of Δt. Since this method assumes that only
7
+ # timed transitions are in the net, delta state is computed simply bu
8
+ # multiplying the gradient by Δt.
13
9
  #
14
10
  def delta Δt
15
11
  gradient * Δt
@@ -2,18 +2,17 @@
2
2
 
3
3
  # Plain Gillespie algorithm.
4
4
  #
5
- # The characteristic of the Gillespie method is, that it does not work starting
6
- # from Δt towards Δstate. Instead, it makes a random choice weighted by the
7
- # transition propensities, and the random choice determines both the next timed
8
- # transition to fire, and the size of Δt to slice off from the time axis.
5
+ # The distinguishing quality of Gillespie method is, that it does not work from
6
+ # from Δt towards Δstate. Instead, it makes a random choice of the transition to
7
+ # fire (weighted by the transition propensities) and a random choice of Δt. Both
8
+ # next transition to fire, and the size of Δt to slice off from the time axis are
9
+ # thus stochastically determined.
9
10
  #
10
11
  module YPetri::Core::Timed::Gillespie
11
- attr_reader :rng
12
-
13
- # Gillespie method initialization.
12
+ # Returns a random number generator, only created once.
14
13
  #
15
- def initialize
16
- @rng = ::Random
14
+ def rng
15
+ @rng ||= ::Random
17
16
  end
18
17
 
19
18
  # Makes a stochastic number of Gillespie steps necessary to span the period Δt.
@@ -25,7 +24,7 @@ module YPetri::Core::Timed::Gillespie
25
24
  update_next_gillespie_time( propensities )
26
25
  until ( @next_gillespie_time > target_time )
27
26
  gillespie_step! propensities
28
- simulation.recorder.alert
27
+ simulation.recorder.alert!
29
28
  propensities = propensity_vector_TS.column_to_a
30
29
  update_next_gillespie_time( propensities )
31
30
  end
@@ -33,12 +32,6 @@ module YPetri::Core::Timed::Gillespie
33
32
  print '.'
34
33
  end
35
34
 
36
- # Name of this method.
37
- #
38
- def simulation_method
39
- :gillespie
40
- end
41
-
42
35
  # This method updates next firing time given propensities.
43
36
  #
44
37
  def update_next_gillespie_time( propensities )
@@ -57,7 +50,8 @@ module YPetri::Core::Timed::Gillespie
57
50
  #
58
51
  def gillespie_delta_time( propensities )
59
52
  sum = Σ propensities
60
- mean_period = 1 / sum
53
+ # mean_period = 1 / sum # TODO: This line seem to be useless
54
+ # Exponential distribution
61
55
  Distribution::Exponential.p_value( rng.rand, sum )
62
56
  end
63
57
 
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ # Timed simulation core.
4
+ #
5
+ module YPetri::Core::Timed
6
+ require_relative 'euler'
7
+ require_relative 'pseudo_euler' # t transitions firing after each step
8
+ require_relative 'quasi_euler' # t transitions firing after each time tick
9
+ require_relative 'gillespie'
10
+ require_relative 'runge_kutta'
11
+
12
+ module Methods
13
+ def method_init
14
+ extend case simulation_method
15
+ when :euler then Euler
16
+ when :pseudo_euler then PseudoEuler
17
+ when :quasi_euler then QuasiEuler
18
+ when :gillespie then Gillespie
19
+ when :runge_kutta then RungeKutta
20
+ else fail TypeError, "Unknown timed simulation method: #{method}!" end
21
+ end
22
+ end
23
+ end
@@ -1,29 +1,26 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Euler method with timeless transitions firing after each step.
3
+ # Adaptation of Euler method for the systems possibly with timeless transitions
4
+ # and assignment transitions.
4
5
  #
5
6
  module YPetri::Core::Timed::PseudoEuler
6
- include YPetri::Core::Timed::Euler
7
-
8
- # Name of this method.
9
- #
10
- def simulation_method
11
- :pseudo_euler
12
- end
13
-
14
- # Computes Δ for the period of Δt.
7
+ # Computes Δ for the period of Δt. Its result is a sum of the contribution of
8
+ # timed transitions over the period Δt and the contribution of timeless
9
+ # transitions as if each fired once.
15
10
  #
16
11
  def delta Δt
17
- super + delta_timeless
12
+ gradient * Δt + delta_timeless
18
13
  end
19
14
  alias Δ delta
20
15
 
21
- # Makes a single step by Δt.
16
+ # Makes a single step by Δt. Computes system delta, increments marking vector
17
+ # by it. On top of that, fires all A transitions, increments the simulation
18
+ # time and alerts the sampler that the system has changed.
22
19
  #
23
20
  def step! Δt=simulation.step
24
21
  increment_marking_vector Δ( Δt )
25
22
  assignment_transitions_all_fire!
26
23
  simulation.increment_time! Δt
27
- alert
24
+ alert! # alerts the sampler that the system has changed
28
25
  end
29
26
  end # YPetri::Core::Timed::PseudoEuler
@@ -1,20 +1,21 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Euler method with timeless transitions firing every time tick.
3
+ # Adaptation of Euler method for the systems possibly with timeless transitions
4
+ # and assignment transitions. Unlike +pseudo_euler+, which fires every step,
5
+ # +quasi_euler+ fires every time tick. Not implemented yet.
4
6
  #
5
7
  module YPetri::Core::Timed::QuasiEuler
6
- include YPetri::Core::Timed::Euler
7
-
8
- # Name of this method.
8
+ # Computes Δ for the period of Δt. Not mplemented yet.
9
9
  #
10
- def simulation_method
11
- :quasi_euler
10
+ def delta Δt
11
+ fail NotImplementedError, "QuasiEuler not implemented yet!"
12
12
  end
13
13
 
14
- # Makes a single step by Δt.
14
+
15
+ # Makes a single step by Δt. Not implemented yet.
15
16
  #
16
17
  def step! Δt=simulation.step_size
17
- fail NotImplementedError
18
+ fail NotImplementedError, "QuasiEuler not implemented yet!"
18
19
  # Now one would have to compare whichever comes first, time tick or the
19
20
  # end of Δt, and then again and again, until Δt is fired...
20
21
  end
@@ -1,22 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Gillespie method.
3
+ # Runge-Kutta method. Like vanilla Euler method, assumes that only T transitions are in the net.
4
4
  #
5
- module YPetri::Core::Timed::Euler
6
- # Name of this method.
7
- #
8
- def simulation_method
9
- :runge_kutta
5
+ module YPetri::Core::Timed::RungeKutta
6
+ def delta Δt
7
+ fail NotImplementedError, "RungeKutta not implemented yet!"
8
+ # Of course, the following line is from Euler method.
9
+ # The formula of Runge-Kutta is more complicated.
10
+ #
11
+ gradient * Δt
10
12
  end
11
-
12
- # FIXME
13
-
14
- # This is from Euler:
15
-
16
- # # Computes Δ for the period of Δt.
17
- # #
18
- # def delta Δt
19
- # gradient * Δt
20
- # end
21
- # alias Δ delta
22
- end # YPetri::Core::Timed::Euler
13
+ alias Δ delta
14
+ end # YPetri::Core::Timed::RungeKutta
@@ -2,18 +2,10 @@
2
2
 
3
3
  # Timed simulation core.
4
4
  #
5
- class YPetri::Core::Timed < YPetri::Core
6
- # Euler method.
7
- require_relative 'timed/euler'
8
- # Euler with timeless transitions firing after each step.
9
- require_relative 'timed/pseudo_euler'
10
- # Euler with timeless transitions firing each time tick.
11
- require_relative 'timed/quasi_euler'
12
- # Gillespie stochastic method.
13
- require_relative 'timed/gillespie'
14
- # Runge-Kutta fifth-order method.
15
- require_relative 'timed/runge_kutta'
16
-
5
+ module YPetri::Core::Timed
6
+ require_relative 'timed/methods'
7
+ Methods
8
+
17
9
  # Makes a single step by Δt.
18
10
  #
19
11
  def step! Δt=simulation.step
@@ -57,9 +49,9 @@ class YPetri::Core::Timed < YPetri::Core
57
49
  simulation.TS_rate_closure.call
58
50
  end
59
51
  alias propensity_vector_TS flux_vector_TS
60
- end # class YPetri::Core::Timed
52
+ end # module YPetri::Core::Timed
61
53
 
62
- # In general, it is not required that all net elements are simulated with the
54
+ # In general, it is not required that all net nodes are simulated with the
63
55
  # same method. Practically, ODE systems have many good simulation methods
64
56
  # available.
65
57
  #
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ # Timed simulation core.
4
+ #
5
+ module YPetri::Core::Timeless
6
+ require_relative 'pseudo_euler'
7
+
8
+ module Methods
9
+ def method_init
10
+ extend case simulation_method
11
+ when :pseudo_euler then PseudoEuler
12
+ else fail TypeError, "Unknown timeless simulation method: #{method}!" end
13
+ end
14
+ end
15
+ end
@@ -1,18 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Implicit Euler for timeless nets. Simply, timeless transitions
4
- # fire simultaneously, after which A transitions (if any) fire.
3
+ # Implicit Euler for timeless nets.
5
4
  #
6
5
  module YPetri::Core::Timeless::PseudoEuler
7
- # Name of this method.
6
+ # Method #step! for timeless +pseudo_euler+ method. Simply, timeless
7
+ # transitions fire simultaneously, after which, A transitions (if any) fire.
8
8
  #
9
- def simulation_method
10
- :pseudo_euler
11
- end
12
-
13
9
  def step!
14
10
  increment_marking_vector Δ
15
11
  assignment_transitions_all_fire!
16
- alert
12
+ alert!
17
13
  end
18
14
  end # module YPetri::Core::Timeless::PseudoEuler
@@ -1,15 +1,20 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Timeless simulation core.
3
+ # Timeless simulator mixin.
4
4
  #
5
- class YPetri::Core::Timeless < YPetri::Core
6
- require_relative 'timeless/pseudo_euler'
5
+ module YPetri::Core::Timeless
6
+ require_relative 'timeless/methods'
7
+ ★ Methods
7
8
 
9
+ # Makes a single step.
10
+ #
8
11
  def delta
9
12
  delta_timeless
10
13
  end
11
14
 
15
+ # Computes the system state delta.
16
+ #
12
17
  def Δ
13
18
  delta
14
19
  end
15
- end # class YPetri::Core::Timeless
20
+ end # module YPetri::Core::Timeless