http://qs321.pair.com?node_id=1023967

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?