nickschurch has asked for the wisdom of the Perl Monks concerning the following question:

This is likely to make little sense to people who don't use the Perl Data Language module but here goes anyway...

I have a piddle containing a sequence of numbers from 0-9 and another piddle containing a subset of these numbers... ie:
my $a = sequence(10); print $a; [0,1,2,3,4,5,6,7,8,9] my $b = pdl(2,5,7); print $b; [2,5,7]
What I want to do is search within the larger piddle for values that match any of those in the second piddle, and return their index values. So in this case I'd end up with a piddle that looks like [3,6,8].
'which' seems like the logical structure for this but it doesn't work for more than one value... ie:
my $z = which($a==$b(1)); print $z; [3]
But
my $z = which($a==$b);
fails completely. Any ideas?

Replies are listed 'Best First'.
Re: perl PDL question
by Anonymous Monk on Nov 27, 2007 at 10:47 UTC
    What is happening is that your 2 arrays are being threaded over, however the dimensions don't match. The case that works has a 1 element pdl, which can be threaded over because pdl replicates length 1 dimensions as many times as necessary. Try this:
    my $a = sequence(10)->dummy; my $b = pdl(2,5,7); my $z = which(sumover($a == $b));
    This inserts a dummy dimension into $a so that $a is dimensionality (10,1) and $b is dimensionality (1,3). Dimensions of length 1 get threaded over nicely. The sumover is there to take away 1 of the dimensions (otherwise you get location in $a times location in $b) for matches
      Replace sumover with any. It is more appropriate for the context.
        The sumover part works, and produces the output array that is the appropriate indexes... brilliant!
        When I replace sumover($a==$b) with any($a==$b) I get an error though....
        perldl> $z = which(any($a == $b)); Can't call method "flat" without a package or object reference at /usr +/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/PDL/Primitive. +pm line 1962, <STDIN> line 20.
      Interestingly, this works fine from the perldl console, but in a scrip I get an error....
      my $time = rcols "testdata.txt"; my $tsearch = $time -> dummy; print $tsearch,"\n";
      produces:
      [njs@localhost]$ ./testcode Use of uninitialized value in numeric lt (<) at /usr/lib64/perl5/site_ +perl/5.8.8/x86_64-linux-thread-multi/PDL/Core.pm line 936. Use of uninitialized value in numeric lt (<) at /usr/lib64/perl5/site_ +perl/5.8.8/x86_64-linux-thread-multi/PDL/Core.pm line 939. Use of uninitialized value in numeric gt (>) at /usr/lib64/perl5/site_ +perl/5.8.8/x86_64-linux-thread-multi/PDL/Core.pm line 942. Use of uninitialized value in repeat (x) at /usr/lib64/perl5/site_perl +/5.8.8/x86_64-linux-thread-multi/PDL/Core.pm line 942. Use of uninitialized value in subtraction (-) at /usr/lib64/perl5/site +_perl/5.8.8/x86_64-linux-thread-multi/PDL/Core.pm line 943. [ [ 50093.199] [ 50094.308] [ 50954.953] [ 51767.383] [ 51958.219] [ 52005.696] [ 52005.763] [ 52142.188] [ 52422.043] [ 52459.414] [ 52482.509] [ 52693.953] [ 52752.918] [ 52836.803] [ 52837.198] [ 53107.974] [ 53125.429] [ 53141.53] [ 53198.495] [ 53243.578] [ 53489.381] [ 53603.709] [ 53661.37] [ 53724.982] [ 53724.983] [ 53864.724] [ 53882.002] [ 53969.248] [ 54224.674] [ 54225.636] [ 54304.474] [ 54304.539] [ 54366.513] ]
      Clearly the dummy is being inserted, so I'm a bit confused as to the uninitiated value errors??
        dummy takes 2 mandatory arguments:
        1. the pdl
        2. the dimension number that will be the dummy dimension
        Somehow, the dimension is defaulting to 0.
        This error should go away if you use
        $tsearch = $time->dummy(0);
        which has the same effect and is more explicit