And since indexND is implemented as a call to range, this might work for you.

This accomplishes the same thing, but without the for loops. It may or may not be easier for you to read at the moment! With this small test case I don't notice a huge improvement in speed but once you scale it up you should. If you didn't have the conditional "only if it's (non?)-zero", this would be much easier! As a bonus, learning about the functions I used here will hopefully start you thinking in vectors, which takes a bit of work.

cheers,
Derek

sub setme2{
   my ($x,$y,$value) = @_;
   my $xy = $x->cat($y)->transpose;
   my $change = ($found->range($xy)==0);
my $xychange = $xy->where($change->dummy(1,2)->transpose)->reshape(2,$change->sum);
   $found->range($xychange).=$value;
}

Craig DeForest wrote:
The routine you want is indexND, which will return a collection of points from your source PDL, but stacked up suitably for threaded assignment. I'll send an example when I'm at a real kbd and not a phone.

Craig DeForest

On Jan 3, 2008, at 12:02 PM, [EMAIL PROTECTED] wrote:

I'm new to PDL, though not new to Perl, and I'm trying to speed my assignment sub. I've read everything I can find about threading in PDL, and it's all
confused me rather than enlightening.

I have a large 2 dimensional piddle. I also have two piddles which are the X & Y coordinates in that piddle. I need to update the value of the large piddle but
only if it's non-zero.

This is the code I've come up with, which works, but is quite slow. Any advice?

#!/usr/bin/perl
use Test::Simple tests=>8;
use strict;
use warnings;
use PDL;

my $found = zeroes ushort,10,10;

my $x=pdl (1,1,2,4,5);
my $y=pdl (2,4,3,6,4);

setme($x,$y,10);

#neither 1,1 or 1,3 were mentioned in the list above, so should be 0
#both 1,2 and 1,4 were, so should be 10
ok(at($found,1,1)==0);
ok(at($found,1,2)==10);
ok(at($found,1,3)==0);
ok(at($found,1,4)==10);

$x=pdl (1,1,4,6,2);
$y=pdl (3,4,8,7,5);

setme($x,$y,11);

# This call updated 1,3 and 1,4, but 1,4 was already set, should not change
ok(at($found,1,1)==0);
ok(at($found,1,2)==10);
ok(at($found,1,3)==11);
ok(at($found,1,4)==10);

sub setme {
       my $x=shift;
       my $y=shift;
       my $value=shift;

       my ($max)=dims $x;
       if($max>0){
               foreach my $i (0..$max-1){
                       if(at($found,at($x,$i), at($y,$i))==0){
                               set $found, at($x,$i), at($y,$i),$value;
                       }
               }
       }
}

_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl


_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl


_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to