在 MATLAB 中执行 "outer product" 二维矩阵和 return 三维数组
Perform "outer product" of 2-D matrix and return a 3-D array in MATLAB
我想对二维矩阵进行运算,它看起来有点像向量的外积。我已经为这个任务写了一些代码,但是它很慢,所以我想知道我是否可以做些什么来加速它。
我想先展示我写的代码,然后用一个例子来说明我想完成的任务。
我的代码,逐行版本
function B = outer2D(A)
B = zeros(size(A,1),size(A,2),size(A,2)); %Pre-allocate the output array
for J = 1 : size(A,1)
B(J,:,:) = transpose(A(J,:))*A(J,:); %Perform outer product on each row of A and assign to the J-th layer of B
end
end
使用矩阵A = randn(30000,20)作为测试输入,耗时0.317秒
我的代码,逐页版本
function B = outer2D(A)
B = zeros(size(A,1),size(A,2),size(A,2)); %Pre-allocate the output array
for J = 1 : size(A,2)
B(:,:,J) = repmat(A(:,J),1,size(A,2)).*A; %Evaluate B page-by-page
end
end
使用矩阵A = randn(30000,20)作为测试输入,耗时0.146秒
示例 1
A = [3 0; 1 1; 1 0; -1 1; 0 -2]; %A is the input matrix.
B = outer2D(A);
disp(B)
那么我希望
(:,:,1) =
9 0
1 1
1 0
1 -1
0 0
(:,:,2) =
0 0
1 1
0 0
-1 1
0 4
B第一行,[9 0; 0 0],是[3 0]的外积,
即 [3; 0]*[3 0] = [9 0; 0 0].
第二行B,[1 1; 1 1], 是 [1 1] 的外积,
即 [1; 1]*[1 1] = [1 1; 1 1].
B第三行,[1 0; 0 0],是[1 0]的外积,
即 [1; 0]*[1 0] = [1 0; 0 0].
其余行也一样。
示例 2
A =
0 -1 -2
0 1 0
-3 0 2
0 0 0
1 0 0
B = outer2D(A)
disp(B)
那么,和例子1类似,预期输出为
(:,:,1) =
0 0 0
0 0 0
9 0 -6
0 0 0
1 0 0
(:,:,2) =
0 1 2
0 1 0
0 0 0
0 0 0
0 0 0
(:,:,3) =
0 2 4
0 0 0
-6 0 4
0 0 0
0 0 0
因为我项目中真正的输入是30000×2000这样的大小,这个任务要执行很多次。所以这个任务的加速对我来说是相当必要的。
我正在考虑取消函数中的 for 循环。请问我对这个问题有什么看法吗?
matlab语言无法实现外积
自动展开:
function B = outer2D(A)
B=permute(permute(A,[3 1 2]).*A',[2 3 1]);
end
没有自动扩展:
function B = outer2Dold(A)
B=permute(bsxfun(@times,permute(A,[3 1 2]),A'),[2 3 1]);
end
我想对二维矩阵进行运算,它看起来有点像向量的外积。我已经为这个任务写了一些代码,但是它很慢,所以我想知道我是否可以做些什么来加速它。
我想先展示我写的代码,然后用一个例子来说明我想完成的任务。
我的代码,逐行版本
function B = outer2D(A)
B = zeros(size(A,1),size(A,2),size(A,2)); %Pre-allocate the output array
for J = 1 : size(A,1)
B(J,:,:) = transpose(A(J,:))*A(J,:); %Perform outer product on each row of A and assign to the J-th layer of B
end
end
使用矩阵A = randn(30000,20)作为测试输入,耗时0.317秒
我的代码,逐页版本
function B = outer2D(A)
B = zeros(size(A,1),size(A,2),size(A,2)); %Pre-allocate the output array
for J = 1 : size(A,2)
B(:,:,J) = repmat(A(:,J),1,size(A,2)).*A; %Evaluate B page-by-page
end
end
使用矩阵A = randn(30000,20)作为测试输入,耗时0.146秒
示例 1
A = [3 0; 1 1; 1 0; -1 1; 0 -2]; %A is the input matrix.
B = outer2D(A);
disp(B)
那么我希望
(:,:,1) =
9 0
1 1
1 0
1 -1
0 0
(:,:,2) =
0 0
1 1
0 0
-1 1
0 4
B第一行,[9 0; 0 0],是[3 0]的外积, 即 [3; 0]*[3 0] = [9 0; 0 0].
第二行B,[1 1; 1 1], 是 [1 1] 的外积, 即 [1; 1]*[1 1] = [1 1; 1 1].
B第三行,[1 0; 0 0],是[1 0]的外积, 即 [1; 0]*[1 0] = [1 0; 0 0].
其余行也一样。
示例 2
A =
0 -1 -2
0 1 0
-3 0 2
0 0 0
1 0 0
B = outer2D(A)
disp(B)
那么,和例子1类似,预期输出为
(:,:,1) =
0 0 0
0 0 0
9 0 -6
0 0 0
1 0 0
(:,:,2) =
0 1 2
0 1 0
0 0 0
0 0 0
0 0 0
(:,:,3) =
0 2 4
0 0 0
-6 0 4
0 0 0
0 0 0
因为我项目中真正的输入是30000×2000这样的大小,这个任务要执行很多次。所以这个任务的加速对我来说是相当必要的。
我正在考虑取消函数中的 for 循环。请问我对这个问题有什么看法吗?
matlab语言无法实现外积
自动展开:
function B = outer2D(A)
B=permute(permute(A,[3 1 2]).*A',[2 3 1]);
end
没有自动扩展:
function B = outer2Dold(A)
B=permute(bsxfun(@times,permute(A,[3 1 2]),A'),[2 3 1]);
end