我很难在 Matlab 上的求根问题中达到足够的准确性。我有一个函数 ,Lik(k)并且想找到kwhere的值Lik(k)=L0。基本上,问题在于各种内置的 Matlab 求解器 ( fzero, fminbnd, fmincon) 并没有像我希望或期望的那样接近解决方案。
Lik()是一个用户定义的函数,它涉及广泛的编码来计算数值拉普拉斯逆变换等,因此我不包括完整的代码。但是,我已广泛使用此功能,并且它似乎可以正常工作。 Lik()实际上需要几个输入参数,但是对于当前步骤,所有这些都是固定的,除了k. 所以这实际上是一个一维求根问题。
我想找到k >= 165.95which的值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.96with Lik(k)-L0=-0.045。好吧,虽然不是很好。出于实际目的,如果没有大量的手动试验和错误,我不会知道如此精确的上限。如果我使用 interval (165.95,200),fzero返回k=167.19where 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下的列表,但没有提出任何有用的信息。)
非常感谢!