我正在使用Matlab R2014a。
我有一个三维M x N x M矩阵A.我想用一种矢量化方法从中提取二维矩阵B,这样对于每个i,我都有
B(I,J)= A(I,J,G(I,J))
其中g是大小为M×N的二维索引矩阵,即在{1,2,...,M}中具有整数值。
上下文是我将函数A(k,z,k')表示为三维矩阵,函数g(k,z)表示为二维矩阵,我想计算功能
H(K,Z)= F(K,Z,G(K,Z))
这似乎是一个简单而常见的尝试,但我真的无法在网上找到任何东西。非常感谢能有所帮助的人!
我的第一个想法是尝试像B = A(:,:,g)或B = A(g)这样的东西,但这些都不起作用,这并不令人惊讶。有类似的东西吗?
答案 0 :(得分:2)
您可以使用最佳的矢量化工具,bsxfun
此处 -
B = A(bsxfun(@plus,[1:M]',M*(0:N-1)) + M*N*(g-1))
步骤1:计算与A
的前两个维度(行和列)对应的索引 -
bsxfun(@plus,[1:M]',M*(0:N-1))
步骤2:添加包含由g
提供的dim-3索引所需的偏移量,并使用这些索引将索引编入A以获得所需的输出 -
A(bsxfun(@plus,[1:M]',M*(0:N-1)) + M*N*(g-1))
这是一个快速基准测试,用于将基于bsxfun
的方法与基于ndgrid + sub2ind
的解决方案进行比较,如Luis's solution中M
和N
100
所示1}}。
使用tic-toc
的基准代码看起来像这样 -
M = 100;
N = 100;
A = rand(M,N,M);
g = randi(M,M,N);
num_runs = 5000; %// Number of iterations to run each approach
%// Warm up tic/toc.
for k = 1:50000
tic(); elapsed = toc();
end
disp('-------------------- With BSXFUN')
tic
for iter = 1:num_runs
B1 = A(bsxfun(@plus,[1:M]',M*(0:N-1)) + M*N*(g-1)); %//'
end
toc, clear B1
disp('-------------------- With NDGRID + SUB2IND')
tic
for iter = 1:num_runs
[ii, jj] = ndgrid(1:M, 1:N);
B2 = A(sub2ind([M N M], ii, jj, g));
end
toc
这是运行时结果 -
-------------------- With BSXFUN
Elapsed time is 2.090230 seconds.
-------------------- With NDGRID + SUB2IND
Elapsed time is 4.133219 seconds.
正如您所看到的那样,基于bsxfun
的方法非常有效,既可以作为矢量化方法,也可以作为性能良好的方法。
为什么bsxfun
在这里更好 -
bsxfun
复制偏移元素并添加它们,即时。
在另一个解决方案中,ndgrid
在内部对repmat
进行两次函数调用,从而导致函数调用开销。在下一步,sub2ind
花费时间添加偏移量来获取线性索引,从而带来另一个函数调用开销。
答案 1 :(得分:0)
尝试使用sub2ind
。这假设g
被定义为M
x N
矩阵,可能值1
,...,M
:
[ii, jj] = ndgrid(1:M, 1:N);
B = A(sub2ind([M N M], ii, jj, g));