【问题标题】:Stuck in infinite loop in ocaml while calculating Pi approximation using Viete's formula在使用 Viete 公式计算 Pi 近似值时陷入 ocaml 中的无限循环
【发布时间】:2015-11-04 10:18:44
【问题描述】:

在计算给定精度的 Pi 近似值时遇到问题。我已经得出结论,无限循环问题是由我的循环退出条件引起的,但是我不知道确切的问题是什么。在我看来,退出条件应该类似于

abs(current_aproximation - previous_approximation) < precision

代码如下:

let pi(prec) = 
let rec loop(curr, prev) = 
    if(abs_float( (2. /. curr) -. (2. /. prev) ) < prec) then  // problematic line
        (2. /. curr)
    else
        loop(curr *. sqrt(2. +. curr) /. 2., curr)
    in loop(sqrt(0.5), 1.);;

感谢您提供解决问题的任何提示。

【问题讨论】:

    标签: ocaml pi approximation


    【解决方案1】:

    您正在计算一个不同的产品:在一次迭代之后,您应该计算 sqrt(2)/2 * sqrt(2+sqrt(2))/2 但您计算的是 sqrt(2)/2 * sqrt(2+ sqrt(2)/2)/2.

    这个算法怎么样?

    let pi prec =
       let rec p2 xn root =
         let nroot = sqrt(2. +. root) in
         let xm = xn *. (nroot /. 2.) in
         if (abs_float (( 2. /. xm ) -. (2. /. xn))) < prec
         then xm
         else p2 xm nroot
       in 2. /. (p2 1.0 0.0)
    

    计算结果为:

    # pi 0.1 ;;
    - : float = 3.12144515225805197
    # pi 0.01 ;;
    - : float = 3.14033115695475251
    # pi 0.001 ;;
    - : float = 3.14127725093277288
    # pi 0.0001 ;;
    - : float = 3.14157294036709134
    

    【讨论】:

    • 非常感谢。我一定错过了计算的那部分。我还有一个额外的问题 - 当更少的参数传递给递归函数时,代码的性能会提高还是只是个人喜好?
    • 您的意思是 p2 作为闭包绑定 prec 与将 prec 作为附加参数添加到内部函数之间的区别吗?我想这取决于编译器,但我可以想象闭包无论如何都会被翻译成第二个版本。在这种特殊情况下,p2 无论如何只创建一次。
    【解决方案2】:

    如果您修改代码以打印出curr 的值,您会注意到您很快就到达了一个固定点:

    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    9.88131291682e-324
    (...)
    

    根据Wikipedia,您的初始值应该是(sqrt 2.) /. 2.,而不是sqrt (0.5)。但即使进行了这种修改,也不可能在不达到前面描述的固定点的情况下请求小于 0.61 的精度。

    我的猜测是floats 不够精确,无法以这种方式表达该算法。

    【讨论】:

    • sqrt(2)/2sqrt(0.5) 是相等的,浮点精度不会导致这样的错误。算法实现错误。
    猜你喜欢
    • 2023-03-16
    • 2015-10-03
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多