y_petri 2.0.15 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/lib/y_petri/{manipulator → agent}/hash_key_pointer.rb +2 -2
  3. data/lib/y_petri/agent/petri_net_related.rb +115 -0
  4. data/lib/y_petri/{manipulator → agent}/selection.rb +2 -1
  5. data/lib/y_petri/{manipulator/simulation_related_methods.rb → agent/simulation_related.rb} +93 -110
  6. data/lib/y_petri/agent.rb +22 -0
  7. data/lib/y_petri/core/timed/euler.rb +20 -0
  8. data/lib/y_petri/core/timed/pseudo_euler.rb +31 -0
  9. data/lib/y_petri/core/timed/quasi_euler.rb +23 -0
  10. data/lib/y_petri/core/timed.rb +70 -0
  11. data/lib/y_petri/core/timeless/pseudo_euler.rb +20 -0
  12. data/lib/y_petri/core/timeless.rb +12 -0
  13. data/lib/y_petri/core.rb +100 -0
  14. data/lib/y_petri/dsl.rb +66 -0
  15. data/lib/y_petri/fixed_assets.rb +7 -0
  16. data/lib/y_petri/net/element_access.rb +239 -0
  17. data/lib/y_petri/net/state/feature/delta.rb +88 -0
  18. data/lib/y_petri/net/state/feature/firing.rb +57 -0
  19. data/lib/y_petri/net/state/feature/flux.rb +58 -0
  20. data/lib/y_petri/net/state/feature/gradient.rb +75 -0
  21. data/lib/y_petri/net/state/feature/marking.rb +62 -0
  22. data/lib/y_petri/net/state/feature.rb +79 -0
  23. data/lib/y_petri/net/state/features/dataset.rb +135 -0
  24. data/lib/y_petri/net/state/features/record.rb +50 -0
  25. data/lib/y_petri/net/state/features.rb +126 -0
  26. data/lib/y_petri/net/state.rb +121 -0
  27. data/lib/y_petri/net/timed.rb +8 -0
  28. data/lib/y_petri/net/visualization.rb +3 -3
  29. data/lib/y_petri/net.rb +73 -77
  30. data/lib/y_petri/place.rb +8 -3
  31. data/lib/y_petri/simulation/dependency.rb +107 -0
  32. data/lib/y_petri/simulation/element_representation.rb +20 -0
  33. data/lib/y_petri/simulation/elements/access.rb +57 -0
  34. data/lib/y_petri/simulation/elements.rb +45 -0
  35. data/lib/y_petri/simulation/feature_set.rb +21 -0
  36. data/lib/y_petri/simulation/initial_marking/access.rb +55 -0
  37. data/lib/y_petri/simulation/initial_marking.rb +15 -0
  38. data/lib/y_petri/simulation/marking_clamps/access.rb +34 -0
  39. data/lib/y_petri/simulation/marking_clamps.rb +18 -0
  40. data/lib/y_petri/simulation/marking_vector/access.rb +106 -0
  41. data/lib/y_petri/simulation/marking_vector.rb +156 -0
  42. data/lib/y_petri/simulation/matrix.rb +64 -0
  43. data/lib/y_petri/simulation/place_mapping.rb +62 -0
  44. data/lib/y_petri/simulation/place_representation.rb +74 -0
  45. data/lib/y_petri/simulation/places/access.rb +121 -0
  46. data/lib/y_petri/simulation/places/clamped.rb +8 -0
  47. data/lib/y_petri/simulation/places/free.rb +8 -0
  48. data/lib/y_petri/simulation/places/types.rb +25 -0
  49. data/lib/y_petri/simulation/places.rb +41 -0
  50. data/lib/y_petri/simulation/recorder.rb +54 -0
  51. data/lib/y_petri/simulation/timed/recorder.rb +53 -0
  52. data/lib/y_petri/simulation/timed.rb +161 -261
  53. data/lib/y_petri/simulation/timeless/recorder.rb +25 -0
  54. data/lib/y_petri/simulation/timeless.rb +35 -0
  55. data/lib/y_petri/simulation/transition_representation/A.rb +58 -0
  56. data/lib/y_petri/simulation/transition_representation/S.rb +45 -0
  57. data/lib/y_petri/simulation/transition_representation/T.rb +80 -0
  58. data/lib/y_petri/simulation/transition_representation/TS.rb +46 -0
  59. data/lib/y_petri/simulation/transition_representation/Ts.rb +32 -0
  60. data/lib/y_petri/simulation/transition_representation/a.rb +30 -0
  61. data/lib/y_petri/simulation/transition_representation/s.rb +29 -0
  62. data/lib/y_petri/simulation/transition_representation/t.rb +37 -0
  63. data/lib/y_petri/simulation/transition_representation/tS.rb +38 -0
  64. data/lib/y_petri/simulation/transition_representation/ts.rb +32 -0
  65. data/lib/y_petri/simulation/transition_representation/types.rb +62 -0
  66. data/lib/y_petri/simulation/transition_representation.rb +79 -0
  67. data/lib/y_petri/simulation/transitions/A.rb +40 -0
  68. data/lib/y_petri/simulation/transitions/S.rb +24 -0
  69. data/lib/y_petri/simulation/transitions/T.rb +34 -0
  70. data/lib/y_petri/simulation/transitions/TS.rb +57 -0
  71. data/lib/y_petri/simulation/transitions/Ts.rb +60 -0
  72. data/lib/y_petri/simulation/transitions/a.rb +8 -0
  73. data/lib/y_petri/simulation/transitions/access.rb +186 -0
  74. data/lib/y_petri/simulation/transitions/s.rb +9 -0
  75. data/lib/y_petri/simulation/transitions/t.rb +22 -0
  76. data/lib/y_petri/simulation/transitions/tS.rb +55 -0
  77. data/lib/y_petri/simulation/transitions/ts.rb +58 -0
  78. data/lib/y_petri/simulation/transitions/types.rb +98 -0
  79. data/lib/y_petri/simulation/transitions.rb +21 -0
  80. data/lib/y_petri/simulation.rb +176 -781
  81. data/lib/y_petri/transition/assignment.rb +7 -5
  82. data/lib/y_petri/transition/construction.rb +119 -187
  83. data/lib/y_petri/transition/init.rb +311 -0
  84. data/lib/y_petri/transition/ordinary_timeless.rb +8 -6
  85. data/lib/y_petri/transition/timed.rb +11 -18
  86. data/lib/y_petri/transition.rb +104 -132
  87. data/lib/y_petri/version.rb +1 -1
  88. data/lib/y_petri/world/dependency.rb +40 -0
  89. data/lib/y_petri/world/petri_net_related.rb +61 -0
  90. data/lib/y_petri/{workspace/simulation_related_methods.rb → world/simulation_related.rb} +42 -49
  91. data/lib/y_petri/world.rb +27 -0
  92. data/lib/y_petri.rb +47 -99
  93. data/test/{manipulator_test.rb → agent_test.rb} +19 -17
  94. data/{lib/y_petri → test/examples}/demonstrator.rb +0 -0
  95. data/{lib/y_petri → test/examples}/demonstrator_2.rb +1 -0
  96. data/{lib/y_petri → test/examples}/demonstrator_3.rb +0 -0
  97. data/{lib/y_petri → test/examples}/demonstrator_4.rb +0 -0
  98. data/test/examples/example_2.rb +16 -0
  99. data/test/{manual_examples.rb → examples/manual_examples.rb} +0 -0
  100. data/test/net_test.rb +126 -121
  101. data/test/place_test.rb +1 -1
  102. data/test/sim_test +565 -0
  103. data/test/simulation_test.rb +338 -264
  104. data/test/transition_test.rb +77 -174
  105. data/test/world_mock.rb +12 -0
  106. data/test/{workspace_test.rb → world_test.rb} +19 -20
  107. data/test/y_petri_test.rb +4 -5
  108. metadata +101 -26
  109. data/lib/y_petri/dependency_injection.rb +0 -45
  110. data/lib/y_petri/manipulator/petri_net_related_methods.rb +0 -74
  111. data/lib/y_petri/manipulator.rb +0 -20
  112. data/lib/y_petri/net/selections.rb +0 -209
  113. data/lib/y_petri/simulation/collections.rb +0 -460
  114. data/lib/y_petri/workspace/parametrized_subclassing.rb +0 -22
  115. data/lib/y_petri/workspace/petri_net_related_methods.rb +0 -88
  116. data/lib/y_petri/workspace.rb +0 -16
  117. data/test/timed_simulation_test.rb +0 -153
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c819010da78d8924cb320612edc32744c5d745a
4
- data.tar.gz: f3320f25920735b13fa67be3793fa3dd768915fc
3
+ metadata.gz: 2b031424367891fe4ff8af4b6c61afb984f5d341
4
+ data.tar.gz: adb9f8df5d999a60beff42aa1f69fa9aed7f0a7a
5
5
  SHA512:
