首页 文章

Matlab:优化器/求解器的准确性差

提问于
浏览
0

我很难在Matlab上找到根发现问题的准确性 . 我有一个函数, Lik(k) ,并希望找到 k 的值 Lik(k)=L0 . 基本上,问题是各种内置的Matlab求解器( fzerofminbndfmincon )没有像我想要的那样接近解决方案 .

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)fzeroLik(k)-L0=-0.045 返回 k=170.96 . 好的,虽然不是很好 . 而且出于实际目的,如果没有大量的手工试错,我就不会知道这样一个精确的上限 . 如果我使用区间 (165.95,200)fzero 返回 k=167.19 ,其中 Lik(k)-L0 = -0.65 ,这是相当差的 . 我一直在运行这些测试,并将Display设置为iter,这样我就可以看到正在发生的事情,并且看起来 fzero 在第4次迭代时命中 167.19 然后在第5次迭代时停留在那里,这意味着 k 从一次迭代变为next小于 TolX (设置为0.001),因此程序结束 . 退出标志表示它已成功收敛到解决方案 .

我也尝试使用 fminbnd (给出 k 的上限和下限)和 fmincon (给出 k 的起点)最小化 abs(Lik(k)-L0) 并遇到类似的准确性问题 . 特别是,使用 fmincon 可以设置 TolXTolFun ,但玩这些(低至10 ^ -6,比我需要的精度高得多)没有任何区别 . 令人困惑的是,有时优化器甚至在较早的迭代中找到k值,该迭代更接近使目标函数为零而不是它返回的最终k值 .

因此,似乎算法迭代到某个点,然后没有采取足够大小的任何进一步步骤来找到更好的解决方案 . 有谁知道为什么算法不采取另一个更大的步骤?有什么我可以调整来改变这个吗? (我在optimset下查看了列表,但没有提出任何有用的信息 . )

非常感谢!

3 回答

  • 0

    由于你似乎有一个看起来在该区域单调的'wild'函数,相当小的兴趣范围,而且对精度的要求不是很高,我认为所有标准都符合推荐蛮力方法 .

    假设在一个点上评估函数不需要太多时间,请尝试这样做:

    找到一个上限 xmax 和下限 xmin ,选择一个首选 stepsize 并评估你的函数at

    xmin:stepsize:xmax
    

    如果需要(并且单调性确实适用),您可以通过执行此操作获得另一个上限和下限,并重复此过程以获得更高的准确性 .

  • 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因素步骤 . 我的第一语言不是英语,所以我为任何错误道歉 .

    干杯,克里斯蒂安

  • 1

    为什么不使用简单的二分法?您总是评估某个间隔的中间值,然后将其减少到右侧或左侧部分,这样您总是有一个边界给出一个负值而另一个边界给出一个正值 . 您可以非常快速地降低到任意精度 . 由于每次将间隔减少一半,它应该很快收敛 .

    我怀疑这个函数还有其他问题,因为它有不连续性 . fzero工作得如此糟糕似乎很奇怪 . 这是一个确定性的功能吧?

相关问题