【问题标题】:secant method in Python to solve f(x) = 0 [closed]Python中的割线方法解决f(x)= 0 [关闭]
【发布时间】:2016-05-27 21:28:09
【问题描述】:

在给定 2 个初始猜测 x0 和 x1 的情况下,如何使用 Python 中的割线法求解方程 f(x) = 0?

def secant(f,x0,x1,tol):

我需要用它来找到 x 的二次方程和更高因子的解,例如,对于给定的区间,x^3 -4x^2 + 1 = 0。 这只是在黑暗中拍摄,因此任何有用网站的链接也将受到赞赏!

【问题讨论】:

  • 请展示您已经尝试过的内容,堆栈溢出不是代码制造机器。
  • 听说过牛顿法吗? youtube.com/watch?v=1uN8cBGVpfs
  • 欢迎来到 Stack Overflow!您似乎在要求某人为您编写一些代码。 Stack Overflow 是一个问答网站,而不是代码编写服务。请see here学习如何写出有效的问题。

标签: python math methods


【解决方案1】:

维基百科有一个quick overview of secant method,看起来像

将第一次迭代翻译成 Python 看起来像

x2 = (x0 * f(x1) - x1 * f(x0)) / (f(x1) - f(x0))

与其多次调用f(x0)和f(x1),不如调用一次并存储值:

fx0 = f(x0)
fx1 = f(x1)
x2 = (x0 * fx1 - x1 * fx0) / (fx1 - fx0)

对于第二次迭代,我们必须计算

x3 = (x1 * fx2 - x2 * fx1) / (fx2 - fx1)

但我们不想每次都用新变量重新编写方程。相反,我们将值移动:让x1 取x2 的值,x2 取x3 的值,等等。我们可以像这样在循环中重复执行此操作

# store initial values
fx0 = f(x0)
fx1 = f(x1)
while (something):
    # do calculation
    x2 = (x0 * fx1 - x1 * fx0) / (fx1 - fx0)
    # shift variables (prepare for next loop)
    x0,  x1  = x1,  x2
    fx0, fx1 = fx1, f(x2)

现在我们只需要知道何时停止,当我们最后一个答案与 0 之间的差值小于tol:abs(f(x2) - 0) < tol,可以简化为abs(fx1) < tol。

所以函数看起来像

def secant(f, x0, x1, tol):
    # store initial values
    fx0 = f(x0)
    fx1 = f(x1)
    while abs(fx1) < tol:
        # do calculation
        x2 = (x0 * fx1 - x1 * fx0) / (fx1 - fx0)
        # shift variables (prepare for next loop)
        x0,  x1  = x1,  x2
        fx0, fx1 = fx1, f(x2)
    return x1

现在我们只剩下一个问题:如果循环永远不会结束会发生什么?割线法不能保证收敛到一个解。如果函数运行次数过多,我们需要一种方法来停止它。

如果我们将while 循环更改为for 循环,则可以保证在设定的次数后停止。如果在此之前找到答案,我们可以提前退出;否则我们会引发一个错误,让用户知道它没有收敛。最终的函数看起来像

def secant(f, x0, x1, tol, max_iterations=100):
    # keep initial values for error reporting
    init_x0 = x0
    init_x1 = x1

    # store y values instead of recomputing them
    fx0 = f(x0)
    fx1 = f(x1)

    # iterate up to maximum number of times
    for _ in range(max_iterations):
        # see whether the answer has converged
        if abs(fx1) < tol:
            return x1

        # do calculation
        x2 = (x0 * fx1 - x1 * fx0) / (fx1 - fx0)
        # shift variables (prepare for next loop)

        x0,  x1  = x1,  x2
        fx0, fx1 = fx1, f(x2)

    # for loop has ended - failed to converge
    raise ValueError(
        "call to secant(f={}, x0={}, x1={}, tol={}," \
        " max_iterations={}) has failed to converge"
        .format(
            f.__name__,
            init_x0,
            init_x1,
            tol,
            max_iterations
        )
    )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 2019-02-12
    • 2012-03-22
    相关资源
    最近更新 更多