Interacting with sympy

pymbolic can help take care of many structural transformations on your expression trees with great ease. Its main purpose is to help with program transformation after all, not to be a full computer algebra system. That said, if you need a full computer algebra system for things like calculus and simplification, it's easy to get your expressions converted between pymbolic and sympy:

In [1]:
import sympy as sp
from pymbolic import var

x = var("x")
y = var("y")
/usr/lib/python3/dist-packages/sympy/core/function.py:105: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() instead
  evalargspec = inspect.getargspec(cls.eval)
In [3]:
expr = (x**2 + 2*x + 1)/(x**2 + x)
print(expr)
(x**2 + 2*x + 1) / (x**2 + x)

Let's import pymbolic's sympy interoperability code.

In [5]:
# pymbolic.interop.sympy in newer versions of pymbolic
from pymbolic.sympy_interface import (
    PymbolicToSympyMapper, SympyToPymbolicMapper)

p2s = PymbolicToSympyMapper()
s2p = SympyToPymbolicMapper()
In [7]:
sympy_expr = p2s(expr)
print(sympy_expr)
(x**2 + 2*x + 1)/(x**2 + x)
In [11]:
sympy_result = sp.cancel(sympy_expr)
print(sympy_result)
(x + 1)/x
In [12]:
result = s2p(sympy_result)
print(result)
x**(-1)*(1 + x)

One thing to note is that PymbolicToSympyMapper is a regular pymbolic mapper, and its behavior can be overridden in case something about the translation to sympy is not quite what you want.

SympyToPymbolicMapper also behaves very similarly (and can be overridden similarly) although it is not entirely the same kind of mapper.