Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^4: Monte Carlo - Coin Toss

by repellent (Priest)
on Mar 13, 2011 at 04:31 UTC ( #892898=note: print w/ replies, xml ) Need Help??


in reply to Re^3: Monte Carlo - Coin Toss
in thread Monte Carlo - Coin Toss

Here's a slightly speedier alternative to get Pascal's triangle row for the number of tosses:

sub pascal_tri_row { my $r = shift; return () if $r < 0; my @row = (1) x ($r + 1); for my $i (1 .. $r - 1) { $row[$_] += $row[$_ - 1] for reverse 1 .. $i; } return @row; } sub triangle { my $numTosses = shift; my @triangle = (0, 1, 0); for (1 .. $numTosses) { my @newTriangle=(0); push @newTriangle, $triangle[$_]+$triangle[$_+1] for 0 .. $#tr +iangle-1; push @newTriangle, 0; @triangle = @newTriangle; } return @triangle; } use Benchmark qw(cmpthese); cmpthese -1, { robo_tri => sub { triangle(32) }, repel_tri => sub { 0, pascal_tri_row(32), 0 }, # 0's to match tria +ngle()'s return }; __END__ Rate robo_tri repel_tri robo_tri 1128/s -- -38% repel_tri 1811/s 60% --


Comment on Re^4: Monte Carlo - Coin Toss
Download Code
Re^5: Monte Carlo - Coin Toss
by roboticus (Canon) on Mar 13, 2011 at 05:45 UTC

    repellent:

    Sweet! So of course I had to take another look:

    sub pascal_tri_row { my $r = shift; return () if $r < 0; my @row = (1) x ($r + 1); for my $i (1 .. $r - 1) { $row[$_] += $row[$_ - 1] for reverse 1 .. $i; } return @row; } sub robo_2 { my $row = shift; my @cols = (1); ++$row; $cols[$_] = $cols[$_-1] * ($row-$_)/$_ for 1 .. $row-1; return @cols; } sub triangle { my $numTosses = shift; my @triangle = (0, 1, 0); for (1 .. $numTosses) { my @newTriangle=(0); push @newTriangle, $triangle[$_]+$triangle[$_+1] for 0 .. $#tr +iangle-1; push @newTriangle, 0; @triangle = @newTriangle; } return @triangle[1..$#triangle-1]; } use Benchmark qw(cmpthese); print "robo_1: ", join(" ",triangle(8)), "\n"; print "repel1: ", join(" ",pascal_tri_row(8)), "\n"; print "robo_2: ", join(" ",robo_2(8)), "\n"; cmpthese -1, { robo_tri => sub { triangle(32) }, repel_tri => sub { pascal_tri_row(32) }, robo_2 => sub { robo_2(32) }, };

    First I put in a trace so I could be sure I wasn't generating useless values. Next, I couldn't bear the zeroes you had to add to your function to match my original return value. They were just sentinel values to simplify the calculation, anyway. So I fixed the original to return only the values of interest. Finally, I had to squeeze a little more speed out of it:

    $ perl 892898.pl robo_1: 1 8 28 56 70 56 28 8 1 repel1: 1 8 28 56 70 56 28 8 1 robo_2: 1 8 28 56 70 56 28 8 1 Rate robo_tri repel_tri robo_2 robo_tri 2196/s -- -42% -93% repel_tri 3775/s 72% -- -88% robo_2 31946/s 1355% 746% --

    You should've read a bit further down in the wikipedia article you linked. It had a much better algorithm for calculating the coefficients of any row. It saved a nested loop.

    ;^)

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Wonderful! That is the one. Thanks, roboticus.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://892898]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2014-07-24 11:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (160 votes), past polls