Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a range for a symbol in Sympy

In Sympy it is possible to define constraints on what values a symbol may take

x = symbols('x', real=True)

Is it possible to say that a symbol should take values only in a certain range, say -1 < x < 1? The reason why I am interested in this is because I am trying to get sympy to automatically simplify expressions like the one below

expr = sqrt(1+x) * sqrt((1-x)*(1+x)) / sqrt(1-x)

Running simplify(expr) yields no simplification, whereas when -1<x<1 the simplified result should be 1+x. How do I get sympy to simplify expressions like the one above?

like image 991
D R Avatar asked Nov 22 '22 03:11

D R


1 Answers

Although a single symbol can't hold that assumption, an expression can. Let's define an expression that has the desired range:

>>> p = Symbol('p', positive=True)
>>> neg1to1 = (p - 1)/(p + 1)

Now replace x with that value and simplify

>>> asp = expr.subs(x, neg1to1).simplify(); asp
2*p/(p + 1)

Now restore x from the relationship between it and neg1to1:

>>> p_as_x = solve(neg1to1 - x, p)[0]
>>> asp.subs(p, p_as_x).simplify()
x + 1

You could turn this into a function to allow for any range for x:

>>> def simplify_assuming_range(expr, x, lo, hi):
...      from sympy import Dummy, solve
...      p = Dummy(positive=True)
...      xr = (p - 1)/(p + 1)*(hi - lo) + lo
...      rx = solve(xr - x, p)[0]
...      return expr.subs(x, xr).simplify().subs(p, rx).simplify()
... 
>>> simplify_assuming_range(expr,x,-1,1)
x + 1
like image 175
smichr Avatar answered Dec 17 '22 00:12

smichr