用迹计算向量化克罗内克乘法
Vectorize kroniker multiplcation with trace calculations
重新发布更多详细信息,这些详细信息极大地改变了我第一个问题的范围。原代码如下:
K = zeros(N*N)
for a=1:N
for i=1:I
for j=1:J
M = kron(X(:,:,a).',Y(:,:,a,i,j));
pr = real(trace(E*M));
K = K+H(i,j,a)*M/pr;
end
end
end
其中 E 是布尔掩码,H 是包含 N IxJ 个直方图的 3D 矩阵。 K是输出
目标是矢量化 kroniker 乘法调用。我的直觉是将 X 和 Y 视为矩阵的容器(作为参考,馈送到 kron 的 X 和 Y 的切片是 7x7 阶方阵)。在此容器方案下,X 显示为 1-D 容器,Y 显示为 3-D 容器。我的下一个猜测是将 Y 重塑为二维容器或更好的一维容器,然后对 X 和 Y 进行元素明智的乘法。问题是:如何以保留 M 和matlab 甚至可以在这个容器想法中处理这个想法,还是需要进一步重塑容器以进一步暴露内部矩阵元素?
带7D
置换的矩阵乘法
% Get sizes
[m1,m2,~] = size(X);
[n1,n2,N,n4,n5] = size(Y);
% Perform kron format elementwise multiplication betwen the first two dims
% of X and Y, keeping the third dim aligned and "pushing out" leftover dims
% from Y to the back
mults = bsxfun(@times,permute(X,[4,2,5,1,3]),permute(Y,[1,6,2,7,3,4,5]));
mults3D = reshape(mults,m1*n1,m2*n2,[]);
Emults3D = reshape(E*reshape(mults3D,size(mults3D,1),[]),size(mults3D));
% Trace summations by using linear indices of diagonal on 3D slices in Emults3D
MN = m1*n1;
idx = 1:MN+1:MN^2;
idx2D = bsxfun(@plus,idx(:),MN^2*(0:size(Emults3D,3)-1));
pr_sums = sum(Emults3D(idx2D),1);
% Perform "M/pr" equivalent elementwise divisions and then use
% matrix-multiplication to reduce the iterative summations
Mp = bsxfun(@rdivide,mults3D,reshape(pr_sums,1,1,[]));
out = reshape(Mp,[],size(Mp,3))*reshape(permute(H,[3,1,2]),[],1);
out = reshape(out,m1*n1,m2*n2);
基准测试
输入是这样设置的-
% Size parameter
n = 5;
% Setup inputs
X = rand(n,n,n);
Y = rand(n,n,n,n,n);
E = rand(n*n,n*n)>0.5;
H = rand(n,n,n);
num_iter = 500; % Number of iterations to run the approaches for
运行时结果为 -
----------------------------- With Loop
Elapsed time is 8.806286 seconds.
----------------------------- With Vectorization
Elapsed time is 1.471877 seconds.
将大小参数 n
设置为 10
,运行时间为 -
----------------------------- With Loop
Elapsed time is 5.068872 seconds.
----------------------------- With Vectorization
Elapsed time is 4.399783 seconds.
重新发布更多详细信息,这些详细信息极大地改变了我第一个问题的范围。原代码如下:
K = zeros(N*N)
for a=1:N
for i=1:I
for j=1:J
M = kron(X(:,:,a).',Y(:,:,a,i,j));
pr = real(trace(E*M));
K = K+H(i,j,a)*M/pr;
end
end
end
其中 E 是布尔掩码,H 是包含 N IxJ 个直方图的 3D 矩阵。 K是输出
目标是矢量化 kroniker 乘法调用。我的直觉是将 X 和 Y 视为矩阵的容器(作为参考,馈送到 kron 的 X 和 Y 的切片是 7x7 阶方阵)。在此容器方案下,X 显示为 1-D 容器,Y 显示为 3-D 容器。我的下一个猜测是将 Y 重塑为二维容器或更好的一维容器,然后对 X 和 Y 进行元素明智的乘法。问题是:如何以保留 M 和matlab 甚至可以在这个容器想法中处理这个想法,还是需要进一步重塑容器以进一步暴露内部矩阵元素?
带7D
置换的矩阵乘法
% Get sizes
[m1,m2,~] = size(X);
[n1,n2,N,n4,n5] = size(Y);
% Perform kron format elementwise multiplication betwen the first two dims
% of X and Y, keeping the third dim aligned and "pushing out" leftover dims
% from Y to the back
mults = bsxfun(@times,permute(X,[4,2,5,1,3]),permute(Y,[1,6,2,7,3,4,5]));
mults3D = reshape(mults,m1*n1,m2*n2,[]);
Emults3D = reshape(E*reshape(mults3D,size(mults3D,1),[]),size(mults3D));
% Trace summations by using linear indices of diagonal on 3D slices in Emults3D
MN = m1*n1;
idx = 1:MN+1:MN^2;
idx2D = bsxfun(@plus,idx(:),MN^2*(0:size(Emults3D,3)-1));
pr_sums = sum(Emults3D(idx2D),1);
% Perform "M/pr" equivalent elementwise divisions and then use
% matrix-multiplication to reduce the iterative summations
Mp = bsxfun(@rdivide,mults3D,reshape(pr_sums,1,1,[]));
out = reshape(Mp,[],size(Mp,3))*reshape(permute(H,[3,1,2]),[],1);
out = reshape(out,m1*n1,m2*n2);
基准测试
输入是这样设置的-
% Size parameter
n = 5;
% Setup inputs
X = rand(n,n,n);
Y = rand(n,n,n,n,n);
E = rand(n*n,n*n)>0.5;
H = rand(n,n,n);
num_iter = 500; % Number of iterations to run the approaches for
运行时结果为 -
----------------------------- With Loop
Elapsed time is 8.806286 seconds.
----------------------------- With Vectorization
Elapsed time is 1.471877 seconds.
将大小参数 n
设置为 10
,运行时间为 -
----------------------------- With Loop
Elapsed time is 5.068872 seconds.
----------------------------- With Vectorization
Elapsed time is 4.399783 seconds.