Reputation: 79
# python 2.7.10
# sympy 0.7.6
import sympy as sym
a, b, c, x = sym.symbols('a b c x')
F = sym.symbols('F', cls=sym.Function)
Suppose we have an expression:
expr = F(a - b) - F(b**2 - c)
Is there a way to replace the unknown function F
with a known function F(x) = x**0.5 + 1
? For example:
result = expr.subs(F(_), _**0.5 + 1)
Which would result in:
(a - b)**0.5 - (b**2 - c)**0.5
Upvotes: 3
Views: 676
Reputation: 19093
replace
is made for this purpose:
>>> import sympy as sym
>>> a, b, c, x = sym.symbols('a b c x')
>>> F = sym.symbols('F', cls=sym.Function)
>>> expr = F(a - b) - F(b**2 - c)
>>> arg=Wild('arg')
>>> expr.replace(F(arg), sqrt(arg) + 1)
sqrt(a - b) - sqrt(b**2 - c)
Upvotes: 2
Reputation: 306
In [1]: import sympy as sm
In [2]: a, b, c, x = sm.symbols('a b c x')
In [3]: F = sm.symbols('F', cls=sm.Function)
In [4]: expr = F(a - b) - F(b**2 - c)
You can use SymPy's Lambda function to define a custom function.
In [5]: G = sm.Lambda(x, sqrt(x) + 1)
In [6]: expr.subs(F, G)
Out[6]: sqrt(a - b) - sqrt(b**2 - c)
Upvotes: 4
Reputation: 2148
This can be done by subclassing Function
and defining the proper eval
method (http://docs.sympy.org/dev/modules/core.html#id50)
In [1]: from sympy import Function, sqrt
In [2]: from sympy.abc import x, y, z, a, b, c
In [4]: f = Function('f')
In [5]: expr = f(a-b)+f(b**2-c)
In [6]: expr
Out[6]: f(a - b) + f(b**2 - c)
In [11]: class F(Function):
....:
....: @classmethod
....: def eval(cls, x):
....: return sqrt(x)+1
....:
In [12]: expr.subs(f, F)
Out[12]: sqrt(a - b) + sqrt(b**2 - c) + 2
Python's type
function can be used to shorten the definition of F
In [13]: G = type('G', (Function, ),
{'eval' : classmethod(lambda self, x : sqrt(x)+1)})
In [14]: expr.subs(f, G)
Out[14]: sqrt(a - b) + sqrt(b**2 - c) + 2
In [15]:
Upvotes: 0