y_petri 2.3.12 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -321,61 +321,222 @@ require_relative '../lib/y_petri' # tested component itself
321
321
  # end
322
322
  # end
323
323
 
324
- describe "timed simulation" do
324
+ # describe "timed simulation" do
325
+ # before do
326
+ # self.class.class_exec { include YPetri }
327
+ # A = Place m!: 0.5
328
+ # B = Place m!: 0.5
329
+ # A_pump = TT s: { A: -1 } do 0.005 end
330
+ # B_decay = Transition s: { B: -1 }, rate: 0.05
331
+ # run!
332
+ # end
333
+
334
+ # it "should work with the default method" do
335
+ # places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
336
+ # s = simulation
337
+ # s.settings.must_equal( { method: :basic, guarded: false,
338
+ # step: 0.1, sampling: 5, time: 0..60 } )
339
+ # assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
340
+ # "0.0,0.5,0.5\n" +
341
+ # "5.0,0.475,0.38916\n" +
342
+ # "10.0,0.45,0.30289\n" +
343
+ # "15.0,0.425,0.23574\n" +
344
+ # "20.0,0.4,0.18348\n" +
345
+ # "25.0,0.375,0.1428\n" )
346
+ # assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
347
+ # s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
348
+ # 25.0, 30.0, 35.0, 40.0, 45.0,
349
+ # 50.0, 55.0, 60.0 ]
350
+ # s.recording.values_at( 5, 10 )
351
+ # .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
352
+ # s.recording.slice( 2..12 )
353
+ # .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
354
+ # s.recording.net
355
+ # .must_equal net
356
+ # s.recording.features
357
+ # .must_equal net.State.Features.marking( :A, :B )
358
+ # net.State.Features.State
359
+ # .must_equal net.State
360
+ # s.recording.net.State
361
+ # .must_equal net.State
362
+ # s.recording.series( marking: [:A] )
363
+ # .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
364
+ # 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
365
+ # s.net.State.Features.firing.map( &:transition ).names
366
+ # .must_equal [ :A_pump, :B_decay ]
367
+ # s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
368
+ # .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
369
+ # .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
370
+ # s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
371
+ # .must_equal [ 0.0005, 0.0025 ]
372
+ # s.recording.Firing( [] )
373
+ # .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
374
+ # s.recording
375
+ # .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
376
+ # .series
377
+ # .must_equal [ [ -0.0005 ] * 13 ]
378
+ # plot_state
379
+ # sleep 5
380
+ # end
381
+ # end
382
+
383
+ describe "timed simulation with other methods" do
384
+ before do
385
+ self.class.class_exec { include YPetri }
386
+ A = Place m!: 0.5 unless places.names.include? :A
387
+ B = Place m!: 0.5 unless places.names.include? :B
388
+ A_pump = TT s: { A: -1 } do 0.005 end unless transitions.names.include? :A_pump
389
+ B_decay = Transition s: { B: -1 }, rate: 0.05 unless transitions.names.include? :B_decay
390
+ end
391
+
392
+ # it "should work with the default method" do
393
+ # basic_simulation = new_simulation
394
+ # s = basic_simulation
395
+ # s.run!
396
+ # places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
397
+ # s.settings.must_equal( { method: :basic, guarded: false,
398
+ # step: 0.1, sampling: 5, time: 0..60 } )
399
+ # assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
400
+ # "0.0,0.5,0.5\n" +
401
+ # "5.0,0.475,0.38916\n" +
402
+ # "10.0,0.45,0.30289\n" +
403
+ # "15.0,0.425,0.23574\n" +
404
+ # "20.0,0.4,0.18348\n" +
405
+ # "25.0,0.375,0.1428\n" )
406
+ # assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
407
+ # s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
408
+ # 25.0, 30.0, 35.0, 40.0, 45.0,
409
+ # 50.0, 55.0, 60.0 ]
410
+ # s.recording.values_at( 5, 10 )
411
+ # .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
412
+ # s.recording.slice( 2..12 )
413
+ # .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
414
+ # s.recording.net
415
+ # .must_equal net
416
+ # s.recording.features
417
+ # .must_equal net.State.Features.marking( :A, :B )
418
+ # net.State.Features.State
419
+ # .must_equal net.State
420
+ # s.recording.net.State
421
+ # .must_equal net.State
422
+ # s.recording.series( marking: [:A] )
423
+ # .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
424
+ # 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
425
+ # s.net.State.Features.firing.map( &:transition ).names
426
+ # .must_equal [ :A_pump, :B_decay ]
427
+ # s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
428
+ # .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
429
+ # .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
430
+ # s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
431
+ # .must_equal [ 0.0005, 0.0025 ]
432
+ # s.recording.Firing( [] )
433
+ # .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
434
+ # s.recording
435
+ # .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
436
+ # .series
437
+ # .must_equal [ [ -0.0005 ] * 13 ]
438
+ # plot_state
439
+ # sleep 5
440
+ # end
441
+
442
+ # it "should work with :runge_kutta method" do
443
+ # rk_simulation = new_simulation( method: :runge_kutta )
444
+ # s = rk_simulation
445
+ # s.run!
446
+ # places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
447
+ # s.settings.must_equal( { method: :runge_kutta, guarded: false,
448
+ # step: 0.1, sampling: 5, time: 0..60 } )
449
+ # assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
450
+ # "0.0,0.5,0.5\n" +
451
+ # "5.0,0.475,0.38916\n" +
452
+ # "10.0,0.45,0.30289\n" +
453
+ # "15.0,0.425,0.23574\n" +
454
+ # "20.0,0.4,0.18348\n" +
455
+ # "25.0,0.375,0.1428\n" )
456
+ # assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
457
+ # s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
458
+ # 25.0, 30.0, 35.0, 40.0, 45.0,
459
+ # 50.0, 55.0, 60.0 ]
460
+ # s.recording.values_at( 5, 10 )
461
+ # .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
462
+ # s.recording.slice( 2..12 )
463
+ # .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
464
+ # s.recording.net
465
+ # .must_equal net
466
+ # s.recording.features
467
+ # .must_equal net.State.Features.marking( :A, :B )
468
+ # net.State.Features.State
469
+ # .must_equal net.State
470
+ # s.recording.net.State
471
+ # .must_equal net.State
472
+ # s.recording.series( marking: [:A] )
473
+ # .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
474
+ # 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
475
+ # s.net.State.Features.firing.map( &:transition ).names
476
+ # .must_equal [ :A_pump, :B_decay ]
477
+ # s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
478
+ # .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
479
+ # .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
480
+ # s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
481
+ # .must_equal [ 0.0005, 0.0025 ]
482
+ # s.recording.Firing( [] )
483
+ # .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
484
+ # s.recording
485
+ # .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
486
+ # .series
487
+ # .must_equal [ [ -0.0005 ] * 13 ]
488
+ # plot_state
489
+ # sleep 5
490
+ # end
491
+ end
492
+
493
+ describe "timed simulation with other methods" do
325
494
  before do
