Kim
Kim

Reputation: 43

Using sympy for symbolic math, the code runs forever

I am trying to solve simultaneous equations for x and y, I am not getting any result (code just keeps on running). I feel the error is related to using sqrt in the equations but not sure. Can someone help me figure this out?

from __future__ import division
from sympy import Symbol,sqrt,solve
x = Symbol('x')
y = Symbol('y')
z = Symbol('z')
a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
d = Symbol('d')
e = Symbol('e')
f = Symbol('f')
g = Symbol('g')
h = Symbol('h')
print (solve((sqrt((c-a)**2+(d-b)**2)+sqrt((x-c)**2+(y-d)**2)-2*sqrt((x-a)**2+(y-b)**2),(y-b)*(e-a)-(x-a)*(f-b))  ,x,y))

Upvotes: 4

Views: 583

Answers (1)

smichr
smichr

Reputation: 19047

This is a(nother) problem were you have to rely on the A of CAS and let SymPy assist you instead of relying on SymPy (in it's current state) to do all the work. The following assumes that eqs is a list of the two equations you want to solve as you gave in the OP.

Notice that the 2nd equation is linear in both symbols. Solve for y and substitute into the first equation.

>>> yis = solve(eqs[1], y)[0]
>>> eq0 = eqs[0].subs(y,yis)

This gives an expression that has a lot of symbols in it and that slows things down. It also has two terms with sqrt that depend on x. Replace those arguments of the sqrt with Dummy symbols and then unrad the expression to get it in polynomial form, restore replacements and factor:

>>> from sympy.solvers.solvers import unrad, S
>>> reps = {i.base:Dummy() for i in eq0.atoms(Pow) if i.has(x) and i.exp==S.Half}
>>> ireps = {v:k for k,v in reps.items()}
>>> poly = unrad(eq0.xreplace(reps), *reps.values())[0].xreplace(ireps).factor()

Using factor is an expensive process to always use, but if you know the problem is going to take a long time without it, it is worth a try. In this case a quartic reduces to a product of quadratics which are easy to solve and don't require checking or simplification:

>>> xis = solve(poly, x)

There are three solutions for x and each of these can be substituted into the expression for y to get the three solutions. The solutions are large enough so they are not shown here.

>>> count_ops(xis)
386

Upvotes: 1

Related Questions