From d0bfc81c9b166da419cbd78f4d74d7718761bf0a Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 6 Sep 2017 16:23:39 +0200 Subject: [PATCH 1/5] Use sympy's Indexed to represent pymbolics Subscript in interop mappers So far, pymbolic Subscripts could not be properly mapped to sympy. There is a node Indexed in sympy though which does exactly what Subscript does. --- pymbolic/interop/common.py | 16 +++++++++++----- test/test_sympy.py | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pymbolic/interop/common.py b/pymbolic/interop/common.py index dd91775..3f55c29 100644 --- a/pymbolic/interop/common.py +++ b/pymbolic/interop/common.py @@ -111,7 +111,13 @@ class SympyLikeToPymbolicMapper(SympyLikeMapperBase): return prim.CommonSubexpression( self.rec(expr.args[0]), expr.prefix) - def not_supported(self, expr): + def map_Indexed(self, expr): + return prim.Subscript( + self.rec(expr.args[0].args[0]), + tuple(self.rec(i) for i in expr.args[1:]) + ) + + def not_supported(self, expr): # noqa if isinstance(expr, int): return expr elif getattr(expr, "is_Function", False): @@ -145,10 +151,10 @@ class PymbolicToSympyLikeMapper(EvaluationMapper): self.raise_conversion_error(expr) def map_subscript(self, expr): - if isinstance(expr.aggregate, prim.Variable) and isinstance(expr.index, int): - return self.sym.Symbol("%s_%d" % (expr.aggregate.name, expr.index)) - else: - self.raise_conversion_error(expr) + return self.sym.tensor.indexed.Indexed( + self.rec(expr.aggregate), + *tuple(self.rec(i) for i in expr.index_tuple) + ) def map_substitution(self, expr): return self.sym.Subs(self.rec(expr.child), diff --git a/test/test_sympy.py b/test/test_sympy.py index 5415cb6..0bcd449 100644 --- a/test/test_sympy.py +++ b/test/test_sympy.py @@ -25,7 +25,8 @@ THE SOFTWARE. import pytest import pymbolic.primitives as prim -x_, y_ = (prim.Variable(s) for s in "x y".split()) +x_, y_, i_, j_ = (prim.Variable(s) for s in "x y i j".split()) + # {{{ to pymbolic test @@ -51,6 +52,11 @@ def _test_to_pymbolic(mapper, sym, use_symengine): assert mapper(sym.Function("f")(x)) == prim.Variable("f")(x_) assert mapper(sym.exp(x)) == prim.Variable("exp")(x_) + # indexed accesses + if not use_symengine: + i, j = sym.symbols("i,j") + assert mapper(sym.tensor.indexed.Indexed(x, i, j)) == x_[i_, j_] + # constants import math # FIXME: Why isn't this exact? @@ -91,7 +97,11 @@ def _test_from_pymbolic(mapper, sym, use_symengine): deriv = sym.Derivative(x**2, x) assert mapper(prim.Derivative(x_**2, ("x",))) == deriv - assert mapper(x_[0]) == sym.Symbol("x_0") + if use_symengine: + assert mapper(x_[0]) == sym.Symbol("x_0") + else: + i, j = sym.symbols("i,j") + assert mapper(x_[i_,j_]) == sym.tensor.indexed.Indexed(x, i, j) assert mapper(prim.Variable("f")(x_)) == sym.Function("f")(x) -- GitLab From e8f18ab52ac313a94af0d06296acd4d2b481ba55 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 6 Sep 2017 17:09:45 +0200 Subject: [PATCH 2/5] Move Indexed implementation to sympy only mappers They are no fit for symengine. --- pymbolic/interop/common.py | 12 ------------ pymbolic/interop/sympy.py | 12 ++++++++++++ test/test_sympy.py | 3 +-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/pymbolic/interop/common.py b/pymbolic/interop/common.py index 3f55c29..b0b73e5 100644 --- a/pymbolic/interop/common.py +++ b/pymbolic/interop/common.py @@ -111,12 +111,6 @@ class SympyLikeToPymbolicMapper(SympyLikeMapperBase): return prim.CommonSubexpression( self.rec(expr.args[0]), expr.prefix) - def map_Indexed(self, expr): - return prim.Subscript( - self.rec(expr.args[0].args[0]), - tuple(self.rec(i) for i in expr.args[1:]) - ) - def not_supported(self, expr): # noqa if isinstance(expr, int): return expr @@ -150,12 +144,6 @@ class PymbolicToSympyLikeMapper(EvaluationMapper): else: self.raise_conversion_error(expr) - def map_subscript(self, expr): - return self.sym.tensor.indexed.Indexed( - self.rec(expr.aggregate), - *tuple(self.rec(i) for i in expr.index_tuple) - ) - def map_substitution(self, expr): return self.sym.Subs(self.rec(expr.child), tuple(self.sym.Symbol(v) for v in expr.variables), diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index b02d5e8..6d7afc8 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -60,6 +60,12 @@ class SympyToPymbolicMapper(SympyLikeToPymbolicMapper): def map_long(self, expr): return long(expr) # noqa + def map_Indexed(self, expr): # noqa + return prim.Subscript( + self.rec(expr.args[0].args[0]), + tuple(self.rec(i) for i in expr.args[1:]) + ) + # }}} @@ -77,6 +83,12 @@ class PymbolicToSympyMapper(PymbolicToSympyLikeMapper): return self.sym.Derivative(self.rec(expr.child), *[self.sym.Symbol(v) for v in expr.variables]) + def map_subscript(self, expr): + return self.sym.tensor.indexed.Indexed( + self.rec(expr.aggregate), + *tuple(self.rec(i) for i in expr.index_tuple) + ) + # }}} diff --git a/test/test_sympy.py b/test/test_sympy.py index 0bcd449..c3b038e 100644 --- a/test/test_sympy.py +++ b/test/test_sympy.py @@ -28,7 +28,6 @@ import pymbolic.primitives as prim x_, y_, i_, j_ = (prim.Variable(s) for s in "x y i j".split()) - # {{{ to pymbolic test def _test_to_pymbolic(mapper, sym, use_symengine): @@ -101,7 +100,7 @@ def _test_from_pymbolic(mapper, sym, use_symengine): assert mapper(x_[0]) == sym.Symbol("x_0") else: i, j = sym.symbols("i,j") - assert mapper(x_[i_,j_]) == sym.tensor.indexed.Indexed(x, i, j) + assert mapper(x_[i_, j_]) == sym.tensor.indexed.Indexed(x, i, j) assert mapper(prim.Variable("f")(x_)) == sym.Function("f")(x) -- GitLab From a27a9e5b2f0f6d7f134d3587dd852fa98b938130 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 6 Sep 2017 17:14:14 +0200 Subject: [PATCH 3/5] [fixup] Add primitives import --- pymbolic/interop/sympy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index 6d7afc8..80fa435 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -28,6 +28,7 @@ THE SOFTWARE. from pymbolic.interop.common import ( SympyLikeToPymbolicMapper, PymbolicToSympyLikeMapper) +import pymbolic.primitives as prim import sympy -- GitLab From 0191653b9492fe5d4cb25e571c78b23f0523e600 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Sat, 9 Sep 2017 20:10:59 -0500 Subject: [PATCH 4/5] Remove remaining conflict marks (oops!) --- pymbolic/interop/sympy.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pymbolic/interop/sympy.py b/pymbolic/interop/sympy.py index 0d7cd12..1e31ead 100644 --- a/pymbolic/interop/sympy.py +++ b/pymbolic/interop/sympy.py @@ -108,13 +108,12 @@ class PymbolicToSympyMapper(PymbolicToSympyLikeMapper): return self.sym.Derivative(self.rec(expr.child), *[self.sym.Symbol(v) for v in expr.variables]) -<<<<<<< HEAD def map_subscript(self, expr): return self.sym.tensor.indexed.Indexed( self.rec(expr.aggregate), *tuple(self.rec(i) for i in expr.index_tuple) ) -======= + def map_if(self, expr): cond = self.rec(expr.condition) return self.sym.Piecewise((self.rec(expr.then), cond), @@ -138,7 +137,6 @@ class PymbolicToSympyMapper(PymbolicToSympyLikeMapper): return self.sym.GreaterThan(left, right) else: raise NotImplementedError("Unknown operator '%s'" % expr.operator) ->>>>>>> c860c0d5a0abcf18b34914b2ccbb0a22c9b98d3f # }}} -- GitLab From 0c2d342e0ec49200a74e660dc0446e38a19e600e Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Tue, 12 Sep 2017 21:58:00 +0200 Subject: [PATCH 5/5] Restore old implementation in base class used by symengine --- pymbolic/interop/common.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pymbolic/interop/common.py b/pymbolic/interop/common.py index b0b73e5..7501a50 100644 --- a/pymbolic/interop/common.py +++ b/pymbolic/interop/common.py @@ -144,6 +144,12 @@ class PymbolicToSympyLikeMapper(EvaluationMapper): else: self.raise_conversion_error(expr) + def map_subscript(self, expr): + if isinstance(expr.aggregate, prim.Variable) and isinstance(expr.index, int): + return self.sym.Symbol("%s_%d" % (expr.aggregate.name, expr.index)) + else: + self.raise_conversion_error(expr) + def map_substitution(self, expr): return self.sym.Subs(self.rec(expr.child), tuple(self.sym.Symbol(v) for v in expr.variables), -- GitLab