y_petri 2.4.0 → 2.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef666cef4bef63ff531f923b5b5c15dbf44f3d01
4
- data.tar.gz: 39b9e0478d5fbe58ea0f351d930c307acdeab419
3
+ metadata.gz: fb7a7b5033fa23e8fbdaee627d1864722a31f850
4
+ data.tar.gz: b17971ab72080978c0877a281e6a22fd7dcef2df
5
5
  SHA512:
6
- metadata.gz: c8c52cbb6efd249b118a8e9347a478725d2916354c894a63b1ef6da8bc7e517f0af702a0479cc39b3ee334b0579d697ce7926fb2e2de03850c8707aaeebea457
7
- data.tar.gz: 8a3ed7e54e271be653a563401abeeebb8409e5c34b76eeba6f8ccc49af59c9e86d3427917840ae0adbab28f4c4f93d92e318acb8776a313ff4f915f856081bad
6
+ metadata.gz: df9453ff5bd03c744158b2d8f848c7700ea3cdc80f0c3eb6fb64c409a0436eb7bae5e7538ed86f96c3e759acd4b68c79d9b07cc0045bad0718d0ae7ea5d761ea
7
+ data.tar.gz: dd0569b0b5a0b402a78b1130b7805d3d8202ccd8219ddcdb35a18c7a10f4c479d12b4e4216f1a6c8cce84ff314ce18d228ab803e2f89d785682719d517901c2e
@@ -75,7 +75,7 @@ module YPetri::Core
75
75
 
76
76
  delegate :alert!, to: :recorder
77
77
 
78
- # Delta for free places from timeless transitions.
78
+ # Delta contribution to free places by timeless transitions.
79
79
  #
80
80
  def delta_timeless
81
81
  delta_ts + delta_tS
@@ -112,6 +112,18 @@ module YPetri::Core
112
112
  simulation.increment_marking_vector_closure.( delta )
113
113
  end
114
114
 
115
+ # For now, alias method for #increment_marking_vector.
116
+ # TODO: I already said to myself that I want the core not to rely
117
+ # on the simulation's increment_marking_vector_closure.
118
+ #
119
+ def increment_free_vector( by: fail( "No delta given!" ) )
120
+ print '.'
121
+ simulation.increment_marking_vector_closure.( by )
122
+ # Also, here it is not clear that #increment_marking_vector_closure
123
+ # returns a closure that expects only Δ for free places. Should have
124
+ # better mnemonic name.
125
+ end
126
+
115
127
  # Fires all the assignment transitions.
116
128
  #
117
129
  def fire_all_assignment_transitions!
@@ -31,10 +31,5 @@ class YPetri::Core::Timeless
31
31
  delta_timeless # this method was taken from core.rb
32
32
  # delta_ts + delta_tS # this is the contents of delta_timeless method
33
33
  end
34
-
35
- # Computes the system state delta.
36
- #
37
- def Δ
38
- delta
39
- end
34
+ alias Δ delta
40
35
  end # module YPetri::Core::Timeless
@@ -10,7 +10,7 @@ module YPetri::Core::Timeless::Basic
10
10
  def step!
11
11
  # Compute the sum of the contribution of ts and tS transitions, and
12
12
  # increment the free marking vector by it.
13
- increment_free_vector by: delta_ts + delta_tS
13
+ increment_free_vector by: Δ
14
14
  # Fire all the assignment transitions in their order.
15
15
  fire_all_assignment_transitions!
16
16
  # before: assignment_transitions_all_fire!
@@ -349,9 +349,13 @@ module YPetri::Simulation::Timed
349
349
  else
350
350
  YPetri::Core::Timed.new( simulation: self, method: method, guarded: false )
351
351
  end
352
+ # TODO: But why am I doing it like this? Did I want to emphasize the standalone
353
+ # nature of Core class? Maybe... And maybe I did it so that the runge-kutta method
354
+ # with its @rk_core instance variable instead of @core does not have @core and #core.
355
+ # In this manner, I'm forcing myself to rethink Simulation class.
352
356
  singleton_class.class_exec do
353
357
  attr_reader :core
354
- delegate :simulation_method,
358
+ delegate :simulation_method, # this looks quite redundant with simulation.rb
355
359
  :step!,
356
360
  :firing_vector_tS,
357
361
  to: :core
@@ -370,5 +374,5 @@ module YPetri::Simulation::Timed
370
374
  else
371
375
  Recorder().new( sampling: settings[:sampling] )
372
376
  end
373
- end
377
+ end # def init
374
378
  end # module YPetri::Simulation::Timed
@@ -27,26 +27,39 @@ module YPetri::Simulation::Timeless
27
27
  method = settings[:method] # the simulation method
28
28
  features_to_record = settings[:record]
29
29
  # Sets up a parametrized subclass of the sampler for timeless simulation.
