【问题标题】:How to know when Newton's Method will fail using Haskell?如何知道使用 Haskell 的牛顿法何时会失败?
【发布时间】:2017-11-04 04:52:10
【问题描述】:

在 Haskell 中,我使用以下函数来查找多项式的根:

polyNewton :: (Fractional a, Ord a) => Poly a -> a -> a`

polyNewton p s = if (abs(polyValue p s) <= (0 + 1e-10)) then s else polyNewton 
p (s - (polyValue p s) / (polyValue (polyDeriv p) s))

其中 polyValue 是一个函数,用于查找多项式 p 的 y 值、一个 x 值 x,而 polyDeriv 是一个返回多项式 p 的导数的函数。

此代码在大多数情况下都运行良好,除非多项式没有任何实际根(函数在 x 轴上方)或给出错误的初始猜测。有没有办法预先确定牛顿法是否会失败,这样我的函数就不会无限期地运行?

【问题讨论】:

  • 你如何确定它是否在 Haskell 以外的其他语言中失败?
  • 我知道如果多项式有奇数次,它将穿过 x 轴。我不确定如何判断偶数多项式是否会穿过 x 轴。我可以考虑使用中值定理,但在哪个域上?
  • 我投票结束这个问题,因为它实际上是关于数学而不是编程。您可以尝试在 math.stackexchange.com 上提问。如果您在执行答案时遇到问题,可以回到这里。
  • 您的回答表明您实际上也没有设法处理奇怪的情况。牛顿法需要一个初始值,但是如何设置初始值呢?在奇怪的情况下,您一定会得到解决方案,但如果有很多解决方案,您要找哪一个?

标签: haskell math functional-programming polynomial-math newtons-method


【解决方案1】:

要粗略地确定 N 次多项式的根(如果有的话),知道它的所有极值就足够了,因为你必须只有一个根

  • 在任何相邻的负最小值和正最大值之间
  • 如果是负最小值或正最大值,则位于最左侧极值的左侧
  • 如果是负最小值或正最大值,则位于最右侧极值的右侧

极值本身就是导数的根,它方便地是次数为 N–1 的多项式,所以你可以递归下去,直到你得到线性(或二次)的情况,它是找到根源很简单(实际上是这样)。

【讨论】:

  • 如何利用这些信息找到合适的初始值,让牛顿法收敛到每个根?
  • @dfeuer 正如我所说,您从 intervals(在极值之间)开始,您知道每个根必须位于其中。然后,您在每个区间的中点启动牛顿,但受到限制,因此它永远不会离开区间。这在实践中意味着,每当 xᵢ + yᵢ / xᵢ' 位于区间之外时,您改为执行简单的二等分步骤来细化区间,直到函数在剩余区间上足够直,以至于牛顿及其二次收敛开始。
猜你喜欢
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2013-10-17
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
相关资源
最近更新 更多