I believe that the code below modifies $x in place, but I'm not too familiar with the internals of PDL. There is a problem with the code below; for elements equal to 0, it will replace all of those elements with the same result...which may not be what you want.
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
use PDL::NiceSlice;
my $x = pdl(0,4,0,-3);
print "Before: $x\n";
$x(which($x > 0)) .= 1;
$x(which($x < 0)) .= 0;
$x(which($x == 0)) .= int(rand(9)) > 5 ? 1: 0;
print "After: $x\n";
exit;
The code below will fix that problem, but you need to iterate through each element of the pdl:
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
my $x = pdl(0,4,0,-3);
print "Before: $x\n";
my $n = nelem($x);
for ( my $i = 0; $i < $n; ++$i ) {
my $val = $x->index($i);
$val = $val > 0 ? 1 :
$val < 0 ? 0 :
$val == 0 ? (int(rand(9)) > 5 ? 1 : 0) : undef;
$x->index($i) .= $val;
}
print "After: $x\n";
exit;
By the way, you may find this node helpful: Processing values of a piddle (PDL) speedup using 'at' vs. 'index'. It's a discussion related to processing the elements of a pdl individually. In general, it's a good idea to avoid processing the elements individually (i.e. it's likely better if you can find a way to use the vector operations of PDL). If you can not avoid processing the elements individually, you may want to consider exporting the pdl to a perl array, performing some operations on the values of the array, and then creating a pdl from the result.
I took a quick looked around for the pdl equivalent of the map command but I did not find one. | [reply] [Watch: Dir/Any] [d/l] [select] |
thanks.. I found today similar solution to what you say .. i.e.:
$x->where($x < 0) .= -1
the link I already saw 2 days ago :)
Can't figure out yet one-pass solution... but at least I dont have to make it array, loop over it and then reconstruct the piddle.
thanks again | [reply] [Watch: Dir/Any] [d/l] |
$inds = $x->whichND($x == 0);
$x->indexND($inds) .= ($x->random < 0.5)->indexND($inds);
$x->inplace->clip(0,1);
This would obviously benefit enormously from loop fusion or making your own custom PDL operation. | [reply] [Watch: Dir/Any] [d/l] |
$view = $x->whereND($x == 0)
$view .= $view->random < .5
| [reply] [Watch: Dir/Any] [d/l] [select] |
A great option! I'll confess I was a bit tired, so after figuring out something that would broadcast over n-dimensional inputs better than using where, I stopped. Your code is clearly better.
| [reply] [Watch: Dir/Any] [d/l] |