tags:

views:

426

answers:

2

In a Perl script I'm working on, I need to build a matrix out of several other matrices. I've looked at a couple of modules in CPAN (Math::Matrix, PDL::Matrix, Math::Cephes::Matrix), but none of these seem to support this.

In Octave, this is very easy. Here's an example of something similar to what I'm trying to do:

octave:1> A = [ 1, 2; 3, 4 ]
A =    
   1   2
   3   4

octave:2> B = [ 5, 6; 7, 8 ]
B =    
   5   6
   7   8

octave:3> C = [ 9, 10; 11, 12 ]
C =    
    9   10
   11   12

octave:4> D = [ 13, 14; 15, 16 ]
D =    
   13   14
   15   16

octave:5> E = [ A, B; C, D ]
E =    
    1    2    5    6
    3    4    7    8
    9   10   13   14
   11   12   15   16

It seems trying to do this myself would get messy kinda quickly, which is probably why these modules don't support it... Has anyone else out there ever had a need for this? Have you solved it?

+4  A: 

Rolling your own isn't too painful.

use List::Util qw(max);

@A = ([1, 2], [3, 4]);
@B = ([5, 6], [7, 8]);
@C = ([9, 10], [11, 12]);
@D = ([13, 14], [15, 16]);

sub hmerge(\@\@;\@\@\@\@\@\@) {
    my @ret;
    for my $i (0 .. max map $#$_, @_) {
        push @ret, [map @{$$_[$i]}, @_];
    }
    @ret;
}

@E = (hmerge(@A, @B), hmerge(@C, @D));
ephemient
This worked beautifully. I can't get back to the temporary account I used to ask this question, but as soon as I get that account merged with this one, I'll mark this as accepted.I'm a little confused though- what is \@\@;\@\@\@\@\@\@?
Ryan Fox
Function prototypes -- not in frequent use in Perl 5. Here, it prevents squashing of the array arguments; you could drop the whole prototype and use `hmerge(\@A, \@B)` instead.
ephemient
A: 

EDIT

I misunderstood the OP, thinking that they wanted to iterate over all possible permutations of several matrices (which is what Iterator::Array::Jagged does).


Take a look at Iterator::Array::Jagged

Here is an example from the synopsis:

use Iterator::Array::Jagged;

# Build up a set of data:
my @data = (
  [qw/ a b /],
  [qw/ c d /],
  [qw/ e f g /]
);

# Iterator is a subref:
my $itersub = Iterator::Array::Jagged->get_iterator( @data );
while( my @set = $itersub->() )
{
  print "Next set: '" . join("&", @set) . "'\n";
}# end while()

The example in the code above code prints the following:

Next set: 'a&c&e'
Next set: 'b&c&e'
Next set: 'a&d&e'
Next set: 'b&d&e'
Next set: 'a&c&f'
Next set: 'b&c&f'
Next set: 'a&d&f'
Next set: 'b&d&f'
Next set: 'a&c&g'
Next set: 'b&c&g'
Next set: 'a&d&g'
Next set: 'b&d&g'
JDrago
I don't see how this helps? OP's example composes a large matrix out of smaller matrices.
ephemient
I completely misunderstood the question. I thought the OP involved iterating through all possible permutations of multiple matrices.
JDrago