我很难在 Matlab 上的求根问题中达到足够的准确性。我有一个函数 ,Lik(k)
并且想找到k
where的值Lik(k)=L0
。基本上,问题在于各种内置的 Matlab 求解器 ( fzero
, fminbnd
, fmincon
) 并没有像我希望或期望的那样接近解决方案。
Lik()
是一个用户定义的函数,它涉及广泛的编码来计算数值拉普拉斯逆变换等,因此我不包括完整的代码。但是,我已广泛使用此功能,并且它似乎可以正常工作。 Lik()
实际上需要几个输入参数,但是对于当前步骤,所有这些都是固定的,除了k
. 所以这实际上是一个一维求根问题。
我想找到k >= 165.95
which的值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
with Lik(k)-L0=-0.045
。好吧,虽然不是很好。出于实际目的,如果没有大量的手动试验和错误,我不会知道如此精确的上限。如果我使用 interval (165.95,200)
,fzero
返回k=167.19
where Lik(k)-L0 = -0.65
,这是相当糟糕的。我一直在将Display设置为iter来运行这些测试,这样我就可以看到发生了什么,并且似乎在第 4 次迭代时fzero
命中167.19
,然后在第 5 次迭代时停留在那里,这意味着k
从一次迭代到下一次迭代的变化较小比TolX
(设置为 0.001),因此程序结束。退出标志表明它成功收敛到一个解决方案。
我还尝试最小化abs(Lik(k)-L0)
使用fminbnd
(给出上限和下限k
)和fmincon
(给出一个起点k
)并遇到类似的准确性问题。特别是,fmincon
可以同时设置TolX
和TolFun
,但是玩弄这些(低至 10^-6,比我需要的精度高得多)并没有任何区别。令人困惑的是,有时优化器甚至会在较早的迭代中找到一个比它返回的最终 k 值更接近使目标函数为零的 k 值。
因此,该算法似乎正在迭代到某个点,然后未能采取任何足够大小的进一步步骤来找到更好的解决方案。有谁知道为什么该算法不采取另一个更大的步骤?有什么我可以调整来改变的吗?(我查看了optimset下的列表,但没有提出任何有用的信息。)
非常感谢!