Sympy.solve is not isolating desired variable in inequality

58 Views Asked by At

I want to use nypy.solve to convert a formular to a certain variable. In my example I want to convert the formular a >= ((b-c)/2)*sy.tan(d) to the variable b. But somehow the result of Sympy is not converted to b.

This is my Code:


import numpy as np
import math
import sympy as sy
a = sy.symbols('a')
b = sy.symbols('b')
c = sy.symbols('c')
d = sy.symbols('d')

eq = sy.Ge(a, ((b-c)/2)*sy.tan(d))
result = sy.solve(eq, 'b')
print(result)

The output is this:

-b*tan(d)/2 >= -a - c*tan(d)/2

what i want to get is:

b >= (2*a+c*tan(d))/tan(d)

How do I use sympy correctly to get this?

1

There are 1 best solutions below

10
smichr On

SymPy won't divide by a factor of an unknown sign when trying to solve an inequality. So use a signed symbol for tan(d), e.g. Dummy(positive=True) or Dummy(negative=True) and put your results in Piecewise((results_pos, (tan(d)>0)),(result_neg, tan(d)<0)):

>>> from sympy import *
>>> f = lambda x: solve(eq.subs(tan(d),x),'b').subs(x,tan(d))
>>> p,n=Dummy(positive=True),Dummy(negative=True)
>>> Piecewise((f(p), tan(d)>0),(f(n), tan(d)<0))
Piecewise((b < -2*(-a - c*tan(d)/2)/tan(d), tan(d) > 0),
          (b > -2*(-a - c*tan(d)/2)/tan(d), tan(d) < 0))

If you are solving linear inequalities, you can just re-arrange the equation by hand instead of using solve:

def solve_ineq(eq, sym):
    i, d = (eq.lhs - eq.rhs).expand().as_independent(sym, as_Add=True)
    m = d.coeff(sym)
    lr = (sym, -i/m)
    return Piecewise((eq.func(*lr), m>0),(eq.reversed.func(*lr), m<0))


>>> from sympy.abc import y
>>> solve_ineq(x*y>=2-x, x)
Piecewise((x >= 2/(y + 1), y > -1), (x <= 2/(y + 1), y < -1))

I highly recommend that you use Piecewise so you don't lose track of what it was that you need to assume is positive. In the example I gave, the value of y could be -1/2 and the pertinent coefficient of x would still be positive.

{note use of from sympy import * at the start which imports all the needed object for this example.}