Here is a version that can handle multiple input
piddles for the whereND condition mask:

sub whereND2 {

   my $mask = pop @_;  # $mask has 0==false, 1==true
   my @to_return;

   foreach my $arr (@_) {

      # $arr  is M dimensional
      # $mask is N < M dimensional
      # dims($arr) 1..N == dims($mask) 1..N
      # thread over N+1 to M dimensions

      my $n = sum($mask);
      my $sub_i = $mask * ones($arr);
      my $where_sub_i = where $arr, $sub_i;

      # count the number of dims in $mask and $arr
      # $mask = a b c d e f.....
      my @idims = dims($arr);

      # ...and pop off the number of dims in $mask
      foreach ( dims($mask) ) { shift(@idims) };

      my $ndim = 0;
      foreach my $id ($n, @idims[0..($#idims-1)]) {
         $where_sub_i = $where_sub_i->splitdim($ndim++,$id);
      }

      push @to_return, $where_sub_i;
   }

   return (@to_return == 1) ? $to_return[0] : @to_return;
}

One interesting test would be if code using where could
replace that with calls to whereND and get the same
results for cases where where works.

--Chris


On 8/7/2011 7:34 PM, chm wrote:
I saw this thread and was thinking about where to
incorporate it into the PDL distribution but I
didn't like the use of whichND and indexND to
work around the fact that reshape is not a slicing
operation.

I was able to implement a slice version of
reshape using the splitdim method which appears
to give the same results. The loop over the
additional pdls could be added to this version
as well...

sub whereND2 {
use strict;
my ($i, $w) = @_;

# w is a mask 0 = false, 1 = true
# i is M dimensional
# w is N < M dimensional
# dims(i) 1..N == dims(i) 1..N
# thread over N+1 to M dimensions

my $n = sum($w);

my $sub_i = $w * ones($i);

my $where_sub_i = $i->where($sub_i);

# count the number of dims in w and i
# w = a b c d e f.....
my @idims = dims($i);
# ...and pop off the number of dims in w
foreach(dims($w)){shift(@idims)};

$where_sub_i = $where_sub_i->splitdim(0,$n);
my $ndim = 1;
foreach my $id (@idims[0..($#idims-1)]) {
$where_sub_i = $where_sub_i->splitdim($ndim++,$id);
}

return ($where_sub_i);
}

Maybe we could make reshape inplace-aware with the
inplace being the original version and the non-inplace
one based on slicing.

--Chris


On 5/13/2010 1:46 AM, David Mertens wrote:
If you want the syntax to be in line with where's syntax, you could
pop $w
off at the beginning and then apply the same routine to each element
in @_.
I've modified your function (untested) to give you an idea of what I
mean:

sub whereND {
use strict; # ?
# w is a mask 0 = false, 1 = true
my $w = pop @_;
my @to_return;
foreach my $i (@_) {
# i is M dimensional
# w is N< M dimensional
# dims(i) 1..N == dims(i) 1..N
# thread over N+1 to M dimensions

my $n = sum($w);
my $mask = $w * ones($i);

# count the number of dims in w and i
# w = a b c d e f.....
my @idims = dims($i);
# ...and pop off the number of dims in w
foreach(dims($w)){shift(@idims)};

# calculate the indicies of $mask
my $t = whichND($mask);

# reshape $t so that it will look into $i correctly
$t->reshape($mask->ndims, $n, @idims);

push (@to_return, $i->indexND($t));
}

return @to_return;
}

David

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


-----
No virus found in this message.
Checked by AVG - www.avg.com
Version: 10.0.1391 / Virus Database: 1520/3818 - Release Date: 08/07/11




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

Reply via email to