Почему SymPy не может решить квадратичное уравнение со сложными коэффициентами

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 ответа

Это не относится к SymPy - другие программы, такие как Maple или Mathematica страдают от той же проблемы: При решении уравнения, solve потребности, чтобы выбрать правильную стратегию решения (смотри, например, SymPy решателей) на основе предположений о переменных и структуре уравнения, Эти варианты обычно эвристичны и часто неправильны (следовательно, ни одно решение, ни ложные стратегии не проверяются в первую очередь). Кроме того, предположения переменных часто бывают широкими (например, сложными, а не реальными).

Таким образом, для сложных уравнений стратегия решения часто задается пользователем. Например, вы можете использовать:

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


Поскольку поддерживаются символические решения, одна вещь, которую вы можете сделать, - решить общую квадратичную и заменить ваши конкретные коэффициенты:

>>> 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)

(Это действительно дорогие части вызова для решения.)

licensed under cc by-sa 3.0 with attribution.