2016-04-05 7 views
2

Gibt es eine schnelle Möglichkeit, jede Zeile einer 3-dimensionalen Matrix zu normalisieren, ohne auf langsame For-Schleifen in Matlab zurückzugreifen?L2 Normalisieren einer 3-dimensionalen Matrix in Matlab

sagen meine Eingangsdaten wie folgt aussehen:

d(:,:,1) = 
1  2  3 
4  5  6 

d(:,:,2) = 
7  8  9 
10 11 12 

Ich weiß, dass ich durch die Verwendung

norms = sqrt(sum(d.^2,2)) 
norms(:,:,1) = 
3.7417 
8.7750 

norms(:,:,2) = 
13.9284 
19.1050 

Aber wie die Norm jeder Reihe bekommen kann nun die zweite Dimension mit dieser Norm zu unterteilen Werte? Ich weiß, dass in 2 Dims kann ich ./ verwenden, aber dies scheint nicht für 3-dimensionale Daten zu arbeiten.

Antwort

3

bsxfun ist dein Freund:

out = bsxfun(@rdivide, d, norms); 

Was dies bedeutet ist, dass es vorübergehend eine 3D-Matrix erstellt, die jede Zeile von norms für so viele Spalten repliziert, da es in d und es teilt sich jedes Element in einem Element sind mit d und norms.

Wir erhalten:

>> d = cat(3, [1 2 3; 4 5 6], [7 8 9; 10 11 12]); 
>> norms = sqrt(sum(d.^2,2)); 
>> out = bsxfun(@rdivide, d, norms) 

out(:,:,1) = 

    0.2673 0.5345 0.8018 
    0.4558 0.5698 0.6838 


out(:,:,2) = 

    0.5026 0.5744 0.6462 
    0.5234 0.5758 0.6281 

Wir auch, dass jede Zeile überprüfen kann, ist L2-normalisiert, indem die Summe der Quadrate entlang jeder Zeile unabhängig zu bestimmen und sicherzustellen, dass jedes Ergebnis Summen bis 1:

>> sum(out.^2, 2) 

ans(:,:,1) = 

    1.0000 
    1.0000 


ans(:,:,2) = 

    1.0000 
    1.0000 

Wenn der Ansatz mit bsxfun nicht ganz sinnvoll ist, könnte man eine Matrix erstellen, die die gleichen Dimensionen wie d behandelt, indem man repmat ... verwendet, dann können Sie die elementweise di ausführen Vision, die Sie sich wünschen:

>> out = d ./ repmat(norms, [1 size(d,2) 1]) 

out(:,:,1) = 

    0.2673 0.5345 0.8018 
    0.4558 0.5698 0.6838 


out(:,:,2) = 

    0.5026 0.5744 0.6462 
    0.5234 0.5758 0.6281 

Mit repmat Sie angeben, wie oft Sie die Matrix in jeder Dimension kopiert werden soll. Wir möchten nur, dass die Matrix über die Spalten repliziert wird, während die Anzahl der Zeilen und Segmente gleich ist. Daher gibt der Vektor [1 size(d,2) 1] an, wie oft die Matrix in jeder Dimension kopiert werden soll.

Eigentlich ist dies, was bsxfun unter der Haube tut, ohne dass Sie mit den Kopfschmerzen der Schaffung dieser temporären Matrix beschäftigen müssen. Diese Replikation ist für Sie erledigt, ohne dass Sie darüber nachdenken.

+1

Es funktioniert, danke! – mcExchange