6
- metadata.gz: e65d106f512773919f4fcf810927ac7f61c8c0e50c0faeea4b23c7671b2ae175a770ef8ce4da9d08366eb14b55e021b7949965b9c55de7f86f501d8f25128561
7
- data.tar.gz: 834d55aeb5103d792a2ff8370352802278815fea76c6286bb465e59973a9e9166c24bce73309d20da1ca85303581cf0ac5cfc015c763f26a3287024dcbc37cdc
6
+ metadata.gz: ed934ecfc8a78e32d65b8174fee3eedab5ee969ae857b847698581ca3b33e002a4ead151e361caa2d14593efaf44d3d8b04b49f4c286f2a72173bd36c1314a25
7
+ data.tar.gz: c4fabc8dcf91e509e249dab7e0af4afb97ec2dc8d2b93b5bd18936e408915913e96ef45eb53756b34767257dff0d842194af6a992354e68f183facbad3b05f15
@@ -1,7 +1,7 @@
1
1
  # Represents a pointer to a key of a specific hash associated with the pointer
2
- # instance. Used to implement pointers of the Manipulator class.
2
+ # instance. Used to implement pointers of the Agent class.
3
3
  #
4
- class YPetri::Manipulator::HashKeyPointer
4
+ class YPetri::Agent::HashKeyPointer
5
5
  # Key at which the pointer points.
