8

行ごとにk個の数値を含むn行k列のサイズの行列があります。これらのk個の数値をk次元行列のインデックスとして使用したいと思います。MATLABでこれを行うコンパクトな方法はありますか、それともforループを使用する必要がありますか?

これは私が(MATLAB擬似コードで)やりたいことですが、よりMATLAB風の方法で:

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

3 に答える 3

15

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

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

最初の行は、indexmatrixを使用しての各列をセル配列の個別のセルに配置しnum2cellます。kこれにより、すべての列をコンマ区切りのリストとしてに渡すことができます。これは、添え字付きのインデックス(行、列など)を線形インデックスに変換sub2indする関数です(各行列要素には1からまでの番号が付けられます。これは、マトリックス)。最後の行では、これらの線形インデックスを使用してforループを置き換えています。行列の索引付け(添え字、線形、および論理)に関する適切な説明は、ここにあります。NN

思考のためのもう少しの食べ物...

ベクトル化されたソリューションを支持してforループを敬遠する傾向は、多くのMATLABユーザー(私自身を含む)が慣れ親しんできたものです。ただし、新しいバージョンのMATLABは、ループをはるかに効率的に処理します。別のSOの質問に対するこの回答で説明したように、forループを使用すると、ベクトル化されたソリューションで得られるよりも高速に実行されるコードが生成される場合があります。

私は確かに、コードをベクトル化しようとすべきではないと言っているのではなく、すべての問題が固有であるということだけを言っています。多くの場合、ベクトル化の方が効率的ですが、常にそうとは限りませ。あなたの問題では、forループとベクトル化されたコードの実行速度はおそらく値nとの大きさに依存しますk

于 2009-04-27T13:44:36.810 に答える
6

ベクトルの要素をindexmatrix(row, :)個別の添え字として扱うには、要素をセル配列として扱う必要があります。だから、あなたはこのようなことをすることができます

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

subsCellをコンマ区切りリストとして展開するには、残念ながら2つの別々の行が必要です。ただし、このコードは。から独立していkます。

于 2009-04-27T09:09:06.347 に答える
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 );

乾杯!

于 2012-12-05T16:10:42.947 に答える