Re: Arbitrarily Many Nested Loops




David Formosa (aka ? the Platypus) wrote:
On 29 Mar 2006 16:51:14 -0800, 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.

I quickly worked out one way to do this, no guarties as to effeceny.

sub closefor (&$@) {
my $sub = shift;
my $range = shift;

return sub {
for my $i (0..$range){
$sub->($i,@_)
}
}
}

sub mulitloop (&@) {
my $sub = shift;
for (@_) {
my $oldsub = $sub;
$sub = closefor {$oldsub->(@_)} $_;
}
$sub->();
}

Your code becomes

mulitloop { my $i = shift;
my $j = shift;
my $k = shift;
$prob_ra->[$i+$j+$k] += $f_raa->[0]->[$i] *
$f_raa->[1]->[$j] *
$f_raa->[2]->[$k]
} @$n_ra;

To convert the algorithm into something that does arbitrarily depth
involves a small reworking the insides so that it works with an
arbitrary number of arguments.

mulitloop {
my $sum = 0;
my $product = 1;
for (my $i; $i<=@#_; $i++) {
$sum += $_[$i];
$product *= $f_raa->[$i]->[$_[$i]];
}
$prob_ra->[$sum] += $product;
} @$n_ra;

--
You know as clever and elegant as this method is, it actually runs
significantly than my original ugly cut-and-paste style, which I
suppose shouldn't have come as any surprise as when is elegance ever
free?

Anyway, I'm going to keep this code for further use and some later
date, but I eventyually went with John Krahn eval method posted above.
Ugly but fast,

Thanks again for your help.

.



Relevant Pages

  • sitemap generator for Perl
    ... I want to run the sitemap generator ... Returns the minimum number of links to traverse from the root URL of ... my $class = shift; ...
    (perl.beginners)
  • Re: Arbitrarily Many Nested Loops
    ... sub closefor { ... my $range = shift; ... sub mulitloop { ... Please excuse my spelling as I suffer from agraphia. ...
    (comp.lang.perl.misc)
  • Re: How can I create instantiable objects (not classes)?
    ... a child object inherits not only its parent object's ... sub fee { ... my $class = shift; ... For example, an object of type Car might receive a message named "ticket," and since a car does not know what to do with a ticket, it would pass that message to an object of type Driver. ...
    (comp.lang.perl.misc)
  • Re: Packages and returning errors
    ... > array intact. ... sub is_a_instance_method { ... my $class = shift; ... You need to fix the scope of $error by moving its declaration outside ...
    (comp.lang.perl.misc)
  • Re: passing database data to a sub
    ... > I'm not sure of the difference, why isn't it a subroutine? ... > sure about this 'shift' thing anyway :-) ... > sub teardown ... > # Setup the template to use for the output. ...
    (perl.beginners)