为什么SymPy不能求解复系数的二次方程

时间:2014-07-22 08:44:39

标签: python sympy solver quadratic

SymPy可以很容易地求解具有短简单系数的二次方程。 例如:

from pprint import pprint
from sympy import *
x,b,f,Lb,z = symbols('x b f Lb z')
eq31 = Eq((x*b + f)**2, 4*Lb**2*z**2*(1 - x**2))
pprint(eq31)
sol = solve(eq31, x)
pprint(sol)

但是系数稍大一些 - 它不能:

from pprint import pprint
from sympy import *
c3,b,f,Lb,z = symbols('c3 b f Lb z')
phi,Lf,r = symbols('phi Lf r')
eq23 = Eq(
    (
        c3 * (2*Lb*b - 2*Lb*f + 2*Lb*r*cos(phi + pi/6))
        + (Lb**2 - Lf**2 + b**2 - 2*b*f + 2*b*r*cos(phi + pi/6) + f**2 - 2*f*r*cos(phi + pi/6) + r**2 + z**2)
    )**2,
    4*Lb**2*z**2*(1 - c3**2)
    )
pprint(eq23)
print("\n\nSolve (23) for c3:")
solutions_23 = solve(eq23, c3)
pprint(solutions_23)

为什么?

2 个答案:

答案 0 :(得分:1)

这不是Sympy特有的 - 其他程序如Maple或Mathematica也遇到同样的问题:在求解方程时,solve需要选择适当的解决方案策略(参见例如Sympy's Solvers)关于变量和等式结构的假设。这些选择通常是启发式的并且通常是不正确的(因此没有解决方案,或者首先尝试错误的策略)。此外,变量的假设通常是宽泛的(例如,复杂而不是实际)。

因此,对于复杂的方程式,解决方案策略通常必须由用户给出。对于您的示例,您可以使用:

sol23 = roots(eq23.lhs - eq23.rhs, c3)

答案 1 :(得分:1)

由于支持符号解决方案,您可以做的一件事是解决通用二次方并替换您的特定系数:

>>> eq = eq23.lhs-eq23.rhs
>>> a,b,c = Poly(eq,c3).all_coeffs()
>>> var('A:C')
(A, B, C)
>>> ans=[i.xreplace({A:a,B:b,C:c}) for i in solve(A*x**2 + B*x + C,x)]
>>> print filldedent(ans)
...

但如果你只是关闭简化和检查,你就可以得到相同的结果:

>>> ans=solve(eq23,c3,simplify=False,check=False)

(这些是要解决的电话中非常昂贵的部分。)