Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Can't figure out simple transformation with PDL

by wanna_code_perl (Pilgrim)
on Mar 18, 2013 at 01:42 UTC ( #1023967=perlquestion: print w/ replies, xml ) 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?

Comment on Can't figure out simple transformation with PDL
Select or Download Code
Re: Can't figure out simple transformation with PDL
by syphilis (Canon) 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] ]

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1023967]
Approved by Crackers2
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2014-07-12 08:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (238 votes), past polls