Perl PDL not working as expected

170 views Asked by At

I really don't understand PDL's input functions. Personally, I've been using the rcols feature to create pdls, as was recommended to me in various places around the web.

I have an input file like this :

 3 -4 -1
 0 5 2
 3 5 6
 2 5 2
 5 5 5
 5 5 6

which, I want to assign to a Piddle. When I assign it to a piddle like so,

my @pdls = rcols $in_fh, { COLSEP => "\\s" } ;
my $pdl = pdl(@pdls[1 .. $#pdls]);

When I print @pdls this is printed :

[
 [ 3  0  3  2  5  5]
 [-4  5  5  5  5  5]
 [-1  2  6  2  5  6]
]

Which made me think it pulled my file by columns, and not rows. Which makes sense looking at the code, really. When I saved this output to a file(After stripping out all the brackets) this is how it looked. :

3  0  3  2  5  5
-4  5  5  5  5  5
-1  2  6  2  5  6

When I ran the same script on the new input file, the result does not follow the same process as before :

[
 [ 0 -4 -1]
 [ 3  0  0]
 [ 0  5  2]
 [ 0  0  0]
 [ 0  5  6]
 [ 3  0  0]
 [ 0  5  2]
 [ 2  0  0]
 [ 0  5  5]
 [ 5  0  0]
 [ 0  5  6]
 [ 5  0  0]
]

And I have no idea why it is doing so. In essence, I want to be able to read my text file into a piddle. Does anyone see what I'm missing, or able to offer any explanation?

Thanks for any help.

2

There are 2 answers

0
Ed. On

As is occasionally the case in PDL, the design of things with several dimensions can be a bit counter-intuitive. But it is designed overall so it's easy to just adjust dimensions. Here, rcols and wcols treat data in files in a FORTRAN-style column-major way. It is easy to adjust that using the transpose method:

pdl> p $x = sequence(3,4)

[
 [ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
]

pdl> wcols($x->transpose, 'myfile')

pdl> p pdl(rcols('myfile', {colsep => qr/\s+/}))->transpose
Reading data into ndarrays of type: [ Double Double Double ]
Read in  4  elements.

[
 [ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
]
0
Mark Baker On

Maybe its just better to make a "3,6 matrix of zeros" then set in each value individually, (which means putting the data from a file into a 1D pdl() first) I would use a open() to read it into a scaler then put that in a 1D piddle; which can be rather involved ... once you get it in a 1D piddle do this:

open(FILE,"yourfile"); while (<FILE>) { $x = $_; } 
    close FILE;

   $y = zeros(3,6);
p  $x = sequence(18);
 [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
for $c(0..5) { for $d(0..2) {  $y($d,$c) .= $x($e++)   }}  
p $y
 [ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
 [12 13 14]
 [15 16 17]