I think dummy dimensions add only a few bytes to PDL-struct header, but your approach really physicalizes arrays from 2D to 4D (edit: well, it's still same 2D but squared dimensions for this example, sorry), which has grave consequences for performance. If no-one ever needs Kronecker product of 80x80 matrices, then count this comment as another nitpick :). + Note report of memory consumption assumes Win32, so disable/replace otherwise.
use strict;
use warnings;
use feature 'say';
use PDL;
use Time::HiRes 'time';
use constant DIM => 80;
my $x = random DIM, DIM;
my $y = random DIM, DIM;
report( 'choroba, vr', \&kronecker_product, $x, $y );
report( 'etj', \&kron, $x, $y );
sub report {
my ( $monk, $code, $x, $y ) = @_;
my $t = time;
my $k = $code-> ( $x, $y );
say "$monk:";
say 'time: ', time - $t;
say 'memory: ', mem();
}
sub mem {
qx{ typeperf "\\Process(perl)\\Working Set Peak" -sc 1 }
=~ /(\d+)\.\d+\"$/m;
( my $s = $1 ) =~ s/(\d{1,3}?)(?=(\d{3})+$)/$1,/g;
return $s
}
sub kronecker_product {
use PDL::NiceSlice;
my ( $x, $y ) = @_;
( $x( *1, *1 ) * $y )
-> clump( 0, 2 )
-> clump( 1, 2 )
}
sub PDL::dupN {
my ($this, @times) = @_;
return $this->copy if !grep $_ != 1, @times;
my $sl = join ',', map ":,*$_", @times;
$this = $this->slice($sl);
$this = $this->clump($_, $_+1) for 0..$#times;
$this;
}
sub PDL::inflateN {
my ($this, @times) = @_;
return $this->copy if !grep $_ != 1, @times;
my $sl = join ',', map "*$_,:", @times;
$this = $this->slice($sl);
$this = $this->clump($_, $_+1) for 0..$#times;
$this;
}
sub kron { my ($x,$y) = @_; $x->inflateN($y->dims) * $y->dupN($x->dims
+) }
__END__
choroba, vr:
time: 0.0958220958709717
memory: 355,741,696
etj:
time: 8.45677018165588
memory: 2,977,234,944
Edit 2. By the way, while we are at this example, the PDL::NiceSlice says
- arguments should not be quoted
- lone '*' inserts a dummy dimension of order 1
but I see that lone unquoted star(s) cause Perl to produce a warning:
Use of uninitialized value in concatenation (.) or string
so I had to insert a pair of very unsightly "1"'s, which of course devalues code nicety by half at least:). Is this a bug in PDL::NiceSlice, documentation flaw, or just me reading it incorrectly?
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.