8

我有一个 n×k 大小的矩阵,每行包含 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

还有一些值得深思的...

许多 MATLAB 用户(包括我自己)已经习惯了回避 for 循环以支持矢量化解决方案的趋势。但是,较新版本的 MATLAB 处理循环的效率更高。正如另一个 SO question 的答案中所讨论的,使用 for 循环有时会导致比使用矢量化解决方案更快地运行代码。

我当然不是说你不应该再尝试向量化你的代码,只是每个问题都是独一无二的。矢量化通常会更有效,但并非总是如此。对于您的问题,for 循环与矢量化代码的执行速度可能取决于值的大小nk大小。

于 2009-04-27T13:44:36.810 回答
6

要将向量的元素indexmatrix(row, :)视为单独的下标,您需要将元素视为元胞数组。所以,你可以做这样的事情

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

不幸的是,要将 subsCell 扩展为逗号分隔列表,您确实需要两个单独的行。但是,此代码独立于k.

于 2009-04-27T09:09:06.347 回答
0

以hacky方式将您的子索引转换为线性索引

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 回答