本文介绍了Python Sympy模块NoConversion:收敛到根失败;请尝试n<;15或MaxSteps>;50的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在使用Sympy解决问题时遇到了一个问题以下是我的代码:from math import pi, hypot
from sympy import solve, solveset, sqrt, Symbol
one_x=-0.08
one_y=1.28
second_x=0
second_y=0
second_r=7
one_r=7.3
slopes=-16.0000000000 (maybe more trailing 0s)
intercepts=0.0
x=Symbol('x')
solveset(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2),x)
这只是我的代码的一部分,但它引发了很多错误但是,我用它的值替换了所有变量,如x=Symbol('x')
solveset(sqrt((x)**2+((-16)*x)**2)+7-7.3-sqrt((x+0.08)**2+((-16)*x-1.28)**2),x)
它运行得很好,我可以得到输出{-0.0493567429232771}
我想这是因为坡度的类型(-16比-16.000000),我真的很想知道为什么浮点数公式不能计算,以及如何修正它(因为我需要更精确,所以我不能只忽略点后的数字)非常感谢!
推荐答案
SymPy+代数方程+浮点数=>故障。浮点数学does not work like normal math,而SymPy是为后者设计的。像16(整数)和16.0(浮点数)这样的小东西在使用SymPy解等式时会有很大的不同:理想情况下,您应该没有浮点数,而是创建精确的有理数,如下所示。
from sympy import S
one_x = S('-0.08')
但是,您有浮点数据,并且正在寻找浮点解决方案。这使得SymPy成为不适合这项工作的工具。SymPy用于对符号进行数学运算,而不是用于处理浮点数。正确的解决方案是使用来自SciPy的适当解决方案,例如brentq
。它接受括号间隔作为输入(其中函数的两端有不同的符号)。例如:from scipy.optimize import brentq
eq = lambda x: np.sqrt((x-second_x)**2 + (slope*x+intercept-second_y)**2) + second_r - one_r - np.sqrt((x-one_x)**2 + (slope*x + intercept - one_y)**2)
brentq(eq, -10, 10) # returns -0.049356742923277075
如果您坚持使用SymPy,这意味着您的方程式将外包到mpmath
库中,后者在数值求根和优化方面受到更多限制。要获得与其方法收敛的解决方案,您需要一个非常好的起点:显然,one_x/2
就是这样一个起点。
from sympy import sqrt, Symbol, nsolve
# ... as in your code
nsolve(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2), one_x/2)
返回-0.0493567429232771
。
sympy.solveset
,您不仅剥夺了您自己使用SciPy强大的数字解算器的机会,而且还失去了为sympy.nsolve
提供的数字搜索设置一个良好的起始值的机会。因此,在这个数值上棘手的问题上缺乏收敛。顺便说一句,这就是它在数值上棘手的原因:该函数在大多数情况下几乎是恒定的,只有一个快速变化。 这篇关于Python Sympy模块NoConversion:收敛到根失败;请尝试n<;15或MaxSteps>;50的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!