note
vr
<p>I have a nitpick and an improvement (well, in my view). The latter: the beauty of "array language" is that it allows one to be succinct. No need to bother with boring details of array shape (i.e. dimensions) explicitly: interpreter ain't stupid, it itself can figure out the info it needs. Size of leading dummy dimensions of <c>$x</c>, if "1" originally, will be stretched as required to fit shape of second array i.e. multiplicand i.e. <c>$y</c>. (Shape of which, in its turn, will be padded with dummy dimensions. So then both multiplicands have matching shapes of 4 dimensions.) Further, oh-please spare me the details that 2D shape of result will be pair of multiplications of widths and heights of original matrices. Can't tolerate too much maths for today already! I only know that 4D shape of multiplication result should be reduced: dims 0 and 2 clumped together (note implicit <c>xchg</c> (or <c>mv</c>) here) to produce 3D, then dims 1 and 2 also clumped to produce 2D. Will shape then be <c>w1*w2 x h1*h2</c>? Fine, but it's none of my business. So:</p>
<c>
sub kronecker_product {
my ($x, $y) = @_;
return $x-> dummy( 0 )
-> dummy( 0 )
-> mult( $y, 0 )
-> clump( 0, 2 )
-> clump( 1, 2 )
}
</c>
<p>Or:</p>
<c>
use PDL::NiceSlice;
sub kronecker_product {
my ($x, $y) = @_;
( $x( *1, *1 ) * $y )
-> clump( 0, 2 )
-> clump( 1, 2 )
}
</c>
<p>A nitpick: operation is non-commutative. Function args are <c>$x, $y</c>, in that order. There was no reason to write computation as <c>$y * $x-> ... </c>etc. Of course scalar multiplication of element by element of 4D arrays is commutative, and so result is correct either way. It's just my preference to keep written expression so it has no unjustified swaps of arguments as <c>$x-> call() * $y</c>. Sorry for nitpick.</p>
11144888
11144888