6
6
  #
7
7
  attr_reader :key
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+
3
+ # Public command interface of YPetri.
4
+ #
5
+ module YPetri::Agent::PetriNetRelated
6
+ # Net selection class.
7
+ #
8
+ NetSelection = Class.new YPetri::Agent::Selection
9
+
10
+ # Net point
11
+ #
12
+ attr_reader :net_point
13
+
14
+ # Net selection.
15
+ #
16
+ attr_reader :net_selection
17
+
18
+ def initialize
19
+ net_point_reset
20
+ @net_selection = NetSelection.new
21
+ super
22
+ end
23
+
24
+ # Elements and selections:
25
+ #
26
+ delegate :place, :transition, :element,
27
+ :nets, :places, :transitions,
28
+ to: :world
29
+
30
+ # Place name.
31
+ #
32
+ def pl( place_id )
33
+ place( place_id ).name
34
+ end
35
+
36
+ # Transition name.
37
+ #
38
+ def tr( transition_id )
39
+ transition( transition_id ).name
40
+ end
41
+
42
+ # Place names.
43
+ #
44
+ def pn
45
+ places.names
46
+ end
47
+
48
+ # Transition names.
49
+ #
50
+ def tn
51
+ transitions.names
52
+ end
53
+
54
+ # Net names.
55
+ #
56
+ def nn
57
+ nets.names
58
+ end
59
+
60
+ # Place constructor: Creates a new place in the current world.
61
+ #
62
+ def Place( *ordered_args, **named_args, &block )
63
+ fail ArgumentError, "If block is given, :guard named argument " +
64
+ "must not be given!" if named_args.has? :guard if block
65
+ named_args.update( guard: block ) if block # use block as a guard
66
+ named_args.may_have :default_marking, syn!: :m!
67
+ named_args.may_have :marking, syn!: :m
68
+ world.Place.new *ordered_args, **named_args
69
+ end
70
+
71
+ # Transition constructor: Creates a new transition in the current world.
72
+ #
73
+ def Transition( *ordered, **named, &block )
74
+ world.Transition.new *ordered, **named, &block
75
+ end
76
+
77
+ # Timed transition constructor: Creates a new timed transition in the current
78
+ # world. Rate closure has to be supplied as a block.
79
+ #
80
+ def T( *ordered, **named, &block )
81
+ world.Transition.new *ordered, **named.update( rate: block )
82
+ end
83
+
84
+ # Assignment transition constructor: Creates a new assignment transition in
85
+ # the current world. Assignment closure has to be supplied as a block.
86
+ #
87
+ def A( *ordered, **named, &block )
88
+ world.Transition.new *ordered,
89
+ **named.update( assignment: true, action: block )
90
+ end
91
+
92
+ # Net constructor: Creates a new Net instance in the current world.
93
+ #
94
+ def Net *ordered, **named, &block
95
+ world.Net.new *ordered, **named, &block
96
+ end
97
+
98
+ # Returns the net identified, or the net at point (if no argument given).
99
+ #
100
+ def net id=nil
101
+ id.nil? ? @net_point : world.net( id )
102
+ end
103
+
104
+ # Sets the net point to a given net, or to world.Net::Top if none given.
105
+ #
106
+ def net_point_reset id=world.Net::Top
107
+ @net_point = world.net( id )
108
+ end
109
+
110
+ # Sets net point to a given net.
111
+ #
112
+ def net_point= id
113
+ net_point_reset id
114
+ end
115
+ end # module YPetri::Agent::PetriNetRelated
@@ -1,4 +1,5 @@
1
- class YPetri::Manipulator::Selection
1
+ class YPetri::Agent::Selection
2
+ # TODO: This calls for refactor as Array subclass.
2
3
  def initialize
