diff --git a/.test-py2.yml b/.test-py2.yml index b53749ce7da5175cb6991aefae8f92244e7fb037..62516d5fb696bb7fdaedf63b7677ba028cbbb927 100644 --- a/.test-py2.yml +++ b/.test-py2.yml @@ -1,6 +1,5 @@ name: py2 channels: - - symengine - conda-forge - defaults dependencies: @@ -9,5 +8,5 @@ dependencies: - conda-forge::numpy - conda-forge::sympy - python=2.7 - - symengine::python-symengine=0.3.0 + - python-symengine=0.6.0 - maxima diff --git a/.test-py3.yml b/.test-py3.yml index bd1f2bd30934d60b3d9ac358a46815ccf8302960..c17b40cbdb183f46fb974494f1e722188f9a398e 100644 --- a/.test-py3.yml +++ b/.test-py3.yml @@ -1,12 +1,11 @@ name: py3 channels: - - symengine - conda-forge - defaults dependencies: - conda-forge::numpy - conda-forge::sympy - python=3.6 - - symengine::python-symengine=0.3.0 + - python-symengine=0.6.0 # - pexpect # - maxima diff --git a/pymbolic/interop/common.py b/pymbolic/interop/common.py index 458c10374d9d0eabd4ba8fec3b24903b629d3b98..568a36430a8a450fe4ca24115cdbe9cd69841671 100644 --- a/pymbolic/interop/common.py +++ b/pymbolic/interop/common.py @@ -108,10 +108,6 @@ class SympyLikeToPymbolicMapper(SympyLikeMapperBase): return prim.Derivative(self.rec(expr.expr), tuple(v.name for v in expr.variables)) - def map_CSE(self, expr): # noqa - return prim.CommonSubexpression( - self.rec(expr.args[0]), expr.prefix) - def map_UnevaluatedExpr(self, expr): # noqa return self.rec(expr.args[0]) diff --git a/pymbolic/interop/symengine.py b/pymbolic/interop/symengine.py index e7491a0ae6f79b1c236ed1d3f91013fb18eae38c..a984400b5888e10c7f2745fa1a3cbccecd0d55f3 100644 --- a/pymbolic/interop/symengine.py +++ b/pymbolic/interop/symengine.py @@ -77,6 +77,19 @@ class SymEngineToPymbolicMapper(SympyLikeToPymbolicMapper): # For builtin functions return type(expr).__name__ + def not_supported(self, expr): # noqa + from symengine.lib.symengine_wrapper import \ + PyFunction # pylint: disable=E0611 + if isinstance(expr, PyFunction) and \ + self.function_name(expr) == "CSE": # pylint: disable=E0611 + sympy_expr = expr._sympy_() + return prim.CommonSubexpression( + self.rec(expr.args[0]), sympy_expr.prefix, sympy_expr.scope) + elif isinstance(expr, symengine.Function) and \ + self.function_name(expr) == "CSE": + return prim.CommonSubexpression(self.rec(expr.args[0])) + return SympyLikeToPymbolicMapper.not_supported(self, expr) + # }}} @@ -93,4 +106,21 @@ class PymbolicToSymEngineMapper(PymbolicToSympyLikeMapper): # }}} + +CSE = symengine.Function("CSE") + + +def make_cse(arg, prefix=None, scope=None): + # SymEngine's classes can't be inherited, but there's a + # mechanism to create one based on SymPy's ones which stores + # the SymPy object inside the C++ object. + # This SymPy object is later retrieved to get the prefix + # These conversions between SymPy and SymEngine are expensive, + # so use it only if necessary. + if prefix is None and scope is None: + return CSE(arg) + from pymbolic.interop.sympy import make_cse as make_cse_sympy + sympy_result = make_cse_sympy(arg, prefix=prefix, scope=scope) + return symengine.sympify(sympy_result) + # vim: fdm=marker diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index cce923b12c53d95d8c36427f23ad2bd771ccbee2..393894e3798f4cdf5e5349ee6e54496bc52c92f5 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -68,6 +68,10 @@ class SympyToPymbolicMapper(SympyLikeToPymbolicMapper): tuple(self.rec(i) for i in expr.args[1:]) ) + def map_CSE(self, expr): # noqa + return prim.CommonSubexpression( + self.rec(expr.args[0]), expr.prefix, expr.scope) + # }}} @@ -94,9 +98,10 @@ class CSE(sympy.Function): nargs = 1 -def make_cse(arg, prefix=None): +def make_cse(arg, prefix=None, scope=None): result = CSE(arg) result.prefix = prefix + result.scope = scope return result