紧凑的MATLAB矩阵索引表示法

时间:2009-04-27 08:44:01

标签: matlab indexing matrix notation

我有一个n-by-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

3 个答案:

答案 0 :(得分:15)

如果你想避免使用for循环,这可能是最干净的方法:

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

第一行使用num2cellindexmatrix的每列放入单元格数组的单独单元格中。这允许我们将所有k列作为comma-separated list传递到sub2ind,这是一个将下标索引(行,列等)转换为线性索引(每个矩阵元素从1到N编号,N是矩阵中元素的总数。最后一行使用这些线性索引来替换for循环。可以找到关于矩阵索引(下标,线性和逻辑)的良好讨论here

还有一些值得思考的东西......

许多MATLAB用户(包括我自己)已经习惯了这种倾向于回避for循环而倾向于使用矢量化解决方案。但是,较新版本的MATLAB可以更有效地处理循环。正如this answer中针对另一个SO问题所讨论的那样,使用for循环有时会导致代码运行速度比使用矢量化解决方案时更快。

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

答案 1 :(得分:6)

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

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

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

答案 2 :(得分: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 );

干杯!