test/simulation_test.rb in y_petri-2.3.12 vs test/simulation_test.rb in y_petri-2.4.0
- old
+ new
@@ -319,63 +319,224 @@
# tmp.must_equal( { 0 => [2.5, 1], 1 => [2.5, 1], 2 => [2.5, 1],
# 3 => [2.5, 1], 4 => [2.5, 1], 5 => [2.5, 1] } )
# end
# end
-describe "timed simulation" do
+# describe "timed simulation" do
+# before do
+# self.class.class_exec { include YPetri }
+# A = Place m!: 0.5
+# B = Place m!: 0.5
+# A_pump = TT s: { A: -1 } do 0.005 end
+# B_decay = Transition s: { B: -1 }, rate: 0.05
+# run!
+# end
+
+# it "should work with the default method" do
+# places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
+# s = simulation
+# s.settings.must_equal( { method: :basic, guarded: false,
+# step: 0.1, sampling: 5, time: 0..60 } )
+# assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
+# "0.0,0.5,0.5\n" +
+# "5.0,0.475,0.38916\n" +
+# "10.0,0.45,0.30289\n" +
+# "15.0,0.425,0.23574\n" +
+# "20.0,0.4,0.18348\n" +
+# "25.0,0.375,0.1428\n" )
+# assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
+# s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
+# 25.0, 30.0, 35.0, 40.0, 45.0,
+# 50.0, 55.0, 60.0 ]
+# s.recording.values_at( 5, 10 )
+# .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
+# s.recording.slice( 2..12 )
+# .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
+# s.recording.net
+# .must_equal net
+# s.recording.features
+# .must_equal net.State.Features.marking( :A, :B )
+# net.State.Features.State
+# .must_equal net.State
+# s.recording.net.State
+# .must_equal net.State
+# s.recording.series( marking: [:A] )
+# .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
+# 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
+# s.net.State.Features.firing.map( &:transition ).names
+# .must_equal [ :A_pump, :B_decay ]
+# s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
+# .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
+# .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
+# s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
+# .must_equal [ 0.0005, 0.0025 ]
+# s.recording.Firing( [] )
+# .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
+# s.recording
+# .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
+# .series
+# .must_equal [ [ -0.0005 ] * 13 ]
+# plot_state
+# sleep 5
+# end
+# end
+
+describe "timed simulation with other methods" do
before do
self.class.class_exec { include YPetri }
- A = Place m!: 0.5
- B = Place m!: 0.5
- A_pump = TT s: { A: -1 } do 0.005 end
- B_decay = Transition s: { B: -1 }, rate: 0.05
- run!
+ A = Place m!: 0.5 unless places.names.include? :A
+ B = Place m!: 0.5 unless places.names.include? :B
+ A_pump = TT s: { A: -1 } do 0.005 end unless transitions.names.include? :A_pump
+ B_decay = Transition s: { B: -1 }, rate: 0.05 unless transitions.names.include? :B_decay
end
- it "should behave" do
- places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
- s = simulation
- s.settings.must_equal( { method: :basic, guarded: false,
- step: 0.1, sampling: 5, time: 0..60 } )
- assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
- "0.0,0.5,0.5\n" +
- "5.0,0.475,0.38916\n" +
- "10.0,0.45,0.30289\n" +
- "15.0,0.425,0.23574\n" +
- "20.0,0.4,0.18348\n" +
- "25.0,0.375,0.1428\n" )
- assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
- s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
- 25.0, 30.0, 35.0, 40.0, 45.0,
- 50.0, 55.0, 60.0 ]
- s.recording.values_at( 5, 10 )
- .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
- s.recording.slice( 2..12 )
- .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
- s.recording.net
- .must_equal net
- s.recording.features
- .must_equal net.State.Features.marking( :A, :B )
- net.State.Features.State
- .must_equal net.State
- s.recording.net.State
- .must_equal net.State
- s.recording.series( marking: [:A] )
- .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
- 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
- s.net.State.Features.firing.map( &:transition ).names
- .must_equal [ :A_pump, :B_decay ]
- s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
- .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
- .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
- s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
- .must_equal [ 0.0005, 0.0025 ]
- s.recording.Firing( [] )
- .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
- s.recording
- .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
- .series
- .must_equal [ [ -0.0005 ] * 13 ]
+ # it "should work with the default method" do
+ # basic_simulation = new_simulation
+ # s = basic_simulation
+ # s.run!
+ # places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
+ # s.settings.must_equal( { method: :basic, guarded: false,
+ # step: 0.1, sampling: 5, time: 0..60 } )
+ # assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
+ # "0.0,0.5,0.5\n" +
+ # "5.0,0.475,0.38916\n" +
+ # "10.0,0.45,0.30289\n" +
+ # "15.0,0.425,0.23574\n" +
+ # "20.0,0.4,0.18348\n" +
+ # "25.0,0.375,0.1428\n" )
+ # assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
+ # s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
+ # 25.0, 30.0, 35.0, 40.0, 45.0,
+ # 50.0, 55.0, 60.0 ]
+ # s.recording.values_at( 5, 10 )
+ # .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
+ # s.recording.slice( 2..12 )
+ # .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
+ # s.recording.net
+ # .must_equal net
+ # s.recording.features
+ # .must_equal net.State.Features.marking( :A, :B )
+ # net.State.Features.State
+ # .must_equal net.State
+ # s.recording.net.State
+ # .must_equal net.State
+ # s.recording.series( marking: [:A] )
+ # .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
+ # 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
+ # s.net.State.Features.firing.map( &:transition ).names
+ # .must_equal [ :A_pump, :B_decay ]
+ # s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
+ # .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
+ # .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
+ # s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
+ # .must_equal [ 0.0005, 0.0025 ]
+ # s.recording.Firing( [] )
+ # .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
+ # s.recording
+ # .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
+ # .series
+ # .must_equal [ [ -0.0005 ] * 13 ]
+ # plot_state
+ # sleep 5
+ # end
+
+ # it "should work with :runge_kutta method" do
+ # rk_simulation = new_simulation( method: :runge_kutta )
+ # s = rk_simulation
+ # s.run!
+ # places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
+ # s.settings.must_equal( { method: :runge_kutta, guarded: false,
+ # step: 0.1, sampling: 5, time: 0..60 } )
+ # assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
+ # "0.0,0.5,0.5\n" +
+ # "5.0,0.475,0.38916\n" +
+ # "10.0,0.45,0.30289\n" +
+ # "15.0,0.425,0.23574\n" +
+ # "20.0,0.4,0.18348\n" +
+ # "25.0,0.375,0.1428\n" )
+ # assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
+ # s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
+ # 25.0, 30.0, 35.0, 40.0, 45.0,
+ # 50.0, 55.0, 60.0 ]
+ # s.recording.values_at( 5, 10 )
+ # .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
+ # s.recording.slice( 2..12 )
+ # .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
+ # s.recording.net
+ # .must_equal net
+ # s.recording.features
+ # .must_equal net.State.Features.marking( :A, :B )
+ # net.State.Features.State
+ # .must_equal net.State
+ # s.recording.net.State
+ # .must_equal net.State
+ # s.recording.series( marking: [:A] )
+ # .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
+ # 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
+ # s.net.State.Features.firing.map( &:transition ).names
+ # .must_equal [ :A_pump, :B_decay ]
+ # s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
+ # .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
+ # .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
+ # s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
+ # .must_equal [ 0.0005, 0.0025 ]
+ # s.recording.Firing( [] )
+ # .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
+ # s.recording
+ # .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
+ # .series
+ # .must_equal [ [ -0.0005 ] * 13 ]
+ # plot_state
+ # sleep 5
+ # end
+end
+
+describe "timed simulation with other methods" do
+ before do
+ self.class.class_exec { include YPetri }
+ A = Place m!: 0.5 unless places.names.include? :A
+ B = Place m!: 0.5 unless places.names.include? :B
+ A_pump = TT s: { A: -1 } do 0.005 end unless transitions.names.include? :A_pump
+ B_decay = Transition s: { B: -1 }, rate: 0.05 unless transitions.names.include? :B_decay
+ end
+
+ it "should work with :runge_kutta method" do
+ rk_simulation = new_simulation( method: :runge_kutta )
+ s = rk_simulation
+ s.state.to_a.must_equal [ 0.5, 0.5 ]
+ c = s.rk_core
+ c.must_be_kind_of YPetri::Core::Timed
+ c.marking_of_free_places.annotation.names.must_equal c.free_pp.names
+ c.marking_of_clamped_places.annotation.names.must_equal c.clamped_pp.names
+ c.simulation_method.must_equal :runge_kutta
+ c.marking_of_free_places.reset! [ 1.5, 1.5 ]
+ c.reset_time! 1.5
+ c.time.must_equal 1.5
+ c.state.to_a.must_equal [ 1.5, 1.5 ]
+ x = []
+ c.set_user_alert_closure do |mv| x << mv.to_a; x.flatten end
+ c.step! 2.0
+ c.time.must_equal 3.5
+ c.state.to_a.must_equal [ 1.49, 1.35725625 ]
+ s.time.must_equal 0.0
+ s.step.must_equal 0.1
+ s.step!
+ s.state.to_a[ 0 ].must_equal 0.4995
+ s.state.to_a[ 1 ].must_be_within_epsilon 0.49750624
+ s.time.must_equal 0.1
+ s.step = 5.0
+ s.run!
+ s.time.must_equal 60.0
+ puts
+ puts "by Runge-Kutta method (step #{s.step}):"
+ p s.state.to_h
+ s.state.to_a[ 0 ].must_be_within_epsilon 0.2
+ s.state.to_a[ 1 ].must_be_within_epsilon 0.024893534
plot_state
+ s = new_simulation
+ s.run!
+ puts
+ puts "by Euler method (step #{s.step}):"
+ p s.state.to_h
sleep 5
end
end