Skip to content

Commit

Permalink
Added unpdl method
Browse files Browse the repository at this point in the history
The unpdl method is roughly an inverse of the pdl constructor.
It takes a piddle and returns a reference to a Perl array containing
a dimensionally equivalent structure of nested arrays. This complements
the list method, which returns a flattened list
of Perl scalars.
  • Loading branch information
jberger committed Jun 30, 2012
1 parent 8aabc20 commit 23212d2
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
68 changes: 65 additions & 3 deletions Basic/Core/Core.pm.PL
Expand Up @@ -288,7 +288,7 @@ print OUT <<"!WITH!SUBS!";
\@EXPORT_OK = qw( howbig threadids topdl nelem dims shape null
$convertfuncs
convert inplace zeroes zeros ones list listindices
convert inplace zeroes zeros ones list listindices unpdl
set at flows thread_define over reshape dog cat barf type diagonal
dummy mslice approx flat sclr squeeze
get_autopthread_targ set_autopthread_targ get_autopthread_actual
Expand All @@ -298,7 +298,7 @@ print OUT <<"!WITH!SUBS!";
\%EXPORT_TAGS = (
Func=>[qw/nelem dims shape null
$convertfuncs
convert inplace zeroes zeros ones list listindices
convert inplace zeroes zeros ones list listindices unpdl
set at flows thread_define over reshape pdl piddle null dog cat barf type
diagonal dummy mslice approx flat sclr
get_autopthread_targ set_autopthread_targ get_autopthread_actual
Expand Down Expand Up @@ -337,7 +337,7 @@ $PDL::toolongtoprint = 10000; # maximum pdl size to stringify for printing
# log10() is now defined in ops.pd
*howbig = \&PDL::howbig;
*howbig = \&PDL::howbig; *unpdl = \&PDL::unpdl;
*nelem = \&PDL::nelem; *inplace = \&PDL::inplace;
*dims = \&PDL::dims; *list = \&PDL::list;
*threadids = \&PDL::threadids; *listindices = \&PDL::listindices;
Expand Down Expand Up @@ -3074,6 +3074,68 @@ sub PDL::list{ # pdl -> @list
@{listref_c($pdl)};
}
=head2 unpdl
=for ref
Convert piddle to nested Perl array references
=for usage
$arrayref = unpdl $x;
Obviously this is grossly inefficient for the large datasets PDL is designed to
handle. Sometimes, however, you really want to move your data back to Perl, and
with proper dimensionality, unlike C<list>. This function attempts to do this for you, returning
a reference to a Perl equivalent to the input piddle.
=for example
use JSON;
my $json = encode_json unpdl $pdl;
=cut
!NO!SUBS!

=pod
If you compile PDL with bad value support (the default), your machine's
docs will also say this:
=cut

if ( $bvalflag ) {
print OUT <<'!NO!SUBS!';
=for bad
unpdl converts any bad values into the string 'BAD'.
=cut
!NO!SUBS!
}

print OUT '# line ' . (__LINE__ + 2) . <<'!NO!SUBS!';
"Basic/Core/Core.pm.PL (i.e. PDL::Core.pm)"
sub PDL::unpdl {
barf 'Usage: unpdl($pdl)' if $#_ != 0;
my $pdl = PDL->topdl(shift);
return [] if $pdl->nelem == 0;
return _unpdl_int($pdl);
}
sub _unpdl_int {
my $pdl = shift;
if ($pdl->ndims > 1) {
return [ map { _unpdl_int($_) } dog $pdl ];
} else {
return listref_c($pdl);
}
}
=head2 listindices
=for ref
Expand Down
18 changes: 18 additions & 0 deletions t/unpdl.t
@@ -0,0 +1,18 @@
use strict;
use warnings;

use PDL;
use Test::More tests => 1;

my $array = [
[[1,2],
[3,4]],
[[5,6],
[7,8]],
[[9,10],
[11,12]]
];
my $pdl = pdl $array;

is_deeply( unpdl($pdl), $array, "back convert 3d");

0 comments on commit 23212d2

Please sign in to comment.