用Symphy在python中求解方程需要花费很长时间

2024-09-07 15:36:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解这个方程,但仍然在运行。 我给出了符号,等式是“Eq((1-(1+x)(-60))/x+32*(1+x)(-60),41.81)”

enter image description here


Tags: 符号eq方程等式
2条回答

{}和{}通常的工作方式是将表达式拆分为分子和分母,并返回不在另一个表达式中的表达式的解

让我们定义一个helper函数,将nsolve的解放入FiniteSet中,一个用于给出最终解:

>>> from sympy import FiniteSet, nsolve, Add, Eq
>>> from sympy.abc import x
>>> rr = lambda x: FiniteSet(*[i[0] for i in real_roots(x, multiple=False)])
>>> sol = lambda n, d: list(rr(n) - rr(d))
>>> go = lambda eq: sol(*eq.rewrite(Add).as_numer_denom())

现在,我们在您的原始表达式上尝试以下操作:

>>> eq = Eq(32/(x + 1)**60 + (1 - 1/(x + 1)**60)/x, 41.81)
>>> fsol = go(eq)  # very slow
>>> [i.n(3) for i in fsol]
[-3.33, -2.56, -1.44, -0.568, -0.228, 0.0220]

如果您通过替换原始表达式(作为表达式编写)来检查这些内容,您将发现只有最后一个是有效的

>>> expr = eq.rewrite(Add)
>>> [expr.subs(x, i).n(3) for i in fsol]
[-42.1, -42.2, 4.72e+22, 2.64e+23, 1.97e+8, 1.31e-15]

现在,让我们用一个Rational替换该浮点,并获得解决方案:

>>> req = nsimplify(eq, rational=True); req
Eq(32/(x + 1)**60 + (1 - 1/(x + 1)**60)/x, 4181/100)
>>> rsol = go(_)  # pretty fast
>>> [i.n(3) for i in rsol]
[-2.00, 0.0220]

我们知道第二种解决方案是正确的;让我们检查一下第一个:

>>> req.subs(x, rsol[0]).rewrite(Add).n(3)
-0.e-114

因此,这两种解决方案似乎都是有效的,而且你不会得到任何虚假的解决方案,这(顺便说一句)是我从nsolve中没有想到的

不太可能得到精确的解析解,但可以得到数值解,例如:

In [18]: nsolve(eq, x, -2)
Out[18]: -1.99561339048822

由于可以将其转换为多项式,因此可以找到所有实际解,如:

In [20]: p = Poly(nsimplify(eq).rewrite(Add).as_numer_denom()[0])

In [21]: [r[0].n() for r in p.real_roots(multiple=False)]
Out[21]: [-1.99561339048822, -1.0, 0, 0.0219988833527669]

像这样使用as_numer_denom可能会引入虚假的解决方案,因此您应该检查它们(例如,通过在每个根周围绘制函数)。例如0实际上不是根

相关问题 更多 >