Hi Zev-

I recommend using the PDL shell (pdl2) to try things out
with PDL.  It is a good way to see what is happening and
you can cut-and-paste the session into an email for
others to try out or comment on.

The key to avoiding perl loops with PDL is to use the
threading engine.  That is the ability to perform
implicit looping over additional dimensions for a
calculation.  However, there is a tradeoff in that
for many calculations using threading, you may
need to create intermediate temporaries that
are much larger than the dimensions of the input
or output arrays (corresponding to the looping).

Here are two examples: one with full implicit
threading, and one with a loop over cols but with
the calculation still being done for all rows
at once.

pdl> p $im =  (random(5,3)*10)->floor

[
 [0 1 4 1 7]
 [3 1 0 1 3]
 [3 3 1 8 3]
]


pdl> p $im->info
PDL: Double D [5,3]

pdl> p $im(,,*3)

[
 [
  [0 1 4 1 7]
  [3 1 0 1 3]
  [3 3 1 8 3]
 ]
 [
  [0 1 4 1 7]
  [3 1 0 1 3]
  [3 3 1 8 3]
 ]
 [
  [0 1 4 1 7]
  [3 1 0 1 3]
  [3 3 1 8 3]
 ]
]


pdl> p $im(,*3)

[
 [
  [0 1 4 1 7]
  [0 1 4 1 7]
  [0 1 4 1 7]
 ]
 [
  [3 1 0 1 3]
  [3 1 0 1 3]
  [3 1 0 1 3]
 ]
 [
  [3 3 1 8 3]
  [3 3 1 8 3]
  [3 3 1 8 3]
 ]
]

pdl> p $im(,*3)->info
PDL: Double D [5,3,3]

pdl> my $pairs = inner($im(,,*3),$im(,*3))

pdl> p $pairs  # harder to leave out diagonal entries

[
 [67 23 36]
 [23 20 29]
 [36 29 92]
]

pdl> $pairs->diagonal(0,1) .= 0

pdl> p $pairs

[
 [ 0 23 36]
 [23  0 29]
 [36 29  0]
]


The other mixed approach is to use a combination of perl loops
together with PDL functions.  You can loop over a single dimension
but use PDL for the calculations over the other dimensions:

pdl> p inner($im(,1:-1),$im(,(0)))
[23 36]

which calculates the inner products between row 0
and rows 1..2.  The performance can be a big win over
straight perl and the memory usage from temps is
much less.

--Chris


On Thu, Dec 22, 2011 at 11:39 AM, zev <[email protected]> wrote:
> Greetings I have a piddle (in matrix form).  For each row I need a
> pairwise comparison to every other row (but not to itself).  I need to use
> 'where'  on the two piddles.  I am subsequently using 'cov' in
> PDL::Stats::Basic to calculate the covariance of the two piddles.
>
> Here is my questions:
>
> How can I avoid an outer and inner for loop in perl to do every
> pairwise comparison?  I understand this is probably a basic question, but I
> haven't had luck after reading the indexing tutorial...
>
>
> --
> Zev Kronenberg
> Graduate Student
> University of Utah
> phone: 208-629-6224

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

Reply via email to