用于查找图形函数交点的Python脚本

用于查找图形函数交点的Python脚本,python,function,math,graph,Python,Function,Math,Graph,我有一段python代码,用于在函数“f(x)=x**2+x-2”和“g(x)=6-x”中查找交点 但我的问题是脚本只适用于特定的数学函数,如果我尝试稍微更改数学函数,代码将无法工作 代码只是检查f(x)和g(x)的Y值何时匹配,并对另一点执行相同的操作 这里是输出: ##INTERSECTION FOUND!! (-4,10) (-4,10) ##INTERSECTION FOUND!! (2,4) (2,4) 您可以使用Python的符号数学库: 从sympy导入符号,等式,求解 X=符

我有一段python代码,用于在函数“f(x)=x**2+x-2”和“g(x)=6-x”中查找交点

但我的问题是脚本只适用于特定的数学函数,如果我尝试稍微更改数学函数,代码将无法工作

代码只是检查f(x)和g(x)的Y值何时匹配,并对另一点执行相同的操作

这里是输出:

##INTERSECTION FOUND!!
(-4,10)
(-4,10)
##INTERSECTION FOUND!!
(2,4)
(2,4)

您可以使用Python的符号数学库:

从sympy导入符号,等式,求解
X=符号('X',实=真)
funcA=(X**2)+X-2
funcB=6-X
sol=求解(等式(funcA,funcB))
打印(sol)#-->[-4,2]
获取
funcA
funcB

for s in sol:
    print(f'X={s}  funcA({s})={funcA.subs(X, s)}  funcB({s})={funcB.subs(X, s)}  ')

# X=-4  funcA(-4)=10  funcB(-4)=10  
# X=2  funcA(2)=4  funcB(2)=4  
对于某些函数,结果仍然可以是象征性的,因为这是最精确的形式
.evalf()
获得数值近似值。例如:

funcA=X**2+X-2
funcB=-2*X**2+X+7
sol=求解(等式(funcA,funcB))
对于sol中的s:
print(f'X={s}funcA(X)={funcA.subs(X,s)}funcB(X)={funcB.subs(X,s)}')
打印(f'X={s.evalf()}funcA(X)={funcA.subs(X,s.evalf()}funcB(X)={funcB.subs(X,s.evalf()}'))
输出:

1.999999999998181
-3.999999999996362
X=-sqrt(3)funcA(X)=1-sqrt(3)funcB(X)=1-sqrt(3)
X=-1.73205080756888 funcA(X)=-0.73205080756887 funcB(X)=-0.73205080756887
X=sqrt(3)funcA(X)=1+sqrt(3)funcB(X)=1+sqrt(3)
X=1.73205080756888 funcA(X)=2.73205080756888 funcB(X)=2.73205080756888

由于您需要交叉点,因此您正在寻找
f(x)-g(x)=0的解决方案。因此,您可以在python中使用
fsolve
来查找
f(x)-g(x)
的根:

来自scipy.optimize import fsolve的

def func(X):
funcA=(X**2)+X-2
funcB=6-X
返回(funcA-funcB)
x=fsolve(func,0)
打印(x)

通常,这是一个根查找问题

定义
h(x)=f(x)-g(x)
。 交点
x
表示
f(x)=g(x)
h(x)=0

对于寻根问题,有很多方法,比如,二分法,牛顿法

这里是一个二分法的数值例子

def f(x):
    return x ** 2 + x - 2


def g(x):
    return 6 - x


def h(x):
    return f(x) - g(x)


def bisection(a, b):
    eps = 10 ** -10

    ha = h(a)
    hb = h(b)
    if ha * hb > 0:
        raise ValueError("Bad input")

    for i in range(1000):  # fix iteration number
        ha = h(a)
        midpoint = (a + b) / 2
        hm = h(midpoint)

        if abs(hm) < eps:
            return midpoint

        if hm * ha >= 0:
            a = midpoint
        else:
            b = midpoint

    raise RuntimeError("Out of iterations")


if __name__ == '__main__':
    print(bisection(0, 100))
    print(bisection(-100, 0))

为什么数字如此接近但不准确?因为这个问题是用数值方法解决的。使用
sympy
软件包的其他答案象征性地解决了问题,给出了准确的答案。但它们只处理简单的问题

为什么
[01100]
[-100,0]
?这是因为我以某种方式绘制了图形,并且知道在间隔内有一个根。实际上,二分法需要间隔
[a,b]
,使得
h(a)*h(b)<0
。给定一个大的间隔
[-100100]
,因此,
h(-100)*h(100)>0
,二分法在这种情况下不起作用。对大间隔进行划分,使得一些子间隔
[a,b]
满足条件
h(a)*h(b)<0
,例如,
[-100,0]
[0,100]

为什么
abs(hm)
?这将测试
hm
是否接近
0
。在计算机中,我们认为两个浮点数相等,如果它们的差异的绝对值<代码> ABS(HM)小于阈值<代码> EPS。code>eps
通常是
10**-10
10**-15
,因为Python或计算机中浮点数通常有15位十进制有效数字

牛顿方法将根据初始点给出一个输出。
为了进一步研究,请搜索
寻根问题
数值寻根问题

您的问题可能是您只测试
循环中的整数作为交点的候选。如果你稍微改变一下你的函数,使相应的交点是非整数,你将找不到结果。嘿@Jan,我测试了将结果转换为浮点值,但它返回了相同的问题,你能给我一些例子或启发吗?如果你的问题现在解决了,你可能会认为其中一个答案是被接受的。它很有效,但我想得到两个结果。点A和点B的坐标。代码只返回点B的坐标。
1.999999999998181
-3.999999999996362