y_petri 2.1.36 → 2.1.37

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: 509f2defaf79d34c62eb0d964c3626fb49d87d2c
4
- data.tar.gz: 192651ad32c9854c72182c637744e4e58e05233d
3
+ metadata.gz: e8bd3d0de26cf79301633503c11a780226ec1e1b
4
+ data.tar.gz: a8da1ce1d92d383d917116dde22356b97a42aabf
5
5
  SHA512:
6
- metadata.gz: 3663b4d86cc496f7ad09209f24dc64754cace4ddf456681bb5dbb4905f4cdaf6b319bd80ecd4d1da738c881e47a9da75e068592135d6af3bba2e159a6c5e2369
7
- data.tar.gz: 02dc44901cdd06c634d2801d9b648186d67b17d3d52efdab31bfd097043af334b7dc4dabd72101958c77de9ae1765c42e562281c091441b9147df23119343672
6
+ metadata.gz: 76b36988750b6ba018af3efe5f33a2017838d702a49331b8e529b05149cfbff662d78e2eeaa02dfb9f3971956be04a597483c4efb4173aa49799d946a3419eb1
7
+ data.tar.gz: 26d6113132e1154ba1a534429316a61382f62e88d7574a6f28339d8b220e9388bd278286011f92e10f5baef4670fb0e59db1bd1d749ce794670e71a874062bf7
@@ -114,7 +114,7 @@ class YPetri::Net::DataSet < Hash
114
114
  sampling = nn.must_have :sampling
115
115
  t0, target_time = time_range.begin, time_range.end
116
116
  t = t0
117
- o = self.class.new
117
+ o = self.class.new type: type
118
118
  loop do
119
119
  o.update t => interpolate( t )
120
120
  t += sampling
@@ -71,7 +71,8 @@ class YPetri::Net::State::Features::Record < Array
71
71
  # (Timed nets eg. require +:time+ named argument for successful construction.)
72
72
  #
73
73
  def reconstruct marking_clamps: {}, **settings
74
- net.simulation marking_clamps: {}, marking: marking, **settings
74
+ m_hsh = features.marking.map { |feat| feat.place } >> marking
75
+ net.simulation marking_clamps: {}, marking: m_hsh, **settings
75
76
  end
76
77
 
77
78
  # Expects a marking feature identifier (place identifier or Marking instance),
@@ -80,11 +81,11 @@ class YPetri::Net::State::Features::Record < Array
80
81
  # corresponding values. If no argument is given, values from this record for
81
82
  # all the present marking features are returned.
82
83
  #
83
- def marking id=nil
84
- return marking( features.marking ) if id.nil?
85
- case id
86
- when Array then id.map { |id| marking id }
87
- else fetch( features.marking id ) end
84
+ def marking arg=nil
85
+ return marking( features.marking ) if arg.nil?
86
+ case arg
87
+ when Array then arg.map { |id| marking id }
88
+ else fetch( features.marking arg ) end
88
89
  end
89
90
 
90
91
  # Expects a flux feature identifier (transition identifier or Flux instance),
@@ -15,7 +15,7 @@ class YPetri::Net::State::Features < Array
15
15
  ç.define_singleton_method symbol do value end
16
16
  }
17
17
  ç.param_class( { Record: Record,
18
- Dataset: YPetri::Net::DataSet },
18
+ DataSet: YPetri::Net::DataSet },
19
19
  with: { Features: ç } )
20
20
  end
21
21
  end
@@ -42,7 +42,7 @@ class YPetri::Net::State::Features < Array
42
42
  # Parametrize them <em>one more time</em> with Features instance.
43
43
  # Banged version of #param_class! ensures that #Record, #Dataset
44
44
  # methods are shadowed.
