DavidT
DavidT

Reputation: 79

placeholder functions in sympy

# 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

Answers (3)

smichr
smichr

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

Sartaj Singh
Sartaj Singh

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

ptb
ptb

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

Related Questions