numpy 二分函数只使用部分函数返回正确的值

hyrbngr7  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(132)

当我对函数中的一个数字应用二分法时,它只会在某些函数中返回正确的值。

import numpy as np

def x_2(x):
    return x**2-5

def x_sin_exp(x):
    return 0.5 + -(x + np.sin(x)) * np.exp(-x**2.0)

def bisection(f: callable, a: float, b: float, tol=0.001, maxiter=100)-> tuple[float, int]:
    r=(a+b)/2
    for nit in range(maxiter+1):
        r = (a + b) / 2.0
        if np.abs(f(r))<tol:
            return (r,nit)
        elif f(a)*f(r)<0:
            b = r
        else:
            a = r
        

    return (r,nit)

例如,当applying x_2时,它可以正常工作,但x_sin_exp不能正常工作,如下所示:
bisection(x_2,-3,3)正确返回(-2.236083984375,12)bisection(x_sin_exp,-3,3)错误返回(3.0,100)
我试着检查二分函数上的符号,并绘制它们来检查第一个输出值是否正确。主要的问题是,当它必须进入函数的else部分时,它从来没有这样做过。我试过另一个精灵,但没有纠正它。

dgtucam1

dgtucam11#

代码中的问题源于函数x_sin_exp的初始选择(a)和(b)。函数x_sin_exp在区间([-3,3])中没有根使得(f(a)\times f(B)< 0)。因此,您的二分方法不会进入“else”部分,并且您会得到不正确的结果。
首先,在运行二分法之前,确保(f(a)\times f(B)< 0)。其次,最好检查端点处的函数是否已经在公差范围内。
下面是你的函数的修改版本:

import numpy as np

def bisection(f: callable, a: float, b: float, tol=0.001, maxiter=100) -> tuple[float, int]:
    if f(a) * f(b) >= 0:
        raise ValueError("f(a) and f(b) must have different signs.")

    for nit in range(1, maxiter + 1):
        r = (a + b) / 2.0
        if np.abs(f(r)) < tol:
            return r, nit
        elif f(a) * f(r) < 0:
            b = r
        else:
            a = r
    return r, nit

现在,调用bisection(x_sin_exp, 3, 3)将引发一个ValueError,并带有一条消息,说明(f(a))和(f(B))必须具有不同的符号。

相关问题