2009-03-03 16 views
9

Dans un script Perl sur lequel je travaille, j'ai besoin de construire une matrice à partir de plusieurs autres matrices. J'ai regardé un couple de modules dans CPAN (Math::Matrix, PDL::Matrix, Math::Cephes::Matrix), mais aucun de ceux-ci semblent soutenir ceci.Matrices de matrices en Perl

Dans Octave, c'est très facile. Voici un exemple de quelque chose de semblable à ce que je suis en train de faire:

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 

Il semble essayer de faire moi-même serait un peu déraper rapidement, ce qui est probablement la raison pour laquelle ces modules ne le supporte pas ... A quelqu'un d'autre a-t-il jamais eu besoin de cela? L'avez-vous résolu?

+0

Peut-être pourriez-vous donner une meilleure réponse si nous savons pour quoi vous les utilisez ... – flussence

+0

Puisque vous ne pouvez pas poster de commentaire, n'hésitez pas à répondre en éditant la question. –

Répondre

5

Rouler les vôtres n'est pas trop douloureux.

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)); 
+0

Cela a fonctionné à merveille. Je ne peux pas revenir au compte temporaire que j'avais l'habitude de poser cette question, mais dès que je fusionnerai ce compte avec celui-ci, je le marquerai comme accepté. Je suis un peu confus cependant - ce qui est \ @ \ @; \ @ \ @ \ @ \ @ \ @ \ @? –

+0

Prototypes de fonctions - peu utilisés en Perl 5. Ici, il empêche l'écrasement des arguments du tableau; vous pouvez abandonner le prototype entier et utiliser 'hmerge (\ @ A, \ @B)' à la place. – ephemient

-1

EDIT

j'ai mal compris l'OP, pensant qu'ils voulaient itérer sur toutes les permutations possibles de plusieurs matrices (qui est ce que Iterator :: :: Tableau Jagged fait).


Jetez un oeil à Iterator::Array::Jagged

Voici un exemple du 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() 

L'exemple dans le code ci-dessus code affiche les éléments suivants:

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' 
+0

Je ne vois pas comment cela aide? L'exemple d'OP compose une grande matrice à partir de matrices plus petites. – ephemient

+0

J'ai complètement mal compris la question. Je pensais que le PO impliquait itération à travers toutes les permutations possibles de plusieurs matrices. – JDrago

0

Le Perl Data Language (PDL) version 2.4.10 prend en charge la commodité de style MATLAB ut pour le constructeur pdl lorsque vous utilisez un argument de chaîne et les routines append et glue peut être utilisé pour coller des sous-réseaux ainsi que cette session pdl2 montre:

pdl> $A = pdl q[ 1, 2 ; 3, 4 ];  # pdl constructor with string argument 

pdl> $B = pdl q[ 5, 6 ; 7, 8 ];  # pdl constructor with string argument 

pdl> $C = pdl q[ 9, 10 ; 11, 12 ]; # pdl constructor with string argument 

pdl> $D = pdl q[ 13, 14 ; 15, 16]; # pdl constructor with string argument 

pdl> ?vars 
PDL variables in package main:: 

Name   Type Dimension  Flow State   Mem 
---------------------------------------------------------------- 
$A   Double D [2,2]    P   0.03KB 
$B   Double D [2,2]    P   0.03KB 
$C   Double D [2,2]    P   0.03KB 
$D   Double D [2,2]    P   0.03KB 


pdl> p $A, $B, $C, $D; 

[ 
[1 2] 
[3 4] 
] 

[ 
[5 6] 
[7 8] 
] 

[ 
[ 9 10] 
[11 12] 
] 

[ 
[13 14] 
[15 16] 
] 

pdl> p $AB = $A->append($B);   # concatenate horizontally (actually on dim(0)) 

[ 
[1 2 5 6] 
[3 4 7 8] 
] 

pdl> p $CD = $C->append($D);   # concatenate horizontally (actually on dim(0)) 

[ 
[ 9 10 13 14] 
[11 12 15 16] 
] 

pdl> p $E = $AB->glue(1,$CD);   # glue vertically (actually on dim(1)) 
[ 
[ 1 2 5 6] 
[ 3 4 7 8] 
[ 9 10 13 14] 
[11 12 15 16] 
] 

Le PDL book et PDL mailing lists sont des sources essentielles pour plus d'informations sur PDL.

Questions connexes