代码矢量化适用于不同的数组元素?

时间:2012-04-11 21:28:31

标签: matlab loops vectorization

刚开始使用matlab和矢量化, FF到问题:

怎么做:

%n,t are vectors(1D arrays) EDIT: these are column vectors.
k=9;
i=1;
kv = 0.6*k:0.2*k:1.4*k;
[zs,zb] = size(k);
error1 = zeros(zs,1);
for k2 = kv
error1(i,1) = error_km(n,t,kv(i));
i= i+1;
end

其中error_km为:(n和t大小相同)

function [ returnV] = error_km( n,t,k )
returnV = 0
    [a,b] = size(n);
    Nt = zeros();
    for i=2:a
        Nt(i,1) = (n(i-1,1)^-1 + k*(t(i,1)-t(i-1,1)))^-1;
        error1 = Nt(i,1) - n(i,1);
        returnV = returnV + error1*error1;
    end

对于小型测试案例,整个程序大约需要3到4分钟, 我能够制作和理解循环的简单矢量化替代方案,但我无法对这个循环进行矢量化,

任何指导?

更新: 在error_km中,现在我正在使用:

Nt = (n(1:a-1,1).^-1 + (diff(t(:,1))).*k).^-1 - n(2:a,1);
Nt = Nt.^2;
returnV = sum(Nt);

运行良好,但仍然在主程序中我被迫使用循环迭代kv,如果我使用kv(:)它传递向量函数不是每次单个值。 在main中使用它:error1 = error_km(n,t,kv.*1);

是否有可能摆脱主循环?

EDIT2,Soln:

要摆脱主循环,只需使用arrayfun

2 个答案:

答案 0 :(得分:1)

error_km中,您没有预先分配Nt。这一步很重要。您可以在this Matlab helpfile中了解有关原因的详情。

如果您知道Nt的大小,可以在调用零()时设置它。否则你可以重构循环:

function [ returnV] = error_km( n,t,k )
returnV = 0
    [a,b] = size(n);
    Nt = zeros();
    for i=a:-1:2
        Nt(i,1) = (n(i-1,1)^-1 + k*(t(i,1)-t(i-1,1)))^-1;
        error1 = Nt(i,1) - n(i,1);
        returnV = returnV + error1*error1;
    end

答案 1 :(得分:1)

以下是您寻求答案的部分内容,我相信您可以解决其余问题。您可以替换表达式:

t(i,1)-t(i-1,1)

使用(矢量化)表达式

diff(t(:,1))

然后,您可以使用以下表达式替换i上的循环:

Nt(a:-1:2,1) = (n(a-1:-1:1),1)^-1 + k*(diff(t(:,1))))^-1;
returnV = dot(Nt(:,1)-n(:,1),Nt(:,1)-n(:,1));

如果我已正确阅读您的代码并正确匹配括号,可能会根据您的喜好进行矢量化。

正如你已经被告知的那样,你应该预先分配Nt,在这种情况下我会写:

Nt = zeros(size(n))