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

Reply via email to