2009-03-03 13 views
9

En un script de Perl en el que estoy trabajando, necesito construir una matriz a partir de varias otras matrices. He visto un par de módulos en CPAN (Math::Matrix, PDL::Matrix, Math::Cephes::Matrix), pero ninguno de estos parece ser compatible con esto.Matrices de matrices dentro de Perl

En Octave, esto es muy fácil. He aquí un ejemplo de algo similar a lo que estoy tratando de hacer:

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 

Parece tratando de hacerlo yo mismo habría causar problemas un poco rápidamente, lo que es probablemente la razón por estos módulos no lo soportan ... Ha ¿alguien más por ahí alguna vez tuvo una necesidad de esto? ¿Lo has resuelto?

+0

Podría ser capaz de dar una mejor respuesta si sabemos lo que los está utilizando para ... – flussence

+0

Dado que no tiene la reputación de publicar un comentario, no dude en responder editando la pregunta en sí. –

Respuesta

5

Rodar por cuenta propia no es demasiado doloroso.

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

Esto funcionó maravillosamente. No puedo volver a la cuenta temporal que solía hacer esta pregunta, pero tan pronto como obtenga esa cuenta fusionada con esta, marcaré esto como aceptado. Aunque estoy un poco confundido, ¿qué es \ @ \ @; \ @ \ @ \ @ \ @ \ @ \ @? –

+0

Prototipos de funciones, que no se usan con frecuencia en Perl 5. Aquí, evita el aplastamiento de los argumentos de la matriz; podrías dejar caer todo el prototipo y usar 'hmerge (\ @ A, \ @B)' en su lugar. – ephemient

-1

EDITAR

no he entendido bien el PO, pensando que querían iterar sobre todas las posibles permutaciones de varias matrices (que es lo que hace Iterator :: :: Matriz Jagged).


Tome un vistazo a Iterator::Array::Jagged

Aquí se muestra un ejemplo de la sinopsis:

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() 

El ejemplo en el código anterior código imprime el siguiente:

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

No veo cómo esto ayuda? El ejemplo de OP compone una matriz grande a partir de matrices más pequeñas. – ephemient

+0

Entendí completamente la pregunta. Pensé que el OP implicaba iterar a través de todas las permutaciones posibles de matrices múltiples. – JDrago

0

El Perl Data Language (PDL) versión 2.4.10 es compatible con conveniencia estilo MATLAB inp UT para el pdl constructor cuando se utiliza un argumento de cadena y los append y glue rutinas puede ser utilizado para pegar subarreglos juntos como esta sesión pdl2 muestra:

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] 
] 

El PDL book y la PDL mailing lists son fuentes esenciales para obtener más información sobre PDL.

Cuestiones relacionadas