3
4
  clear
4
5
  end
@@ -1,32 +1,34 @@
1
- # -*- coding: utf-8 -*-
2
- # Manipulator instance methods related to simulation (initial marking
3
- # collections, clamp collections, initial marking collections, management
4
- # of simulations...)
1
+ # encoding: utf-8
2
+
3
+ # Agent instance methods related to simulation (initial marking collections,
4
+ # clamp collections, initial marking collections, management of simulations...)
5
5
  #
6
- module YPetri::Manipulator::SimulationRelatedMethods
6
+ module YPetri::Agent::SimulationRelated
7
7
  require_relative 'hash_key_pointer'
8
8
  require_relative 'selection'
9
9
 
10
10
  # Simulation selection class.
11
11
  #
12
- SimulationSelection = Class.new YPetri::Manipulator::Selection
12
+ SimulationSelection = YPetri::Agent::Selection.parametrize agent: self
13
13
 
14
14
  # Simulation settings collection selection class.
15
15
  #
16
- SscSelection = Class.new YPetri::Manipulator::Selection
16
+ SscSelection = YPetri::Agent::Selection.parametrize agent: self
17
17
 
18
18
  # Clamp collection selection class.
19
19
  #
20
- CcSelection = Class.new YPetri::Manipulator::Selection
20
+ CcSelection = YPetri::Agent::Selection.parametrize agent: self
21
21
 
22
22
  # Initial marking collection selection class.
23
23
  #
24
- ImcSelection = Class.new YPetri::Manipulator::Selection
24
+ ImcSelection = YPetri::Agent::Selection.parametrize agent: self
25
25
 
26
- class SimulationPoint < YPetri::Manipulator::HashKeyPointer
26
+ class SimulationPoint < YPetri::Agent::HashKeyPointer
27
27
  # Reset to the first simulation, or nil if that is absent.
28
28
  #
29
- def reset; @key = @hash.empty? ? nil : set( @hash.first[0] ) end
29
+ def reset
30
+ @key = @hash.empty? ? nil : set( @hash.first[0] )
31
+ end
30
32
 
31
33
  # A simulation is identified either by its name (if named), or by its
32
34
  # parameters and settings (:net, :cc, :imc, :ssc).
@@ -47,19 +49,24 @@ module YPetri::Manipulator::SimulationRelatedMethods
47
49
 
48
50
  # Pointer to a collection of simulation settings.
49
51
  #
50
- SscPoint = Class.new YPetri::Manipulator::HashKeyPointer
52
+ SscPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
51
53
 
52
54
  # Pointer to a clamp collection.
53
55
  #
54
- CcPoint = Class.new YPetri::Manipulator::HashKeyPointer
56
+ CcPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
55
57
 
56
58
  # Pointer to a collection of initial markings.
57
59
  #
58
- ImcPoint = Class.new YPetri::Manipulator::HashKeyPointer
60
+ ImcPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
59
61
 
60
- attr_reader :simulation_point, :ssc_point, :cc_point, :imc_point,
61
- :simulation_selection, :ssc_selection,
62
- :cc_selection, :imc_selection
62
+ attr_reader :simulation_point,
63
+ :ssc_point,
64
+ :cc_point,
65
+ :imc_point,
66
+ :simulation_selection,
67
+ :ssc_selection,
68
+ :cc_selection,
69
+ :imc_selection
63
70
 
