首页 > 解决方案 > 通过条件停止迭代循环并返回与条件匹配的值

问题描述

我正在尝试在 Haskell 上实现 Newton-Raphson 方法,到目前为止,我已经设法通过使用该iterate函数使其工作,但问题是由于迭代函数的性质,它会重新调整无限列表,所以我当迭代中获得的值落入设定的误差范围内时,m寻找一种停止循环的方法,并返回所述值

我在这里查看了一些博客文章甚至一些问题,但是我对 haskell 还很陌生,并且对语法并不完全精通,所以对我来说阅读代码示例或文档现在真的很难。

f(x) 和 g(x)(导数)的定义不相关:

newton x0 = iterate step x0
    where step xn = xn - ((f xn)/(g xn))

我目前正在通过take 4 $ newton 3.5在 GHCi 提示符中使用给定列表的第一个元素来工作,但是返回的列表iterate是无限的,所以我不能在它上面使用 tail 函数。

我的想法是在某个地方设置一个常量,margin = 0.0001或者类似的东西,当牛顿函数的最后一次迭代落在边距之后,iterate函数停止,我得到了最终结果

标签: haskellnewtons-method

解决方案


仅使用标准功能的 duplode 答案的变体:

newton :: Double -> Double
newton x0 = (snd . head . dropWhile (not . goal)) (zip approxs (tail approxs)) 
    where
    approxs = iterate step x0
    step xn = xn - (f xn / g xn)
    goal (xa, xb) = abs (xb - xa) < margin

为了确定我们的目标是否已经达到,我们需要检查由 生成的无限列表的相邻元素对iterate。为此,我们使用了标准技巧,即用自己的尾部压缩列表。(如果你觉得特别厚颜无耻,可以考虑使用(zip <*> tail) approxs代替zip approxs (tail approxs)。这样你就不必approxs在表达中提到两次,这无疑有点毫无意义。)

这给了我们一个无限的对列表,我们从中删除元素,直到一对组件之间的差异变得足够小。此时,我们提取剩余列表(一对)的头部并获取第二个组件。


推荐阅读