Skip to content

Commit c24387d

Browse files
committed
Test pickle of Dummy, make Dummy SymPy-convertible (roundtrip)
1 parent 0d3c056 commit c24387d

File tree

6 files changed

+58
-12
lines changed

6 files changed

+58
-12
lines changed

symengine/lib/symengine.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ cdef extern from "<symengine/basic.h>" namespace "SymEngine":
323323
rcp_const_basic make_rcp_Symbol "SymEngine::make_rcp<const SymEngine::Symbol>"(string name) nogil
324324
rcp_const_basic make_rcp_Dummy "SymEngine::make_rcp<const SymEngine::Dummy>"() nogil
325325
rcp_const_basic make_rcp_Dummy "SymEngine::make_rcp<const SymEngine::Dummy>"(string name) nogil
326+
rcp_const_basic make_rcp_Dummy "SymEngine::make_rcp<const SymEngine::Dummy>"(string &name, size_t index) nogil
326327
rcp_const_basic make_rcp_PySymbol "SymEngine::make_rcp<const SymEngine::PySymbol>"(string name, PyObject * pyobj, bool use_pickle) except +
327328
rcp_const_basic make_rcp_Constant "SymEngine::make_rcp<const SymEngine::Constant>"(string name) nogil
328329
rcp_const_basic make_rcp_Infty "SymEngine::make_rcp<const SymEngine::Infty>"(RCP[const Number] i) nogil

symengine/lib/symengine_wrapper.in.pyx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,10 @@ def sympy2symengine(a, raise_error=False):
278278
"""
279279
import sympy
280280
from sympy.core.function import AppliedUndef as sympy_AppliedUndef
281-
if isinstance(a, sympy.Symbol):
281+
if isinstance(a, sympy.Dummy):
282+
return Dummy(a.name, a.dummy_index)
283+
elif isinstance(a, sympy.Symbol):
282284
return Symbol(a.name)
283-
elif isinstance(a, sympy.Dummy):
284-
return Dummy(a.name)
285285
elif isinstance(a, sympy.Mul):
286286
return mul(*[sympy2symengine(x, raise_error) for x in a.args])
287287
elif isinstance(a, sympy.Add):
@@ -1301,10 +1301,10 @@ cdef class Symbol(Expr):
13011301
return sympy.Symbol(str(self))
13021302

13031303
def __reduce__(self):
1304-
if type(self) == Symbol:
1304+
if type(self) in (Symbol, Dummy):
13051305
return Basic.__reduce__(self)
13061306
else:
1307-
raise NotImplementedError("pickling for Symbol subclass not implemented")
1307+
raise NotImplementedError("pickling for subclass of Symbol or Dummy not implemented")
13081308

13091309
def _sage_(self):
13101310
import sage.all as sage
@@ -1337,11 +1337,16 @@ cdef class Symbol(Expr):
13371337

13381338
cdef class Dummy(Symbol):
13391339

1340-
def __init__(Basic self, name=None, *args, **kwargs):
1341-
if name is None:
1342-
self.thisptr = symengine.make_rcp_Dummy()
1340+
def __init__(Basic self, name=None, dummy_index=None, *args, **kwargs):
1341+
cdef size_t index
1342+
if dummy_index is None:
1343+
if name is None:
1344+
self.thisptr = symengine.make_rcp_Dummy()
1345+
else:
1346+
self.thisptr = symengine.make_rcp_Dummy(name.encode("utf-8"))
13431347
else:
1344-
self.thisptr = symengine.make_rcp_Dummy(name.encode("utf-8"))
1348+
index = dummy_index
1349+
self.thisptr = symengine.make_rcp_Dummy(name.encode("utf-8"), index)
13451350

13461351
def _sympy_(self):
13471352
import sympy

symengine/tests/test_pickling.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos, Symbol
1+
from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos, Symbol, Dummy
22
from symengine.test_utilities import raises
33
import pickle
44
import unittest
@@ -57,3 +57,19 @@ def test_llvm_double():
5757
ll = pickle.loads(ss)
5858
inp = [1, 2, 3]
5959
assert np.allclose(l(inp), ll(inp))
60+
61+
62+
def _check_pickling_roundtrip(arg):
63+
s2 = pickle.dumps(arg)
64+
arg2 = pickle.loads(s2)
65+
assert arg == arg2
66+
s3 = pickle.dumps(arg2)
67+
arg3 = pickle.loads(s3)
68+
assert arg == arg3
69+
70+
71+
def test_pickling_roundtrip():
72+
x, y, z = symbols('x y z')
73+
_check_pickling_roundtrip(x+y)
74+
_check_pickling_roundtrip(Dummy('d'))
75+
_check_pickling_roundtrip(Dummy('d') - z)

symengine/tests/test_symbol.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ def test_dummy():
157157
xdummy1 = Dummy('x')
158158
xdummy2 = Dummy('x')
159159
assert xdummy1.dummy_index != xdummy2.dummy_index # maybe test using "less than"?
160+
assert xdummy1.name == 'x'
161+
assert xdummy2.name == 'x'
160162

161163
assert x1 == x2
162164
assert x1 != xdummy1

symengine/tests/test_sympy_conv.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from symengine import (Symbol, Integer, sympify, SympifyError, log,
22
function_symbol, I, E, pi, oo, zoo, nan, true, false,
3-
exp, gamma, have_mpfr, have_mpc, DenseMatrix, sin, cos, tan, cot,
3+
exp, gamma, have_mpfr, have_mpc, DenseMatrix, Dummy, sin, cos, tan, cot,
44
csc, sec, asin, acos, atan, acot, acsc, asec, sinh, cosh, tanh, coth,
55
asinh, acosh, atanh, acoth, atan2, Add, Mul, Pow, diff, GoldenRatio,
66
Catalan, EulerGamma, UnevaluatedExpr, RealDouble)
@@ -833,3 +833,25 @@ def test_conv_large_integers():
833833
if have_sympy:
834834
c = a._sympy_()
835835
d = sympify(c)
836+
837+
838+
def _check_sympy_roundtrip(arg):
839+
arg_sy1 = sympy.sympify(arg)
840+
arg_se2 = sympify(arg_sy1)
841+
print(f"{type(arg)=} {type(arg_se2)=}")
842+
assert arg == arg_se2
843+
arg_sy2 = sympy.sympify(arg_se2)
844+
assert arg_sy2 == arg_sy1
845+
arg_se3 = sympify(arg_sy2)
846+
assert arg_se3 == arg
847+
848+
849+
@unittest.skipIf(not have_sympy, "SymPy not installed")
850+
def test_sympy_roundtrip():
851+
x = Symbol("x")
852+
y = Symbol("y")
853+
d = Dummy("d")
854+
_check_sympy_roundtrip(x)
855+
_check_sympy_roundtrip(x+y)
856+
_check_sympy_roundtrip(x**y)
857+
_check_sympy_roundtrip(d)

symengine_version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c9510fb4b5c30b84adb993573a51f2a9a38a4cfe
1+
c574fa8d7018a850481afa7a59809d30e774d78d

0 commit comments

Comments
 (0)