我正在为一篇论文写一篇目标函数。它需要一个嵌套循环,如下所示:
for j=1:m
if j==m
for i=1:n
consumedE(j) = consumedE(j)+ b(i,j)*e(i,j);
for k=1:m-1
for l=1:n
consumedE(j) = consumedE(j) + b(i,j)*(et(end)*Data(i).Vin);
end
end
end
else
for i=1:n
consumedE(j) = consumedE(j) + b(i,j)*(e(i,j)+et(j)*Data(i).Vout);
end
end
end
其中m和n约为200。
即使在非常强大的PC上,它也非常耗时。我怎样才能加快速度?答案 0 :(得分:0)
在你的内心循环中,你根本不参考你的内在指数。
for k=1:m-1
for l=1:n
consumedE(j) = consumedE(j) + b(i,j)*(et(end)*Data(i).Vin);
end
end
这应该与:
相同consumedE(j) = consumedE(j)+ (m-1)*n*b(i,j)*(et(end)*Data(i).Vin);
我希望这会显着提升效果。
答案 1 :(得分:0)
让我们创建一些随机样本数据。我将Data(i).Vout
简化为向量DataVout
。您可以使用[Data.Vout].'
轻松完成此操作。 Data.Vin
也是如此。
m = 10;
n = 5;
b = rand(n,m);
e = rand(n,m);
et = rand(1,m);
DataVout = rand(n,1);
DataVin = rand(n,1);
现在,您的else子句是遍历所有i
和j
的循环,您可以在其中为每个组合执行以下操作:
b(i,j) * ( e(i,j) + et(j) * Data(i).Vout )
然后你总结所有i
。您可以通过以下步骤以矢量化方式执行此操作:
DataVout * et
创建一个包含et(j) * DataVout(i)
的矩阵。此矩阵的大小为 n-by-m ,其大小与e
和b
相同。e
添加到此矩阵,并在结果与b
之间进行逐元素相乘。这是:b .* (e + DataVout * et)
consumedE = sum(b .* (e + DataVout * et), 1)
。最后一个值j==m
在您的计算中很特别:您重复内部计算n * (m-1)
次,因为您不使用k
和l
任何计算。这导致
b(i,j) * ( e(i,j) + n * (m-1) * et(j) * Data(i).Vin )
与之前的计算相同 - 除了Data.Vout
替换为n*(m-1)*Data.Vin
。 (你确定这是正确的吗?)
我们可以简化先前的计算,因为我们只对单个固定j=m
进行计算,这导致了
sum(b(:,m) .* (e(:,m) + n * (m-1) * DataVin * et(m)), 1)
。
一切都在一起,整个代码变成:
consumedE = sum(b .* (e + DataVout * et), 1);
consumedE(m) = sum(b(:,m) .* (e(:,m) + n * (m-1) * DataVin * et(m)), 1);
比较:对于m=200
和n=150
,您的代码在我的计算机上占用0.109523 seconds
。向量化代码采用0.005665 seconds
,这是因子20的加速。