y_petri 2.4.6 → 2.4.8
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.
- checksums.yaml +4 -4
- data/lib/y_petri/net/data_set.rb +39 -10
- data/lib/y_petri/net/own_state.rb +38 -6
- data/lib/y_petri/net/state/features.rb +1 -1
- data/lib/y_petri/net.rb +1 -1
- data/lib/y_petri/place.rb +2 -0
- data/lib/y_petri/simulation/timed.rb +17 -12
- data/lib/y_petri/transition/types.rb +66 -31
- data/lib/y_petri/version.rb +1 -1
- data/test/net_test.rb +21 -4
- metadata +2 -4
- data/Introduction_to_YNelson_and_YPetri.pdf +0 -0
- data/Object_model_of_YNelson_and_YPetri.pdf +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d3c0ff2334a05d996f1a735b660efd890de6c81
|
4
|
+
data.tar.gz: d994bc1a0f2a7f38966482f5abdf9db7b8dbec5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32baae30b3f9e610fc483a0557c2f0309666bdbe65155f309002389290fb384979f106a2d7f7c78efc29ea6c94a9acb523cfc032e197ae3b9b0973db932c105a
|
7
|
+
data.tar.gz: 6b2a8788679308f900331d12f553108ce1801289b674530a76e0767be773c78b086560193f2c86a35c6e22a9ed40d67118ecf12c1937f0ac511e86661fdda0e8
|
data/lib/y_petri/net/data_set.rb
CHANGED
@@ -30,6 +30,26 @@
|
|
30
30
|
# from it or otherwise integrate with it for the purposes of +DataSet+.
|
31
31
|
#
|
32
32
|
class YPetri::Net::DataSet < Hash
|
33
|
+
# FIXME: User story:
|
34
|
+
#
|
35
|
+
# I ran a long simulation (Virginia Tech cell cycle) and then
|
36
|
+
# I found that instead of 200_000 time units, I ran it for
|
37
|
+
# 360_000 time units. As we know, method recording (or
|
38
|
+
# simulation.recording is of DataSet type. I had troubles
|
39
|
+
# cutting down the recording to 200_000 time units.
|
40
|
+
# I had these troubles because there is no special select
|
41
|
+
# method defined for DataSet, or no way to only select
|
42
|
+
# the keys within certain time range, and Hash#select and
|
43
|
+
# other built-in Hash methods return Hash type which no
|
44
|
+
# longer can be plotted easily. Add a way of taking only
|
45
|
+
# certain records, or certain time section
|
46
|
+
#
|
47
|
+
# Finally, I found that #plot method directly accepts
|
48
|
+
# :time alias :time_range parameter, which can be used
|
49
|
+
# to do what I want. But I still think DataSet should have
|
50
|
+
# a method for cutting itself down to only certain lines.
|
51
|
+
# We cannot rely on Gnuplot :x_range parameter only...
|
52
|
+
|
33
53
|
class << self
|
34
54
|
alias __new__ new
|
35
55
|
|
@@ -345,20 +365,28 @@ class YPetri::Net::DataSet < Hash
|
|
345
365
|
map { |lbl, rec| [ lbl, *rec ].join ',' }.join( "\n" )
|
346
366
|
end
|
347
367
|
|
348
|
-
# Plots the dataset
|
349
|
-
#
|
350
|
-
#
|
351
|
-
# the
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
#
|
368
|
+
# Plots the dataset using Ruby Gnuplot gem. Takes several
|
369
|
+
# optional arguments: The list of nodes to plot can be
|
370
|
+
# supplied as optional first ordered argument. If supplied,
|
371
|
+
# the nodes are converted into features using
|
372
|
+
# +Net::State::Features.infer_from_nodes+ method. Similarly,
|
373
|
+
# the features to exclude can be specified as a list of
|
374
|
+
# nodes supplied under +except:+ parameter. Under +except:+
|
375
|
+
# parameter, it is also possible to supply a
|
376
|
+
# feature-specifying hash. Otherwise, feature specification
|
377
|
+
# can be passed to the method via named arguments. By
|
378
|
+
# default, it is assumed that the caller means to plot all
|
379
|
+
# the features of this dataset.
|
380
|
+
#
|
381
|
+
# Named arguments admit Gnuplot keywords that control the
|
382
|
+
# plot. These parameters include +title:+, +xlabel:+ and
|
383
|
+
# +ylabel:+.
|
356
384
|
#
|
357
385
|
def plot( nodes=nil, except: [], **named_args )
|
358
386
|
nn = named_args
|
359
387
|
time = nn.may_have :time, syn!: :time_range
|
360
388
|
events = events()
|
361
|
-
# Figure out features.
|
389
|
+
# Figure out the features to plot.
|
362
390
|
ff = if nodes.nil? then
|
363
391
|
nn_ff = nn.slice [ :marking, :flux, :firing,
|
364
392
|
:gradient, :delta, :assignment ]
|
@@ -366,7 +394,8 @@ class YPetri::Net::DataSet < Hash
|
|
366
394
|
else
|
367
395
|
net.State.Features.infer_from_nodes( nodes )
|
368
396
|
end
|
369
|
-
# Figure out the features
|
397
|
+
# Figure out the features to exclude from plotting
|
398
|
+
# ("except" features).
|
370
399
|
xff = case except
|
371
400
|
when Array then net.State.Features.infer_from_nodes( except )
|
372
401
|
when Hash then net.State.Features( except )
|
@@ -8,18 +8,50 @@ module YPetri::Net::OwnState
|
|
8
8
|
# class (a subclass of Array), containing marking owned by the net's places.
|
9
9
|
#
|
10
10
|
def state
|
11
|
-
State().new(
|
11
|
+
State().new( m )
|
12
|
+
end
|
13
|
+
|
14
|
+
# Like #m method, but instead of returning an array of markings, it returns
|
15
|
+
# a string of the form "A: 1, B: 2, ...", where A, B, ... are the places
|
16
|
+
# and 1, 2, ... their marking. This method is intended to produce output
|
17
|
+
# easy to read by humans, while #m method produces regular output (an
|
18
|
+
# Array) suitable for further processing. Method accepts arbitrary number
|
19
|
+
# of optional arguments, each of which must be a place identifier. If
|
20
|
+
# no arguments are given, full marking of the net is described. If
|
21
|
+
# arguments are given, only marking of the places identified by the
|
22
|
+
# arguments is described.
|
23
|
+
#
|
24
|
+
def marking *place_ids
|
25
|
+
return pp.size == 0 ? "" : marking( *pp ) if place_ids.empty?
|
26
|
+
a = [ place_ids.map { |id| place( id ) },
|
27
|
+
m( place_ids ) ].transpose
|
28
|
+
a.map { |pair| pair.join ": " }.join ', '
|
12
29
|
end
|
13
30
|
|
14
31
|
# If no argument is supplied, the method returns the array of the markings
|
15
32
|
# owned by the net's places. If an array of place identifiers is supplied,
|
16
33
|
# the return value is the array of the markings owned by those places.
|
17
|
-
#
|
18
|
-
def
|
19
|
-
return
|
34
|
+
#
|
35
|
+
def m place_ids=nil
|
36
|
+
return m( pp ) if place_ids.nil?
|
20
37
|
place_ids.map { |id| place( id ).marking }
|
21
38
|
end
|
22
|
-
|
39
|
+
|
40
|
+
# If no argument is supplied, the method resets its places to their default
|
41
|
+
# marking. If an array of place identifiers is supplied, only the specified
|
42
|
+
# places are reset. Attempts to reset places that have no default marking
|
43
|
+
# result in +TypeError+.
|
44
|
+
#
|
45
|
+
def reset! place_ids=nil
|
46
|
+
return reset!( pp ) if place_ids.nil?
|
47
|
+
place_ids.map { |id|
|
48
|
+
begin
|
49
|
+
place( id ).reset_marking
|
50
|
+
rescue TypeError => err
|
51
|
+
raise TypeError, "Unable to reset the net! " + err.message
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
23
55
|
|
24
56
|
# Takes an array of tS transition identifiers as an optional argument, and
|
25
57
|
# returns the array of their firing under current net state. If no argument
|
@@ -55,7 +87,7 @@ module YPetri::Net::OwnState
|
|
55
87
|
fail NotImplementedError
|
56
88
|
end
|
57
89
|
|
58
|
-
# Takes an array of place
|
90
|
+
# Takes an array of place identifiers, and a named argument +:transitions+,
|
59
91
|
# and returns the array of the place delta contribution by the indicated
|
60
92
|
# transitions.
|
61
93
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
# A feature set. In other words, a set of state features, such as marking,
|
4
|
-
# flux etc.
|
4
|
+
# flux etc. The supported features are:
|
5
5
|
#
|
6
6
|
# marking:: Applicable to all places, all places have marking.
|
7
7
|
# firing:: Applicable to all stoichiometric transitions, but delta time has
|
data/lib/y_petri/net.rb
CHANGED
@@ -171,7 +171,7 @@ class YPetri::Net
|
|
171
171
|
# Networks are equal when their places and transitions are equal.
|
172
172
|
#
|
173
173
|
def == other
|
174
|
-
return false unless other.class_complies?
|
174
|
+
return false unless other.class_complies? self.class
|
175
175
|
places == other.places && transitions == other.transitions
|
176
176
|
end
|
177
177
|
|
data/lib/y_petri/place.rb
CHANGED
@@ -353,29 +353,34 @@ module YPetri::Simulation::Timed
|
|
353
353
|
|
354
354
|
rk_core.step! Δt
|
355
355
|
|
356
|
-
# TODO: In the above lines, setting rec = recorder and then calling
|
357
|
-
# the block is a bit weird. It would be nicer to use
|
356
|
+
# TODO: In the above lines, setting rec = recorder and then calling
|
357
|
+
# rec!.alert in the block is a bit weird. It would be nicer to use
|
358
|
+
# recorder.alert!, but maybe
|
358
359
|
# wise Ruby closure mechanism does not allow it...
|
359
360
|
end # def step!
|
360
|
-
end
|
361
|
-
else
|
361
|
+
end # singleton_class.class_exec
|
362
|
+
else # the method is not :runge_kutta
|
362
363
|
@core = if @guarded then
|
363
|
-
YPetri::Core::Timed.new( simulation: self,
|
364
|
+
YPetri::Core::Timed.new( simulation: self,
|
365
|
+
method: method, guarded: true )
|
364
366
|
else
|
365
|
-
YPetri::Core::Timed.new( simulation: self,
|
367
|
+
YPetri::Core::Timed.new( simulation: self,
|
368
|
+
method: method, guarded: false )
|
366
369
|
end
|
367
|
-
# TODO: But why am I doing it like this? Did I want to
|
368
|
-
# nature of Core class? Maybe... And
|
369
|
-
#
|
370
|
-
#
|
370
|
+
# TODO: But why am I doing it like this? Did I want to
|
371
|
+
# emphasize the standalone nature of Core class? Maybe... And
|
372
|
+
# maybe I did it so that the runge-kutta method with its
|
373
|
+
# @rk_core instance variable instead of @core does not have
|
374
|
+
# @core and #core. In this manner, I'm forcing myself to
|
375
|
+
# rethink Simulation class.
|
371
376
|
singleton_class.class_exec do
|
372
377
|
attr_reader :core
|
373
378
|
delegate :simulation_method, # this looks quite redundant with simulation.rb
|
374
379
|
:step!,
|
375
380
|
:firing_vector_tS,
|
376
381
|
to: :core
|
377
|
-
end
|
378
|
-
end
|
382
|
+
end # singleton_class.class_exec
|
383
|
+
end
|
379
384
|
@recorder = if features_to_record then
|
380
385
|
# we'll have to figure out features
|
381
386
|
ff = case features_to_record
|
@@ -5,29 +5,49 @@ require_relative 't'
|
|
5
5
|
require_relative 'A'
|
6
6
|
|
7
7
|
module YPetri::Transition::Types
|
8
|
-
# Is this a
|
8
|
+
# Is this a transition with assignment action? (Transitions with assignment
|
9
|
+
# action, or "assignment transitions", completely replace the marking of their
|
10
|
+
# codomain with their action closure result, like in spreadsheets.)
|
9
11
|
#
|
10
|
-
def
|
11
|
-
|
12
|
+
def assignment_action?
|
13
|
+
@assignment_action
|
12
14
|
end
|
15
|
+
alias assignment? assignment_action?
|
16
|
+
alias A? assignment_action?
|
13
17
|
|
14
|
-
# Is this a
|
18
|
+
# Is this a non-assignment transition? (Opposite of +#A?+)
|
15
19
|
#
|
16
|
-
def
|
17
|
-
|
20
|
+
def a?
|
21
|
+
! assignment_action?
|
18
22
|
end
|
19
23
|
|
24
|
+
# Is this a timeless non-stoichiometric transition?
|
25
|
+
#
|
26
|
+
def ts?
|
27
|
+
type == :ts
|
28
|
+
end
|
29
|
+
alias B? ts?
|
30
|
+
|
20
31
|
# Is this a timeless stoichiometric transition?
|
21
32
|
#
|
22
33
|
def tS?
|
23
34
|
type == :tS
|
24
35
|
end
|
36
|
+
alias C? tS?
|
25
37
|
|
26
|
-
# Is this a
|
38
|
+
# Is this a timed non-stoichiometric transition?
|
27
39
|
#
|
28
|
-
def
|
29
|
-
type == :
|
40
|
+
def Ts?
|
41
|
+
type == :Ts
|
30
42
|
end
|
43
|
+
alias D? Ts?
|
44
|
+
|
45
|
+
# Is this a timed stoichiometric transition?
|
46
|
+
#
|
47
|
+
def TS?
|
48
|
+
type == :TS
|
49
|
+
end
|
50
|
+
alias E? TS?
|
31
51
|
|
32
52
|
# Is this a stoichiometric transition?
|
33
53
|
#
|
@@ -78,35 +98,50 @@ module YPetri::Transition::Types
|
|
78
98
|
not functional?
|
79
99
|
end
|
80
100
|
|
81
|
-
# Reports the transition's membership in one of the
|
82
|
-
#
|
83
|
-
# 1. TS .... timed stoichiometric
|
84
|
-
# 2. tS .... timeless stoichiometric
|
85
|
-
# 3. Ts .... timed nonstoichiometric
|
86
|
-
# 4. ts .... timeless nonstoichiometric
|
101
|
+
# Reports the transition's membership in one of the 5 basic types
|
102
|
+
# using one-letter abbreviation:
|
87
103
|
#
|
88
|
-
#
|
104
|
+
# 1. A .... assignment
|
105
|
+
# 2. B .... timeless nonstoichiometric (ts)
|
106
|
+
# 3. C .... timeless stoichiometric (tS)
|
107
|
+
# 4. D .... timed nonstoichiometric (Ts)
|
108
|
+
# 5. E .... timed stoichiometric (TS)
|
89
109
|
#
|
90
|
-
|
91
|
-
#
|
92
|
-
def type
|
110
|
+
def t
|
93
111
|
return :A if assignment_action?
|
94
|
-
timed? ? ( stoichiometric? ? :
|
112
|
+
timed? ? ( stoichiometric? ? :E : :D ) : ( stoichiometric? ? :C : :B )
|
95
113
|
end
|
96
114
|
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
115
|
+
# Reports the transition's membership in one of the 5 basic types
|
116
|
+
# using two-letter abbreviation + A for assignment transition.
|
117
|
+
# This methods reflects the fact that the new users may take time
|
118
|
+
# to memorize the meaning of A, B, C, D, E transition types.
|
119
|
+
# Two-letter abbreviations may be easier to figure out.
|
120
|
+
#
|
121
|
+
# 1. A .... assignment transitions (A-type)
|
122
|
+
# 2. ts .... timeless nonstoichiometric (B-type)
|
123
|
+
# 3. tS .... timeless stoichiometric (C-type)
|
124
|
+
# 4. Ts .... timed nonstoichiometric (D-type)
|
125
|
+
# 5. TS .... timed stoichiometric (E-type)
|
100
126
|
#
|
101
|
-
def
|
102
|
-
|
127
|
+
def type
|
128
|
+
{ A: :A, B: :ts, C: :tS, D: :Ts, E: :TS }[ t ]
|
103
129
|
end
|
104
|
-
alias assignment? assignment_action?
|
105
|
-
alias A? assignment_action?
|
106
130
|
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
|
131
|
+
# Reports the transition's membership in one of the 5 basic types
|
132
|
+
# as a full string.
|
133
|
+
#
|
134
|
+
# 1. assignment (A-type)
|
135
|
+
# 2. timeless nonstoichiometric (B-type)
|
136
|
+
# 3. timeless stoichiometric (C-type)
|
137
|
+
# 4. timed nonstoichiometric (D-type)
|
138
|
+
# 5. timed stoichiometric (E-type)
|
139
|
+
#
|
140
|
+
def type_full
|
141
|
+
{ A: "assignment",
|
142
|
+
ts: "timeless nonstoichiometric",
|
143
|
+
tS: "timeless stoichiometric",
|
144
|
+
Ts: "timed nonstoichiometric",
|
145
|
+
TS: "timed stoichiometric" }[ type ]
|
111
146
|
end
|
112
147
|
end # class YPetri::Transition::Types
|
data/lib/y_petri/version.rb
CHANGED
data/test/net_test.rb
CHANGED
@@ -35,6 +35,24 @@ describe YPetri::Net do
|
|
35
35
|
@net.Places( [] ).must_equal []
|
36
36
|
@net.places( :A ).must_equal [ p ]
|
37
37
|
end
|
38
|
+
|
39
|
+
describe "#reset!" do
|
40
|
+
it "should work as expected" do
|
41
|
+
place_with_default_marking =
|
42
|
+
@w.Place.send :new, name: "A", default_marking: 42
|
43
|
+
place_without_default_marking =
|
44
|
+
@w.Place.send :new, name: "B", marking: 43
|
45
|
+
@net.include_place( place_with_default_marking )
|
46
|
+
place_with_default_marking.marking = 0
|
47
|
+
@net.reset!
|
48
|
+
assert place_with_default_marking.marking == 42
|
49
|
+
@net.include_place( place_without_default_marking )
|
50
|
+
place_with_default_marking.marking = 0
|
51
|
+
-> { @net.reset! }.must_raise TypeError
|
52
|
+
@net.reset! [ :A ]
|
53
|
+
assert place_with_default_marking.marking == 42
|
54
|
+
end
|
55
|
+
end
|
38
56
|
end
|
39
57
|
|
40
58
|
describe "world with 3 places" do
|
@@ -78,10 +96,9 @@ describe YPetri::Net do
|
|
78
96
|
it "should know its state (marking owned by the places)" do
|
79
97
|
@net.state.must_be_kind_of YPetri::Net::State
|
80
98
|
@net.state.must_equal [ @p1, @p2, @p3 ].map( &:marking )
|
81
|
-
@net.
|
82
|
-
|
83
|
-
|
84
|
-
@net.m.must_equal @net.marking
|
99
|
+
@net.m.must_equal [ @p1, @p2, @p3 ].map( &:marking )
|
100
|
+
# Easy-to-read marking information.
|
101
|
+
@net.marking.must_equal "A: 1.1, B: 2.2, C: 3.3"
|
85
102
|
end
|
86
103
|
|
87
104
|
it "should have standard equipment expected of a class" do
|
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.
|
4
|
+
version: 2.4.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -131,9 +131,7 @@ files:
|
|
131
131
|
- ACKNOWLEDGMENT.txt
|
132
132
|
- Gemfile
|
133
133
|
- Introduction_to_Ruby_for_YPetri_and_YNelson_Users.pdf
|
134
|
-
- Introduction_to_YNelson_and_YPetri.pdf
|
135
134
|
- LICENSE.txt
|
136
|
-
- Object_model_of_YNelson_and_YPetri.pdf
|
137
135
|
- README.md
|
138
136
|
- Rakefile
|
139
137
|
- lib/y_petri.rb
|
Binary file
|
Binary file
|