30
- param_class( { Recorder: Recorder }, with: { simulation: self } )
31
- @core = if @guarded then
32
- YPetri::Core::Timeless
33
- .new( simulation: self, method: method, guarded: true )
34
- else
35
- YPetri::Core::Timeless
36
- .new( simulation: self, method: method, guarded: false )
37
- end
38
- @recorder = if features_to_record then
39
- # we'll have to figure out features
40
- ff = case features_to_record
41
- when Array then
42
- net.State.Features
43
- .infer_from_nodes( features_to_record )
44
- when Hash then
45
- net.State.features( features_to_record )
46
- end
47
- Recorder().new( features: ff )
48
- else
49
- Recorder().new # init the recorder
50
- end
30
+ param_class( { Recorder: Recorder }, with: { simulation: self } )
31
+ @core = if @guarded then
32
+ YPetri::Core::Timeless
33
+ .new( simulation: self, method: method, guarded: true )
34
+ else
35
+ YPetri::Core::Timeless
36
+ .new( simulation: self, method: method, guarded: false )
37
+ end
38
+
39
+ # TODO: But why am I doing it like this? Did I want to emphasize the standalone
40
+ # nature of Core class? Maybe... And maybe I did it so that the runge-kutta method
41
+ # with its @rk_core instance variable instead of @core does not have @core and #core.
42
+ # In this manner, I'm forcing myself to rethink Simulation class.
43
+ singleton_class.class_exec do
44
+ attr_reader :core
45
+ delegate :simulation_method, # this looks quite redundant with simulation.rb
46
+ :step!,
47
+ :firing_vector_tS,
48
+ to: :core
51
49
  end
50
+
51
+ @recorder = if features_to_record then
52
+ # we'll have to figure out features
53
+ ff = case features_to_record
54
+ when Array then
55
+ net.State.Features
56
+ .infer_from_nodes( features_to_record )
57
+ when Hash then
58
+ net.State.features( features_to_record )
59
+ end
60
+ Recorder().new( features: ff )
61
+ else
62
+ Recorder().new # init the recorder
63
+ end
64
+ end # def init
52
65
  end # module YPetri::Simulation::Timeless
@@ -1,4 +1,4 @@
1
1
  module YPetri
2
- VERSION = "2.4.0"
2
+ VERSION = "2.4.2"
3
3
  DEBUG = false
4
4
  end
@@ -321,7 +321,7 @@ module YPetri::World::SimulationAspect
321
321
  #
322
322
  # * default_ss = { step_size: 0.1, sampling_period: 5, target_time: 60 }
323
323
  #
324
- def new_simulation( net: Net()::Top, **nn )
324
+ def new_simulation( net: Net().instance( :Top ), **nn )
325
325
  net_inst = net( net )
326
326
  nn.may_have :cc, syn!: :clamp_collection
327
327
  nn.may_have :imc, syn!: :initial_marking_collection
@@ -330,13 +330,13 @@ module YPetri::World::SimulationAspect
330
330
  imc_id = nn.delete( :imc ) || :Base
331
331
  ssc_id = nn.delete( :ssc ) || :Base
332
332
  # Construct the simulation key:
333
- key = if nn.has? :name, syn!: :ɴ then # explicit key (name)
333
+ key = if nn.has? :name, syn!: :ɴ then # explicit key (name)
334
334
  nn[:name]
335
- else # constructed key
335
+ else # constructed key
336
336
  {}.merge( net: net_inst,
337
337
  cc: cc_id,
338
- imc: imc_id,
339
- ssc: ssc_id )
338
+ imc: imc_id,
339
+ ssc: ssc_id )
340
340
  .merge( nn )
341
341
  end
342
342
  # Let's clarify what we got so far.
@@ -7,8 +7,10 @@ require_relative '../lib/y_petri' # tested component itself
7
7
  # require 'y_petri'
8
8
  # require 'sy'
9
9
 
10
- describe "use of timed and timeless core" do
10
+ describe "core" do
11
11
  before do
12
+ @timed_core_class = YPetri::Core::Timed
13
+ @timeless_core_class = YPetri::Core::Timeless
12
14
  # set up a user of core, which will imitate some of the needs
13
15
  # of the Simulation class, or be an actual instance of that class
14
16
  end
@@ -22,5 +24,40 @@ describe "use of timed and timeless core" do
22
24
  # number of steps or until some other condition is fulfilled, or
23
25
  # step backward, or even run backward, if the system allows such thing
24
26
  # at all.
