http://qs321.pair.com?node_id=1214017


in reply to RFC: 100 PDL Exercises (ported from numpy)

I'll pick an easy one of "TODO" first and will add some more later, in no order -- so there'll be a few edits, return for more :-)

99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n:

use strict; use warnings; use PDL; my $x = pdl([1.0, 0.0, 3.0, 8.0], [2.0, 0.0, 1.0, 1.0], [1.5, 2.5, 1.0, 0.0]); my $n = 4; my $mask = ( $x == $x-> rint )-> andover & ( $x-> sumover == $n ); print $x-> transpose -> whereND( $mask ) -> transpose;

--------------------------

Added:

--------------------------

print $PDL::Version::VERSION;

Is it officially recommended way? What's the benefit over usual $PDL::VERSION;? I also wonder what's the $VERSION = eval $VERSION; in that tiny module.

--------------------------

4. How to find the memory size of any matrix?

print $z-> info( '%M' );

--------------------------

35. How to compute ((A+B)*(-A/2)) in place?

There's maybe a typo or two in Python solution (what's the "C"?). But to operate inplace, I'd do this:

my $a = ones(3); my $b = 2 * ones(3); $b += $a; $a /= -2; $b *= $a; print $b;

IIRC, combined assignment operators are overloaded to work inplace, but I can't find a reference right now, will do it later.

--------------------------

53. How to convert a float (32 bits) array into an integer (32 bits) in place?

Good question. The ceil and floor convert double to long inplace. Not sure if PDL allows to do so for 32-bit types.

--------------------------

45. Create random vector of size 10 and replace the maximum value by 0:

More efficient:

my $z = random( 10 ); $z( $z-> maximum_ind ) .= 0; print $z;

--------------------------

64. Consider a given vector, how to add 1 to each element indexed by a second vector (be careful with repeated indices)?

my $z = zeroes( 10 ); my $i = pdl( 1, 3, 5, 3, 1 ); indadd( 1, $i, $z ); print $z;

--------------------------

81. Consider an array Z = [1,2,3,4,5,6,7,8,9,10,11,12,13,14], how to generate an array R = [[1,2,3,4], [2,3,4,5], [3,4,5,6], ..., [11,12,13,14]]:

my $z = 1 + sequence 14; my $len = 4; print $z-> lags( 0, 1, 1 + $z-> nelem - $len ) -> slice( '','-1:0' );

--------------------------

87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)?

If I understand the task correctly, and now that I've learned about lags:

my $x = sequence 16, 16; print $x-> lags( 1, 4, 4 ) -> slice( '', '', '-1:0' ) -> xchg( 0, 1 ) -> sumover -> lags( 0, 4, 4 ) -> slice( '', '-1:0' ) -> sumover;

(Sigh...) Utilizing benefits of idle commuting and thinking things over:

my $x = sequence 16, 16; print $x-> reshape( 4, 4, 4, 4 ) -> reorder( 0, 2, 1, 3 ) -> clump( 2 ) -> sumover