45
- inst.param_class!( { Record: Record(), Dataset: Dataset() },
45
+ inst.param_class!( { Record: Record(), DataSet: DataSet() },
46
46
  with: { features: inst } )
47
47
  end
48
48
  end
@@ -137,7 +137,7 @@ class YPetri::Net::State::Features < Array
137
137
  # Constructs a new dataset from these features.
138
138
  #
139
139
  def new_dataset *args, &blk
140
- Dataset().new *args, &blk
140
+ DataSet().new *args, &blk
141
141
  end
142
142
 
143
143
  # Feature summation -- of feature class.
@@ -183,14 +183,14 @@ class YPetri::Net::State::Features < Array
183
183
  # corresponding features from this feature set. If no argument is given, all
184
184
  # the marking features from this set are returned.
185
185
  #
186
- def marking id=nil
187
- return marking( select { |f| f.is_a? Marking() } ) if id.nil?
188
- case id
189
- when Array then self.class.new( id.map { |id| marking id } )
186
+ def marking arg=nil
187
+ return marking( select { |feat| feat.is_a? Marking() } ) if arg.nil?
188
+ case arg
189
+ when Array then self.class.new( arg.map { |id| marking id } )
190
190
  else
191
- Marking( id ).tap do |feature|
191
+ Marking( arg ).tap do |feature|
192
192
  include? feature or
193
- fail KeyError, "No marking feature '#{id}' in this feature set!"
193
+ fail KeyError, "No marking feature '#{arg}' in this feature set!"
194
194
  end
195
195
  end
196
196
  end
@@ -201,14 +201,14 @@ class YPetri::Net::State::Features < Array
201
201
  # array of corresponding features from this feature set. If no argument is
202
202
  # given, all the firing features from this set are returned.
203
203
  #
204
- def firing id=nil
205
- return firing( select { |f| f.is_a? Firing() } ) if id.nil?
206
- case id
207
- when Array then self.class.new( id.map { |id| firing id } )
204
+ def firing arg=nil
205
+ return firing( select { |feat| feat.is_a? Firing() } ) if arg.nil?
206
+ case arg
207
+ when Array then self.class.new( arg.map { |id| firing id } )
208
208
  else
209
- Firing( id ).tap do |feature|
209
+ Firing( arg ).tap do |feature|
210
210
  include? feature or
211
- fail KeyError, "No firing feature '#{id}' in this feature set!"
211
+ fail KeyError, "No firing feature '#{arg}' in this feature set!"
212
212
  end
213
213
  end
214
214
  end
@@ -219,14 +219,14 @@ class YPetri::Net::State::Features < Array
219
219
  # of corresponding features from this feature set. If no argument is given,
220
220
  # all the flux features from this set are returned.
221
221
  #
222
- def flux id=nil
223
- return flux( select { |f| f.is_a? Flux() } ) if id.nil?
224
- case id
225
- when Array then self.class.new( id.map { |id| flux id } )
222
+ def flux arg=nil
223
+ return flux( select { |feat| feat.is_a? Flux() } ) if arg.nil?
224
+ case arg
225
+ when Array then self.class.new( arg.map { |id| flux id } )
226
226
  else
227
- Flux( id ).tap do |feature|
227
+ Flux( arg ).tap do |feature|
228
228
  include? feature or
229
- fail KeyError, "No flux feature '#{id}' in this feature set!"
229
+ fail KeyError, "No flux feature '#{arg}' in this feature set!"
230
230
  end
231
231
  end
232
232
  end
@@ -239,18 +239,19 @@ class YPetri::Net::State::Features < Array
239
239
  # corresponding features from this feature set. If no argument is given,
240
240
  # all the gradient features from this feature set are returned.
241
241
  #
242
- def gradient id=nil, transitions: nil
243
- if id.nil? then
244
- return gradient( select { |f| f.is_a? Gradient() } ) if transitions.nil?
245
- gradient.select { |f| f.transitions == net.tt( transitions ) }
242
+ def gradient arg=nil, transitions: nil
243
+ if arg.nil? then
244
+ return gradient( select { |feat| feat.is_a? Gradient() } ) if
245
+ transitions.nil?
246
+ gradient.select { |feat| feat.transitions == net.tt( transitions ) }
246
247
  else
247
- case id
248
+ case arg
248
249
  when Array then
249
- self.class.new( id.map { |id| gradient id, transitions: transitions } )
250
+ self.class.new( arg.map { |id| gradient id, transitions: transitions } )
250
251
  else
251
- Gradient( id, transitions: transitions ).tap do |feature|
252
+ Gradient( arg, transitions: transitions ).tap do |feature|
252
253
  include? feature or
253
- fail KeyError, "No gradient feature '#{id}' in this fature set!"
254
+ fail KeyError, "No gradient feature '#{arg}' in this fature set!"
254
255
  end
255
256
  end
256
257
  end
@@ -263,18 +264,19 @@ class YPetri::Net::State::Features < Array
263
264
  # identifiers is supplied, it is mapped to the array of corresponding features
264
265
  # from thie feature set.
265
266
  #
266
- def delta
267
- if id.nil? then
268
- return delta( select { |f| f.is_a? Delta() } ) if transitions.nil?
269
- delta.select { |f| f.transitions == net.tt( transitions ) }
267
+ def delta arg=nil, transitions: nil
268
+ if arg.nil? then
269
+ return delta( select { |feat| feat.is_a? Delta() } ) if
270
+ transitions.nil?
271
+ delta.select { |feat| feat.transitions == net.tt( transitions ) }
270
272
  else
271
- case id
273
+ case arg
272
274
  when Array then
273
- self.class.new( id.map { |id| delta id, transitions: transitions } )
275
+ self.class.new( arg.map { |id| delta id, transitions: transitions } )
274
276
  else
275
- Delta( id, transitions: transitions ).tap do |feature|
277
+ Delta( arg, transitions: transitions ).tap do |feature|
276
278
  include? feature or
277
- fail KeyError, "No delta feature '#{id}' in this feature set!"
279
+ fail KeyError, "No delta feature '#{arg}' in this feature set!"
278
280
  end
279
281
  end
280
282
  end
data/lib/y_petri/net.rb CHANGED
@@ -135,7 +135,8 @@ class YPetri::Net
135
135
  def to_s
136
136
  "#<Net: " +
137
137
  ( name.nil? ? "%s" : "name: #{name}, %s" ) %
138
- "#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" + ">"
138
+ "#{pp.size rescue '∅'} places, #{tt.size rescue '∅'} transitions" +
139
+ ">"
139
140
  end
140
141
 
141
142
  # Inspect string of the instance.
@@ -92,7 +92,13 @@ class YPetri::Simulation
92
92
  # given, starting vector is used.
93
93
  #
94
94
  def reset! arg=self.class.starting
95
- arg.each.to_a.zip( annotation ).map { |value, place| set place, value }
95
+ case arg
96
+ when Hash then
97
+ mapping = simulation.PlaceMapping().load( arg )
98
+ reset! places.map { |pl| mapping[ pl ] }
99
+ else # array arg assumed
100
+ arg.each.to_a.zip( annotation ).map { |value, place| set place, value }
101
+ end
96
102
  end
97
103
 
98
104
  # Access of the vector elements.
@@ -81,21 +81,29 @@ class YPetri::Simulation
81
81
 
82
82
  # The basic simulation parameter is :net – +YPetri::Net+ instance which to
83
83
  # simulate. Net implies the collection of places and transitions. Other
84
- # required attributes are marking clamps and initial marking. These can be
85
- # extracted from the Place and Transition instances if not given explicitly.
84
+ # required attributes are +:marking_clamps+ and +:initial_marking+
85
+ # (or +:marking -- if no +:initial_marking+ is supplied, +:marking+ will be
86
+ # used in its stead). There is a possibility to extract the initial marking
87
+ # from the net elements directly, controlled by the optional argument
88
+ # +:use_default_marking+, _true_ by default. It means that even if the caller
89
+ # does not supply required +:initial_marking+ values, the constructor will
90
+ # extract them from the places, so long as these have their initial markings
91
+ # set. Setting +:use_default_marking+ to _false_ will cause an error unless
92
+ # +:initial_marking+ and +:place_clamps+ are supplied explicitly.
93
+ #
86
94
  # Simulation method is controlled by the :method argument, guarding is
87
- # switched on and off by the :guarded argument (true/false). If timed
88
- # transitions are present, the simulation is considered timed. Timed
89
- # simulation constructor has additional arguments :time, establishing time
90
- # range, :step, controlling the simulation step size, and :sampling,
91
- # controlling the sampling frequency.
95
+ # switched on and off by the :guarded argument (_true_ / _false_). Simulations
96
+ # of timed nets are timed. A timed simulation constructor may have +:time+
97
+ # (alias +:time_range+), +:step+, controlling the size of the simulation step,
98
+ # and +:sampling+, controlling the sampling period. At least one of these named
99
+ # arguments has to be set for timed simulations.
92
100
  #
93
101
  def initialize **settings
94
102
  method = settings[:method] # the simulation method
95
103
  @guarded = settings[:guarded] # guarding on / off
96
104
  m_clamps = settings[:marking_clamps] || {}
97
105
  m = settings[:marking]
98
- init_m = settings[:initial_marking] || {}
106
+ init_m = settings[:initial_marking] || m || {}
99
107
  use_default_marking = if settings.has? :use_default_marking then
100
108
  settings[ :use_default_marking ]
101
109
  else true end
@@ -193,7 +201,7 @@ class YPetri::Simulation
193
201
  "#<Simulation: pp: %s, tt: %s, oid: %s>" % [ pp.size, tt.size, object_id ]
194
202
  end
195
203
 
196
- # Resets the simulation
204
+ # Resets the simulation.
197
205
  #
198
206
  def reset! **nn
199
207
  m = nn[:marking]
@@ -1,4 +1,4 @@
1
1
  module YPetri
2
- VERSION = "2.1.36"
2
+ VERSION = "2.1.37"
3
3
  DEBUG = false
4
4
  end
data/test/net_test.rb CHANGED
@@ -199,3 +199,53 @@ describe YPetri::Net::State do
199
199
  -> { @St.feature( marking: :A ) }.must_raise NameError
200
200
  end
201
201
  end
202
+
203
+
204
+ describe YPetri::Net::DataSet do
205
+ before do
206
+ @w = YPetri::World.new
207
+ @net = @w.Net.send :new
208
+ @net << @w.Place.send( :new, ɴ: :A )
209
+ @net << @w.Place.send( :new, ɴ: :B )
210
+ @net << @w.Transition.send( :new, ɴ: :A2B, s: { A: -1, B: 1 }, rate: 0.01 )
211
+ @net << @w.Transition.send( :new, ɴ: :A_plus, s: { A: 1 }, rate: 0.001 )
212
+ end
213
+
214
+ it "should be constructible" do
215
+ ds = @net.State.marking( [:A, :B] ).new_dataset( type: :foobar )
216
+ ds.update foo: [ 42, 43 ]
217
+ ds.update bar: [ 43, 42 ]
218
+ ds.timed?.must_equal false
219
+ ds2 = @net.State.marking.new_dataset( type: :timed )
220
+ ds2.timed?.must_equal true
221
+ ds2.features.must_equal @net.State.marking( [:A, :B] )
222
+ end
223
+
224
+ describe "timed dataset" do
225
+ before do
226
+ @ds = @net.State.marking.new_dataset( type: :timed )
227
+ @ds.update 0.0 => [ 0, 0 ]
228
+ @ds.update 10.0 => [ 1, 0.5 ]
229
+ @ds.update 50.0 => [ 2, 3 ]
230
+ @ds.update 200.0 => [ 2.5, 7 ]
231
+ end
232
+
233
+ it "should give a nice plot" do
234
+ @ds.plot
235
+ end
236
+
237
+ describe "resampling" do
238
+ before do
239
+ @resampled_ds = @ds.resample sampling: 11
240
+ end
241
+
242
+ it "should give a nice plot" do
243
+ @resampled_ds.plot
244
+ end
245
+
246
+ it "should be able to reconstruct the flux" do
247
+ @resampled_ds.flux.plot
248
+ end
249
+ end
250
+ end
251
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: y_petri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.36
4
+ version: 2.1.37
5
5
  platform: ruby
6
6
  authors:
7
7
  - boris