用数值方法求解非线性方程组

Joo*_*kka 11 java math numerical mathematical-optimization scientific-computing

我需要在我的Java程序中解决非线性最小化(N个未知数的最小残差平方)问题.解决这些问题的常用方法是Levenberg-Marquardt算法.我有一些问题

  • 有没有人对不同的LM实现有经验?LM的味道略有不同,我听说算法的确切实现对其数值稳定性有重要影响.我的功能非常好,所以这可能不是问题,但当然我想选择一个更好的选择.以下是我发现的一些替代方案:

  • 是否有任何常用的启发式方法来进行LM所需的初始猜测?

  • 在我的应用程序中,我需要对解决方案设置一些约束,但幸运的是它们很简单:我只是要求解决方案(为了成为物理解决方案)是非负的.略微负面的解决方案是数据中测量不准确的结果,显然应该为零.我正在考虑使用"常规"LM但是迭代以便如果一些未知数变为负数,我将其设置为零并从中解决其余部分.真正的数学家可能会嘲笑我,但你认为这可行吗?

感谢您的任何意见!

更新:这不是火箭科学,要解决的参数数量(N)最多为5,而数据集只有不足以使解决成为可能,所以我相信Java足以解决这个问题.而且我相信聪明的应用数学家已经多次解决了这个问题,所以我只是在寻找一些现成的解决方案,而不是自己做饭.例如,如果它是纯Python,Scipy.optimize.minpack.leastsq可能会没问题.

Dav*_*d Z 0

我实际上没有使用过任何这些 Java 库,所以对此持保留态度:基于后端,我可能会首先查看 JLAPACK。我相信 LAPACK 是Numpy的后端,它本质上是在 Python 中进行线性代数/数学操作的标准。至少,您绝对应该使用优化良好的 C 或 Fortran 库,而不是纯 Java,因为对于大型数据集,此类任务可能会变得极其耗时。

为了创建初始猜测,这实际上取决于您想要拟合的函数类型(以及您拥有的数据类型)。基本上,只需寻找一些相对快速(可能是 O(N) 或更好)的计算即可给出所需参数的近似值。(我最近在 Numpy 中使用高斯分布做到了这一点,并且我估计了平均值average(values, weights = counts)- 即直方图中计数的加权平均值,这是数据集的真实平均值。它不是我正在寻找的峰值,但它已经足够接近了,算法完成了剩下的过程。)

至于保持积极的约束,你的方法似乎是合理的。由于您正在编写一个程序来完成这项工作,也许只需创建一个布尔标志,即可让您轻松启用或禁用“强制非负”行为,并以两种方式运行它以进行比较。只有当您得到很大的差异(或者算法的一个版本花费的时间过长)时,才可能需要担心。(真正的数学家会从头开始分析最小二乘法;-P 所以我认为你是那个可以嘲笑他们的人......开玩笑。也许吧。)