如何优化非线性方程的解?
Posted
技术标签:
【中文标题】如何优化非线性方程的解?【英文标题】:How to optimize solution of nonlinear equations? 【发布时间】:2010-12-08 10:08:43 【问题描述】:我有非线性方程,例如:
Y = f1(X)
Y = f2(X)
...
Y = fn(X)
一般来说,它们没有确切的解决方案,因此我使用Newton's method 来解决它们。方法是基于迭代的,我正在寻找优化计算的方法。 有哪些方法可以减少计算时间?避免计算平方根或其他数学函数? 也许我应该在 C++ 代码中使用汇编(解决方案是用 C++ 编写的)?
【问题讨论】:
在使用 ASM 之前更新您的算法。过早的优化是邪恶的。 请为您的方程式发布示例。 我想说,如果不告诉你有什么样的非线性方程组,以及你是否有好的起点,你不会得到很好的问题答案。对于非线性方程没有好的通用方法,像 Newton-Raphson 这样的方法需要良好的起点才能完成任何实质性的工作。 【参考方案1】:非线性最小二乘问题的一种流行方法是 Levenberg-Marquardt 算法。它是高斯牛顿法和梯度下降法的一种混合。它结合了两全其美(在搜索空间中很好地导航不适定问题并快速收敛)。但在实施方面有很大的回旋余地。例如,如果方阵 J^T J(其中 J 是包含所有方程的所有导数的雅可比矩阵)是稀疏的,您可以使用迭代 CG 算法来快速求解方程组,而不是像 J 的 Cholesky 分解这样的直接方法^T J 或 J 的 QR 分解。
但不要只是假设某些部分很慢并且需要用汇编程序编写。汇编程序是最后要考虑的事情。在你走这条路之前,你应该始终使用分析器来检查瓶颈在哪里。
【讨论】:
【参考方案2】:您是在谈论一次求解一个的多个单参数函数还是要一起求解的多参数方程组?
如果是前者,那么我经常发现找到更好的初始近似值(从 Newton-Raphson 循环开始的位置)可以比完善循环本身节省更多的执行时间,因为循环中的收敛最初可能很慢但后来很快。如果您对函数一无所知,那么很难找到一个像样的初始近似值,但首先尝试一些割线迭代可能是值得的。你可能还想看看Brent's method
【讨论】:
【参考方案3】:考虑并行使用 Rational Root Test。如果不可能使用绝对精度值,则使用最接近零的结果作为继续使用牛顿法的最佳拟合。 一旦找到单根,您可以通过将其除以 monom (x-root) 来降低方程等级。 除法和有理根检验在这里实现https://github.com/ohhmm/openmind/blob/sh/omnn/math/test/Sum_test.cpp#L260
【讨论】:
注意,您可以将所有系数乘以任意值以使它们成为实数。以上是关于如何优化非线性方程的解?的主要内容,如果未能解决你的问题,请参考以下文章