>>> 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]
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]
{}和{}通常的工作方式是将表达式拆分为分子和分母,并返回不在另一个表达式中的表达式的解
让我们定义一个helper函数,将
nsolve
的解放入FiniteSet
中,一个用于给出最终解:现在,我们在您的原始表达式上尝试以下操作:
如果您通过替换原始表达式(作为表达式编写)来检查这些内容,您将发现只有最后一个是有效的
现在,让我们用一个Rational替换该浮点,并获得解决方案:
我们知道第二种解决方案是正确的;让我们检查一下第一个:
因此,这两种解决方案似乎都是有效的,而且你不会得到任何虚假的解决方案,这(顺便说一句)是我从
nsolve
中没有想到的不太可能得到精确的解析解,但可以得到数值解,例如:
由于可以将其转换为多项式,因此可以找到所有实际解,如:
像这样使用
as_numer_denom
可能会引入虚假的解决方案,因此您应该检查它们(例如,通过在每个根周围绘制函数)。例如0
实际上不是根相关问题 更多 >
编程相关推荐