2013-03-18 29 views
0

我有以下错误:如何在Matlab中更改lsqcurvefit中的步骤?

lsqcurvefit stopped because the size of the current step is less than 
the default value of the step size tolerance. 

步长公差为默认(1E-6)。问题是我在X中使用了巨大的函数(X = 1e7中的一个步骤)。正如你所猜测的那样,lsqcurvefit根本不会收敛。

如何修改步骤以便更轻松地收敛?

这里的Lorentzien的创建:

Gamma=[4e6 4e6 4e6]; 
C=1; 
m=0; 
Amplitude=[1.5 5]; 
Width=[0.15 0.25]; 
Offset=[1 2]; 
GuessC=Offset; 

Aub = 2e7; 
Alb = 5e6; 
NUub = FreqR*0.999; 
NUlb = FreqR*0.800; 


for i=1:Nombre 
    Ampl(i,1) = Alb + (Aub-Alb).*rand; 
    Ampl(i,2) = Alb + (Aub-Alb).*rand; 
    Ampl(i,3) = Alb + (Aub-Alb).*rand; 
    Pic1 = RoundTo(NUlb + (NUub-NUlb).*rand,-6); 
    Pic2 = RoundTo(NUlb + (NUub-NUlb).*rand,-6); 
    Pic3 = RoundTo(NUlb + (NUub-NUlb).*rand,-6); 

    T0=[Ampl(i,1) Ampl(i,2) Ampl(i,3)]; 
    nurG(i,1) = min([Pic1 Pic2 Pic3]); 
    nurG(i,2) = median([Pic1 Pic2 Pic3]); 
    nurG(i,3) = max([Pic1 Pic2 Pic3]); 
    X1=nurG(i,1)-FreqR*0.025:FreqR*0.0003:FreqR; 
    N=length(X1); 
    Y1=zeros(1,N); 

    for j=1:N 
     Y1(j)=(2*T0(1)/pi)*(Gamma(1)/(4*(X1(j)-nurG(i,1))^2+Gamma(1)^2))+(2*T0(2)/pi)*(Gamma(2)/(4*(X1(j)-nurG(i,2))^2+Gamma(2)^2))+(2*T0(3)/pi)*(Gamma(3)/(4*(X1(j)-nurG(i,3))^2+Gamma(3)^2))+C+m*randn(); 
    end 

XP1 = X1/(FreqR*0.009); 

Frequency=[nurG(i,1)/(FreqR*0.009) nurG(i,3)/(FreqR*0.009)]; 
GuessP11=(Width./(2*pi)).*(Amplitude-Offset); 
GuessP21=Frequency; 
GuessP31=Width.^2/4; 
GuessP12=(Width./(2*pi)).*(Amplitude-Offset); 
GuessP22=Frequency; 
GuessP32=Width.^2/4; 
GuessP13=(Width./(2*pi)).*(Amplitude-Offset); 
GuessP23=Frequency; 
GuessP33=Width.^2/4; 

[yprime params resnorm residual]=lorentzfit3(XP1,Y1,[],[GuessP11(1) GuessP21(1) GuessP31(1) GuessP12(1) GuessP22(1) GuessP32(1) GuessP13(1) GuessP23(1) GuessP33(1) GuessC(1); GuessP11(2) GuessP21(2) GuessP31(2) GuessP12(2) GuessP22(2) GuessP32(2) GuessP13(2) GuessP23(2) GuessP33(2) GuessC(2)]); 

在lorentzfit3,还有一系列的,如果看到如果猜测是正确的。但我会跳过那部分。猜测给出了一个想法从哪里开始寻找。

[params resnorm residual] = lsqcurvefit(@lfun3c,p0,x,y,lb,ub,optimset('MaxFunEvals',200000,'MaxIter',10000,'TolFun',1e-18)); 
yprime = lfun3c(params,x); 

end % MAIN 

function F = lfun3c(p,x) 
F = p(1)./((x-p(2)).^2+p(3)) + p(4)./((x-p(5)).^2+p(6)) + p(7)./((x-p(8)).^2+p(9)) + p(10); 
end % LFUN3C 
+0

您可以使用optimset(“lsqcurvefit”),以获得lsqcurvefit选项结构,改变任何你想要的值,然后在您的lsqcurvefit调用中提供该结构。不过,我怀疑你所遇到的任何融合问题都不会因改变选项而得到帮助。 – ioums 2013-03-18 14:28:12

+0

步长容差可以修改,但它确实无助于收敛。就我所知,这些步骤的大小不能这样修改。 – Vissenbot 2013-03-18 15:32:01

+0

我不能运行你的代码,因为你没有定义'FreqR'和'Nombre'。此外,你可以绘制你的'Y1'阵列 - 我尝试了一些'FreqR'的值,并且基本上得到了“所有三个顶点的峰值”。这使得它不可能工作......峰之间的间隔必须大于宽度,否则你正在战斗中失败。也请说明'lorentzfit3'是如何定义的(至少要显示函数的第一行 - 否则很难猜测'lsqcurvefit'是如何调用的。] – Floris 2013-03-19 15:19:45

回答

1

你可以重写你的功能,所以它需要一个更合理的缩放参数:

function f = myfun(x) 
f = myBigFun(1e7 * x); 

哪里myBigFun是你原来的功能 - 但现在myfun有缩放在较小范围内的步骤的X 。

当你看一个函数返回的值时,这是一个好主意;有时优化不能看到你感兴趣的顺序的变化,所以再一次,将你的函数的输出缩放到“合理的范围”有助于确保“事物的行为”。

另一件常常有意义的事情,特别是当你的最佳状态是“围绕一个非常大的数字”时,正在重新定位你的功能:而不是从1000000到1000001进行探索,你将你的功能置于中心,值到0.5之间-0.5

只是一些想法,可以帮助你对你的方式...

+0

正如我所说的,问题是lsqcurvefit将会停止,因为他的步长在步长容差范围内。函数根本不会收敛。 – Vissenbot 2013-03-18 15:15:45

+0

我的函数现在从-10到10,而不是2.6e9到3.5e9。 – Vissenbot 2013-03-18 15:24:22

+0

您是否可以更新您的问题以显示提出问题的功能以及扩展方式?也许这会给我一些其他想法。 – Floris 2013-03-18 15:39:12