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