我需要填写一个矩阵(size_out,size_in)。我一直在寻找类似的问题,但他们的解决方案都无法帮助我。
这是我的第一次尝试
for k= 0:size_out-1
for n= 0:size_in-1
part1= sincd(2*No-2, 2*size_in, (k+1/2)/factor -n -1/2);
part3= sincd(2*No-2, 2*size_in, (k+1/2)/factor +n +1/2);
part2= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor -n -1/2) );
part4= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor +n +1/2) );
A(k+1,n+1)= part1*part2+part3*part4;
end
end
我通过消除内循环来对这段代码进行矢量化:
for k= 0:size_out-1
A(k+1,1:size_in)= ...
sincd(2*No-2, 2*size_in, (k+1/2)/factor -(0:size_in-1) -1/2 ) .* ...
cos( pi/(2*size_in) * ( (k+1/2)/factor -(0:size_in-1) -1/2 ) ) + ...
sincd(2*No-2, 2*size_in, (k+1/2)/factor +(0:size_in-1) +1/2 ) .* ...
cos( pi/(2*size_in) * ( (k+1/2)/factor +(0:size_in-1) +1/2 ) );
end
我的问题是:如何对外循环进行矢量化?
我不确定reshape& permute或bsxfun的组合是否有帮助。
提前致谢。
答案 0 :(得分:0)
由于一些参数和函数未定义,我冒昧地定义它们。
通过'矢量化'看到非常好的加速效果真是太好了 - 虽然很多可能是MATLAB并行化。这对克朗来说有点滥用,但这是一种方法。
注意这里的for循环是测试各种比例
% // testing for a range of scales
t1 = [];
t2 = [];
scales = floor(logspace(1,3,20));
for scale = scales
% // Some guessed parameters and large sizes
size_out = scale;
size_in = scale;
No = 2; %?
factor = 3;
% // Arbitrary function for sincd
sincd = @(x, y, z) x.*y.*z;
tic
% // Provided code
A = zeros(size_out,size_in);
for k= 0:size_out-1
for n= 0:size_in-1
part1= sincd(2*No-2, 2*size_in, (k+1/2)/factor -n -1/2);
part3= sincd(2*No-2, 2*size_in, (k+1/2)/factor +n +1/2);
part2= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor -n -1/2) );
part4= cos( (pi/(2*size_in) ) * ( (k+1/2)/factor +n +1/2) );
A(k+1,n+1)= part1*part2+part3*part4;
end
end
t1 = [t1; toc];
tic
在这里,我使用kronecker张量积来构建两个矩阵,其中包含行和列索引,后跟一个单位矩阵,以便所有内容都是相同的形状进入sincd
ns = kron([1:size_in]-1,ones(1,size_out)');
ks = kron(ones(1,size_in),[1:size_out]'-1);
ident = ones(size_out,size_in);
这里我简单地用ks和ns替换k,n,确保我保持操作元素的明智和相同的大小
B = sincd( 2*No-2*ident, 2*size_in*ident, (ks+1/2)/factor -ns -1/2) ...
.* cos( (pi/(2*size_in) ) * ( (ks+1/2)/factor -ns -1/2) ) ...
+ sincd(2*No-2*ident, 2*size_in*ident, (ks+1/2)/factor +ns +1/2) ...
.*cos( (pi/(2*size_in) ) * ( (ks+1/2)/factor +ns +1/2) );
t2 = [t2; toc];
% // Should be zero
norm(A-B)
end
loglog(scales, t1./t2)
title('speed up')