Is it possible with sympy Wild symbols and replace to match arbitrary function applications?
What I would ideally like to do is the following:
x = Symbol('x')
expr1 = sin(x)
expr2 = exp(x)
F = Wild('F') #or maybe WildFunction('F')?
result1 = expr1.replace(F(x), lambda F: F(tan(x))) #expected: sin(tan(x))
result2 = expr2.replace(F(x), lambda F: F(tan(x))) #expected: exp(tan(x))
Unfortunately this does not work: it throws a TypeError since Wild symbols are not callable. So is there a way to make this work? Note that I really don't want to match and replace specific functions, nor do I want to match and replace symbolic functions like Function('f'). I want to match and replace arbitrary (sympy?) functions like sin, exp, im, tan, re, conjguate and so on.
What does work is
F = WildFunction('F')
result1 = expr1.replace(F, lambda F: F.func(*F.args))
But it feels a little unnatural and fragile.
Thank you!
Yes, but you're looking for Wild's properties
argument and can use the type()
of the match to nest a function call
>>> F = Wild("F", properties=[lambda F: F.is_Function])
>>> expr1.replace(F, lambda F: type(F)(tan(x)))
sin(tan(x))
Or to be more picky about which functions are replaced
>>> F = Wild("F", properties=[lambda F: type(F) in [sin,tan,cos]])
>>> (sin(x) + cosh(x) + cos(x)).replace(F, lambda F: type(F)(csc(x)))
sin(csc(x)) + cos(csc(x)) + cosh(x)
A somewhat shameless plug, but check out my other Answer about how .replace
et al. behave (also links to more on Wild
)!