Sympy Piecewise and refine - sympy

I try to simplify this Piecewise expression using refine without success. I use sympy version 1.8.
import sympy as sp
x,y = sp.symbols('x,y', real=True, positive=True)
expr = sp.Piecewise((1, x>=y),(0, True))
expr variable contain
⎧1 for x ≥ y
⎨
⎩0 otherwise
now I try to obtain 1 assuming that x>y
sp.refine(expr, sp.Q.gt(x,y))
but I obtain the same expression
⎧1 for x ≥ y
⎨
⎩0 otherwise
Any ideas to force this simplification ?
Thank you for your help

If you give expr a value for x that satisfies the requirement, it will evaluate:
>>> eps = Symbol('eps', positive=True)
>>> expr.subs(x, y + eps).simplify()
1

Related

Sympy: Is there a function that gives all the factors of an expression but does not work sums?

I have an expression which is composed only of factors (e.g. (x**2+1)*(x**2)*(x+4). I want to delete the factor x**2 from it using the function .args with an if condition. However, if I have the following equation x**2+1+x+4, the .args thinks I have x**2 in the expression which is not true (I only have one factor). I have the code below.:
if q**2 in expr.args:
expr = expr.func(*[term for term in expr.args if term != q**2])
else:
expr = expr*2
By using Mul.make_args(expr) you will get a singleton if the expression is not a product, otherwise a tuple of the factors:
>>> from sympy.abc import x, y
>>> from sympy import Mul
>>> Mul.make_args(x + y)
(x + y,)
>>> Mul.make_args(x*y)
(x, y)

Sympy .replace() doesn't detect product

I'm trying to make some replacements, but .replace() is confusingly missing occurrences:
from sympy import *
x, y = symbols('x y')
f = Function('f')
expr = x*f(x)*f(y)
expr.replace(x*f(x), 1)
# Output: x*f(x)*f(y)
# Expected: f(y)
Is this a bug?
It does work when I use .subs() instead of .replace(), but I have no idea why this would be needed.
(also, I wanna use this in the context of a Sum expression where .subs() would not work).

How to rewrite an abstract derivative of a sum as a sum of derivatives in sympy?

I want to convert (L + L')' into L' + L'' using sympy and some sort of expanding or simplifying function.
import sympy
sympy.init_printing() # math as latex
z, L = sympy.symbols('z,L')
expr = sympy.Derivative(L + sympy.Derivative(L,z), z)
expr
I tried standard functions like expand, which rewrites the expression (even with a flag force=True), or doit which returns zero.
Question. Is there a way to apply sp.Derivative to sum of two functions and expand it to sum of sp.Derivative's?
If we work with derivatives, it is better to use sympy.Function instead of sympy.Symbol. In order to expand the derivative, one can use .doit() method.
Example.
import sympy
sympy.init_printing() # math as latex
z = sympy.Symbol('z')
f = sympy.Function("f")(z)
expr = sympy.Derivative(sympy.Derivative(f) + f)
expr
expr.doit()

check if expression contains symbol

I would like to find out programatically if a SymPy expression contains a symbol. E.g., for
import sympy
x = sympy.Symbol('x')
y = sympy.Symbol('y')
a = 4 + x**2 + y
b = 4 + y**2
a contains both x and y, b contains only y.
>>> x in a.free_symbols, y in a.free_symbols
(True, True)
>>> x in b.free_symbols, y in b.free_symbols
(False, True)
You can also use .atoms(Symbol) to check that. atoms(Symbol) differs from .free_symbols in some cases. free_symbols doesn't return dummy symbols, like integration variables.
it's usually what you want, since expressions don't mathematically depend on dummy symbols
example:
>>> Integral(f(x), (x, 0, 1)).atoms(Symbol)
set([x])
>>> Integral(f(x), (x, 0, 1)).free_symbols
set([])

How to prevent generation of substitions

Sympy sometimes automatically generates substitutions in my experessions:
How can I prevent this? Or, how can I remove the substitution from the expression?
from sympy import *
R, T = symbols('R T', cls=Function)
u = symbols('u', cls=Function)
x, y, z= symbols('x y z')
R(u(x,y)).diff(x)
gives
Derivative(u(x, y), x)*Subs(Derivative(R(_xi_1), _xi_1), (_xi_1,), (u(x, y),))
I'd like to have
Derivative(u(x, y), x)*Derivative(R(u(x, y), (u(x, y)))
PS: http://docs.sympy.org/latest/modules/core.html#subs says "When evaluating derivatives at a point that is not a symbol, a Subs object is returned."
The following will give you what you ask for
>>> s=R(u(x,y)).diff(x)
>>> s.replace(Subs, lambda a,b,c: a.xreplace(dict(zip(b,c))))
(It will revert to a Subs instance if you apply the doit method.)