用于查找图形函数交点的Python脚本
我有一段python代码,用于在函数“f(x)=x**2+x-2”和“g(x)=6-x”中查找交点 但我的问题是脚本只适用于特定的数学函数,如果我尝试稍微更改数学函数,代码将无法工作 代码只是检查f(x)和g(x)的Y值何时匹配,并对另一点执行相同的操作 这里是输出:用于查找图形函数交点的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=符
##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