2009-04-27 14 views
8

Ich habe eine n-mal-k große Matrix, die k Zahlen pro Zeile enthält. Ich möchte diese k Zahlen als Indizes in eine k-dimensionale Matrix verwenden. Gibt es eine kompakte Methode in MATLAB oder muss ich eine for-Schleife verwenden?Kompakte MATLAB-Matrix-Indexierungsnotation

Dies ist, was ich (in MATLAB Pseudo-Code) tun will, aber in einer MATLAB-ish Art und Weise:

for row=1:1:n 
    finalTable(row) = kDimensionalMatrix(indexmatrix(row, 1),... 
      indexmatrix(row, 2),...,indexmatrix(row, k)) 
end 

Antwort

15

Wenn Sie möchten, um zu vermeiden, eine for-Schleife zu verwenden, ist dies wahrscheinlich der sauberste Weg, es zu tun:

indexCell = num2cell(indexmatrix,1); 
linearIndexMatrix = sub2ind(size(kDimensionalMatrix),indexCell{:}); 
finalTable = kDimensionalMatrix(linearIndexMatrix); 

ERKLÄRUNG:

Die erste Zeile jeder Spalte von indexmatrix legt in separate Zellen eines Zellenarrays mit NUM2CELL. Dies ermöglicht es uns, alle k Spalten als comma-separated list in SUB2IND passieren, eine Funktion, die subscripted Indizes (Zeile, Spalte, etc.) in linearen Indizes (jedes Matrixelement konvertiert wird nummeriert von 1 bis N, wobei N die Gesamtzahl der Elemente in der Matrix). Die letzte Zeile verwendet diese linearen Indizes, um Ihre for-Schleife zu ersetzen. Eine gute Diskussion über Matrixindizierung (tiefgestellt, linear und logisch) findet sich here.

etwas mehr DENKANSTOSS ...

Die Tendenz von for-Schleifen für vektorisiert Lösungen zu scheuen ist etwas, was viele MATLAB-Anwender (mich eingeschlossen) haben sich daran gewöhnt zu. Neuere Versionen von MATLAB verarbeiten Schleifen jedoch wesentlich effizienter. Wie in this answer zu einer anderen SO-Frage diskutiert, kann die Verwendung von for-Schleifen manchmal zu schnellerem Code führen als bei einer vektorisierten Lösung.

Ich sage NICHT, dass Sie nicht versuchen sollten, Ihren Code mehr zu vektorisieren, nur dass jedes Problem einzigartig ist. Vectorizing wird oft effizienter sein, aber nicht immer. Für Ihr Problem wird die Ausführungsgeschwindigkeit von for-Schleifen im Vergleich zu vektorisiertem Code wahrscheinlich davon abhängen, wie groß die Werte n und k sind.

6

Um die Elemente des Vektors indexmatrix(row, :) als separater Indizes zu behandeln, müssen Sie die Elemente als ein Zellenarray. So könnte man so etwas tun

subsCell = num2cell(indexmatrix(row, :)); 
finalTable(row) = kDimensionalMatrix(subsCell{:}); 

Um subsCell als kommagetrennte Liste zu erweitern, leider Sie die zwei separaten Leitungen tun müssen. Dieser Code ist jedoch unabhängig von k.

+0

Großartig! Kannst du es auch unabhängig von der Anzahl der Zeilen bekommen? – AnnaR

+0

@AnnaR - Ich habe gerade eine Antwort geschrieben, die alle 'n' Zeilen von' indexmatrix' gleichzeitig behandelt. – Shai

0

Konvertieren Sie Ihre Subindizes in lineare Indizes in einer hacky Weise

ksz = size(kDimensionalMatrix); 
cksz = cumprod([ 1 ksz(1:end-1)]); 
lidx = (indexmatrix - 1) * cksz' + 1; #' 
% lindx is now (n)x1 linear indices into kDimensionalMatrix, one index per row of indexmatrix 
% access all n values: 
selectedValues = kDimensionalMatrix(lindx); 

Prost!

Verwandte Themen