haskell - 递归 Haskell;牛顿法 : Why Doesn't This Converge?

标签 haskell recursion floating-point calculus

我一直在尝试通过构建简短的程序来学习 Haskell。我对函数式编程世界有点陌生,但已经做了大量的阅读。

我在 Haskell 中有一个相对较短的递归函数,用于使用牛顿法找到一个函数的根,达到浮点数允许的精度:

newtonsMethod :: (Ord a, Num a, Fractional a)  => (a -> a) -> (a -> a) -> a -> a
newtonsMethod f f' x
    | f x < epsilon = x
    | otherwise = 
        newtonsMethod f f' (x - (f x / f' x))
    where
        epsilon = last . map (subtract 1) . takeWhile (/= 1) 
            . map (+ 1) . iterate (/2) $ 1

当我在 GHCi 中解释并插入时 newtonsMethod (\ x -> cos x + 0.2) (\ x -> -1 * sin x) (-1) , 我得到 -1.8797716370899549 ,这是调用值的牛顿方法的第一次迭代。

我的第一个问题很简单:为什么它只递归一次?如果您发现此代码的结构方式有任何潜在改进或明显错误,也请告诉我。

我的第二个问题,稍微复杂一点,是这样的:是否有一些干净的方法来测试这个函数的父调用,看看它是否无法收敛,并相应地退出?

预先感谢您提供的任何答案!

最佳答案

它只运行一次,因为 -1.8...小于 epsilon ,一个严格的正数。您想检查差值的绝对值是否在容差范围内。

获得此类代码的收敛诊断的一种方法是将结果生成为惰性列表,这与您找到 epsilon 的方式不同。使用 iterate .这意味着您可以通过遍历列表来获得最终结果,但您也可以在导致它的结果的上下文中看到它。

关于haskell - 递归 Haskell;牛顿法 : Why Doesn't This Converge?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19720457/

相关文章:

haskell - 需要一个类型,但 ‘Request’ 的类型为 ‘* -> *’

swift - 带有异步请求的递归函数

javascript - 在 JS 函数中使用递归的奇怪循环

c - float的printf如何不打印正确的浮点值

c++ - printf 如何从 float 中提取数字?

Java GUI Xmonad 不工作

parsing - 使用 Maybe 进行错误检测和报告

haskell - 在状态 monad 中使用 put 和 >>

recursion - 在递归枚举上使用附带移动值错误

java - Float 和 Double NaN(非数字)值