normrnd()和norm()操作没有" for循环"

时间:2015-02-03 16:12:40

标签: matlab for-loop vectorization normal-distribution norm

我一直在寻找以下代码而没有" for循环"。我已经研究过诸如bsxfun()arrayfun或其他MATLAB内置函数之类的数组操作,但无法弄清楚它。

n = 10;
d= 2;

x = rand(n,d);
P_best = rand(n,d);
V_i = rand(n,d)
g = rand(1,d);
r_t = rand(n,1);


a1 = 0.91;
a2 = 0.21;
a3 = 0.51;
a4 = 0.58;

l = a1*a3/(n^a2*d^a4);

for i=1:n
    N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
    N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end

V_o = 0.7298*V_i+N_p+N_g

任何解决方案都将非常感激。 另外,我的第二个问题是,取代上述循环会减少运行时间,特别是对于庞大的数据集吗?还有其他提示会缩短运行时间吗?我问这样一个问题的原因是我正在处理大数据集,显然减少我工作每一步的运行时间将大大降低流程的成本。

2 个答案:

答案 0 :(得分:3)

讨论和代码

您可以使用基于bsxfun的矢量化版本

删除loop
N_g_sigma = l*sqrt(sum(bsxfun(@minus,x,g).^2,2));
N_g_normrnd = bsxfun(@plus,randn(size(N_g_sigma)).*N_g_sigma,g);
N_g = bsxfun(@times,N_g_normrnd - x,1.4962*r_t);

N_p_sigma = l*sqrt(sum(bsxfun(@minus,x,P_best).^2,2));
N_p_normrnd = bsxfun(@plus,randn(size(N_p_sigma)).*N_p_sigma,P_best);
N_p = bsxfun(@times,N_p_normrnd - x,1.4962*r_t);

它基于normrnd.m黑客攻击版本,也在Stackoverflow - Improve speed of NORMRND for a family of distributions in MATLAB上的另一个问题中被利用,它为我们带来了巨大的加速。

需要注意的是,normrnd.m使用了给定标量musigma的随机数生成,如其语法所示 -

function r = normrnd(mu,sigma,varargin); 
%NORMRND Random arrays from the normal distribution...

使用提出的矢量化技术,我们在每次迭代时输入 musigma的数组而不是标量值,从而带来{{1}生效。


快速运行结果

vectorization

这里看到的巨大加速与使用other normrnd related problem进行矢量化所获得的加速一致。

答案 1 :(得分:1)

抱歉我的不好,我再次检查了你的问题,我无法帮助解决for-loop的问题。关于提高for循环速度的一些建议:

% fastest way: Elapsed time is 0.000006 seconds.
tic
for i=n:1
  N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc

% slowest way: Elapsed time is 0.004444 seconds.
tic
for i=1:n
  N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc

% 2nd choice: Elapsed time is 0.000969 seconds.
tic
N_p2(n, 2) = nan;
N_g2(n, 2) = nan;
for i=1:n
  N_p2(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g2(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc