我希望我的问题有一个非常简单的解决方案。我找不到它:
假设您有两个向量(一个是列向量,一个是行向量)A,B:
A = [1,2,3]
B = [4;5;6]
如果我们将它们乘以如下,我们得到一个矩阵:
>> B*A
ans =
4 8 12
5 10 15
6 12 18
现在我的问题是:我有两个尺寸为m × n × p
和m × n × q
想象一下,沿着维度 m 和 n ,我们有像素,对于每个像素,我们有一个向量(长度为p或q)。 现在我想要的是将两个图像的矢量乘以每个对应的像素,这样,对于每个像素,我得到一个矩阵,因此总共得到一个4D矩阵结束。
我该如何有效地做到这一点?
答案 0 :(得分:4)
Matlab中的循环不再是一件令人恐惧的事情,也不再是本身。
当然,在使用它们时应该非常小心,但是,JIT可以处理多种循环,甚至超越内置函数也能提高性能。
考虑以下测试用例:
clc
m = 512; n = 384;
p = 5; q = 3;
A = rand(m,n,p); % some sample data
B = rand(m,n,q); % some sample data
%% non-loop approach
tic
A2 = reshape(A,[],p);
B2 = reshape(B,[],q);
C2 = arrayfun(@(ii) A2(ii,:)'*B2(ii,:),1:m*n,'uni',false);
C0 = permute(reshape(cell2mat(C2),p,q,m,n),[3 4 1 2]);
toc
%% looped approach, simplest
tic
C = zeros(m,n,p,q);
for mm = 1:m
for nn = 1:n
C(mm,nn,:,:) = ...
squeeze(A(mm,nn,:))*squeeze(B(mm,nn,:)).';
end
end
toc
% check for equality
all(C0(:) == C(:))
%% looped approach, slightly optimized
tic
C = zeros(m,n,p,q);
pp = zeros(p,1);
qq = zeros(1,q);
for mm = 1:m
for nn = 1:n
pp(:) = A(mm,nn,:);
qq(:) = B(mm,nn,:);
C(mm,nn,:,:) = pp*qq;
end
end
toc
% check for equality
all(C0(:) == C(:))
%% looped approach, optimized
tic
C = zeros(p,q,m*n);
A2 = reshape(A,[],p);
B2 = reshape(B,[],q);
for mn = 1:m*n
C(:,:,mn) = A2(mn,:).'*B2(mn,:);
end
C = permute(reshape(C, p,q,m,n), [3,4,1,2]);
toc
% check for equality
all(C0(:) == C(:))
结果:
Elapsed time is 3.955728 seconds.
Elapsed time is 21.013715 seconds.
ans =
1
Elapsed time is 1.334897 seconds.
ans =
1
Elapsed time is 0.573624 seconds.
ans =
1
无论性能如何,我还发现最后一种情况比非循环情况更直观,更易读。
答案 1 :(得分:3)
m=5;
n=4;
p=3;
q=2;
A=randi(10,m,n,p); %some sample data
B=randi(10,m,n,q); %some sample data
A2=reshape(A,[],p);
B2=reshape(B,[],q);
C2=arrayfun(@(ii) A2(ii,:)'*B2(ii,:),1:m*n,'uni',false);
C=permute(reshape(cell2mat(C2),p,q,m,n),[3 4 1 2]);
击穿:
mxnx(p or q)
矩阵更改为(m*n)x(p or q)
格式mxnxpxq
格式答案 2 :(得分:0)
我使用rody_o的解决方案并修改它以摆脱重塑和置换:
C = zeros(m*n, p, q);
A2 = reshape(A,[],p);
B2 = reshape(B,[],q);
for mn = 1:m*n
C(mn,:,:) = A2(mn,:).' * B2(mn,:);
end