326
495
  self.class.class_exec { include YPetri }
327
- A = Place m!: 0.5
328
- B = Place m!: 0.5
329
- A_pump = TT s: { A: -1 } do 0.005 end
330
- B_decay = Transition s: { B: -1 }, rate: 0.05
331
- run!
496
+ A = Place m!: 0.5 unless places.names.include? :A
497
+ B = Place m!: 0.5 unless places.names.include? :B
498
+ A_pump = TT s: { A: -1 } do 0.005 end unless transitions.names.include? :A_pump
499
+ B_decay = Transition s: { B: -1 }, rate: 0.05 unless transitions.names.include? :B_decay
332
500
  end
333
501
 
334
- it "should behave" do
335
- places.map( &:marking ).must_equal [0.5, 0.5] # marking unaffected
336
- s = simulation
337
- s.settings.must_equal( { method: :basic, guarded: false,
338
- step: 0.1, sampling: 5, time: 0..60 } )
339
- assert s.recording.to_csv.start_with?( ":event,:A,:B\n" +
340
- "0.0,0.5,0.5\n" +
341
- "5.0,0.475,0.38916\n" +
342
- "10.0,0.45,0.30289\n" +
343
- "15.0,0.425,0.23574\n" +
344
- "20.0,0.4,0.18348\n" +
345
- "25.0,0.375,0.1428\n" )
346
- assert s.recording.to_csv.end_with?( "60.0,0.2,0.02471" )
347
- s.recording.events.must_equal [ 0.0, 5.0, 10.0, 15.0, 20.0,
348
- 25.0, 30.0, 35.0, 40.0, 45.0,
349
- 50.0, 55.0, 60.0 ]
350
- s.recording.values_at( 5, 10 )
351
- .must_equal [ [0.475, 0.38916], [0.45, 0.30289] ]
352
- s.recording.slice( 2..12 )
353
- .must_equal( { 5.0 => [0.475, 0.38916], 10.0=>[0.45, 0.30289] } )
354
- s.recording.net
355
- .must_equal net
356
- s.recording.features
357
- .must_equal net.State.Features.marking( :A, :B )
358
- net.State.Features.State
359
- .must_equal net.State
360
- s.recording.net.State
361
- .must_equal net.State
362
- s.recording.series( marking: [:A] )
363
- .must_equal [ [ 0.5, 0.475, 0.45, 0.425, 0.4, 0.375, 0.35, 0.325,
364
- 0.3, 0.275, 0.25, 0.225, 0.2 ] ]
365
- s.net.State.Features.firing.map( &:transition ).names
366
- .must_equal [ :A_pump, :B_decay ]
367
- s.recording.reduce_features( s.net.State.Features.firing, Δt: 1 )
368
- .to_h.take( 2 ).map( &:flatten! ).map { |a| a.map &[:round, 6 ] }
369
- .must_equal [ [ 0.0, 0.005, 0.025 ], [ 5.0, 0.005, 0.019458 ] ]
370
- s.recording.firing( Δt: 0.1 ).series.map( &:first ).map( &[ :round, 6 ] )
371
- .must_equal [ 0.0005, 0.0025 ]
372
- s.recording.Firing( [] )
373
- .must_equal( [*0..12].map { |n| n * 5.0 } >> [[]] * 13 )
374
- s.recording
375
- .delta( :A, transitions: [:A_pump], delta_time: 0.1 )
376
- .series
377
- .must_equal [ [ -0.0005 ] * 13 ]
502
+ it "should work with :runge_kutta method" do
503
+ rk_simulation = new_simulation( method: :runge_kutta )
504
+ s = rk_simulation
505
+ s.state.to_a.must_equal [ 0.5, 0.5 ]
506
+ c = s.rk_core
507
+ c.must_be_kind_of YPetri::Core::Timed
508
+ c.marking_of_free_places.annotation.names.must_equal c.free_pp.names
509
+ c.marking_of_clamped_places.annotation.names.must_equal c.clamped_pp.names
510
+ c.simulation_method.must_equal :runge_kutta
511
+ c.marking_of_free_places.reset! [ 1.5, 1.5 ]
512
+ c.reset_time! 1.5
513
+ c.time.must_equal 1.5
514
+ c.state.to_a.must_equal [ 1.5, 1.5 ]
515
+ x = []
516
+ c.set_user_alert_closure do |mv| x << mv.to_a; x.flatten end
517
+ c.step! 2.0
518
+ c.time.must_equal 3.5
519
+ c.state.to_a.must_equal [ 1.49, 1.35725625 ]
520
+ s.time.must_equal 0.0
521
+ s.step.must_equal 0.1
522
+ s.step!
523
+ s.state.to_a[ 0 ].must_equal 0.4995
524
+ s.state.to_a[ 1 ].must_be_within_epsilon 0.49750624
525
+ s.time.must_equal 0.1
526
+ s.step = 5.0
527
+ s.run!
528
+ s.time.must_equal 60.0
529
+ puts
530
+ puts "by Runge-Kutta method (step #{s.step}):"
531
+ p s.state.to_h
532
+ s.state.to_a[ 0 ].must_be_within_epsilon 0.2
533
+ s.state.to_a[ 1 ].must_be_within_epsilon 0.024893534
378
534
  plot_state
535
+ s = new_simulation
536
+ s.run!
537
+ puts
538
+ puts "by Euler method (step #{s.step}):"
539
+ p s.state.to_h
379
540
  sleep 5
380
541
  end
381
542
  end
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.3.12
4
+ version: 2.4.0
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-09 00:00:00.000000000 Z
11
+ date: 2015-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler