我很难在Matlab上找到根发现问题的准确性。我有一个函数Lik(k)
,并希望找到k
Lik(k)=L0
的值。基本上,问题是各种内置的Matlab求解器(fzero
,fminbnd
,fmincon
)没有像我希望的那样接近解决方案。
Lik()
是一个用户定义的函数,它涉及大量编码以计算数值逆拉普拉斯变换等,因此我不包括完整代码。但是,我已广泛使用此功能,它似乎正常工作。 Lik()
实际上需要多个输入参数,但对于当前步骤,除了k
之外,所有这些参数都是固定的。所以它确实是一个根本寻找问题。
我想找到k >= 165.95
的{{1}}的值。 Lik(k)-L0 = 0
小于Lik(165.95)
,我希望L0
从此处单调增加。事实上,我可以在感兴趣的范围内评估Lik(k)
,它似乎平滑地过零:例如Lik(k)-L0
。所以看起来这个功能表现得很好。
但是,我试图通过几种不同的方法“自动”找到根,并且准确性不如我预期的那么好......
使用Lik(165.95)-L0 = -0.7465, ..., Lik(170.5)-L0 = -0.1594, Lik(171)-L0 = -0.0344, Lik(171.5)-L0 = 0.1015, ... Lik(173)-L0 = 0.5730, ..., Lik(200)-L0 = 19.80
:如果约束到fzero(@(k) Lik(k)-L0)
区间,(165.95,173)
会返回fzero
k=170.96
。好的,虽然不是很好。而且出于实际目的,如果没有大量的手工试错,我就不会知道这样一个精确的上限。如果我使用区间Lik(k)-L0=-0.045
,(165.95,200)
会返回fzero
k=167.19
,而Lik(k)-L0 = -0.65
则相当差。我一直在运行这些测试,并将显示设置为 iter ,这样我就可以看到正在发生的事情,并且fzero
点击了167.19
第4次迭代然后在第5次迭代中保持不变,这意味着k
从一次迭代到下一次迭代的变化小于TolX
(设置为0.001),因此过程结束。退出标志表示它已成功收敛到解决方案。
我还尝试使用abs(Lik(k)-L0)
{给出fminbnd
的上限和下限)和k
(给出fmincon
的起点)来最小化k
和遇到了类似的准确性问题。特别是,使用fmincon
可以同时设置TolX
和TolFun
,但玩这些(低至10 ^ -6,比我需要的精度高得多)没有任何区别。令人困惑的是,有时优化器甚至会在较早的迭代中找到一个k值,该值更接近于使目标函数为零而不是它返回的最终k值。
因此,似乎算法迭代到某个点,然后没有采取足够大小的任何进一步步骤来找到更好的解决方案。有谁知道为什么算法不采取另一个更大的步骤?有什么我可以调整来改变这个吗? (我查看了 optimset 下的列表,但没有提供任何有用的信息。)
非常感谢!
答案 0 :(得分:1)
由于你似乎有一个'野性'功能,在该地区看似单调,相当小的兴趣范围,而不是对精度的要求非常高我认为所有标准都符合推荐蛮力方法。
假设在一个点上评估函数不需要太多时间,请尝试:
找到上限xmax
和下限xmin
,选择首选stepsize
并评估您的功能
xmin:stepsize:xmax
如果需要(并且单调性确实适用),您可以通过这样做获得另一个上限和下限,并重复该过程以获得更好的准确性。
答案 1 :(得分:1)
使用fmincon时我也遇到过这个问题。以下是我修复它的方法。
我需要在优化循环(多个变量)中找到函数(单变量)的解。因此,我需要为单变量函数的解决方案提供一个大的间隔。问题是如果搜索间隔太大,fmincon(或fzero)不会收敛到解决方案。为了解决这个问题,我解决了while循环中的问题,使用了一个巨大的起始上限(1e200),并对求解器产生的fval值进行了约束。如果得到的fval不够小,我会将上限减少一个因子。代码看起来像这样:
fval = 1;
factor = 1;
while fval>1e-7
UB = factor*1e200;
[x,fval,exitflag] = fminbnd(@(x)function(x,...),LB,UB,options);
factor = factor * 0.001;
end
当找到一个好的解决方案时,求解器会退出。你当然可以通过引入另一个因子和/或增加因子步骤来玩LB。 我的第一语言不是英语,所以我为任何错误道歉。
干杯, 克里斯蒂安
答案 2 :(得分:0)
为什么不使用简单的二分法?您总是评估某个间隔的中间值,然后将其减少到右侧或左侧部分,这样您总是有一个边界给出一个负值而另一个边界给出一个正值。您可以非常快速地降低到任意精度。由于每次将间隔减少一半,它应该很快收敛。
我怀疑该函数存在其他问题,因为它具有不连续性。 fzero工作得如此糟糕似乎很奇怪。这是一个确定性的功能吧?