haskell - 通过条件停止迭代循环并返回与条件匹配的值
问题描述
我正在尝试在 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
函数停止,我得到了最终结果
解决方案
仅使用标准功能的 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
在表达中提到两次,这无疑有点毫无意义。)
这给了我们一个无限的对列表,我们从中删除元素,直到一对组件之间的差异变得足够小。此时,我们提取剩余列表(一对)的头部并获取第二个组件。
推荐阅读
- c# - 显示一个 OpenFileDialog 并在一行中从中获取 FileName 属性
- sql - 如何添加内连接来查询多个连接?
- android - 获取文本在 TextView 中的位置
- c - 替换 __aeabi_dsub 以节省空间(-flto 问题)
- python - 在 Python 中包装的 c 函数出错后获取 errno
- spring-boot - 问题 Spring Boot Jasperreports
- javascript - 对象作为 React 子级无效。如果您打算渲染一组孩子,请改用数组
- haskell - 与 Data.Data.toConstr 混淆
- c++ - 添加重载更改选择了哪个重载
- javascript - 防止在 window.location 上触发 'beforeunload' 事件