3d矩阵到2d矩阵matlab [英] 3d Matrix to 2d Matrix matlab
问题描述
我正在使用Matlab R2014a。
I am using Matlab R2014a.
我有一个三维M x N x M矩阵A.我想要一种矢量化方法来提取二维矩阵B来自它,这样对于每个i,j我有
I have a 3-dimensional M x N x M matrix A. I would like a vectorized way to extract a 2 dimensional matrix B from it, such that for each i,j I have
B(i,j)= A(i,j,g(i,j))
B(i,j)=A(i,j,g(i,j))
其中g是大小为M×N的二维索引矩阵,即在{1,2,...,M}中具有整数值。
where g is a 2-dimensional index matrix of size M x N, i.e. with integral values in {1,2,...,M}.
上下文是我将函数A(k,z,k')表示为三维矩阵,函数g(k,z)表示为2维矩阵,我想计算函数
The context is that I am representing a function A(k,z,k') as a 3-dimensional matrix, the function g(k,z) as a 2-dimensional matrix, and I would like to compute the function
h(k,z)= f(k,z,g(k,z))
h(k,z)=f(k,z,g(k,z))
这似乎是一个简单而常见的尝试,但我真的无法在网上找到任何东西。非常感谢能有所帮助的人!
This seems like a simple and common thing to try to do but I really can't find anything online. Thank you so much to whoever can help!
我的第一个想法是尝试像B = A(:,:,g)或B = A(g)但是毫不奇怪,这些都不起作用。是否有类似的东西?
My first thought was to try something like B = A(:,:,g) or B=A(g) but neither of these works, unsurprisingly. Is there something similar?
推荐答案
你可以使用最好的矢量化工具, bsxfun
-
You can employ the best tool for vectorization, bsxfun
here -
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:添加包含dim-3索引所需的偏移量由 g
提供,并使用这些索引编入索引以获得我们想要的输出 -
Step #2: Add the offset needed to include the dim-3 indices being supplied by g
and index into A with those indices to get our desired output -
A(bsxfun(@plus,[1:M]',M*(0:N-1)) + M*N*(g-1))
基准测试
这里一个快速的基准测试来比较基于 bsxfun
的方法与 ndgrid + sub2ind 的解决方案https://stackoverflow.com/a/27339316/3293881\">路易斯的解决方案, M
和 N
as 100
。
Benchmarking
Here's a quick benchmark test to compare this bsxfun
based approach against the ndgrid + sub2ind
based solution as presented in Luis's solution with M
and N
as 100
.
使用 tic-toc
的基准代码看起来像这样 -
The benchmarking code using tic-toc
would look something like this -
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
这是运行时结果 -
Here's the runtime results -
-------------------- With BSXFUN
Elapsed time is 2.090230 seconds.
-------------------- With NDGRID + SUB2IND
Elapsed time is 4.133219 seconds.
结论
正如您所见<基于code> bsxfun 的方法非常有效,既可以作为矢量化方法,也可以作为性能良好的方法。
Conclusions
As you can see bsxfun
based approach works really well, both as a vectorized approach and good with performance too.
为什么 bsxfun
更好 -
Why is bsxfun
better here -
-
bsxfun
复制偏移元素并添加它们,即时> strong>。
bsxfun
does replication of offsetted elements and adding them, both on-the-fly.
在另一个解决方案中, ndgrid
在内部对<$ c $进行两次函数调用c> repmat ,从而产生函数调用开销。在下一步, sub2ind
花费时间添加偏移量以获得线性索引,从而带来另一个函数调用开销。
In the other solution, ndgrid
internally makes two function calls to repmat
, thus incurring the function call overheads. At the next step, sub2ind
spends time in adding the offsets to get the linear indices, bringing in another function call overhead.
这篇关于3d矩阵到2d矩阵matlab的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!