y_petri 2.1.22 → 2.1.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/y_petri.rb +1 -0
- data/lib/y_petri/agent/simulation_related.rb +15 -35
- data/lib/y_petri/core.rb +2 -2
- data/lib/y_petri/core/timed.rb +12 -4
- data/lib/y_petri/core/timed/gillespie.rb +82 -0
- data/lib/y_petri/core/timed/runge_kutta.rb +22 -0
- data/lib/y_petri/dsl.rb +4 -5
- data/lib/y_petri/net/data_set.rb +2 -1
- data/lib/y_petri/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11b347e148cffde329b5fd9e3fb104f302e4066a
|
4
|
+
data.tar.gz: 37450ab4794d26f0af7ba7055fa8ffe8d59975d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62f0f1af0ad89d1db56f134cadbc3d23065740e4967c4771392cfc341c91e2cf070e3e449c2beaa337bb2ae76b47ed51d87cc5fbf9533383ce8d772cf56ede3a
|
7
|
+
data.tar.gz: 65dd95f028636d47da4d9068938825845eefc32117e9151afbe60be6dd0092e2e51cfff1deb341f60a9ed397a8f826825269dd12d337aa3e8307a2607e2454f4
|
data/lib/y_petri.rb
CHANGED
@@ -22,6 +22,7 @@ require 'gnuplot' # used for graph visualization
|
|
22
22
|
require 'csv' # not used at the moment
|
23
23
|
require 'graphviz' # used for Petri net visualization
|
24
24
|
require 'pp' # usef for pretty
|
25
|
+
require 'distribution' # used in the simulation core
|
25
26
|
|
26
27
|
require_relative 'y_petri/version'
|
27
28
|
require_relative 'y_petri/fixed_assets'
|
@@ -9,19 +9,19 @@ module YPetri::Agent::SimulationRelated
|
|
9
9
|
|
10
10
|
# Simulation selection class.
|
11
11
|
#
|
12
|
-
SimulationSelection = YPetri::Agent::Selection.parametrize agent: self
|
12
|
+
SimulationSelection = YPetri::Agent::Selection.parametrize( agent: self )
|
13
13
|
|
14
14
|
# Simulation settings collection selection class.
|
15
15
|
#
|
16
|
-
SscSelection = YPetri::Agent::Selection.parametrize agent: self
|
16
|
+
SscSelection = YPetri::Agent::Selection.parametrize( agent: self )
|
17
17
|
|
18
18
|
# Clamp collection selection class.
|
19
19
|
#
|
20
|
-
CcSelection = YPetri::Agent::Selection.parametrize agent: self
|
20
|
+
CcSelection = YPetri::Agent::Selection.parametrize( agent: self )
|
21
21
|
|
22
22
|
# Initial marking collection selection class.
|
23
23
|
#
|
24
|
-
ImcSelection = YPetri::Agent::Selection.parametrize agent: self
|
24
|
+
ImcSelection = YPetri::Agent::Selection.parametrize( agent: self )
|
25
25
|
|
26
26
|
class SimulationPoint < YPetri::Agent::HashKeyPointer
|
27
27
|
# Reset to the first simulation, or nil if that is absent.
|
@@ -49,15 +49,15 @@ module YPetri::Agent::SimulationRelated
|
|
49
49
|
|
50
50
|
# Pointer to a collection of simulation settings.
|
51
51
|
#
|
52
|
-
SscPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
|
52
|
+
SscPoint = YPetri::Agent::HashKeyPointer.parametrize( agent: self )
|
53
53
|
|
54
54
|
# Pointer to a clamp collection.
|
55
55
|
#
|
56
|
-
CcPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
|
56
|
+
CcPoint = YPetri::Agent::HashKeyPointer.parametrize( agent: self )
|
57
57
|
|
58
58
|
# Pointer to a collection of initial markings.
|
59
59
|
#
|
60
|
-
ImcPoint = YPetri::Agent::HashKeyPointer.parametrize agent: self
|
60
|
+
ImcPoint = YPetri::Agent::HashKeyPointer.parametrize( agent: self )
|
61
61
|
|
62
62
|
attr_reader :simulation_point,
|
63
63
|
:ssc_point,
|
@@ -68,8 +68,10 @@ module YPetri::Agent::SimulationRelated
|
|
68
68
|
:cc_selection,
|
69
69
|
:imc_selection
|
70
70
|
|
71
|
+
# Agent initialziation method.
|
72
|
+
#
|
71
73
|
def initialize
|
72
|
-
# set up this
|
74
|
+
# set up this agent's pointers
|
73
75
|
@simulation_point = SimulationPoint.new( hash: simulations,
|
74
76
|
hash_value_is: "simulation" )
|
75
77
|
@ssc_point = SscPoint.new( hash: simulation_settings_collections,
|
@@ -161,6 +163,7 @@ module YPetri::Agent::SimulationRelated
|
|
161
163
|
|
162
164
|
# Returns or modifies current initial marking(s) as indicated by the argument
|
163
165
|
# field:
|
166
|
+
#
|
164
167
|
# * No arguments: returns current imc
|
165
168
|
# * Exactly one ordered argument: it is assumed to identify a place whose
|
166
169
|
# im in the current imc will be returned.
|
@@ -257,34 +260,11 @@ module YPetri::Agent::SimulationRelated
|
|
257
260
|
end
|
258
261
|
end
|
259
262
|
|
260
|
-
# Plot the
|
263
|
+
# Plot the recording reduced into the given feature set.
|
261
264
|
#
|
262
|
-
def plot
|
263
|
-
|
264
|
-
|
265
|
-
# --> delta feature ids
|
266
|
-
# --> flux feature ids
|
267
|
-
# --> firing feature ids
|
268
|
-
# take these features together
|
269
|
-
# construct the labels and the time series for each
|
270
|
-
# plot them
|
271
|
-
|
272
|
-
return nil unless sim = world.simulations.values[-1] # sim@point
|
273
|
-
# Decide abnout the features
|
274
|
-
features = sim.places.dup.map { |p|
|
275
|
-
collection.include?( p ) ? p : nil
|
276
|
-
}
|
277
|
-
# Get recording
|
278
|
-
rec = sim.recording
|
279
|
-
# Select a time series for each feature.
|
280
|
-
time_series = features.map.with_index do |feature, i|
|
281
|
-
feature and rec.map { |key, val| [ key, val[i] ] }.transpose
|
282
|
-
end
|
283
|
-
# Time axis
|
284
|
-
ᴛ = sim.target_time
|
285
|
-
# Gnuplot call
|
286
|
-
gnuplot( ᴛ, features.compact.map( &:name ), time_series.compact,
|
287
|
-
title: "Selected features plot", ylabel: "Marking" )
|
265
|
+
def plot features
|
266
|
+
ff = simulation.net.state.features( features )
|
267
|
+
simulation.recording.reduce_features( ff ).plot
|
288
268
|
end
|
289
269
|
|
290
270
|
# Plot system state history.
|
data/lib/y_petri/core.rb
CHANGED
@@ -54,13 +54,13 @@ class YPetri::Core
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
#
|
57
|
+
# Simulation is not guarded by default.
|
58
58
|
#
|
59
59
|
def guarded?
|
60
60
|
false
|
61
61
|
end
|
62
62
|
|
63
|
-
# Delta for free places.
|
63
|
+
# Delta for free places from timeless transitions.
|
64
64
|
#
|
65
65
|
def delta_timeless
|
66
66
|
delta_ts + delta_tS
|
data/lib/y_petri/core/timed.rb
CHANGED
@@ -3,10 +3,17 @@
|
|
3
3
|
# Timed simulation core.
|
4
4
|
#
|
5
5
|
class YPetri::Core::Timed < YPetri::Core
|
6
|
-
|
7
|
-
require_relative 'timed/
|
8
|
-
|
9
|
-
|
6
|
+
# Euler method.
|
7
|
+
require_relative 'timed/euler'
|
8
|
+
# Euler with timeless transitions firing after each step.
|
9
|
+
require_relative 'timed/pseudo_euler'
|
10
|
+
# Euler with timeless transitions firing each time tick.
|
11
|
+
require_relative 'timed/quasi_euler'
|
12
|
+
# Gillespie stochastic method.
|
13
|
+
require_relative 'timed/gillespie'
|
14
|
+
# Runge-Kutta fifth-order method.
|
15
|
+
require_relative 'timed/runge_kutta'
|
16
|
+
|
10
17
|
# Makes a single step by Δt.
|
11
18
|
#
|
12
19
|
def step! Δt=simulation.step
|
@@ -49,6 +56,7 @@ class YPetri::Core::Timed < YPetri::Core
|
|
49
56
|
def flux_vector_TS
|
50
57
|
simulation.TS_rate_closure.call
|
51
58
|
end
|
59
|
+
alias propensity_vector_TS flux_vector_TS
|
52
60
|
end # class YPetri::Core::Timed
|
53
61
|
|
54
62
|
# In general, it is not required that all net elements are simulated with the
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Plain Gillespie algorithm.
|
4
|
+
#
|
5
|
+
# The characteristic of the Gillespie method is, that it does not work starting
|
6
|
+
# from Δt towards Δstate. Instead, it makes a random choice weighted by the
|
7
|
+
# transition propensities, and the random choice determines both the next timed
|
8
|
+
# transition to fire, and the size of Δt to slice off from the time axis.
|
9
|
+
#
|
10
|
+
module YPetri::Core::Timed::Gillespie
|
11
|
+
attr_reader :rng
|
12
|
+
|
13
|
+
# Gillespie method initialization.
|
14
|
+
#
|
15
|
+
def initialize
|
16
|
+
@rng = ::Random
|
17
|
+
end
|
18
|
+
|
19
|
+
# Makes a stochastic number of Gillespie steps necessary to span the period Δt.
|
20
|
+
#
|
21
|
+
def step! Δt=simulation.step
|
22
|
+
current_time = simulation.time
|
23
|
+
target_time = current_time + Δt
|
24
|
+
@gillespie_time = current_time
|
25
|
+
propensities = propensity_vector_TS
|
26
|
+
puts "Propensity vector TS is:"
|
27
|
+
Kernel::p propensities
|
28
|
+
gillespie_update_next_firing_time( propensities )
|
29
|
+
until ( @gillespie_next_firing_time > target_time )
|
30
|
+
gillespie_step!
|
31
|
+
propensities = propensity_vector_TS
|
32
|
+
gillespie_update_next_firing_time( propensities )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Name of this method.
|
37
|
+
#
|
38
|
+
def simulation_method
|
39
|
+
:gillespie
|
40
|
+
end
|
41
|
+
|
42
|
+
# This method updates next firing time given propensities.
|
43
|
+
#
|
44
|
+
def gillespie_update_next_firing_time( propensities )
|
45
|
+
@gillespie_next_firing_time =
|
46
|
+
@gillespie_time + gillespie_delta_time( propensities )
|
47
|
+
end
|
48
|
+
|
49
|
+
# Step.
|
50
|
+
#
|
51
|
+
def gillespie_step! propensities
|
52
|
+
t = choose_TS_transition( propensities )
|
53
|
+
fire! t
|
54
|
+
end
|
55
|
+
|
56
|
+
# Computes Δ for the period of Δt.
|
57
|
+
#
|
58
|
+
def gillespie_delta_time( propensities )
|
59
|
+
sum = Σ propensities
|
60
|
+
mean_period = 1 / sum
|
61
|
+
Distribution::Exponential.p_value( rng.rand, sum )
|
62
|
+
end
|
63
|
+
|
64
|
+
# Chooses the transition to fire.
|
65
|
+
#
|
66
|
+
def choose_TS_transition( propensities )
|
67
|
+
n = rng.rand
|
68
|
+
propensities.index do |propensity|
|
69
|
+
n -= propensity
|
70
|
+
n <= 0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Fires a transition.
|
75
|
+
#
|
76
|
+
def fire!( transition )
|
77
|
+
transition.∇.map { |place, change|
|
78
|
+
mv = simulation.marking_vector
|
79
|
+
mv.set( place, mv.fetch( place ) + change )
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end # YPetri::Core::Timed::Euler
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Gillespie method.
|
4
|
+
#
|
5
|
+
module YPetri::Core::Timed::Euler
|
6
|
+
# Name of this method.
|
7
|
+
#
|
8
|
+
def simulation_method
|
9
|
+
:runge_kutta
|
10
|
+
end
|
11
|
+
|
12
|
+
# FIXME
|
13
|
+
|
14
|
+
# This is from Euler:
|
15
|
+
|
16
|
+
# # Computes Δ for the period of Δt.
|
17
|
+
# #
|
18
|
+
# def delta Δt
|
19
|
+
# gradient * Δt
|
20
|
+
# end
|
21
|
+
# alias Δ delta
|
22
|
+
end # YPetri::Core::Timed::Euler
|
data/lib/y_petri/dsl.rb
CHANGED
@@ -56,11 +56,10 @@ module YPetri
|
|
56
56
|
:print_recording,
|
57
57
|
:plot,
|
58
58
|
:plot_selected,
|
59
|
-
|
59
|
+
:plot_state,
|
60
60
|
:plot_flux,
|
61
|
+
:plot_firing,
|
62
|
+
:plot_gradient,
|
63
|
+
:plot_delta,
|
61
64
|
to: :y_petri_agent
|
62
|
-
|
63
|
-
def plot_state **nn
|
64
|
-
simulation.recording.marking.plot **nn
|
65
|
-
end
|
66
65
|
end
|
data/lib/y_petri/net/data_set.rb
CHANGED
@@ -253,7 +253,8 @@ class YPetri::Net::DataSet < Hash
|
|
253
253
|
to_s
|
254
254
|
end
|
255
255
|
|
256
|
-
# Pretty print the dataset.
|
256
|
+
# Pretty print the dataset. Takes +:precision+ and +:distance+ named arguments,
|
257
|
+
# that control the shape of the printed table.
|
257
258
|
#
|
258
259
|
def print precision: 4, distance: precision + 4
|
259
260
|
features.labels.print_as_line precision: precision, distance: distance
|
data/lib/y_petri/version.rb
CHANGED
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.1.
|
4
|
+
version: 2.1.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: y_support
|
@@ -73,8 +73,10 @@ files:
|
|
73
73
|
- lib/y_petri/core.rb
|
74
74
|
- lib/y_petri/core/timed.rb
|
75
75
|
- lib/y_petri/core/timed/euler.rb
|
76
|
+
- lib/y_petri/core/timed/gillespie.rb
|
76
77
|
- lib/y_petri/core/timed/pseudo_euler.rb
|
77
78
|
- lib/y_petri/core/timed/quasi_euler.rb
|
79
|
+
- lib/y_petri/core/timed/runge_kutta.rb
|
78
80
|
- lib/y_petri/core/timeless.rb
|
79
81
|
- lib/y_petri/core/timeless/pseudo_euler.rb
|
80
82
|
- lib/y_petri/dsl.rb
|