2012-12-11 25 views
2

我需要填写一个矩阵(size_out,size_in)。我正在寻找类似的问题,但他们的解决方案都不能帮助我。向量化MATLAB中的double循环:每行分配表达式

这是我第一次尝试

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 

我的问题是:如何向量化外循环?

我不确定重塑& permute或bsxfun的组合是否可以帮助您。

在此先感谢。

+1

我的问题是:*为什么vectorise外环* –

+0

我想,如果你打破它归结为所有本地运营商移植到类似的GPU会更快 – ccook

回答

0

由于几个参数和函数没有定义,我冒昧地定义它们。

不错的是看到'矢量化'非常好的加速 - 尽管它的很多可能是MATLAB并行化。这对克朗来说有点滥用,但这是一种方法。

speed up plot

注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 

在这里,我使用克罗内克张量积来构建包含行和列索引,随后的单位矩阵的两个矩阵,以便这一切都是相同的形状进入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); 

在这里,我简单地更换K,N,与KS和NS确保我把歌剧蒸发散元素明智的尺寸相同,并

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') 
+1

表示感谢?你,那正是我的想法,你钉了。我在寻找像kron这样的功能。 – WizardValle

+0

我的荣幸 - 我花费了相当长的时间试图消除克朗本身的成本 - 约90%的成本,但其非线性使其难以分解。 – ccook

+0

在这种情况下,它的价值kron和repmat表现相同。 – ccook