2015-10-15 26 views
5

Sto cercando di replicare il prodotto Kron usando solo repmat e reshape e credo di essere abbastanza vicino ma non riesco a fare l'ultimo rimodellamento corretto. Particolarmente Ho problema nel ridisegnare AReplica il tensore di Kronecker con repmat in MATLAB

Per rendere le cose semplici let supponiamo di avere

A=[1 3; 2 4] 
B=[5 10; 10 5] 

quindi il mio kron(A,B) sta per essere una matrice 4x4.

kron=[5 10 15 30 
     10 5 30 15 
     10 20 20 40 
     20 10 40 20] 

sto procedendo in questo modo:

Y=repmat(B,2,2) 
X=A(:); 
X=repmat(X,1,2)'; 
X=X(:); 
X=repmat(X,1,2); 

che mi dà il seguente 8x2 Matrix:

X= [1 1 
    1 1 
    2 2 
    2 2 
    3 3 
    3 3 
    4 4 
    4 4] 

Non posso capire come fare il rimodellare corretta per ottenere la mia matrice 4x4:

X=[1 1 3 3 
    1 1 3 3 
    2 2 4 4 
    2 2 4 4] 

T gallina sarò in grado di calcolare: X.*Y=kron(A,B)

+3

Sarai sempre nella dimensione 2? – BillBokeey

+0

quando si esegue 'kron (A, B)' Ottengo '[5 10 15 30; 10 5 30 15; 10 20 20 40; 20 10 40 20] ' –

+0

@ m.s. Ho ragione, ho invertito Y nel mio matlab, lo sto correggendo ora. – Gio

risposta

4

Ecco uno approccio utilizzando il potente trio di bsxfun, permute e reshape -

M = bsxfun(@times,B,permute(A,[3 4 1 2])); 
out = reshape(permute(M,[1 3 2 4]),size(A,1)*size(B,1),[]); 

Se siete inferno piegato sull'uso repmat, eseguire il calcolo di M con esso, in questo modo -

M = repmat(B,[1 1 size(A)]).*permute(repmat(A,[1 1 size(B)]),[3 4 1 2]) 

Verificare risultato confrontando contro kron per generici dimensioni matrici -

>> A = rand(4,5); 
>> B = rand(6,7); 
>> M = bsxfun(@times,B,permute(A,[3 4 1 2])); 
>> out = reshape(permute(M,[1 3 2 4]),size(A,1)*size(B,1),[]); 
>> out_kron = kron(A,B); 
>> max(abs(out(:) - out_kron(:))) 
ans = 
    0 

Ecco uno utilizzando matrix-multiplication e come tali devono essere abbastanza efficiente -

[mA,nA] = size(A); 
[mB,nB] = size(B); 
out = reshape(permute(reshape(B(:)*A(:).',mB,nB,mA,nA),[1 3 2 4]),mA*mB,[]) 
+0

Grande, mi sembra perfetto e tu hai anche fornito una soluzione senza 'bsxfun' (altrimenti siamo praticamente tornati alla funzione incorporata' kron'). grazie, G. – Gio

3

Se non si desidera utilizzare qualsiasi loop o bsxfun/arrayfun - soluzioni, è possibile effettuare le seguenti operazioni:

[ma,na] = size(A); 
[mb,nb] = size(B); 
Y = repmat(B,ma,mb); 
X = reshape(repmat(reshape(repmat(A(:),1,mb)',ma*mb,na),nb,1),ma*mb,na*nb); 
X.*Y 
+0

Questo è abbastanza pulito ed è esattamente quello che stavo cercando di fare. Basta attenersi a ripmat e rimodellare. – Gio

Problemi correlati