10

我有一个非固定维度矩阵 M,我想从中访问单个元素。元素的索引包含在向量 J 中。

例如:

M = rand(6,4,8,2);
J = [5 2 7 1];

output = M(5,2,7,1)

这次 M 有 4 个维度,但这是事先不知道的。这取决于我正在编写的算法的设置。也可能是这样

M = rand(6,4);
J = [3 1];

output = M(3,1)

所以我不能简单地使用

output=M(J(1),J(2))

我正在考虑使用sub2ind,但这也需要它的变量逗号分隔..

@gnovice

这行得通,但我打算大量使用这种从矩阵中提取的元素McellJ因此,如果我每次访问时都必须创建一个临时变量M,这不会极大地减慢计算速度吗?

我也可以写一个单独的函数

function x= getM(M,J)
    x=M(J(1),J(2));
    % M doesn't change in this function, so no mem copy needed = passed by reference
end

并使其适应算法的不同配置。这当然是速度与灵活性的考虑,我的问题中没有包含。

但是:这仅可用于获取元素,用于设置除了实际使用索引(最好是线性索引)之外别无他法。我仍然认为 sub2ind 是一种选择。我想要的最终结果是这样的:

function idx = getLinearIdx(J, size_M)
    idx = ...
end

结果:

function lin_idx = Lidx_ml( J, M )%#eml
%LIDX_ML converts an array of indices J for a multidimensional array M to
%linear indices, directly useable on M
%
% INPUT
%   J       NxP matrix containing P sets of N indices
%   M       A example matrix, with same size as on which the indices in J
%           will be applicable.
%
% OUTPUT
%   lin_idx Px1 array of linear indices
%

% method 1
%lin_idx = zeros(size(J,2),1);
%for ii = 1:size(J,2)
%    cellJ = num2cell(J(:,ii)); 
%    lin_idx(ii) = sub2ind(size(M),cellJ{:}); 
%end

% method 2
sizeM = size(M);
J(2:end,:) = J(2:end,:)-1;
lin_idx = cumprod([1 sizeM(1:end-1)])*J;

end

方法 2 比方法 1 快 20(少量索引集(=P)转换)到 80(大量索引集(=P))倍。容易选择

4

2 回答 2

12

对于可以是任何长度的一般情况J(我假设它总是与 中的维数匹配M),您有几个选项:

  1. 您可以J使用该函数将 的每个条目放在元胞数组的一个元胞中,然后使用冒号运算符从此元胞数组num2cell创建一个逗号分隔的列表

    cellJ = num2cell(J);
    output = M(cellJ{:});
    
  2. 您可以回避该函数并通过一些数学自己sub2ind计算线性索引:

    sizeM = size(M);
    index = cumprod([1 sizeM(1:end-1)]) * (J(:) - [0; ones(numel(J)-1, 1)]);
    output = M(index);
    
于 2012-04-13T18:28:05.740 回答
0

这是 gnovices 选项 2) 的一个版本,它允许处理整个下标矩阵,其中每一行包含一个下标。例如对于 3 个下标:

J = [5 2 7 1 
     1 5 2 7
     4 3 9 2];

sizeM = size(M);
idx = cumprod([1 sizeX(1:end-1)])*(J - [zeros(size(J,1),1) ones(size(J,1),size(J,2)-1)]).';
于 2017-07-19T20:32:05.737 回答