Skip to content

Commit 9c99b5b

Browse files
authored
Merge pull request #152 from ShikharJ/Ccode
Wrapped ccode and implemented class CodePrinter
2 parents 5fadf70 + 50697c0 commit 9c99b5b

File tree

6 files changed

+67
-8
lines changed

6 files changed

+67
-8
lines changed

symengine/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ add_subdirectory(lib)
22
add_subdirectory(tests)
33

44
set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine)
5-
install(FILES __init__.py utilities.py compatibility.py sympy_compat.py functions.py
5+
install(FILES __init__.py utilities.py compatibility.py sympy_compat.py functions.py printing.py
66
DESTINATION ${PY_PATH}
77
)

symengine/lib/symengine.pxd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,3 +802,6 @@ IF HAVE_SYMENGINE_MPC:
802802

803803
cdef extern from "<symengine/parser.h>" namespace "SymEngine":
804804
RCP[const Basic] parse(const string &n) nogil except +
805+
806+
cdef extern from "<symengine/codegen.h>" namespace "SymEngine":
807+
string ccode(const Basic &x) nogil except +

symengine/lib/symengine_wrapper.pyx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@ cdef class _DictBasic(object):
389389
self.add(key, value)
390390

391391
def add(self, key, value):
392-
cdef Basic K = _sympify(key)
393-
cdef Basic V = _sympify(value)
392+
cdef Basic K = sympify(key)
393+
cdef Basic V = sympify(value)
394394
cdef symengine.std_pair_rcp_const_basic_rcp_const_basic pair
395395
pair.first = K.thisptr
396396
pair.second = V.thisptr
@@ -405,27 +405,27 @@ cdef class _DictBasic(object):
405405
return self.c.size()
406406

407407
def __getitem__(self, key):
408-
cdef Basic K = _sympify(key)
408+
cdef Basic K = sympify(key)
409409
it = self.c.find(K.thisptr)
410410
if it == self.c.end():
411411
raise KeyError(key)
412412
else:
413413
return c2py(deref(it).second)
414414

415415
def __setitem__(self, key, value):
416-
cdef Basic K = _sympify(key)
417-
cdef Basic V = _sympify(value)
416+
cdef Basic K = sympify(key)
417+
cdef Basic V = sympify(value)
418418
self.c[K.thisptr] = V.thisptr
419419

420420
def clear(self):
421421
self.clear()
422422

423423
def __delitem__(self, key):
424-
cdef Basic K = _sympify(key)
424+
cdef Basic K = sympify(key)
425425
self.c.erase(K.thisptr)
426426

427427
def __contains__(self, key):
428-
cdef Basic K = _sympify(key)
428+
cdef Basic K = sympify(key)
429429
it = self.c.find(K.thisptr)
430430
return it != self.c.end()
431431

@@ -3393,5 +3393,9 @@ def has_symbol(obj, symbol=None):
33933393
return symengine.has_symbol(deref(b.thisptr),
33943394
deref(symengine.rcp_static_cast_Symbol(s.thisptr)))
33953395

3396+
def ccode(expr):
3397+
cdef Basic expr_ = sympify(expr)
3398+
return symengine.ccode(deref(expr_.thisptr)).decode("utf-8")
3399+
33963400
# Turn on nice stacktraces:
33973401
symengine.print_stack_on_segfault()

symengine/printing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from symengine.lib.symengine_wrapper import ccode, _sympify, Basic
2+
3+
class CCodePrinter:
4+
5+
def doprint(self, expr, assign_to=None):
6+
if not isinstance(assign_to, (Basic, type(None), str)):
7+
raise TypeError("{0} cannot assign to object of type {1}".format(
8+
type(self).__name__, type(assign_to)))
9+
10+
expr = _sympify(expr)
11+
if not assign_to:
12+
if expr.is_Matrix:
13+
raise RuntimeError("Matrices need a assign_to parameter")
14+
return ccode(expr)
15+
16+
assign_to = str(assign_to)
17+
if not expr.is_Matrix:
18+
return "{} = {};".format(assign_to, ccode(expr))
19+
20+
code_lines = []
21+
for i, element in enumerate(expr):
22+
code_line = '{}[{}] = {};'.format(assign_to, i, element)
23+
code_lines.append(code_line)
24+
return '\n'.join(code_lines)

symengine/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ install(FILES __init__.py
88
test_number.py
99
test_matrices.py
1010
test_ntheory.py
11+
test_printing.py
1112
test_sage.py
1213
test_series_expansion.py
1314
test_subs.py

symengine/tests/test_printing.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from symengine.utilities import raises
2+
from symengine.lib.symengine_wrapper import (ccode, Symbol, sqrt, Pow, Max, sin, Integer, MutableDenseMatrix)
3+
from symengine.printing import CCodePrinter
4+
5+
def test_ccode():
6+
x = Symbol("x")
7+
y = Symbol("y")
8+
assert ccode(x) == "x"
9+
assert ccode(x**3) == "pow(x, 3)"
10+
assert ccode(x**(y**3)) == "pow(x, pow(y, 3))"
11+
assert ccode(x**-1.0) == "pow(x, -1.0)"
12+
assert ccode(Max(x, x*x)) == "max(x, pow(x, 2))"
13+
assert ccode(sin(x)) == "sin(x)"
14+
assert ccode(Integer(67)) == "67"
15+
assert ccode(Integer(-1)) == "-1"
16+
17+
def test_CCodePrinter():
18+
x = Symbol("x")
19+
y = Symbol("y")
20+
myprinter = CCodePrinter()
21+
22+
assert myprinter.doprint(1+x, "bork") == "bork = 1 + x;"
23+
assert myprinter.doprint(1*x) == "x"
24+
assert myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]), "larry") == "larry[0] = x;\nlarry[1] = y;"
25+
raises(TypeError, lambda: myprinter.doprint(sin(x), Integer))
26+
raises(RuntimeError, lambda: myprinter.doprint(MutableDenseMatrix(1, 2, [x, y])))
27+

0 commit comments

Comments
 (0)