Zev
Zev

Reputation: 3491

Replacing composed functions in Sympy

I am trying to generate some random expressions in the form f(g(x)). I'd like to be able to replace g with something like sin(x) or x**2 and f with something like cos(x) or log(x). So I'd get something like sin(cos(x)) or log(x**2) (but randomized).

The part of this task I'm having trouble with is replacing both an outer and inner function.

Here's my code:

import sympy
from sympy import abc

x = abc.x
f = sympy.Function('f')(x)
g = sympy.Function('g')(x)

full=f.subs(x, g)
newExpr = sympy.sin(x)
newExpr2 = sympy.cos(x)

print(full)

replaced_inner = full.subs(g, newExpr)
print(replaced_inner)

both = replaced_inner.subs(f, newExpr2)
print(both)

full prints f(g(x)) so that works
replaced_inner prints f(sin(x)) so that works as well
both prints f(sin(x)) when I want it to print cos(sin(x))

I've tried using args[0] and f.func but haven't made progress.

How can I replace both the inner and outer functions (and eventually more complex things like f(g(h(x))).

I could simply create cos(sin(x)) but I want to do it using variables so I can randomize what function gets replaced.

Upvotes: 3

Views: 2007

Answers (1)

user6655984
user6655984

Reputation:

The problem is in confusion of functions like sympy.Function('f') and expressions like sympy.Function('f')(x). Having defined f = sympy.Function('f')(x) you made f the expression f(x). And since the expression f(g(x)) does not have f(x) as a subexpression, attempted substitution fails.

All this is fixed if you work with actual functions, not plugging x in prematurely.

f = sympy.Function('f')
g = sympy.Function('g')

full = f(g(x))
newExpr = sympy.sin
newExpr2 = sympy.cos

print(full)

replaced_inner = full.subs(g, newExpr)
print(replaced_inner)

both = replaced_inner.subs(f, newExpr2)
print(both)

This prints

f(g(x))
f(sin(x))
cos(sin(x))

Aside: you may also be interested in replace method which supports certain patterns. Not necessary here, but may be necessary for more advanced replacements.

Upvotes: 2

Related Questions