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_define
d 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)
.