64
71
  def initialize
65
72
  # set up this manipulator's pointers
@@ -83,20 +90,20 @@ module YPetri::Manipulator::SimulationRelatedMethods
83
90
  super
84
91
  end
85
92
 
86
- # Simulation-related methods delegated to the workspace.
93
+ # Simulation-related methods delegated to the world.
87
94
  delegate :simulations,
88
95
  :clamp_collections,
89
96
  :initial_marking_collections,
90
97
  :simulation_settings_collections,
91
- :clamp_collection_names, :cc_names,
92
- :initial_marking_collection_names, :imc_names,
93
- :simulation_settings_collection_names, :ssc_names,
94
- :set_clamp_collection, :set_cc,
95
- :set_initial_marking_collection, :set_imc,
98
+ :clamp_collection_names, :ncc,
99
+ :initial_marking_collection_names, :nimc,
100
+ :simulation_settings_collection_names, :nssc,
101
+ :set_clamp_collection, :ncc,
102
+ :set_initial_marking_collection, :nimc,
96
103
  :set_simulation_settings_collection, :set_ssc,
97
- :new_timed_simulation,
104
+ :new_simulation,
98
105
  :clamp_cc, :initial_marking_cc, :simulation_settings_cc,
99
- to: :workspace
106
+ to: :world
100
107
 
101
108
  # Returns the simulation identified by the argument, or one at simulation
102
109
  # point, if no argument given. The simulation is identified in the same way
@@ -107,10 +114,6 @@ module YPetri::Manipulator::SimulationRelatedMethods
107
114
  SimulationPoint.new( hash: simulations, hash_value_is: "simulation" ).get
108
115
  end
109
116
 
110
- # # TEMPORARY KLUGE - FIXME
111
- # #
112
- # def simulation; @workspace.simulations.values[-1] end
113
-
114
117
  # Returns identified clamp collection, or (if no argument given) one
115
118
  # corresponding to cc_point.
116
119
  #
@@ -143,7 +146,7 @@ module YPetri::Manipulator::SimulationRelatedMethods
143
146
 
144
147
  def clamp clamp_hash
145
148
  clamp_hash.each_pair do |place, clamp|
146
- clamp_collection.merge! workspace.place( place ) => clamp
149
+ clamp_collection.merge! world.place( place ) => clamp
147
150
  end
148
151
  end
149
152
 
@@ -151,7 +154,7 @@ module YPetri::Manipulator::SimulationRelatedMethods
151
154
  # field:
152
155
  # * No arguments: returns current imc
153
156
  # * Exactly one ordered argument: it is assumed to identify a place whose
154
- # im in teh current imc will be returned.
157
+ # im in the current imc will be returned.
155
158
  # * A hash: Assumed to be { place_id => im }, current imc is updated with it.
156
159
  # * One ordered argument, and a hash: The imc identified by the ordered
157
160
  # ordered arg is updated with the hash.
@@ -222,8 +225,8 @@ module YPetri::Manipulator::SimulationRelatedMethods
222
225
  # Create a new timed simulation and make it available in the simulations
223
226
  # table.
224
227
  #
225
- def new_timed_simulation *args, &block
226
- instance = workspace.new_timed_simulation( *args, &block )
228
+ def new_simulation *args, &block
229
+ instance = world.new_simulation( *args, &block )
227
230
  # Set the point to it
228
231
  simulation_point.set( simulations.rassoc( instance )[0] )
229
232
  return instance
@@ -232,43 +235,37 @@ module YPetri::Manipulator::SimulationRelatedMethods
232
235
  # Create a new timed simulation and run it.
233
236
  #
234
237
  def run!
235
- new_timed_simulation.run!
238
+ new_simulation.run!
236
239
  end
237
240
 
238
241
  # Write the recorded samples in a file (csv).
239
242
  #
240
- def print_recording( filename = nil )
243
+ def print_recording( filename=nil )
241
244
  if filename.nil? then
242
- puts simulation.recording_csv_string
245
+ puts simulation.recording.to_csv
243
246
  else
244
247
  File.open( filename, "w" ) do |f|
245
- f << simulation.recording_csv_string
248
+ f << simulation.recording.to_csv
246
249
  end
247
250
  end
248
251
  end
249
252
 
250
253
  # Plot the recorded samples.
251
254
  #
252
- def plot *args
253
- oo = args.extract_options!
254
- case args.size
255
- when 0 then plot_recording oo
256
- when 1 then
257
- plot_what = args[0]
258
- case plot_what
259
- when :state then plot_recording oo
260
- when :flux then plot_flux oo
261
- when :all then plot_all oo
262
- else plot_selected *args end
263
- else raise "Too many ordered arguments!" end
264
- end
255
+ def plot **features
256
+ # --> state feature ids
257
+ # --> gradient feature ids
258
+ # --> delta feature ids
259
+ # --> flux feature ids
260
+ # --> firing feature ids
265
261
 
266
- # Plot the selected features.
267
- #
268
- def plot_selected *args
269
- oo = args.extract_options!
270
- collection = Array args[0]
271
- return nil unless sim = @workspace.simulations.values[-1] # sim@point
262
+ # take these features together
263
+
264
+ # construct the labels and the time series for each
265
+
266
+ # plot them
267
+
268
+ return nil unless sim = world.simulations.values[-1] # sim@point
272
269
  # Decide abnout the features
273
270
  features = sim.places.dup.map { |p|
274
271
  collection.include?( p ) ? p : nil
@@ -285,82 +282,68 @@ module YPetri::Manipulator::SimulationRelatedMethods
285
282
  gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
286
283
  title: "Selected features plot", ylabel: "Marking" )
287
284
  end
288
-
289
285
 
290
286
  # Plot the recorded samples (system state history).
291
287
  #
292
- def plot_state( *args )
293
- oo = args.extract_options!
294
- excluded = Array oo[:except]
295
- return nil unless sim = @workspace.simulations.values[-1] # sim@point
296
- # Decide about the features to plot.
297
- features = excluded.each_with_object sim.places.dup do |x, α|
298
- i = α.index x
299
- α[i] = nil if i
300
- end
301
- # Get recording
302
- rec = sim.recording
303
- # Select a time series for each feature.
304
- time_series = features.map.with_index do |feature, i|
305
- feature and rec.map { |key, val| [ key, val[i] ] }.transpose
306
- end
307
- # Time axis
308
- ᴛ = sim.target_time
309
- # Gnuplot call
310
- gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
311
- title: "State plot", ylabel: "Marking" )
288
+ def plot_state( place_ids=nil, except: [] )
289
+ sim = simulation or return nil
290
+ feat = sim.pp( place_ids || sim.pp ) - sim.pp( Array except )
291
+ gnuplot sim.record.marking( feat ), time: sim.target_time,
292
+ title: "State plot", ylabel: "Marking"
312
293
  end
294
+ alias plot_marking plot_state
313
295
 
314
296
  # Plot the recorded flux (computed flux history at the sampling points).
315
297
  #
316
- def plot_flux( *args )
317
- oo = args.extract_options!
318
- excluded = Array oo[:except]
319
- return nil unless sim = @workspace.simulations.values[-1] # sim@point
320
- # Decide about the features to plot.
321
- all = sim.SR_transitions
322
- features = excluded.each_with_object all.dup do |x, α|
323
- i = α.index x
324
- if i then α[i] = nil end
298
+ def plot_flux( transition_ids=nil, **options )
299
+ sim = world.simulations.values[-1] or return nil # sim@point
300
+ tt = sim.TS_transitions( transition_ids ).sources
301
+ excluded = sim.transitions( Array options[:except] ).sources
302
+ tt -= excluded
303
+ flux = sim.recording.modify do |time, record|
304
+ [ time,
305
+ sim.at( time: time, marking: record ).TS_transitions( tt ).flux_vector ]
325
306
  end
326
- # Get recording.
327
- rec = sim.recording
328
- # Get flux recording.
329
- flux = rec.modify { |ᴛ, ᴍ| [ ᴛ, sim.at( t: ᴛ, m: ᴍ ).flux_for( *all ) ] }
330
307
  # Select a time series for each feature.
331
- time_series = features.map.with_index do |feature, i|
332
- feature and flux.map { |ᴛ, flux| [ ᴛ, flux[i] ] }.transpose
308
+ time_series = tt.map.with_index do |tr, i|
309
+ tr and flux.map { |time, flux| [ time, flux[i] ] }.transpose
333
310
  end
