刚开始使用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
答案 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))