### Can't figure out simple transformation with PDL

by wanna_code_perl (Pilgrim)
 on Mar 18, 2013 at 01:42 UTC Need Help??
wanna_code_perl has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks

I'm new to PDL, giving it a whirl to speed up some 2D matrix crunching at the heart of an algorithm that has been rigorously proven to be the most efficient waste use of a week's worth of CPU time to solve the given problem. But I digress. :-)

I'm having the most trouble fully wrapping my head around threading, specifically how to fetch adjacent cells in a 2D matrix which match an arbitrary boolean expression.

Below follow some (annotated) pdl> commands hopefully showing what I'm trying to accomplish.

```# Set up initial 4x4 matrix with some arbitrary data
pdl> p \$b = pdl (10..25)->reshape(4,4);
[
[10 11 12 13]
[14 15 16 17]
[18 19 20 21]
[22 23 24 25]
]

# Fetch the 2D index for the position of element with value 21
pdl> p \$pos = whichND(\$b == 21);
[
[3 2]
]

# Simple transformation matrix to mark adjacent cells.
pdl> \$xfrm = pdl [-1,0],[0,-1],[1,0],[0,1];

# Show the results of the transformation: So far so good (even though
# one of the values is out of bounds, we're expecting that.)
pdl> p \$pos + \$xfrm;
[
[2 2]
[3 1]
[4 2]
[3 3]
]

# Here's the rub. The following command returns the *values* of
# the adjacent cells, but I want the indicies instead. (See discussion
+)
pdl> p \$b->indexND(\$pos + \$xfrm, 'truncate');
[20 17 0 25]
# \$b->range(\$pos + \$xfrm, 1, 'truncate') gives similar results

### What I need:

The above code gets me halfway to where I need to be; from the \$pos + \$xfrm line, I need to basically grep those elements which are a) valid (i.e., within the piddle dimensions), and b) match a given boolean expression. Hence I tried this (obviously broken) code:

```pdl> p \$indicies = \$b->indexND(\$pos + \$xfrm, 'truncate')->which(\$b % 2
+);
# Returns: empty
#
# Expected: Should contain two single element piddles:
# [17 25]
# OR, the indicies in the original matrix would be fine:
# [
#  [3 1]   # 17
#  [3 3]   # 25
# ]
# N.b. [2 2] would be omitted (value = 20, even), as would [4 2] (inde
+x out of bounds)

I'm thinking this sort of thing must be a very common pattern, but I can't seem to find a workable example anywhere. What's the most concise and efficient way to iterate over adjacent cells matching a given boolean expression?

Replies are listed 'Best First'.
Re: Can't figure out simple transformation with PDL
by syphilis (Chancellor) on Mar 19, 2013 at 08:28 UTC
The best way to ensure that you get a good (and prompt) answer to questions relating to PDL is to ask those questions on the perldl mailing list.

You'll *sometimes* get a good answer right here on perlmonks ... but that depends upon who is present in the monastery.

Cheers,
Rob
Re: Can't figure out simple transformation with PDL
by fglock (Vicar) on Mar 19, 2013 at 09:17 UTC

I'm starting with your original statements, and then setting the selected elements to '-1' here:

```perldl> p \$b = pdl (10..25)->reshape(4,4);
[
[10 11 12 13]
[14 15 16 17]
[18 19 20 21]
[22 23 24 25]
]
perldl> p \$pos = whichND(\$b == 21);
[
[3 2]
]
perldl> \$xfrm = pdl [-1,0],[0,-1],[1,0],[0,1];
perldl> p \$around = \$b->indexND(\$pos + \$xfrm, 'truncate');
[20 17 0 25]
perldl> p \$odd = \$around->where( \$around % 2 );
[17 25]
perldl> \$odd .= -1;  # set original matrix through dataflow
perldl> p \$b
[
[10 11 12 13]
[14 15 16 -1]   # odd elements around 21 are set to -1
[18 19 20 21]
[22 23 24 -1]
]

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1023967]
Approved by Crackers2
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2017-06-27 13:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How many monitors do you use while coding?

Results (606 votes). Check out past polls.