use Benchmark qw(:all); use File::Path qw(mkpath); use application 'polytope'; # prints a progressbar # @param Int got : the amount of stuff you have already got # @param Int total : the total amount of stuff # @param Int width : the width of the progressbar # @param Char char : a character which symbolize done stuff # @param String text : additional text behind the bar. sub progress_bar { my ( $got, $total, $width, $char, $text) = @_; local $| = 1; printf "|%-${width}s| $got/$total | %-80s \r", $char x (($width)*$got/$total). '>', $text; } # computes a random voronoi diagram prefering a specific convex hull # algorithm and takes the time # @param String ch the prefered convex hull method (possible options: beneath_beyond, lrs, cdd) # @param Int d the dimension # @param Int n the number of random points in the cube sub time_voronoi($$$) { my ($ch, $d, $n) = @_; my $c=cube($d-1); my $r=rand_inner_points($c,$n); my $v=new VoronoiDiagram(SITES=>$r->POINTS); my $t; if(($ch eq "beneath_beyond") || ($ch eq "porta")) { $v=polarize($v); prefer_now $ch; my $s=$v->get_schedule("FACETS"); my $t0=Benchmark->new; $s->apply($v); my $t1=Benchmark->new; $t=timediff($t1,$t0); } elsif($ch eq "libnormaliz"){ # code calling nmz directly: my$t0=Benchmark->new; normaliz_compute($v,from_facets=>1, dual_algorithm=>0,rays=>1,verbose=>0,skip_long=>1); my $t1=Benchmark->new; $t=timediff($t1,$t0); } else { prefer_now $ch; my $s=$v->get_schedule("VERTICES"); my $t0=Benchmark->new; $s->apply($v); my $t1=Benchmark->new; $t=timediff($t1,$t0); } if($ch eq "porta"){ return $t->cpu_c; }else{ return $t->cpu_p; } } # computes several voronoi diagrams and takes the time. The number of points goes up by 100 # @param Array ch the prefered convex hull method (possible options: beneath_beyond, lrs, cdd) # @param Int start_d the lower bound of the dimension # @param Int end_d the upper bound of the dimension # @param Int start_n the lower bound of the number of random points in the cube # @param Int end_n the upper bound of the number of random points in the cube # @option Int dimstep stepsize of the dimension # @option Int bstep stepsize of the right hand side # @option Int av number of experiments for one parameter set # @option String path output path # @option Hash only_once parameters that should run only once # @option Int time_limit maximum time (+10%) to skip following tests sub start_time_voronoi($$$$$;$) { my ($ch, $start_d, $end_d, $start_n, $end_n, $options) = @_; my $dimstep = $options->{"dimstep"}; # stepsize of the dimension my $nstep = $options->{"nstep"}; # stepsize of n my $av = $options->{"av"}; # number of experiements with the same parameterset my $path = $options->{"path"}; # output path my $only_once = $options->{"only_once"}; # which parameters should run only once my $time_limit = $options->{"time_limit"}; # time limit # set defaults for options if (!defined($options->{"dimstep"})) { $dimstep=1; } if (!defined($options->{"nstep"})) { $nstep=500; } if (!defined($options->{"av"})) { $av=10; } if (!defined($options->{"path"})) { $path="."; } if (!defined($options->{"only_once"})) { $only_once = {}; } if (!defined($options->{"time_limit"})) { $time_limit = 3600; } # create output path if (!-d $path){ mkpath $path or die "can't create ouput directory: $path"; } # convert $end_n to an array if (!(ref($end_n) eq "ARRAY")){ my @array=(); map { push @array, $end_n } ($start_d .. $end_d); $end_n = \@array; } # for pretty print for progress bar my $length_d = length $end_d; my $length_n = length $end_n->[0]; foreach my $chcode (@{$ch}) { my $skip = 0; my $file = "$path/voronoi_".$chcode.".csv"; # Open output file open OUTPUT_FILE, ">$file" or die "can't create outputfile $file: $!"; $|=1; OUTPUT_FILE->autoflush(1); print OUTPUT_FILE '"time(dimension x number) where dimension starts from '.$start_d.' to '.$end_d.' (steps are '.$dimstep.') and numbers from '. $start_n.' to '. $end_n->[0].' (number steps are '.$nstep.')"'. "\n"; print OUTPUT_FILE '"Matlab Commands: dim = '.$start_d.':'.$end_d.' and points ='.$start_n.':'.$nstep.':'.$end_n->[0].' and mesh(points,dim,import)"'."\n"; print "\n=== $chcode ===\n"; # first time without timing. Just to make sure no recompiling comes in the way #time_voronoi($chcode,$start_d,$start_n); for(my $d = $start_d; $d <= $end_d; ++$d){ for(my $n = $start_n; $n <= $end_n->[$d - $start_d]; $n+=$nstep){ # For every set of parameters do $av experiments and take the average my $t = 0; my $date=localtime(time); my $localav = exists($only_once->{ "$d,$n" }) ? 1: $av; progress_bar(0,$localav,10,'=',(sprintf "($d,$n): $date")); for(my $i=0; $i < $localav; ++$i){ my $time = time_voronoi($chcode,$d,$n); $t += $time; $date=localtime(time); progress_bar($i+1,$localav,10,'=',(sprintf "($d,$n): %9.3f -- $date", $time)); if($time > 1.1*$time_limit){ $skip=1; $localav = $i+1; #for correct average last; } } $t = sprintf "%.3f", $t/$localav; my $date=localtime(time); printf "(%${length_d}s,%${length_n}s): %9.3f -- %-80s\n", $d, $n, $t, $date; print OUTPUT_FILE $t.';'; last if($skip); } print OUTPUT_FILE "\n"; # we do not want to skip the dimension computations which follows #last if($skip); $skip = 0; } close OUTPUT_FILE; } } # computes several voronoi diagrams and takes the time. The number of points goes up by 100 # @param Array ch the prefered convex hull method (possible options: beneath_beyond, lrs, cdd) # @param Int d the dimension # @param Int n the number of random points in the cube # @param Int times the number of experiments # @option String path output path sub stats_voronoi($$$$;$) { my ($ch, $d, $n, $times, $options) = @_; my $length_d = length $d; # needed for pretty print for progress bar my $length_n = length $n; # needed for pretty print for progress bar my $path = $options->{"path"}; # output path if (!defined($options->{"path"})) { $path="."; } # create output path if (!-d $path){ mkpath $path or die "can't create ouput directory: $path"; } foreach my $chcode (@{$ch}) { my $file= "$path/voronoi_stat_".$chcode.".csv"; # Open output file open OUTPUT_FILE, ">$file" or die "can't create outputfile $file: $!"; $|=1; OUTPUT_FILE->autoflush(1); print OUTPUT_FILE '"time(dimension x number) where dimension is '.$d.' and the number of points is '. $n.'. The number of experiments is '.$times.'"'. "\n"; print "\n=== $chcode ===\n"; my $date=localtime(time); progress_bar(0,$times,10,'=',(sprintf "($d,$n): $date")); for(my $i = 1; $i <= $times; ++$i){ # first time without timing. Just to make sure no recompiling comes in the way #time_voronoi($chcode,$d,$n); # For every set of parameters do 10 experiments and take the average my $time = time_voronoi($chcode,$d,$n); $date=localtime(time); progress_bar($i+1,$times,10,'=',(sprintf "($d,$n): %9.3f -- $date", $time)); print OUTPUT_FILE $time."\n"; } my $date=localtime(time); printf "(%${length_d}s,%${length_n}s): %-80s\n", $d, $n, $date; close OUTPUT_FILE; } } # computes several voronoi diagrams and computes the vertices # @param Int d the dimension # @param Int n the number of random points in the cube # @param Int times the number of experiments sub stats_vertices_voronoi($$$$;$) { my ($ch,$d, $n, $times, $options) = @_; my $length_d = length $d; # needed for pretty print for progress bar my $length_n = length $n; # needed for pretty print for progress bar my $file= "voronoi_stat_vertices.csv"; # Open output file open OUTPUT_FILE, ">$file" or die "can't create outputfile $file: $!"; $|=1; OUTPUT_FILE->autoflush(1); print OUTPUT_FILE '"time(dimension x number) where dimension is '.$d.' and the number of points is '. $n.'. The number of experiments is '.$times.'"'. "\n"; print "\n=== Stats Vertices ===\n"; for(my $i = 1; $i <= $times; ++$i){ my $c=cube($d-1); my $r=rand_inner_points($c,$n); my $v=new VoronoiDiagram(SITES=>$r->POINTS); prefer_now $ch; my $s=$v->get_schedule("VERTICES"); $s->apply($v); my $date=localtime(time); progress_bar($i,$times,10,'=',"($d,$n): $date"); print OUTPUT_FILE $v->N_VERTICES."\n"; } my $date=localtime(time); printf "(%${length_d}s,%${length_n}s): %-80s\n", $d, $n, $date; close OUTPUT_FILE; } ## If you want to trigger the run commands automatically just remove the next line return; # set environment: export OMP_NUM_THREADS=1 $path = "/path/to/store/the/output/files"; # no porta because coordinates are too ugly (porta does not use gmp) start_time_voronoi(["beneath_beyond"],3,7,500,[3000,3000,3000,3000,1000], { path=>$path, only_once=>{"7,1000"=>1 } }); start_time_voronoi(["cdd"],3,6,500,[3000,3000,1500,500], { path=>$path, "5,1500"=>1 }); start_time_voronoi(["lrs"],3,7,500,[3000,3000,3000,3000,1000], { path=>$path, only_once=>{"6,3000"=>1 } }); start_time_voronoi(["libnormaliz"],3,7,500,[3000,3000,3000,1500,500], { path=>$path }); start_time_voronoi(["ppl"],3,6,500,[3000,3000,2500,1000], { path=>$path, only_once=>{"5,2500"=>1, "6,1000"=>1 } }); ## Running one example many times (1000) to check standard deviation #stats_voronoi(["beneath_beyond","cdd","lrs","ppl","libnormaliz"],5,500,1000, { path=>$path } );