Matlab 如何对嵌套循环进行矢量化
我很难想象如何将这组循环矢量化。任何指导都将不胜感激Matlab 如何对嵌套循环进行矢量化,matlab,loops,for-loop,octave,vectorization,Matlab,Loops,For Loop,Octave,Vectorization,我很难想象如何将这组循环矢量化。任何指导都将不胜感激 ind_1 = [1,2,3]; ind_2 = [1,2,4]; K = zeros(3,3,3,3,3,3,3,3,3); pp = rand(4,4,4); for s = 1:3 for t = 1:3 for k = 1:3 for l = 1:3 for m = 1:3 for n = 1:3 for o = 1:3 for p = 1:3 for r =
ind_1 = [1,2,3];
ind_2 = [1,2,4];
K = zeros(3,3,3,3,3,3,3,3,3);
pp = rand(4,4,4);
for s = 1:3
for t = 1:3
for k = 1:3
for l = 1:3
for m = 1:3
for n = 1:3
for o = 1:3
for p = 1:3
for r = 1:3
% the following loops are singular valued except when
% y=3 for ind_x(y) in this case
for a_s = ind_1(s):ind_2(s)
for a_t = ind_1(t):ind_2(t)
for a_k = ind_1(k):ind_2(k)
for a_l = ind_1(l):ind_2(l)
for a_m = ind_1(m):ind_2(m)
for a_n = ind_1(n):ind_2(n)
for a_o = ind_1(o):ind_2(o)
for a_p = ind_1(p):ind_2(p)
for a_r = ind_1(r):ind_2(r)
K(s,t,k,l,m,n,o,p,r) = K(s,t,k,l,m,n,o,p,r) + ...
pp(a_s, a_t, a_r) * pp(a_k, a_l, a_r) * ...
pp(a_n, a_m, a_s) * pp(a_o, a_n, a_t) * ...
pp(a_p, a_o, a_k) * pp(a_m, a_p, a_l);
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
编辑:
根据ind_1
和ind_2
的值,代码通过对每个索引的pp
s乘积的值求和一次或两次来创建一个指数为1到3的秩9张量
编辑:
这里是一个3d示例,但请记住,pp
的索引只是简单地排列,这一事实在9d版本中没有保留:
ind_1 = [1,2,3];
ind_2 = [1,2,4];
K = zeros(3,3,3);
pp = rand(4,4,4);
for s = 1:3
for t = 1:3
for k = 1:3
% the following loops are singular valued except when
% y=3 for ind_x(y) in this case
for a_s = ind_1(s):ind_2(s)
for a_t = ind_1(t):ind_2(t)
for a_k = ind_1(k):ind_2(k)
K(s,t,k) = K(s,t,k) + ...
pp(a_s, a_t, a_r) * pp(a_t, a_s, a_k) * ...
pp(a_k, a_t, a_s) * pp(a_k, a_s, a_t);
end
end
end
end
end
end
哇!非常简单的解决方案,但不容易找到。顺便问一下,我想知道你的公式是从哪里来的 如果您不介意暂时丢失一点内存(4^9数组与之前的3^9数组的2倍),您可以推迟第3个和第4个超平面在最后的累积 在unix机箱上使用octave 3.2.4进行测试,它从23s(67Mb)下降到0.17s(98Mb)
function K = tensor9_opt(pp)
ppp = repmat(pp, [1 1 1 4 4 4 4 4 4]) ;
% The 3 first numbers are variable indices (eg 1 for a_s to 9 for a_r)
% Other numbers must complete 1:9 indices in any order
T = ipermute(ppp, [1 2 9 3 4 5 6 7 8]) .* ...
ipermute(ppp, [3 4 9 1 2 5 6 7 8]) .* ...
ipermute(ppp, [6 5 1 2 3 4 7 8 9]) .* ...
ipermute(ppp, [7 6 2 1 3 4 5 8 9]) .* ...
ipermute(ppp, [8 7 3 1 2 4 5 6 9]) .* ...
ipermute(ppp, [5 8 4 1 2 3 6 7 9]) ;
% I have not found how to manipulate 'multi-ranges' programmatically.
T1 = T (:,:,:,:,:,:,:,:,1:end-1) ; T1(:,:,:,:,:,:,:,:,end) += T (:,:,:,:,:,:,:,:,end) ;
T = T1(:,:,:,:,:,:,:,1:end-1,:) ; T (:,:,:,:,:,:,:,end,:) += T1(:,:,:,:,:,:,:,end,:) ;
T1 = T (:,:,:,:,:,:,1:end-1,:,:) ; T1(:,:,:,:,:,:,end,:,:) += T (:,:,:,:,:,:,end,:,:) ;
T = T1(:,:,:,:,:,1:end-1,:,:,:) ; T (:,:,:,:,:,end,:,:,:) += T1(:,:,:,:,:,end,:,:,:) ;
T1 = T (:,:,:,:,1:end-1,:,:,:,:) ; T1(:,:,:,:,end,:,:,:,:) += T (:,:,:,:,end,:,:,:,:) ;
T = T1(:,:,:,1:end-1,:,:,:,:,:) ; T (:,:,:,end,:,:,:,:,:) += T1(:,:,:,end,:,:,:,:,:) ;
T1 = T (:,:,1:end-1,:,:,:,:,:,:) ; T1(:,:,end,:,:,:,:,:,:) += T (:,:,end,:,:,:,:,:,:) ;
T = T1(:,1:end-1,:,:,:,:,:,:,:) ; T (:,end,:,:,:,:,:,:,:) += T1(:,end,:,:,:,:,:,:,:) ;
K = T (1:end-1,:,:,:,:,:,:,:,:) ; K (end,:,:,:,:,:,:,:,:) += T (end,:,:,:,:,:,:,:,:) ;
endfunction
pp = rand(4,4,4);
K = tensor9_opt(pp) ;
你能详细说明一下这段代码的作用并添加注释吗?你能创建一个2D或3D示例来说明吗?对我们来说,使用它会更容易,创建示例可能会帮助您自己找到一个策略。@t Pearce:编辑以提供一个3d示例。这是一个令人印象深刻的字母水果循环汤。您研究过内置函数吗:?如果可以使用此功能,我怀疑其他任何功能是否会显示出更好的性能。