我有两个函数f(x,y)和g(x,y),其中,假设x和y从x = x0变化:xt:xN和y = y0:yt:yM(在我的实际问题中)这些是长矢量)。首先,我想找到每组的最小值,例如说Min(i,j)= min(f(x(i),y(j)),g(x(i),y(j))),然后我想找到所有Min的最大值(i, j),以及相应的x(i)和y(j)。
我在这里做了什么。但我明白这需要很长时间,并且PC对于长阵列来说会变慢:
x=[2:1:5];
y=[4:2:10];
xl=length(x);
yl=length(y);
a=zeros(xl,yl);
for j=1:yl
for i=1:xl
f=x(i)+y(j);
g=x(i)*y(j);
a(i,j)=min(f,g);
end
end
max(a(:))
这里我对f和g使用了两个简单的函数,但实际的函数是更复杂的形式,包括日志函数等。
更重要的是,我还希望获得相应的x(i)和y(j)。
有人可以用更简单/更快的代码帮助我吗?
hvar=0.02:0.02:2.5;
hl=length(hvar);
hfix=1.0*ones(1,hl);
a=hvar;
b=hvar;
output = zeros(hl,3);
step=0.0001;
x=1.001:step:1.999;
y=0.001:step:0.999;
xl=length(x);
yl=length(y);
for k=1:hl
r=zeros(xl,yl);
for j=1:yl
for i=1:xl
L=y(j)*log(1+2*a(k)-(2*a(k)/x(i)));
R=y(j)*log(1-a(k)*b(k)*x(i)+(2*a(k)*b(k)/y(j)));
r(i,j)=min(L,R);
end
end
[output(k,1) ind]=max(r(:)); %val in 1st column
[p q] = ind2sub(size(r),ind);
output(k,2)=1.001+(p-1)*step; %opt x in 2nd column
output(k,3)=0.001+(q-1)*step; %opt y on 3rd column
end
save('output');
答案 0 :(得分:3)
你有三个巨大的嵌套循环,因为循环迭代很多。我在vectorization
上已经全油门,并且我使用给定的大数据量耗尽了内存。所以,你能做的最好的事情是摆脱两个最里面的循环,并用迭代器k
保持最外面的循环。
因此,在设置参数和输入之后提出的方法看起来像这样 -
for k=1:hl
L1 = bsxfun(@times,log(1+2*a(k)-(2*a(k)./x)).',y); %//'
R1 = bsxfun(@times,log(bsxfun(@plus,1-ab(k)*x(:),2*ab(k)./y)),y);
r1 = min([L1(:) R1(:)],[],2);
[output(k,1), ind] = max(r1);
[p, q] = ind2sub(size(L1),ind);
output(k,2)=1.001+(p-1)*step;
output(k,3)=0.001+(q-1)*step;
end
无法对完整数据集进行基准测试,因为即使对于k
的单次迭代,典型的运行时也很多。因此,对于比较建议方法和原始方法之间的运行时间的基准测试,我运行一次迭代的代码:k = 1
然后进行五次迭代:k = 1:5
。
使用这两种情况背后的想法是看看随着我们使用迭代器k
增加迭代次数,所提出的方法的加速可能会扩大。
接下来列出了如此获得的运行时间。
案例1:k = 1
--------------------------------- With Proposed Approach
Elapsed time is 1.934156 seconds.
--------------------------------- With Original Approach
Elapsed time is 9.659695 seconds.
案例2:k = 1:5
--------------------------------- With Proposed Approach
Elapsed time is 10.387461 seconds.
--------------------------------- With Original Approach
Elapsed time is 49.094747 seconds.
结论:正如人们可以很容易地注意到, ~5x
的加速比建议的矢量化方法优于原始方法并且可以扩展线性,因为我们增加了k
的循环迭代。