没有 "for loop" 的 normrnd() 和 norm() 操作

normrnd() and norm() operations without "for loop"

我一直在四处寻找以编写以下没有 "for loop" 的代码。我已经研究过数组操作,例如 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

任何解决方案将不胜感激。 另外,我的第二个问题是,替换上述循环是否会减少 运行 时间,尤其是对于大型数据集?还有其他可以减少 运行 时间的技巧吗?我问这个问题的原因是我正在处理大数据集,显然减少我工作的每个步骤的时间 运行 将导致过程成本的显着降低。

对不起,我已经再次检查了你的问题,我无法帮助删除 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

讨论和代码

您可以使用基于 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 黑客版本,在 Whosebug - 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 的数组而不是标量值,因此使 vectorization 生效。


快速运行结果

*****************  Datasize : n = 100000 , d = 10 *******************
-------------------------------------- With original loopy code
Elapsed time is 82.344671 seconds.
-------------------------------------- With Proposed vectorized code
Elapsed time is 0.033276 seconds.

*****************  Datasize : n = 10000 , d = 100 *******************
-------------------------------------- With original loopy code
Elapsed time is 7.776902 seconds.
-------------------------------------- With Proposed vectorized code
Elapsed time is 0.032324 seconds.

此处看到的巨大加速与使用矢量化的 other normrnd related problem 获得的加速一致。