334
311
  # Time axis
335
- = sim.target_time
312
+ time = sim.target_time
336
313
  # Gnuplot call
337
- gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
314
+ gnuplot( time, tt.compact.names, time_series.compact,
338
315
  title: "Flux plot", ylabel: "Flux [µMⁿ.s⁻¹]" )
339
316
  end
340
317
 
341
318
  private
342
319
 
343
- # Gnuplots things.
320
+ # Gnuplots a recording. Target time or time range can be supplied as :time
321
+ # named argument.
344
322
  #
345
- def gnuplot( time, labels, time_series, *args )
346
- labels = labels.dup
347
- time_series = time_series.dup
348
- oo = args.extract_options!
323
+ def gnuplot( dataset, time: nil, **nn )
324
+ event_vector = dataset.events
325
+ data_vectors = dataset.values.transpose
326
+ x_range = if time.is_a? Range then
327
+ "[#{time.begin}:#{time.end}]"
328
+ else
329
+ "[-0:#{SY::Time.magnitude( time ).amount rescue time}]"
330
+ end
331
+ labels = recording.features.labels
349
332
 
350
333
  Gnuplot.open do |gp|
351
334
  Gnuplot::Plot.new( gp ) do |plot|
352
- plot.xrange "[-0:#{SY::Time.magnitude( time ).amount rescue time}]"
353
- plot.title oo[:title] || "Simulation plot"
354
- plot.ylabel oo[:ylabel] || "Values"
355
- plot.xlabel oo[:xlabel] || "Time [s]"
356
-
357
- labels.zip( time_series ).each { |label, series|
358
- plot.data << Gnuplot::DataSet.new( series ) do |data_series|
359
- data_series.with = "linespoints"
360
- data_series.title = label
361
- end
335
+ plot.xrange x_range
336
+ plot.title nn[:title] || "Simulation plot"
337
+ plot.ylabel nn[:ylabel] || "Values"
338
+ plot.xlabel nn[:xlabel] || "Time [s]"
339
+
340
+ labels.zip( data_vectors ).each { |label, data_vector|
341
+ plot.data << Gnuplot::DataSet.new( [event_vector, data_vector] ) { |ds|
342
+ ds.with = "linespoints"
343
+ ds.title = lbl
344
+ }
362
345
  }
363
346
  end
364
347
  end
365
348
  end
366
- end # module YPetri::Manipulator
349
+ end # module YPetri::Agent::SimulationRelated
@@ -0,0 +1,22 @@
1
+ #encoding: utf-8
2
+
3
+ # Public command interface of YPetri.
4
+ #
5
+ module YPetri
6
+ class Agent
7
+ attr_reader :world
8
+
9
+ def initialize
10
+ @world = YPetri::World.new
11
+ super
12
+ end
13
+
14
+ require_relative 'agent/selection'
15
+ require_relative 'agent/hash_key_pointer'
16
+ require_relative 'agent/petri_net_related'
17
+ require_relative 'agent/simulation_related'
18
+
19
+ include self::PetriNetRelated
20
+ include self::SimulationRelated
21
+ end # class Agent
22
+ end # module YPetri
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ # Euler method.
4
+ #
5
+ class YPetri::Core::Timed
6
+ module Euler
7
+ # Name of this method.
8
+ #
9
+ def simulation_method
10
+ :euler
11
+ end
12
+
13
+ # Computes Δ for the period of Δt.
14
+ #
15
+ def delta Δt
16
+ gradient * Δt
17
+ end
18
+ alias Δ delta
19
+ end # Euler
20
+ end # YPetri::Core::Timed
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ # Euler method with timeless transitions firing after each step.
4
+ #
5
+ class YPetri::Core::Timed
6
+ module PseudoEuler
7
+ include Euler
8
+
9
+ # Name of this method.
10
+ #
11
+ def simulation_method
12
+ :pseudo_euler
13
+ end
14
+
15
+ # Computes Δ for the period of Δt.
16
+ #
17
+ def delta Δt
18
+ super + delta_timeless
19
+ end
20
+ alias Δ delta
21
+
22
+ # Makes a single step by Δt.
23
+ #
24
+ def step! Δt=simulation.step
25
+ increment_marking_vector Δ( Δt )
26
+ assignment_transitions_all_fire!
27
+ simulation.increment_time! Δt
28
+ alert
29
+ end
30
+ end # PseudoEuler
31
+ end # YPetri::Core::Timed
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ # Euler method with timeless transitions firing every time tick.
4
+ #
5
+ class YPetri::Core::Timed
6
+ module QuasiEuler
7
+ include Euler
8
+
9
+ # Name of this method.
10
+ #
11
+ def simulation_method
12
+ :quasi_euler
13
+ end
14
+
15
+ # Makes a single step by Δt.
16
+ #
17
+ def step! Δt=simulation.step_size
18
+ fail NotImplementedError
19
+ # Now one would have to compare whichever comes first, time tick or the
20
+ # end of Δt, and then again and again, until Δt is fired...
21
+ end
22
+ end # QuasiEuler
23
+ end # YPetri::Core::Timed
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ # Timed simulation core.
4
+ #
5
+ class YPetri::Core
6
+ class Timed < YPetri::Core
7
+ require_relative 'timed/euler.rb'
8
+ require_relative 'timed/pseudo_euler.rb' # timeless fire after each step
9
+ require_relative 'timed/quasi_euler.rb' # timeless fire each time tick
10
+
11
+ # Makes a single step by Δt.
12
+ #
13
+ def step! Δt=simulation.step
14
+ increment_marking_vector Δ( Δt )
15
+ increment_time! Δt
16
+ note_state_change
17
+ end
18
+
19
+ # Gradient for free places.
20
+ #
21
+ def gradient
22
+ gradient_Ts + gradient_TS
23
+ end
24
+ alias ∇ gradient
25
+
26
+ # Gradient contribution by Ts transitions.
27
+ #
28
+ def gradient_Ts
29
+ simulation.Ts_gradient_closure.call
30
+ end
31
+
32
+ # Gradient contribution by TS transitions.
33
+ #
34
+ def gradient_TS
35
+ ( simulation.TS_stoichiometry_matrix * flux_vector_TS )
36
+ end
37
+
38
+ # Flux vector. The caller asserts that all the timed transitions are
39
+ # stoichiometric, or error.
40
+ #
41
+ def flux_vector
42
+ msg = "#flux_vector method only applies to the timed simulations with " +
43
+ "no Ts transitions. Try #flux_vector_TS instead!"
44
+ fail msg unless Ts_transitions().empty?
45
+ simulation.TS_rate_closure.call
46
+ end
47
+
48
+ # Flux vector of TS transitions.
49
+ #
50
+ def flux_vector_TS
51
+ simulation.TS_rate_closure.call
52
+ end
53
+ end # class Timed
54
+ end # class YPetri::Core
55
+
56
+ # In general, it is not required that all net elements are simulated with the
57
+ # same method. Practically, ODE systems have many good simulation methods
58
+ # available.
59
+ #
60
+ # (1) ᴍ(t) = ϝ f(ᴍ, t).dt, where f(ᴍ, t) is a known function.
61
+ #
62
+ # Many of these methods depend on the Jacobian, but that may not be available
63
+ # for some places. Therefore, the places, whose marking defines the system
64
+ # state, are divided into two categories: "A" (accelerated), for which as
65
+ # common Jacobian can be found, and "E" places, where "E" can stand either for
66
+ # "External" or "Euler".
67
+ #
68
+ # If we apply the definition of "causal orientation" on A and E places, then it
69
+ # can be said, that only the transitions causally oriented towards "A" places
70
+ # are allowed for compliance with the equation (1).
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ # Implicit Euler for timeless nets. Simply, timeless transitions
4
+ # fire simultaneously, after which A transitions (if any) fire.
5
+ #
6
+ class YPetri::Core::Timeless
7
+ module PseudoEuler
8
+ # Name of this method.
9
+ #
10
+ def simulation_method
11
+ :pseudo_euler
12
+ end
13
+
14
+ def step!
15
+ increment_marking_vector Δ
16
+ assignment_transitions_all_fire!
17
+ alert
18
+ end
19
+ end # module PseudoEuler
20
+ end # class YPetri::Core::Timeless
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ # Timeless simulation core.
4
+ #
5
+ class YPetri::Core
6
+ class Timeless < YPetri::Core
7
+ require_relative 'timeless/pseudo_euler'
8
+
9
+ alias delta delta_timeless
10
+ alias Δ delta
11
+ end # class Timeless
12
+ end # class YPetri::Core