27
+ @timed_core_class::METHODS.keys.must_include :basic
28
+ @timeless_core_class::METHODS.keys.must_include :basic
29
+ end
30
+
31
+ describe "timed core" do
32
+ end
33
+
34
+ describe "timeless core" do
35
+ describe "basic method" do
36
+ before do
37
+ # @timeless_core_class.new( method: :basic )
38
+ # TODO: The above logically fails, because core now
39
+ # requires simulation. But newly, a core should no
40
+ # longer require a simulation. It should simply receive
41
+ # initial marking vector, information about places
42
+ # (including clamped places and their clamps), information
43
+ # above processes (ie. transitions). Surely, this looks
44
+ # like a third redundant layer of place and transition
45
+ # representations (the first two are in Net and Simulation
46
+ # class). But it serves me right since I want to do things
47
+ # properly :-) Core represents a simulation machine,
48
+ # hardware. Of course, I have no hardware other than
49
+ # Ruby itself. I am not even able to compile the simulation
50
+ # into C. It is quite imaginable that Simulation would
51
+ # be flexible about using cores and simulation methods
52
+ # to do what the user requires it to do, while cores would
53
+ # be more inflexible, method specific and machine specific.
54
+ # So Core is a machine abstraction, while Simulation is the
55
+ # abstraction of what the user might require from a Simulation.
56
+ # Anyway a good way to kill time.
57
+ end
58
+
59
+ it "should behave" do
60
+ end
61
+ end
25
62
  end
26
63
  end
@@ -0,0 +1,71 @@
1
+ #encoding: utf-8
2
+
3
+ # Found things that do not work with YPetri.
4
+
5
+ require 'y_petri'
6
+ include YPetri
7
+
8
+ A = Place default_marking: 5
9
+ B = Place default_marking: 5
10
+ C = Place default_marking: 0
11
+ D = Place default_marking: 0
12
+
13
+ T1 = Transition stoichiometry: { A: -1, B: -1, C: 1 }
14
+ T2 = Transition stoichiometry: { C: -1, D: 1 }
15
+
16
+ net.timed? # The net is timeless
17
+
18
+ new_simulation # This produces timed simulation (same as run!)
19
+
20
+ net.simulation # While this produces timeless simulation.
21
+
22
+ # This is happening because I have deleted :core selector from
23
+ # Simulation class code. I did this because when adding Runge-Kutta
24
+ # method, I construct instance-specific instance variable @rk_core
25
+ # instead of @core.
26
+
27
+ # This, again, will produce timed simulation.
28
+ net.simulation **ssc
29
+
30
+ # Simulation#initialize has hard times deciding whether it is
31
+ # constructing timed or timeless simulation. When it sees time
32
+ # mentioned (:step, :sampling, :time parameters are all set)
33
+ # in ssc, it decides to construct a timed simulation.
34
+ #
35
+ # When it does not see the time mentioned, it decides to construct
36
+ # a timeless simulation. The decision is quite right when I merely
37
+ # call net.simulation, because the net is actually quite timeless.
38
+ #
39
+ # But once I call for :basic simulation method ...
40
+ #
41
+ # Now I used to call :basic method :pseudo_euler, which would suggest
42
+ # timed simulation. But timeless simulations also have :basic method
43
+ # among them...
44
+ #
45
+ # The question is whether I should have timed and timeless methods
46
+ # with same names...
47
+
48
+ # I should keep at this and rethink the Simulation class
49
+
50
+ # also, another problem
51
+ #
52
+ # set_ssc :Hello
53
+ #
54
+ # instead of trying to set the simulation settings collection
55
+ # to the one named :Hello will cause the simulation settings
56
+ # collection named :Base be set to :Hello
57
+
58
+ simulation_settings_collection # alias ssc
59
+
60
+ simulation_settings_collections
61
+
62
+ set_simulation_settings_collection :Hello
63
+
64
+ simulation_settings_collection # alias ssc
65
+
66
+ simulation_settings_collections
67
+
68
+ # This is obviously wrong. Whole idea of collections of clamps
69
+ # and initial values and simulation settings is quite dated, it
70
+ # dates back to the times when I was not at the top of my Ruby
71
+ # proficiency yet. Maybe time to rethink World / Agent classes.
@@ -9,7 +9,7 @@ set_step 10
9
9
  set_target_time 600
10
10
  set_sampling 10
11
11
  # Euler with timeless transitions firing after each step:
12
- set_simulation_method :PseudoEuler
12
+ set_simulation_method :basic
13
13
 
14
14
  A = Place m!: 1
15
15
  B = Place m!: 10
@@ -25,4 +25,4 @@ Transition name: :C_held_at_half_B,
25
25
  assignment: -> x { x / 2 }
26
26
 
27
27
  run!
28
- plot_recording
28
+ recording.plot
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: y_petri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - boris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-16 00:00:00.000000000 Z
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -253,6 +253,7 @@ files:
253
253
  - test/examples/example_2.rb
254
254
  - test/examples/example_IV.rb
255
255
  - test/examples/example_VI_gillespie.rb
256
+ - test/examples/issues.rb
256
257
  - test/examples/manual_examples.rb
257
258
  - test/net_test.rb
258
259
  - test/place_test.rb
@@ -305,6 +306,7 @@ test_files:
305
306
  - test/examples/example_2.rb
306
307
  - test/examples/example_IV.rb
307
308
  - test/examples/example_VI_gillespie.rb
309
+ - test/examples/issues.rb
308
310
  - test/examples/manual_examples.rb
309
311
  - test/net_test.rb
310
312
  - test/place_test.rb