0

刚开始用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,索恩:

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

4

2 回答 2

1

error_km你不预先分配Nt。这一步很重要。您可以在这个 Matlab 帮助文件中了解更多关于原因的信息。

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

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
于 2012-04-11T23:01:35.363 回答
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));

如果我已经正确阅读了您的代码并正确匹配了括号,那么这可能足以满足您的口味。

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

Nt = zeros(size(n))
于 2012-04-12T08:51:02.273 回答