y_petri 2.0.15 → 2.1.3

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/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