I would like to do something like this to call myfunc() on each element in-place on an existing PDL:
$pdl = pdl [1,2,3];
$pdl = pdl [ map { myfunc($_) } @{ unpdl($pdl) } ];
I've searched through the documentation, but nothing yet:
Is there a way to visit each element of a PDL and run something on the element?
CodePudding user response:
You can use broadcast_define (thread_define in older versions) for this:
use PDL;
broadcast_define('square(a();[o]b())', over { $_[1] .= $_[0] ** 2 });
my $pdl = pdl [[1,2,3], [4,5,6]];
square($pdl, (my $out = null));
print($out); # $out is pdl [[1,4,9], [16,25,36]]
this is slower than using native ops ($pdl**2 gets the same result in this case, and many more complicated things are possible by composing native ops), or PDL::PP, in which you write your function in C, but it is faster than unpdl/map/pdl.
You have to look at the PDL::PP docs for explanations of the signature like (a();[o]b()), but this is the simple case: the function has a scalar input and a scalar output, and can be broadcast to any number of dimensions.
I can't seem to get broadcast_defined functions to return a value when the output argument is omitted (e.g. my $out = square($pdl)), but you can do in-place modification with square($pdl, $pdl).
