Re: Arbitrarily Many Nested Loops



In article <1143679874.629703.156690@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>,
Jacob JKW <jacobcdf@xxxxxxxxx> wrote:

This is what I have:

-------------
#!perl

for (my $i = 0; $i<=$n_ra->[0]; $i++) {
for (my $j = 0; $j<=$n_ra->[1]; $j++) {
for (my $k = 0; $k<=$n_ra->[2]; $k++) {
$prob_ra->[$i+$j+$k] += (
$f_raa->[0]->[$i] *
$f_raa->[1]->[$j] *
$f_raa->[2]->[$k] *
);
}
}
-------------
But that's obviously messy and more imprtantly I'd like to be able to
decide at run time to have how nested levels to go (probably be on the
order of 50 or 60). I assume that there's a canonical manner in which
this should be handled (using closures I'd guess) but I can't
sufficiently summarize my issue to make it Google-able.

Any advice?

This question was asked several weeks ago, and Anno Siegel had a most
elegant solution. I googled for it but couldn't find. While I can't
hope to reproduce Anno's elegance, here is one possible solution in
three dimensions which can be extended to more dimensions:


#!/usr/local/bin/perl
use warnings;
use strict;

my @n_ra = ( 3, 4, 2 );
my $len = @n_ra;

my( $prob_ra, $f_raa );

for my $i ( 0 .. $#n_ra ) {
for my $j ( 0 .. $n_ra[$i] ) {
$f_raa->[$i]->[$j] = rand;
}
}

my @current = ( 0 ) x $len;
my $position = $#n_ra;

while( $position >= 0 ) {
process(\@current);
$position = $#n_ra;
while( $position >= 0 ) {
if( $current[$position] < $n_ra[$position] ) {
$current[$position]++;
last;
}else{
$current[$position] = 0;
$position--;
}
}
}

for my $i ( 0 .. $#{$prob_ra} ) {
print "\$prob_ra[$i] = $prob_ra->[$i]\n";
}

sub process
{
my $current = shift;
print "processing (", join(',',@$current), ")\n";
my $index = 0;
my $prob = 1;
for my $i ( 0 .. $#{$current} ) {
$index += $current->[$i];
$prob *= $f_raa->[$i]->[$current->[$i]];
}
$prob_ra->[$index] += $prob;
}


which produces ...

processing (0,0,0)
processing (0,0,1)
processing (0,0,2)
processing (0,1,0)
processing (0,1,1)
processing (0,1,2)
processing (0,2,0)
processing (0,2,1)
processing (0,2,2)
..
.. [48 lines snipped]
..
processing (3,4,0)
processing (3,4,1)
processing (3,4,2)
$prob_ra[0] = 0.0410682133293649
$prob_ra[1] = 0.136947054256266
$prob_ra[2] = 0.314276516273359
$prob_ra[3] = 0.518803631872173
$prob_ra[4] = 0.736548073593054
$prob_ra[5] = 0.880817464919632
$prob_ra[6] = 0.737055690539397
$prob_ra[7] = 0.623231710116926
$prob_ra[8] = 0.33823563959137
$prob_ra[9] = 0.0982766937328925

Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
.



Relevant Pages

  • Re: kd trees in c#?
    ... I'm new to C# but have done some perl and other bits of programming in ... dimensions, let's just say 4 dimesions but could be more. ... d will return the the items closest the point - so 1-10 first then ... I've read that a kd-tree is the way to go but not sure how to ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: transform numbers in an array
    ... M> Thank you David and Uri. ... M> Very elegant solution! ... it isn't elegant but rather basic perl. ...
    (perl.beginners)
  • Re: Piping output to and from external perl routine
    ... Dan Fish wrote: ... > elegant solution, because I'm sure I'll need to do something similar ... use Perl; ...
    (perl.beginners)