第三维向量的Matlab产品

时间:2012-07-27 15:35:35

标签: matlab matrix matrix-multiplication

我希望我的问题有一个非常简单的解决方案。我找不到它:

假设您有两个向量(一个是列向量,一个是行向量)A,B:

A = [1,2,3]
B = [4;5;6]

如果我们将它们乘以如下,我们得到一个矩阵:

>> B*A
ans =
 4     8    12
 5    10    15
 6    12    18

现在我的问题是:我有两个尺寸为m × n × pm × n × q

的3D矩阵

想象一下,沿着维度 m n ,我们有像素,对于每个像素,我们有一个向量(长度为p或q)。 现在我想要的是将两个图像的矢量乘以每个对应的像素,这样,对于每个像素,我得到一个矩阵,因此总共得到一个4D矩阵结束。

我该如何有效地做到这一点?

3 个答案:

答案 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)

有些reshapingarrayfunpermute

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]);

击穿:

  • 前两次转化将A和B mxnx(p or q)矩阵更改为(m*n)x(p or q)格式
  • 以便arrayfun可以轻松遍历它们以计算行的矢量积
  • 然后使用cell2mat,重新整形和置换将结果更改回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