如何在Matlab中对此操作进行矢量化?

时间:2014-10-20 20:40:45

标签: matlab

代码:

A = NxMxLxD matrix
B = NxMxL matrix
index = NxMxL matrix containing values between 1 and D

for i=1:N
 for j=1:M
  for k=1:L
   B(i,j,k) = A(i,j,k,index(i,j,k));
  end
 end
end

如何以矢量形式编写,即使用一些内置函数?我基本上每个点都选择索引。

2 个答案:

答案 0 :(得分:1)

可以按照以下方式完成:

ind = bsxfun(@plus, bsxfun(@plus, ...
      (1:N).', N*(0:M-1)), N*M*permute(0:L-1, [3 1 2])) + N*M*L*(index-1);
B = A(ind);

诀窍是构建一个linear indexind变量),它对应于矢量化的索引(i,j,k,index(i,j,k))。我通过两次调用bsxfun来做到这一点。关键是要记住线性索引首先沿着列运行,然后沿着行运行,然后沿着第三个暗淡的切片运行。

标准方式是使用ndgrid然后使用sub2ind(请参阅@rayryeng`s answer),但这需要更多内存。

答案 1 :(得分:1)

好的,B的输出数组看起来是这样的,对于此输出中的每个位置,A中的相应位置都有一个D - 元素向量,你想要的根据{{​​1}}中存储的值D选择要从此index - 元素向量中选择的元素,其大小与B相同。

我们可以使用meshgridsub2ind的组合来实现这一目标。首先使用meshgrid生成3D坐标网格,其大小与矩阵B相同。之后,使用sub2ind确定一组线性索引,以访问A的第四维。在此之后,我们只使用sub2ind的输出执行直接分配,该输出使用meshgridindex的输出的组合。

因此,尝试这样的事情:

[cols,rows,dim] = meshgrid(1:size(A,2), 1:size(A,1), 1:size(A,3));
ind = sub2ind(size(A), rows, cols, dim, index);
B = A(ind);