Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

first stumbling steps in PDL

by Discipulus (Canon)
on Dec 15, 2022 at 11:54 UTC ( [id://11148889]=perlquestion: print w/replies, xml ) Need Help??

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

Dear ones,

Inspired by this post and by the underlying forest problem I had the genial ( grin ;) idea of just making the check horizontally and then repeat it on a rotated by 90° AoA.

Rotating the AoA lead me to PDL and here troubles and stumbling started.

Firstly because once something is a piddle I cannot anymore use it as a comfortable perl datastrucure: if my piddle is a 2d array and I take a slice of it, a row, then I cannot use it as an array: @{ $x->slice('0,') } gives a nasty not an array reference error.

But I insisted and now I have the following code:

# see for the actual problem to solve: https://adventofcode.com/2022/d +ay/8 use strict; use warnings; use PDL; use PDL::NiceSlice; my $debug = 1; my $x = rcols( *DATA, {COLSEP => qr//}, []); is_visible( $x ); # piddle rotated 90° counterclockwise is_visible( $x->transpose()->slice( ':', '-1:0' ) ); sub is_visible{ my $pdl = shift; print "Working on the piddle: $pdl(skipping first and last rows)\n +" if $debug; # # the idea is to consider only rows from second one to last but on +e foreach my $nrow ( 1 .. nelem($pdl->slice('0,'))-2 ){ # # now the idea is to consider only from second element to last + but one print "in ROW $nrow considering only: ", $pdl->slice("1:-2,($n +row)"),"\n" if $debug; # # ..and now checking these elements.. foreach my $to_check ( $pdl->slice("1:-2,($nrow)")->dog ){ print "\tchecking $to_check\n" if $debug; # # ...against all other members of the rows # like in (PSEUDOCODE) assuming @array being the current r +ow # foreach my $idx_to_check ( 1 .. $#array-1 ){ # my $res = map{ my_check( $array[$idx_to_check], $arr +ay[$_]) }grep{ $idx_to_check != $_ } 0..$#array; # } } } } __DATA__ 30373 25512 65332 33549 35390

In the meanwhile his Anonymousness posted a PDL solution to the problem, code I dont understand at all.

Can someone be so kind to guide me expanding my own solution? If such is possible I'd like it explained plainly, just to let me understanding PDL a bit more.

As side note I have found PDL QuickRef but I suspect some syntax has changed in PDL since then (would be nice to have an updated version of this ;) and this tutorial

Thanks for reading

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re: first stumbling steps in PDL
by karlgoethebier (Abbot) on Dec 15, 2022 at 13:56 UTC

    You may like PDL::Course (Updated Oct 25, 2022).

    «The Crux of the Biscuit is the Apostrophe»

Re: first stumbling steps in PDL (PDL References)
by eyepopslikeamosquito (Archbishop) on Dec 15, 2022 at 20:46 UTC
      I've built up a lot of PDL References here over the years

      Well...you are The Monastery's Reference Clerk 😉

Re: first stumbling steps in PDL
by Anonymous Monk on Dec 15, 2022 at 21:43 UTC

    TIMTOWTDI, but PDL is not about explicit loops. Not how it works. Consider this vector:

    pdl> p $v = pdl split '', '30373' [3 0 3 7 3]

    Now then e.g. the cumulative sum or running total:

    pdl> p cumusumover $v [3 3 6 13 16]

    Not very useful, but I have a vague feeling that "cumulative maximum" would be handy if someone is looking at a forest. You could type

    pdl> ?? cumulative

    to investigate what's available. OK, then, consider "strictly lower triangular matrix" or whatever it's called in mathematics if non-zero members are all 1's:

    pdl> p $SLTM [ [0 0 0 0 0] [1 0 0 0 0] [1 1 0 0 0] [1 1 1 0 0] [1 1 1 1 0] ]

    Hm-m, looks interesting. Not sure about forestry, but what if it's multiplied by our vector?

    pdl> p $SLTM * $v [ [0 0 0 0 0] [3 0 0 0 0] [3 0 0 0 0] [3 0 3 0 0] [3 0 3 7 0] ]

    That's even more interesting! What could we use this result for? What about computing maximum over rows?

    pdl> p maxover $SLTM * $v [0 3 3 3 7]

    Now that's what I call interesting! Isn't it cumulative maximum of all elements before current for original vector? Let's check it without further ado:

    pdl> p $v > maxover $SLTM * $v [1 0 0 1 0]

    But wait, that's exactly the answer we were looking for -- what trees are seen if forest patch is looked at from the left!

    And all the rest was just further expansion of investigation performed above.

      A slightly more concise way to get a lower triangular matrix of 1s:
      use PDL::LinearAlgebra; sub ltm { my ($size, $strictly) = @_; my $ltm = ones($size,$size)->tricpy(1); $strictly ? $ltm - identity($size) : $ltm; }

        Is there an advantage of using tricpy over mtri? At least mtri may be called without argument when an upper triangle is requested, while with tricpy it is always required.

        Greetings,
        -jo

        $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
        Today it was bugging me that there is no tritosquare, to provide another way to make a lower-triangular matrix. Now there is, on git master and soonish to be released:
        pdl> p ones(10)->tritosquare [ [1 0 0 0] [1 1 0 0] [1 1 1 0] [1 1 1 1] ]

        A slightly different approach for a strictly lower triangular matrix:

        use PDL::LinearAlgebra::Real ... tricpy(zeros($size,$size), 0, my $sltm = ones($size, $size));

        Greetings,
        -jo

        $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11148889]
Approved by Athanasius
Front-paged by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-03-28 18:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found