use strict; use warnings; use experimental qw/ say postderef signatures /; use Time::HiRes 'time'; use PDL; use PDL::NiceSlice; use Test::PDL 'eq_pdl'; use constant STEPS => 100; my \$x = zeroes( 200, 200 ); # Put in a simple glider. \$x(1:3,1:3) .= pdl ( [1,1,1], [0,0,1], [0,1,0] ); my \$backup = \$x-> copy; printf "Game of Life!\nMatrix: %s, %d generations\n", \$x-> info, STEPS; # Tutorial my \$t = time; my \$ct = 0; for ( 1 .. STEPS ) { my \$t_ = time; # Calculate the number of neighbours per cell. my \$n = \$x->range(ndcoords(\$x)-1,3,"periodic")->reorder(2,3,0,1); \$n = \$n->sumover->sumover - \$x; \$ct += time - \$t_; # Calculate the next generation. \$x = (((\$n == 2) + (\$n == 3))* \$x) + ((\$n==3) * !\$x); } printf "Tutorial: %0.3f s (core time: %0.3f)\n", time - \$t, \$ct; # "Lags" my \$m = \$backup-> copy; \$t = time; \$ct = 0; for ( 1 .. STEPS ) { my \$t_ = time; # Calculate the number of neighbours per cell. my \$n = sms_GoL_lags( \$m ) - \$m; \$ct += time - \$t_; # Calculate the next generation. \$m = (((\$n == 2) + (\$n == 3))* \$m) + ((\$n == 3) * !\$m); } printf "\"lags\": %0.3f s (core time: %0.3f)\n", time - \$t, \$ct; die unless eq_pdl( \$x, \$m ); sub _do_dimension_GoL ( \$m ) { \$m-> slice( -1 )-> glue( 0, \$m, \$m-> slice( 0 )) -> lags( 0, 1, ( \$m-> dims )[0] ) -> sumover -> slice( '', '-1:0' ) -> xchg( 0, 1 ) } sub sms_GoL_lags ( \$m ) { _do_dimension_GoL _do_dimension_GoL \$m } __END__ Game of Life! Matrix: PDL: Double D [200,200], 100 generations Tutorial: 1.016 s (core time: 0.835) "lags": 0.283 s (core time: 0.108)