2009-04-27 3 views
8

私は行列ごとにk個の数値を含むn行k列の行列を得ました。これらのk個の数値をインデックスとしてk次元の行列に使用したいと考えています。 MATLABのコンパクトな方法はありますか?またはforループを使用する必要がありますか?コンパクトなMATLAB行列インデックス表記

これは私が(MATLABの擬似コードで)何をしたいのかですが、より多くのMATLABっぽい方法で:

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

答えて

15

あなたがforループを使用する必要がないようにしたい場合は、これはおそらくそれを行うにはクリーンな方法です:

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

説明:

最初の行は、indexmatrixの各列を置きますを、NUM2CELLを使用して細胞アレイの別々の細胞に導入することによって達成される。これは、私たちは、SUB2INDcomma-separated listとして(各行列要素があるN、Nに1から番号付けされ線形インデックス添字インデックス(行、列、など)に変換する機能を全てKカラムを通過させます行列内の要素の総数)。最後の行は、これらの線形インデックスを使用してforループを置き換えます。行列索引付け(下付き文字、線形、および論理)についての良い議論はhereです。

THOUGHT FOR SOME MORE FOOD ...離れてベクトル化ソリューションの賛成でループのから敬遠する

傾向は何か、多くのMATLABユーザが(私自身を含め)に慣れてきています。しかし、MATLABの新しいバージョンでは、ループ処理がはるかに効率的です。別のSOの質問にthis answerで説明したように、forループを使用すると、ベクトル化されたソリューションよりも速く実行するコードが生成されることがあります。

私は確かにあなたのコードをベクトル化しようとすべきではない、すべての問題は一意であると言っているわけではありません。ベクトル化は、しばしばが効率的ですが、は常にではありません。あなたの問題では、forループとベクトル化されたコードの実行速度はおそらく値nkの値に依存します。

6

別の添字としてベクトルindexmatrix(row, :)の要素を処理するために、あなたが要素を必要とします細胞アレイとして。だから、あなたは、残念ながらあなたは二つの別々のラインが必要なのか、カンマ区切りリストとしてsubsCellを展開するには、この

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

ような何かを行うことができます。ただし、このコードはkから独立しています。

+0

素晴らしい!あなたはそれも行の数から独立して得ることができますか? – AnnaR

+0

@AnnaR - 私は 'indexmatrix'のすべての' n'行を一度に処理する答えを投稿しました。 – Shai

0

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

乾杯ハック方法で、線形インデックスにあなたのサブインデックスを変換!

関連する問題