From 785f70ab697fc95e35877d80c29b1901b04cb7dd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 2 Mar 2020 19:38:31 -0600 Subject: [PATCH 001/314] Add support for UnevaluatedExpr --- symengine/__init__.py | 2 +- symengine/lib/symengine.pxd | 3 ++- symengine/lib/symengine_wrapper.pyx | 22 ++++++++++++++++++++++ symengine/tests/test_functions.py | 16 +++++++++++++++- symengine/tests/test_sympy_conv.py | 11 ++++++++++- symengine_version.txt | 2 +- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 5b5e1062a..7d806d279 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -7,7 +7,7 @@ ImmutableMatrix, ImmutableDenseMatrix, MutableDenseMatrix, MatrixBase, Basic, DictBasic, symarray, series, diff, zeros, eye, diag, ones, Derivative, Subs, expand, has_symbol, - UndefFunction, Function, latex, + UndefFunction, Function, UnevaluatedExpr, latex, have_numpy, true, false, Equality, Unequality, GreaterThan, LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le, Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 348f6fb21..97120aba6 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -307,7 +307,7 @@ cdef extern from "" namespace "SymEngine": bool is_a_Complement "SymEngine::is_a"(const Basic &b) nogil bool is_a_ConditionSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_ImageSet "SymEngine::is_a"(const Basic &b) nogil - + bool is_a_UnevaluatedExpr "SymEngine::is_a"(const Basic &b) nogil bool is_a_Piecewise "SymEngine::is_a"(const Basic &b) nogil bool is_a_Contains "SymEngine::is_a"(const Basic &b) nogil bool is_a_And "SymEngine::is_a"(const Basic &b) nogil @@ -534,6 +534,7 @@ cdef extern from "" namespace "SymEngine": cdef rcp_const_basic conjugate(rcp_const_basic &x) nogil except+ cdef rcp_const_basic log(rcp_const_basic &x) nogil except+ cdef rcp_const_basic log(rcp_const_basic &x, rcp_const_basic &y) nogil except+ + cdef rcp_const_basic unevaluated_expr(rcp_const_basic &x) nogil except+ cdef cppclass Function(Basic): pass diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 3772dcb1e..c16ab8c25 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -245,6 +245,8 @@ cdef object c2py(rcp_const_basic o): r = Boolean.__new__(Or) elif (symengine.is_a_Xor(deref(o))): r = Boolean.__new__(Xor) + elif (symengine.is_a_UnevaluatedExpr(deref(o))): + r = Function.__new__(UnevaluatedExpr) else: raise Exception("Unsupported SymEngine class.") r.thisptr = o @@ -451,6 +453,8 @@ def sympy2symengine(a, raise_error=False): return imageset(*(a.args)) elif isinstance(a, sympy.Function): return PyFunction(a, a.args, a.func, sympy_module) + elif isinstance(a, sympy.UnevaluatedExpr): + return UnevaluatedExpr(a.args[0]) elif isinstance(a, sympy.MatrixBase): row, col = a.shape v = [] @@ -2567,6 +2571,24 @@ add = Add mul = Mul +class UnevaluatedExpr(OneArgFunction): + def __new__(cls, x): + cdef Basic X = sympify(x) + return c2py(symengine.unevaluated_expr(X.thisptr)) + + @property + def is_number(self): + return self.args[0].is_number + + @property + def is_integer(self): + return self.args[0].is_number + + @property + def is_finite(self): + return self.args[0].is_number + + class Abs(OneArgFunction): @property diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 9c016a23b..2086394ce 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -3,7 +3,7 @@ Rational, EulerGamma, Function, Subs, Derivative, LambertW, zeta, dirichlet_eta, zoo, pi, KroneckerDelta, LeviCivita, erf, erfc, oo, lowergamma, uppergamma, exp, loggamma, beta, polygamma, digamma, trigamma, sign, floor, ceiling, conjugate, - nan, Float + nan, Float, UnevaluatedExpr ) import unittest @@ -386,3 +386,17 @@ def test_ceiling(): def test_conjugate(): assert conjugate(pi) == pi assert conjugate(I) == -I + + +def test_unevaluated_expr(): + x = Symbol("x") + t = UnevaluatedExpr(x) + assert x + t != 2 * x + assert not t.is_number + assert not t.is_integer + assert not t.is_finite + + t = UnevaluatedExpr(1) + assert t.is_number + assert t.is_integer + assert t.is_finite diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index c58b9f713..6dfdc6442 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -3,7 +3,7 @@ exp, gamma, have_mpfr, have_mpc, DenseMatrix, sin, cos, tan, cot, csc, sec, asin, acos, atan, acot, acsc, asec, sinh, cosh, tanh, coth, asinh, acosh, atanh, acoth, Add, Mul, Pow, diff, GoldenRatio, - Catalan, EulerGamma) + Catalan, EulerGamma, UnevaluatedExpr) from symengine.lib.symengine_wrapper import (Subs, Derivative, RealMPFR, ComplexMPC, PyNumber, Function, LambertW, zeta, dirichlet_eta, KroneckerDelta, LeviCivita, erf, erfc, lowergamma, uppergamma, @@ -651,6 +651,15 @@ def test_conjugate(): assert e2._sympy_() == e1 +@unittest.skipIf(not have_sympy, "SymPy not installed") +def test_unevaluated_expr(): + x = Symbol("x") + e1 = sympy.UnevaluatedExpr(sympy.Symbol("x")) + e2 = UnevaluatedExpr(x) + assert sympify(e1) == e2 + assert e2._sympy_() == e1 + + @unittest.skipIf(not have_sympy, "SymPy not installed") def test_logic(): x = true diff --git a/symengine_version.txt b/symengine_version.txt index 60f634328..063fc9d99 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.6.0 +fbd501264a86b7452ec35bb0370fbabc6d83b5c6 From c2deccc8b96a42cec2ae085b62c83641a2be46b3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 2 Mar 2020 22:55:01 -0600 Subject: [PATCH 002/314] Fix is_integer and is_finite --- symengine/lib/symengine_wrapper.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c16ab8c25..cd8fcdd95 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -2582,11 +2582,11 @@ class UnevaluatedExpr(OneArgFunction): @property def is_integer(self): - return self.args[0].is_number + return self.args[0].is_integer @property def is_finite(self): - return self.args[0].is_number + return self.args[0].is_finite class Abs(OneArgFunction): From a021d4510845b16f1485834a80723f72f0b7ffe2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 9 Mar 2020 00:09:02 -0500 Subject: [PATCH 003/314] Use xreplace from C++ instead of subs --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 97120aba6..9806d25c1 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -322,6 +322,7 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) nogil rcp_const_basic ssubs (rcp_const_basic &x, const map_basic_basic &x) nogil + rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) nogil cdef extern from "" namespace "SymEngine": rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index cd8fcdd95..387131dae 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -911,7 +911,11 @@ cdef class Basic(object): cdef _DictBasic D = get_dict(*args) return c2py(symengine.ssubs(self.thisptr, D.c)) - replace = xreplace = subs + def xreplace(Basic self not None, *args): + cdef _DictBasic D = get_dict(*args) + return c2py(symengine.xreplace(self.thisptr, D.c)) + + replace = xreplace def msubs(Basic self not None, *args): cdef _DictBasic D = get_dict(*args) @@ -3531,7 +3535,11 @@ cdef class DenseMatrixBase(MatrixBase): cdef _DictBasic D = get_dict(*args) return self.applyfunc(lambda x: x.subs(D)) - replace = xreplace = subs + def xreplace(self, *args): + cdef _DictBasic D = get_dict(*args) + return self.applyfunc(lambda x: x.xreplace(D)) + + replace = xreplace @property def free_symbols(self): From 1562a4cdd61d33cae912bc3d8b4d3f8e02d02083 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 18 Mar 2020 11:55:56 -0500 Subject: [PATCH 004/314] Fixes for PyPy support --- cmake/FindCython.cmake | 22 ++++++++++++---------- cmake/FindPython.cmake | 18 ++++++------------ cmake/get_suffix.py | 7 +++++++ 3 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 cmake/get_suffix.py diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 8d9c47316..e474bbcbc 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -4,7 +4,8 @@ # This finds the "cython" executable in your PATH, and then in some standard # paths: -SET(CYTHON_BIN cython CACHE STRING "Cython executable name") + +find_program(CYTHON_BIN NAMES cython cython3 cython2) SET(CYTHON_FLAGS --cplus --fast-fail) SET(Cython_FOUND FALSE) @@ -27,21 +28,22 @@ ENDIF (CYTHON_BIN) IF (Cython_FOUND) - IF (NOT Cython_FIND_QUIETLY) - MESSAGE(STATUS "Found CYTHON: ${CYTHON_BIN}") - ENDIF (NOT Cython_FIND_QUIETLY) + IF (NOT Cython_FIND_QUIETLY) + MESSAGE(STATUS "Found CYTHON: ${CYTHON_BIN}") + ENDIF (NOT Cython_FIND_QUIETLY) ELSE (Cython_FOUND) - IF (Cython_FIND_REQUIRED) + IF (Cython_FIND_REQUIRED) if(Cython_Compilation_Failed) MESSAGE(STATUS "Found CYTHON: ${CYTHON_BIN}") - # On Win the testing of Cython does not return any accessible value, so the test is not carried out. Fresh Cython install was tested and works. - IF(NOT MSVC) - MESSAGE(FATAL_ERROR "Your Cython version is too old. Please upgrade Cython.") - ENDIF(NOT MSVC) + # On Win the testing of Cython does not return any accessible value, so the test is not carried out. + # Fresh Cython install was tested and works. + IF(NOT MSVC) + MESSAGE(FATAL_ERROR "Your Cython version is too old. Please upgrade Cython.") + ENDIF(NOT MSVC) else(Cython_Compilation_Failed) MESSAGE(FATAL_ERROR "Could not find Cython. Please install Cython.") endif(Cython_Compilation_Failed) - ENDIF (Cython_FIND_REQUIRED) + ENDIF (Cython_FIND_REQUIRED) ENDIF (Cython_FOUND) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index a74ef4ac0..f4f8dd99e 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -56,18 +56,12 @@ set(PYTHON_INSTALL_PATH ${PYTHON_INSTALL_PATH_tmp} CACHE BOOL "Python install path") message(STATUS "Python install path: ${PYTHON_INSTALL_PATH}") -if (NOT WIN32) - execute_process( - COMMAND ${PYTHON_BIN} -c "from distutils.sysconfig import get_config_var; print(get_config_var('SOABI'))" - OUTPUT_VARIABLE PYTHON_EXTENSION_SOABI_tmp - ) - string(STRIP ${PYTHON_EXTENSION_SOABI_tmp} PYTHON_EXTENSION_SOABI_tmp) - if (NOT "${PYTHON_EXTENSION_SOABI_tmp}" STREQUAL "None") - set(PYTHON_EXTENSION_SOABI_tmp ".${PYTHON_EXTENSION_SOABI_tmp}") - else() - set(PYTHON_EXTENSION_SOABI_tmp "") - endif() -endif() +execute_process( + COMMAND ${PYTHON_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/get_suffix.py + OUTPUT_VARIABLE PYTHON_EXTENSION_SOABI_tmp +) +string(STRIP ${PYTHON_EXTENSION_SOABI_tmp} PYTHON_EXTENSION_SOABI_tmp) + set(PYTHON_EXTENSION_SOABI ${PYTHON_EXTENSION_SOABI_tmp} CACHE STRING "Suffix for python extensions") diff --git a/cmake/get_suffix.py b/cmake/get_suffix.py new file mode 100644 index 000000000..4871c489f --- /dev/null +++ b/cmake/get_suffix.py @@ -0,0 +1,7 @@ +from __future__ import print_function +from distutils.sysconfig import get_config_var +extsuffix = get_config_var('EXT_SUFFIX') +if extsuffix is None: + print("") +else: + print(extsuffix[0:].rsplit(".", 1)[0]) From c0681b23602e96e276ef779fa589c93e1303fe0d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 18 Mar 2020 22:16:58 -0500 Subject: [PATCH 005/314] Skip a test on PyPy --- symengine/tests/test_symbol.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/symengine/tests/test_symbol.py b/symengine/tests/test_symbol.py index bd0243285..ad9d923b9 100644 --- a/symengine/tests/test_symbol.py +++ b/symengine/tests/test_symbol.py @@ -1,5 +1,7 @@ from symengine import Symbol, symbols, symarray, has_symbol, Dummy from symengine.utilities import raises +import unittest +import platform def test_symbol(): @@ -8,9 +10,6 @@ def test_symbol(): assert str(x) == "x" assert str(x) != "y" assert repr(x) == str(x) - # Verify the successful use of slots. - assert not hasattr(x, "__dict__") - assert not hasattr(x, "__weakref__") def test_symbols(): @@ -163,6 +162,17 @@ def test_dummy(): assert xdummy1 != xdummy2 assert Dummy() != Dummy() assert Dummy('x') != Dummy('x') + +# Cython cdef classes on PyPy has a __dict__ attribute always +# __slots__ on PyPy are useless anyways. https://stackoverflow.com/a/23077685/4768820 +@unittest.skipUnless(platform.python_implementation()=="CPython", "__slots__ are useless on PyPy") +def test_slots(): + x = Dummy('x') # Verify the successful use of slots. - assert not hasattr(xdummy1, "__dict__") - assert not hasattr(xdummy1, "__weakref__") + assert not hasattr(x, "__dict__") + assert not hasattr(x, "__weakref__") + + x1 = Symbol('x') + # Verify the successful use of slots. + assert not hasattr(x, "__dict__") + assert not hasattr(x, "__weakref__") From e5809ca3138618d60da5f7cad9a63d0e26af8d6c Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 03:35:12 -0400 Subject: [PATCH 006/314] test --- symengine/lib/symengine_wrapper.pyx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 387131dae..3b9227aaf 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -38,6 +38,12 @@ include "config.pxi" class SympifyError(Exception): pass +from cpython.pycapsule cimport PyCapsule_GetPointer + +def sympify_pycapsule(cap): + void *p = PyCapsule_GetPointer(cap, NULL) + return c2py(p) + cdef object c2py(rcp_const_basic o): cdef Basic r if (symengine.is_a_Add(deref(o))): From 6e8f0b315782cad5dc2e557d2cc213fabcb48761 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 03:57:18 -0400 Subject: [PATCH 007/314] test --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 3b9227aaf..7f410da00 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -40,7 +40,7 @@ class SympifyError(Exception): from cpython.pycapsule cimport PyCapsule_GetPointer -def sympify_pycapsule(cap): +cpdef object sympify_pycapsule(object cap): void *p = PyCapsule_GetPointer(cap, NULL) return c2py(p) From 427450f4e4d4b4df8676bf00ac91bbe0c5f2fd9d Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 04:00:10 -0400 Subject: [PATCH 008/314] test --- symengine/lib/symengine_wrapper.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 7f410da00..1312fc61e 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -41,7 +41,8 @@ class SympifyError(Exception): from cpython.pycapsule cimport PyCapsule_GetPointer cpdef object sympify_pycapsule(object cap): - void *p = PyCapsule_GetPointer(cap, NULL) + cdef void *p + p = PyCapsule_GetPointer(cap, NULL) return c2py(p) cdef object c2py(rcp_const_basic o): From fa59f4e0a7dddc2491bac3f9a2125093eb1b543b Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 05:29:19 -0400 Subject: [PATCH 009/314] Try basic_struct --- symengine/lib/symengine.pxd | 4 ++++ symengine/lib/symengine_wrapper.pyx | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 9806d25c1..0603d3b36 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -7,6 +7,10 @@ from libcpp.pair cimport pair include "config.pxi" +cdef extern from 'symengine/cwrapper.h': + ctypedef struct basic_struct: + pass + cdef extern from 'symengine/mp_class.h' namespace "SymEngine": ctypedef unsigned long mp_limb_t ctypedef struct __mpz_struct: diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1312fc61e..b96840ee8 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3,7 +3,7 @@ cimport symengine from symengine cimport (RCP, pair, map_basic_basic, umap_int_basic, umap_int_basic_iterator, umap_basic_num, umap_basic_num_iterator, rcp_const_basic, std_pair_short_rcp_const_basic, - rcp_const_seriescoeffinterface) + rcp_const_seriescoeffinterface, basic_struct) from libcpp cimport bool as cppbool from libcpp.string cimport string from libcpp.vector cimport vector @@ -41,8 +41,8 @@ class SympifyError(Exception): from cpython.pycapsule cimport PyCapsule_GetPointer cpdef object sympify_pycapsule(object cap): - cdef void *p - p = PyCapsule_GetPointer(cap, NULL) + cdef basic_struct *p + p = PyCapsule_GetPointer(cap, NULL) return c2py(p) cdef object c2py(rcp_const_basic o): From 291037a20143632e495770e5c6e35501dec1d5b6 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 21:33:13 -0400 Subject: [PATCH 010/314] Add ctypedef basic --- symengine/lib/symengine.pxd | 1 + 1 file changed, 1 insertion(+) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 0603d3b36..b2bfb8b3c 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -10,6 +10,7 @@ include "config.pxi" cdef extern from 'symengine/cwrapper.h': ctypedef struct basic_struct: pass + ctypedef basic_struct basic[1] cdef extern from 'symengine/mp_class.h' namespace "SymEngine": ctypedef unsigned long mp_limb_t From 6980586f43c467f875fb44b95109df4a632e072e Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 23:33:50 -0400 Subject: [PATCH 011/314] Use CRCPBasic --- symengine/lib/symengine.pxd | 6 +++--- symengine/lib/symengine_wrapper.pyx | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index b2bfb8b3c..e3dcc43f6 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -8,9 +8,9 @@ from libcpp.pair cimport pair include "config.pxi" cdef extern from 'symengine/cwrapper.h': - ctypedef struct basic_struct: - pass - ctypedef basic_struct basic[1] + ctypedef struct CRCPBasic: + rcp_const_basic m + ctypedef CRCPBasic basic[1] cdef extern from 'symengine/mp_class.h' namespace "SymEngine": ctypedef unsigned long mp_limb_t diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index b96840ee8..5aa48f69d 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3,7 +3,7 @@ cimport symengine from symengine cimport (RCP, pair, map_basic_basic, umap_int_basic, umap_int_basic_iterator, umap_basic_num, umap_basic_num_iterator, rcp_const_basic, std_pair_short_rcp_const_basic, - rcp_const_seriescoeffinterface, basic_struct) + rcp_const_seriescoeffinterface, CRCPBasic, basic) from libcpp cimport bool as cppbool from libcpp.string cimport string from libcpp.vector cimport vector @@ -41,9 +41,9 @@ class SympifyError(Exception): from cpython.pycapsule cimport PyCapsule_GetPointer cpdef object sympify_pycapsule(object cap): - cdef basic_struct *p - p = PyCapsule_GetPointer(cap, NULL) - return c2py(p) + cdef CRCPBasic *p + p = PyCapsule_GetPointer(cap, NULL) + return c2py(p.m) cdef object c2py(rcp_const_basic o): cdef Basic r From 7e3cbe9e062d900e06b41ab41b48fa9e186038f2 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 23:35:39 -0400 Subject: [PATCH 012/314] Change order --- symengine/lib/symengine.pxd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index e3dcc43f6..3564ed836 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -7,11 +7,6 @@ from libcpp.pair cimport pair include "config.pxi" -cdef extern from 'symengine/cwrapper.h': - ctypedef struct CRCPBasic: - rcp_const_basic m - ctypedef CRCPBasic basic[1] - cdef extern from 'symengine/mp_class.h' namespace "SymEngine": ctypedef unsigned long mp_limb_t ctypedef struct __mpz_struct: @@ -1069,3 +1064,8 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + + +cdef extern from 'symengine/cwrapper.h': + ctypedef struct CRCPBasic: + rcp_const_basic m + ctypedef CRCPBasic basic[1] From 9e947b2e3979a1e36ada605230a32870abcce350 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 23:46:59 -0400 Subject: [PATCH 013/314] Fix cdef --- symengine/lib/symengine.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 3564ed836..c01a52555 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -1066,6 +1066,6 @@ cdef extern from "" namespace "SymEngine": string latex(const Basic &x) nogil except + cdef extern from 'symengine/cwrapper.h': - ctypedef struct CRCPBasic: + cdef struct CRCPBasic: rcp_const_basic m ctypedef CRCPBasic basic[1] From 1eb85d324c297fc052e867c8564ac192ff8a23ca Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Sun, 3 May 2020 23:47:59 -0400 Subject: [PATCH 014/314] redef --- symengine/lib/symengine.pxd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index c01a52555..bc897bf98 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -1065,7 +1065,8 @@ cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + +cdef struct CRCPBasic: + rcp_const_basic m + cdef extern from 'symengine/cwrapper.h': - cdef struct CRCPBasic: - rcp_const_basic m ctypedef CRCPBasic basic[1] From 0fbf6f6d6ee304059054646dd0110bf2b7e8f981 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 01:03:16 -0400 Subject: [PATCH 015/314] Add assign_to_pycapsule --- symengine/lib/symengine_wrapper.pyx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 5aa48f69d..1a3cb8867 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -45,6 +45,11 @@ cpdef object sympify_pycapsule(object cap): p = PyCapsule_GetPointer(cap, NULL) return c2py(p.m) +cpdef void assign_to_pycapsule(object x, object value): + cdef CRCPBasic *p_x + p_x = PyCapsule_GetPointer(cap, NULL) + p_x.m = sympify(value).thisptr + cdef object c2py(rcp_const_basic o): cdef Basic r if (symengine.is_a_Add(deref(o))): From 5f3aa3c060fab9972aa2c236d72a5cbc7335db50 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 01:08:20 -0400 Subject: [PATCH 016/314] Fix variable name --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1a3cb8867..da7f40187 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -47,7 +47,7 @@ cpdef object sympify_pycapsule(object cap): cpdef void assign_to_pycapsule(object x, object value): cdef CRCPBasic *p_x - p_x = PyCapsule_GetPointer(cap, NULL) + p_x = PyCapsule_GetPointer(x, NULL) p_x.m = sympify(value).thisptr cdef object c2py(rcp_const_basic o): From 160f63ccc4eb8fb1d9e03d32601a65a1874a2cbe Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 01:21:10 -0400 Subject: [PATCH 017/314] Test --- symengine/lib/symengine_wrapper.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index da7f40187..e9d4b34aa 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -47,8 +47,10 @@ cpdef object sympify_pycapsule(object cap): cpdef void assign_to_pycapsule(object x, object value): cdef CRCPBasic *p_x + cdef rcp_const_basic v p_x = PyCapsule_GetPointer(x, NULL) - p_x.m = sympify(value).thisptr + v = sympify(value).thisptr + p_x.m = v cdef object c2py(rcp_const_basic o): cdef Basic r From 9caa812fb04f86792437f31bf803544a3db5cc95 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 01:31:53 -0400 Subject: [PATCH 018/314] test --- symengine/lib/symengine_wrapper.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index e9d4b34aa..4602fd732 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -46,11 +46,9 @@ cpdef object sympify_pycapsule(object cap): return c2py(p.m) cpdef void assign_to_pycapsule(object x, object value): - cdef CRCPBasic *p_x - cdef rcp_const_basic v - p_x = PyCapsule_GetPointer(x, NULL) - v = sympify(value).thisptr - p_x.m = v + cdef CRCPBasic *p_x = PyCapsule_GetPointer(x, NULL) + cdef Basic v = sympify(value) + p_x.m = v.thisptr cdef object c2py(rcp_const_basic o): cdef Basic r From c1fac94424d73919edffb841a7167c0ff68f2d80 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 02:31:50 -0400 Subject: [PATCH 019/314] Tweak --- symengine/lib/symengine.pxd | 4 +--- symengine/lib/symengine_wrapper.pyx | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index bc897bf98..19c8608e7 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -1065,8 +1065,6 @@ cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + +## Defined in 'symengine/cwrapper.cpp' cdef struct CRCPBasic: rcp_const_basic m - -cdef extern from 'symengine/cwrapper.h': - ctypedef CRCPBasic basic[1] diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4602fd732..013394967 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3,7 +3,7 @@ cimport symengine from symengine cimport (RCP, pair, map_basic_basic, umap_int_basic, umap_int_basic_iterator, umap_basic_num, umap_basic_num_iterator, rcp_const_basic, std_pair_short_rcp_const_basic, - rcp_const_seriescoeffinterface, CRCPBasic, basic) + rcp_const_seriescoeffinterface, CRCPBasic) from libcpp cimport bool as cppbool from libcpp.string cimport string from libcpp.vector cimport vector @@ -20,6 +20,7 @@ import warnings from symengine.compatibility import is_sequence import os import sys +from cpython.pycapsule cimport PyCapsule_GetPointer if sys.version_info[0] == 2: from collections import MutableMapping @@ -38,11 +39,8 @@ include "config.pxi" class SympifyError(Exception): pass -from cpython.pycapsule cimport PyCapsule_GetPointer - cpdef object sympify_pycapsule(object cap): - cdef CRCPBasic *p - p = PyCapsule_GetPointer(cap, NULL) + cdef CRCPBasic *p = PyCapsule_GetPointer(cap, NULL) return c2py(p.m) cpdef void assign_to_pycapsule(object x, object value): From cbf1b9bcfd32c2fabf07f9e8c82e3f775b243f0d Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 13:24:58 -0400 Subject: [PATCH 020/314] Rename --- symengine/lib/symengine_wrapper.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 013394967..47f4a6195 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -39,14 +39,14 @@ include "config.pxi" class SympifyError(Exception): pass -cpdef object sympify_pycapsule(object cap): - cdef CRCPBasic *p = PyCapsule_GetPointer(cap, NULL) +cpdef object capsule_to_basic(object capsule): + cdef CRCPBasic *p = PyCapsule_GetPointer(capsule, NULL) return c2py(p.m) -cpdef void assign_to_pycapsule(object x, object value): - cdef CRCPBasic *p_x = PyCapsule_GetPointer(x, NULL) - cdef Basic v = sympify(value) - p_x.m = v.thisptr +cpdef void basic_to_capsule(object capsule, object basic): + cdef CRCPBasic *p_cap = PyCapsule_GetPointer(capsule, NULL) + cdef Basic v = sympify(basic) + p_cap.m = v.thisptr cdef object c2py(rcp_const_basic o): cdef Basic r From 3e9ad779bc0e3ef5a8f606a58df554b4a9bb8417 Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 23:32:43 -0400 Subject: [PATCH 021/314] Use name assign_to_capsule --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 47f4a6195..a57780108 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -43,7 +43,7 @@ cpdef object capsule_to_basic(object capsule): cdef CRCPBasic *p = PyCapsule_GetPointer(capsule, NULL) return c2py(p.m) -cpdef void basic_to_capsule(object capsule, object basic): +cpdef void assign_to_capsule(object capsule, object basic): cdef CRCPBasic *p_cap = PyCapsule_GetPointer(capsule, NULL) cdef Basic v = sympify(basic) p_cap.m = v.thisptr From d4115b15ed84c106f76e8736de9561b3fa1f1abb Mon Sep 17 00:00:00 2001 From: Jialin Ma Date: Mon, 4 May 2020 23:36:48 -0400 Subject: [PATCH 022/314] Argument name basic -> value --- symengine/lib/symengine_wrapper.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index a57780108..f5cd0e25e 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -43,9 +43,9 @@ cpdef object capsule_to_basic(object capsule): cdef CRCPBasic *p = PyCapsule_GetPointer(capsule, NULL) return c2py(p.m) -cpdef void assign_to_capsule(object capsule, object basic): +cpdef void assign_to_capsule(object capsule, object value): cdef CRCPBasic *p_cap = PyCapsule_GetPointer(capsule, NULL) - cdef Basic v = sympify(basic) + cdef Basic v = sympify(value) p_cap.m = v.thisptr cdef object c2py(rcp_const_basic o): From 417abec4550af26c5d9acebd763cf597bcd5287f Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 12:17:50 +0100 Subject: [PATCH 023/314] Add Reals --- symengine/__init__.py | 2 +- symengine/lib/symengine.pxd | 4 ++++ symengine/lib/symengine_wrapper.pyx | 22 ++++++++++++++++++++++ symengine/tests/test_sets.py | 8 +++++++- symengine/tests/test_sympy_conv.py | 5 ++++- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 78546e962..2698d4f6e 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -12,7 +12,7 @@ LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le, Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet, - EmptySet, linsolve, + EmptySet, Reals, linsolve, FunctionSymbol as AppliedUndef, golden_ratio as GoldenRatio, catalan as Catalan, diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 19c8608e7..679190f4e 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -301,6 +301,7 @@ cdef extern from "" namespace "SymEngine": bool is_a_Conjugate "SymEngine::is_a"(const Basic &b) nogil bool is_a_Interval "SymEngine::is_a"(const Basic &b) nogil bool is_a_EmptySet "SymEngine::is_a"(const Basic &b) nogil + bool is_a_Reals "SymEngine::is_a"(const Basic &b) nogil bool is_a_UniversalSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_FiniteSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_Union "SymEngine::is_a"(const Basic &b) nogil @@ -1032,6 +1033,8 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass EmptySet(Set): pass + cdef cppclass Reals(Set): + pass cdef cppclass UniversalSet(Set): pass cdef cppclass FiniteSet(Set): @@ -1047,6 +1050,7 @@ cdef extern from "" namespace "SymEngine": ctypedef set[RCP[Set], RCPBasicKeyLess] set_set "SymEngine::set_set" cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except + cdef RCP[const EmptySet] emptyset() nogil except + + cdef RCP[const Reals] reals() nogil except + cdef RCP[const UniversalSet] universalset() nogil except + cdef RCP[const Set] finiteset(set_basic &container) nogil except + cdef RCP[const Set] set_union(set_set &a) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index f5cd0e25e..20e776a3e 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -235,6 +235,8 @@ cdef object c2py(rcp_const_basic o): r = Set.__new__(Interval) elif (symengine.is_a_EmptySet(deref(o))): r = Set.__new__(EmptySet) + elif (symengine.is_a_Reals(deref(o))): + r = Set.__new__(Reals) elif (symengine.is_a_UniversalSet(deref(o))): r = Set.__new__(UniversalSet) elif (symengine.is_a_FiniteSet(deref(o))): @@ -447,6 +449,8 @@ def sympy2symengine(a, raise_error=False): return interval(*(a.args)) elif a is sympy.S.EmptySet: return emptyset() + elif a is sympy.S.Reals: + return reals() elif a is sympy.S.UniversalSet: return universalset() elif isinstance(a, sympy.FiniteSet): @@ -2962,6 +2966,20 @@ class EmptySet(Set): return self.__class__ +class Reals(Set): + + def __new__(self): + return reals() + + def _sympy_(self): + import sympy + return sympy.S.Reals + + @property + def func(self): + return self.__class__ + + class UniversalSet(Set): def __new__(self): @@ -5050,6 +5068,10 @@ def universalset(): return c2py((symengine.universalset())) +def reals(): + return c2py((symengine.reals())) + + def finiteset(*args): cdef symengine.set_basic s cdef Basic e_ diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index 8260ae42d..38533dd51 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -1,6 +1,6 @@ from symengine.utilities import raises from symengine.lib.symengine_wrapper import (Interval, EmptySet, UniversalSet, - FiniteSet, Union, Complement, ImageSet, ConditionSet, + FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, And, Or, oo, Symbol, true, Ge, Eq, Gt) @@ -32,6 +32,12 @@ def test_UniversalSet(): assert U.contains(0) == true +def test_Reals(): + R = Reals() + assert R.union(Interval(2, 4)) == R + assert R.contains(0) == true + + def test_FiniteSet(): x = Symbol("x") A = FiniteSet(1, 2, 3) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 6dfdc6442..ea514d580 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -9,7 +9,7 @@ KroneckerDelta, LeviCivita, erf, erfc, lowergamma, uppergamma, loggamma, beta, polygamma, sign, floor, ceiling, conjugate, And, Or, Not, Xor, Piecewise, Interval, EmptySet, FiniteSet, Contains, - Union, Complement, UniversalSet) + Union, Complement, UniversalSet, Reals) import unittest # Note: We test _sympy_() for SymEngine -> SymPy conversion, as those are @@ -718,6 +718,9 @@ def test_sets(): assert sympify(sympy.S.UniversalSet) == UniversalSet() assert sympy.S.UniversalSet == UniversalSet()._sympy_() + assert sympify(sympy.S.Reals) == Reals() + assert sympy.S.Reals == Reals()._sympy_() + assert FiniteSet(x, y) == FiniteSet(x1, y1) assert FiniteSet(x1, y) == FiniteSet(x1, y1) assert FiniteSet(x, y)._sympy_() == sympy.FiniteSet(x1, y1) From 5dbf1009ddf6f69a22d5dec67c19d143322efa9a Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 12:21:50 +0100 Subject: [PATCH 024/314] Add UniversalSet to Symengine module --- symengine/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 2698d4f6e..f16ea7655 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -12,7 +12,7 @@ LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le, Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet, - EmptySet, Reals, linsolve, + EmptySet, UniversalSet, Reals, linsolve, FunctionSymbol as AppliedUndef, golden_ratio as GoldenRatio, catalan as Catalan, From c51dba0660bac8d18039088c8357906b47e1d29e Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 12:30:06 +0100 Subject: [PATCH 025/314] Add Integers --- symengine/__init__.py | 2 +- symengine/lib/symengine.pxd | 4 ++++ symengine/lib/symengine_wrapper.pyx | 22 ++++++++++++++++++++++ symengine/tests/test_sets.py | 8 +++++++- symengine/tests/test_sympy_conv.py | 5 ++++- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index f16ea7655..1aed1cd2b 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -12,7 +12,7 @@ LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le, Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet, - EmptySet, UniversalSet, Reals, linsolve, + EmptySet, UniversalSet, Reals, Integers, linsolve, FunctionSymbol as AppliedUndef, golden_ratio as GoldenRatio, catalan as Catalan, diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 679190f4e..9071298fe 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -302,6 +302,7 @@ cdef extern from "" namespace "SymEngine": bool is_a_Interval "SymEngine::is_a"(const Basic &b) nogil bool is_a_EmptySet "SymEngine::is_a"(const Basic &b) nogil bool is_a_Reals "SymEngine::is_a"(const Basic &b) nogil + bool is_a_Integers "SymEngine::is_a"(const Basic &b) nogil bool is_a_UniversalSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_FiniteSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_Union "SymEngine::is_a"(const Basic &b) nogil @@ -1035,6 +1036,8 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass Reals(Set): pass + cdef cppclass Integers(Set): + pass cdef cppclass UniversalSet(Set): pass cdef cppclass FiniteSet(Set): @@ -1051,6 +1054,7 @@ cdef extern from "" namespace "SymEngine": cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except + cdef RCP[const EmptySet] emptyset() nogil except + cdef RCP[const Reals] reals() nogil except + + cdef RCP[const Integers] integers() nogil except + cdef RCP[const UniversalSet] universalset() nogil except + cdef RCP[const Set] finiteset(set_basic &container) nogil except + cdef RCP[const Set] set_union(set_set &a) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 20e776a3e..7c8013365 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -237,6 +237,8 @@ cdef object c2py(rcp_const_basic o): r = Set.__new__(EmptySet) elif (symengine.is_a_Reals(deref(o))): r = Set.__new__(Reals) + elif (symengine.is_a_Integers(deref(o))): + r = Set.__new__(Integers) elif (symengine.is_a_UniversalSet(deref(o))): r = Set.__new__(UniversalSet) elif (symengine.is_a_FiniteSet(deref(o))): @@ -451,6 +453,8 @@ def sympy2symengine(a, raise_error=False): return emptyset() elif a is sympy.S.Reals: return reals() + elif a is sympy.S.Integers: + return integers() elif a is sympy.S.UniversalSet: return universalset() elif isinstance(a, sympy.FiniteSet): @@ -2980,6 +2984,20 @@ class Reals(Set): return self.__class__ +class Integers(Set): + + def __new__(self): + return integers() + + def _sympy_(self): + import sympy + return sympy.S.Integers + + @property + def func(self): + return self.__class__ + + class UniversalSet(Set): def __new__(self): @@ -5072,6 +5090,10 @@ def reals(): return c2py((symengine.reals())) +def integers(): + return c2py((symengine.integers())) + + def finiteset(*args): cdef symengine.set_basic s cdef Basic e_ diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index 38533dd51..d7bccb5be 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -1,6 +1,6 @@ from symengine.utilities import raises from symengine.lib.symengine_wrapper import (Interval, EmptySet, UniversalSet, - FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, + FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, Integers, And, Or, oo, Symbol, true, Ge, Eq, Gt) @@ -38,6 +38,12 @@ def test_Reals(): assert R.contains(0) == true +def test_Reals(): + Z = Integers() + assert Z.union(Interval(2, 4)) == Z + assert Z.contains(0) == true + + def test_FiniteSet(): x = Symbol("x") A = FiniteSet(1, 2, 3) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index ea514d580..9015cda14 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -9,7 +9,7 @@ KroneckerDelta, LeviCivita, erf, erfc, lowergamma, uppergamma, loggamma, beta, polygamma, sign, floor, ceiling, conjugate, And, Or, Not, Xor, Piecewise, Interval, EmptySet, FiniteSet, Contains, - Union, Complement, UniversalSet, Reals) + Union, Complement, UniversalSet, Reals, Integers) import unittest # Note: We test _sympy_() for SymEngine -> SymPy conversion, as those are @@ -721,6 +721,9 @@ def test_sets(): assert sympify(sympy.S.Reals) == Reals() assert sympy.S.Reals == Reals()._sympy_() + assert sympify(sympy.S.Integers) == Integers() + assert sympy.S.Integers == Integers()._sympy_() + assert FiniteSet(x, y) == FiniteSet(x1, y1) assert FiniteSet(x1, y) == FiniteSet(x1, y1) assert FiniteSet(x, y)._sympy_() == sympy.FiniteSet(x1, y1) From 28b4678999d45aefcc109758a369ab1e661cb27a Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 13:10:50 +0100 Subject: [PATCH 026/314] Update symengine version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 063fc9d99..761d3b5d4 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -fbd501264a86b7452ec35bb0370fbabc6d83b5c6 +46090cfd20b92e73b6ddd8c203e3173b106adabb From 014d0037767e14364a96c75e5402f4f408eda013 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 14:38:39 +0100 Subject: [PATCH 027/314] Fix test issues for Real --- symengine/lib/symengine_wrapper.pyx | 8 ++++---- symengine/tests/test_sets.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 7c8013365..c4d050a88 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -447,14 +447,14 @@ def sympy2symengine(a, raise_error=False): return function_symbol(name, *(a.args)) elif isinstance(a, (sympy.Piecewise)): return piecewise(*(a.args)) - elif isinstance(a, sympy.Interval): - return interval(*(a.args)) - elif a is sympy.S.EmptySet: - return emptyset() elif a is sympy.S.Reals: return reals() elif a is sympy.S.Integers: return integers() + elif isinstance(a, sympy.Interval): + return interval(*(a.args)) + elif a is sympy.S.EmptySet: + return emptyset() elif a is sympy.S.UniversalSet: return universalset() elif isinstance(a, sympy.FiniteSet): diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index d7bccb5be..c36f63e72 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -40,7 +40,7 @@ def test_Reals(): def test_Reals(): Z = Integers() - assert Z.union(Interval(2, 4)) == Z + assert Z.union(FiniteSet(2, 4)) == Z assert Z.contains(0) == true From b88d58b12710d2dfbb9ce6720f72c38662425286 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 21:47:52 +0100 Subject: [PATCH 028/314] Add elementwise_mul_matrix matrix method --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 6 ++++++ symengine/tests/test_matrices.py | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 9071298fe..9123ad2a7 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -783,6 +783,7 @@ cdef extern from "" namespace "SymEngine": void inv(MatrixBase &) void add_matrix(const MatrixBase &other, MatrixBase &result) nogil void mul_matrix(const MatrixBase &other, MatrixBase &result) nogil + void elementwise_mul_matrix(const MatrixBase &other, MatrixBase &result) nogil void add_scalar(rcp_const_basic k, MatrixBase &result) nogil void mul_scalar(rcp_const_basic k, MatrixBase &result) nogil void transpose(MatrixBase &result) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c4d050a88..54bc85ce4 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3523,6 +3523,12 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).mul_matrix(deref(A_.thisptr), deref(result.thisptr)) return result + def elementwise_mul_matrix(self, A): + cdef MatrixBase A_ = sympify(A) + cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) + deref(self.thisptr).elementwise_mul_matrix(deref(A_.thisptr), deref(result.thisptr)) + return result + def add_scalar(self, k): cdef Basic k_ = sympify(k) cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 375fbef84..daeaf6b6e 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -238,6 +238,13 @@ def test_mul_matrix(): raises(ShapeError, lambda: A*D) +def test_elementwise_mul_matrix(): + A = DenseMatrix(2, 2, [1, 2, 3, 4]) + B = DenseMatrix(2, 2, [1, 0, 0, 1]) + + assert A.elementwise_mul_matrix(B) == DenseMatrix(2, 2, [1, 0, 0, 4]) + + def test_add_scalar(): A = DenseMatrix(2, 2, [1, 2, 3, 4]) From 5f7ec1374c892cf3a1396299b5c647bedf510a73 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 21:56:07 +0100 Subject: [PATCH 029/314] Add conjugate matrix method --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 6 ++++++ symengine/tests/test_matrices.py | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 9123ad2a7..e3e888e05 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -784,6 +784,7 @@ cdef extern from "" namespace "SymEngine": void add_matrix(const MatrixBase &other, MatrixBase &result) nogil void mul_matrix(const MatrixBase &other, MatrixBase &result) nogil void elementwise_mul_matrix(const MatrixBase &other, MatrixBase &result) nogil + void conjugate(MatrixBase &result) nogil void add_scalar(rcp_const_basic k, MatrixBase &result) nogil void mul_scalar(rcp_const_basic k, MatrixBase &result) nogil void transpose(MatrixBase &result) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 54bc85ce4..762ea4018 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3546,6 +3546,12 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).transpose(deref(result.thisptr)) return result + def conjugate(self): + cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) + deref(self.thisptr).conjugate(deref(result.thisptr)) + return result + + @property def T(self): return self.transpose() diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index daeaf6b6e..29d36834e 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -311,6 +311,11 @@ def test_transpose(): assert A.transpose() == A +def test_conjugate(): + A = DenseMatrix(2, 2, [1, 2, 3, I]) + assert A.conjugate() == DenseMatrix(2, 2, [1, 2, 3, -I]) + + def test_LU(): A = DenseMatrix(3, 3, [1, 3, 5, 2, 5, 6, 8, 3, 1]) L, U = A.LU() From 8828cc73de8758dcb6c02d9d35a5c3d76fe20143 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 22:00:00 +0100 Subject: [PATCH 030/314] Add conjugate_transpose matrix method --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 6 ++++++ symengine/tests/test_matrices.py | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index e3e888e05..641e5c6e3 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -785,6 +785,7 @@ cdef extern from "" namespace "SymEngine": void mul_matrix(const MatrixBase &other, MatrixBase &result) nogil void elementwise_mul_matrix(const MatrixBase &other, MatrixBase &result) nogil void conjugate(MatrixBase &result) nogil + void conjugate_transpose(MatrixBase &result) nogil void add_scalar(rcp_const_basic k, MatrixBase &result) nogil void mul_scalar(rcp_const_basic k, MatrixBase &result) nogil void transpose(MatrixBase &result) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 762ea4018..8733f26b3 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3551,6 +3551,12 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).conjugate(deref(result.thisptr)) return result + def conjugate_transpose(self): + cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) + deref(self.thisptr).conjugate_transpose(deref(result.thisptr)) + return result + + @property def T(self): diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 29d36834e..96311be70 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -316,6 +316,11 @@ def test_conjugate(): assert A.conjugate() == DenseMatrix(2, 2, [1, 2, 3, -I]) +def test_conjugate_transpose(): + A = DenseMatrix(2, 2, [1, 2, 3, I]) + assert A.conjugate_transpose() == DenseMatrix(2, 2, [1, 3, 2, -I]) + + def test_LU(): A = DenseMatrix(3, 3, [1, 3, 5, 2, 5, 6, 8, 3, 1]) L, U = A.LU() From d28465112b20ace266ce2de7bb98c3f069c01f74 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 28 Oct 2020 22:05:49 +0100 Subject: [PATCH 031/314] Use symengine native is_square --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 641e5c6e3..7672ca686 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -781,6 +781,7 @@ cdef extern from "" namespace "SymEngine": bool eq(const MatrixBase &) nogil rcp_const_basic det() nogil void inv(MatrixBase &) + bool is_square() nogil void add_matrix(const MatrixBase &other, MatrixBase &result) nogil void mul_matrix(const MatrixBase &other, MatrixBase &result) nogil void elementwise_mul_matrix(const MatrixBase &other, MatrixBase &result) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 8733f26b3..4e72a5cdb 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3417,7 +3417,7 @@ cdef class DenseMatrixBase(MatrixBase): @property def is_square(self): - return self.rows == self.cols + return deref(self.thisptr).is_square() def nrows(self): return deref(self.thisptr).nrows() From 96337a73eb2385e66a4e5787263c353fc0e162b2 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Tue, 17 Nov 2020 22:08:19 +0100 Subject: [PATCH 032/314] Add is_zero property for Basic --- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 21 +++++++++++++++++---- symengine/tests/test_number.py | 6 +++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 7672ca686..ed80f9459 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -347,6 +347,7 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass NumberWrapper(Basic): pass + cdef int is_zero(const Basic &x) nogil cdef extern from "pywrapper.h" namespace "SymEngine": cdef cppclass PyNumber(NumberWrapper): diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4e72a5cdb..cc6217cce 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1052,6 +1052,10 @@ cdef class Basic(object): def is_Matrix(self): return False + @property + def is_zero(self): + return is_zero(self) + def copy(self): return self @@ -1583,10 +1587,6 @@ cdef class Number(Expr): def is_negative(Basic self): return deref(symengine.rcp_static_cast_Number(self.thisptr)).is_negative() - @property - def is_zero(Basic self): - return deref(symengine.rcp_static_cast_Number(self.thisptr)).is_zero() - @property def is_nonzero(self): return not (self.is_complex or self.is_zero) @@ -5128,6 +5128,19 @@ def contains(expr, sset): return c2py((symengine.contains(expr_.thisptr, s))) +def tribool(value): + if value == -1: + return None + else: + return bool(value) + + +def is_zero(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_zero(deref(expr_.thisptr)) + return tribool(tbool) + + def set_union(*args): cdef symengine.set_set s cdef Set e_ diff --git a/symengine/tests/test_number.py b/symengine/tests/test_number.py index 40649b005..de965666d 100644 --- a/symengine/tests/test_number.py +++ b/symengine/tests/test_number.py @@ -1,6 +1,6 @@ from symengine.utilities import raises -from symengine import Integer, I, S, pi +from symengine import Integer, I, S, Symbol, pi from symengine.lib.symengine_wrapper import (perfect_power, is_square, integer_nthroot) @@ -151,3 +151,7 @@ def test_integer_nthroot(): assert integer_nthroot(c2, 2) == (c, True) assert integer_nthroot(c2 + 1, 2) == (c, False) assert integer_nthroot(c2 - 1, 2) == (c - 1, False) + + +def test_is_zero(): + assert Symbol('x').is_zero is None From 7f5d4009d321b54b346fb940e32cd91fe363ca82 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 18 Nov 2020 21:02:55 +0100 Subject: [PATCH 033/314] Rename elementwise_mul_matrix method to multiply_elementwise --- symengine/lib/symengine_wrapper.pyx | 2 +- symengine/tests/test_matrices.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index cc6217cce..59b4835e6 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3523,7 +3523,7 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).mul_matrix(deref(A_.thisptr), deref(result.thisptr)) return result - def elementwise_mul_matrix(self, A): + def multiply_elementwise(self, A): cdef MatrixBase A_ = sympify(A) cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) deref(self.thisptr).elementwise_mul_matrix(deref(A_.thisptr), deref(result.thisptr)) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 96311be70..621becc0d 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -238,11 +238,11 @@ def test_mul_matrix(): raises(ShapeError, lambda: A*D) -def test_elementwise_mul_matrix(): +def test_multiply_elementwise(): A = DenseMatrix(2, 2, [1, 2, 3, 4]) B = DenseMatrix(2, 2, [1, 0, 0, 1]) - assert A.elementwise_mul_matrix(B) == DenseMatrix(2, 2, [1, 0, 0, 4]) + assert A.multiply_elementwise(B) == DenseMatrix(2, 2, [1, 0, 0, 4]) def test_add_scalar(): From e03223e7fa3444f8db748509d64705c22bb77e83 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Thu, 19 Nov 2020 08:36:51 +0100 Subject: [PATCH 034/314] Add matrix property H for conjugate_transpose Co-authored-by: Isuru Fernando --- symengine/lib/symengine_wrapper.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 59b4835e6..01d62cff1 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3556,7 +3556,9 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).conjugate_transpose(deref(result.thisptr)) return result - + @property + def H(self): + return self.conjugate_transpose() @property def T(self): From 08afb47bc3ac39c9c0a2e4eb7158e26dd637f451 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sat, 21 Nov 2020 14:50:41 +0100 Subject: [PATCH 035/314] Put EmptySet, UniversalSet, Reals and Integers in Singleton --- symengine/lib/symengine_wrapper.pyx | 30 +++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 01d62cff1..2e48a54f5 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -448,15 +448,15 @@ def sympy2symengine(a, raise_error=False): elif isinstance(a, (sympy.Piecewise)): return piecewise(*(a.args)) elif a is sympy.S.Reals: - return reals() + return S.Reals elif a is sympy.S.Integers: - return integers() + return S.Integers elif isinstance(a, sympy.Interval): return interval(*(a.args)) elif a is sympy.S.EmptySet: - return emptyset() + return S.EmptySet elif a is sympy.S.UniversalSet: - return universalset() + return S.UniversalSet elif isinstance(a, sympy.FiniteSet): return finiteset(*(a.args)) elif isinstance(a, sympy.Contains): @@ -657,6 +657,22 @@ class Singleton(object): def false(self): return false + @property + def EmptySet(self): + return empty_set_singleton + + @property + def UniversalSet(self): + return universal_set_singleton + + @property + def Integers(self): + return integers_singleton + + @property + def Reals(self): + return reals_singleton + S = Singleton() @@ -5192,6 +5208,12 @@ def imageset(sym, expr, base): return c2py((symengine.imageset(sym_.thisptr, expr_.thisptr, b))) +universal_set_singleton = UniversalSet() +integers_singleton = Integers() +reals_singleton = Reals() +empty_set_singleton = EmptySet() + + def solve(f, sym, domain=None): cdef Basic f_ = sympify(f) cdef Basic sym_ = sympify(sym) From d6fc03dc83115c21ef1459ef96cb24885f1957a2 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sun, 22 Nov 2020 09:52:51 +0100 Subject: [PATCH 036/314] Add tests for numbers and matrices and trace --- symengine/lib/symengine.pxd | 13 +++++ symengine/lib/symengine_wrapper.pyx | 81 +++++++++++++++++++++++++++++ symengine/tests/test_matrices.py | 64 +++++++++++++++++++++++ symengine/tests/test_number.py | 31 ++++++++++- symengine_version.txt | 2 +- 5 files changed, 189 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index ed80f9459..b6b009c2c 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -348,6 +348,11 @@ cdef extern from "" namespace "SymEngine": cdef cppclass NumberWrapper(Basic): pass cdef int is_zero(const Basic &x) nogil + cdef int is_positive(const Basic &x) nogil + cdef int is_negative(const Basic &x) nogil + cdef int is_nonnegative(const Basic &x) nogil + cdef int is_nonpositive(const Basic &x) nogil + cdef int is_real(const Basic &x) nogil cdef extern from "pywrapper.h" namespace "SymEngine": cdef cppclass PyNumber(NumberWrapper): @@ -814,6 +819,14 @@ cdef extern from "" namespace "SymEngine": void col_insert(const DenseMatrix &B, unsigned pos) nogil void row_del(unsigned k) nogil void col_del(unsigned k) nogil + rcp_const_basic trace() nogil + int is_zero() nogil + int is_real() nogil + int is_diagonal() nogil + int is_symmetric() nogil + int is_hermitian() nogil + int is_weakly_diagonally_dominant() nogil + int is_strictly_diagonally_dominant() nogil bool is_a_DenseMatrix "SymEngine::is_a"(const MatrixBase &b) nogil DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 2e48a54f5..d2075a2cc 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1072,6 +1072,26 @@ cdef class Basic(object): def is_zero(self): return is_zero(self) + @property + def is_positive(self): + return is_positive(self) + + @property + def is_negative(self): + return is_negative(self) + + @property + def is_nonpositive(self): + return is_nonpositive(self) + + @property + def is_nonnegative(self): + return is_nonnegative(self) + + @property + def is_real(self): + return is_real(self) + def copy(self): return self @@ -3576,6 +3596,37 @@ cdef class DenseMatrixBase(MatrixBase): def H(self): return self.conjugate_transpose() + def trace(self): + return c2py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).trace()) + + @property + def is_zero_matrix(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_zero()) + + @property + def is_real_matrix(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_real()) + + @property + def is_diagonal(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_diagonal()) + + @property + def is_symmetric(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_symmetric()) + + @property + def is_hermitian(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_hermitian()) + + @property + def is_weakly_diagonally_dominant(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_weakly_diagonally_dominant()) + + @property + def is_strongly_diagonally_dominant(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_strictly_diagonally_dominant()) + @property def T(self): return self.transpose() @@ -5159,6 +5210,36 @@ def is_zero(expr): return tribool(tbool) +def is_positive(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_positive(deref(expr_.thisptr)) + return tribool(tbool) + + +def is_negative(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_negative(deref(expr_.thisptr)) + return tribool(tbool) + + +def is_nonpositive(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_nonpositive(deref(expr_.thisptr)) + return tribool(tbool) + + +def is_nonnegative(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_nonnegative(deref(expr_.thisptr)) + return tribool(tbool) + + +def is_real(expr): + cdef Basic expr_ = sympify(expr) + cdef int tbool = symengine.is_real(deref(expr_.thisptr)) + return tribool(tbool) + + def set_union(*args): cdef symengine.set_set s cdef Set e_ diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 621becc0d..9e40658c9 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -321,6 +321,70 @@ def test_conjugate_transpose(): assert A.conjugate_transpose() == DenseMatrix(2, 2, [1, 3, 2, -I]) +def test_trace(): + A = DenseMatrix(2, 2, [1, 2, 3, 4]) + assert A.trace() == 5 + + +def test_is_zero_matrix(): + A = DenseMatrix(2, 2, [1, 2, 3, I]) + assert not A.is_zero_matrix + B = DenseMatrix(1, 1, [Symbol('x')]) + assert B.is_zero_matrix is None + C = DenseMatrix(3, 3, [0, 0, 0, 0, 0, 0, 0, 0, 0]) + assert C.is_zero_matrix + + +def test_is_real_matrix(): + A = DenseMatrix(2, 2, [1, 2, 3, I]) + assert not A.is_real_matrix + B = DenseMatrix(1, 1, [Symbol('x')]) + assert B.is_real_matrix is None + C = DenseMatrix(3, 3, [0, 0, 0, 0, 0, 0, 0, 0, 0]) + assert C.is_real_matrix + + +def test_is_diagonal(): + A = DenseMatrix(2, 2, [1, 0, 0, I]) + assert A.is_diagonal + B = DenseMatrix(1, 1, [Symbol('x')]) + assert B.is_diagonal + C = DenseMatrix(3, 3, [0, 0, 0, 0, 0, 0, 0, 2, 0]) + assert not C.is_diagonal + + +def test_is_symmetric(): + A = DenseMatrix(2, 2, [1, 3, 2, I]) + assert not A.is_symmetric + B = DenseMatrix(1, 1, [Symbol('x')]) + assert B.is_symmetric + C = DenseMatrix(3, 3, [0, 0, 0, 0, 0, 0, 0, 2, 0]) + assert not C.is_symmetric + + +def test_is_hermitian(): + A = DenseMatrix(2, 2, [1, 3, 2, I]) + assert not A.is_hermitian + B = DenseMatrix(1, 1, [Symbol('x')]) + assert B.is_hermitian is None + C = DenseMatrix(3, 3, [0, I, 0, 0, 0, 0, 0, 2, 0]) + assert not C.is_hermitian + + +def test_is_weakly_diagonally_dominant(): + A = DenseMatrix(2, 2, [2, 1, 1, 2]) + assert A.is_weakly_diagonally_dominant + C = DenseMatrix(3, 3, [Symbol('x'), 0, 0, 0, 3, 0, 0, 0, 4]) + assert C.is_weakly_diagonally_dominant is None + + +def test_is_strongly_diagonally_dominant(): + A = DenseMatrix(2, 2, [2, 1, 1, 2]) + assert A.is_strongly_diagonally_dominant + C = DenseMatrix(3, 3, [Symbol('x'), 2, 0, 0, 4, 0, 0, 0, 4]) + assert C.is_strongly_diagonally_dominant is None + + def test_LU(): A = DenseMatrix(3, 3, [1, 3, 5, 2, 5, 6, 8, 3, 1]) L, U = A.LU() diff --git a/symengine/tests/test_number.py b/symengine/tests/test_number.py index de965666d..0f3ca872f 100644 --- a/symengine/tests/test_number.py +++ b/symengine/tests/test_number.py @@ -1,6 +1,6 @@ from symengine.utilities import raises -from symengine import Integer, I, S, Symbol, pi +from symengine import Integer, I, S, Symbol, pi, Rational from symengine.lib.symengine_wrapper import (perfect_power, is_square, integer_nthroot) @@ -155,3 +155,32 @@ def test_integer_nthroot(): def test_is_zero(): assert Symbol('x').is_zero is None + + +def test_is_positive(): + assert Rational(1, 2).is_positive + assert not Rational(-2, 3).is_positive + assert Symbol('x').is_positive is None + + +def test_is_negative(): + assert not Rational(1, 2).is_negative + assert Rational(-2, 3).is_negative + assert Symbol('x').is_negative is None + + +def test_is_nonpositive(): + assert not Rational(1, 2).is_nonpositive + assert Rational(-2, 3).is_nonpositive + assert Symbol('x').is_nonpositive is None + + +def test_is_nonnegative(): + assert Rational(1, 2).is_nonnegative + assert not Rational(-2, 3).is_nonnegative + assert Symbol('x').is_nonnegative is None + + +def test_is_real(): + assert Rational(1, 2).is_real + assert Symbol('x').is_real is None diff --git a/symengine_version.txt b/symengine_version.txt index 761d3b5d4..e6b825d21 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -46090cfd20b92e73b6ddd8c203e3173b106adabb +44eb47e3bbfa7e06718f2f65f3f41a0a9d133b70 From a68f7fc95b4c39a480b09b79159372c58269e100 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Mon, 23 Nov 2020 21:58:27 +0100 Subject: [PATCH 037/314] Export singleton sets from S Co-authored-by: Isuru Fernando --- symengine/__init__.py | 17 ++++++++++++++++- symengine/tests/test_solve.py | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 1aed1cd2b..c8a26e26b 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -1,3 +1,5 @@ +import symengine.lib.symengine_wrapper as wrapper + from .lib.symengine_wrapper import ( have_mpfr, have_mpc, have_flint, have_piranha, have_llvm, have_llvm_long_double, I, E, pi, oo, zoo, nan, Symbol, Dummy, S, sympify, SympifyError, @@ -12,7 +14,7 @@ LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le, Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet, - EmptySet, UniversalSet, Reals, Integers, linsolve, + linsolve, FunctionSymbol as AppliedUndef, golden_ratio as GoldenRatio, catalan as Catalan, @@ -22,6 +24,13 @@ from .functions import * from .printing import init_printing + +EmptySet = wrapper.S.EmptySet +UniversalSet = wrapper.S.UniversalSet +Reals = wrapper.S.Reals +Integers = wrapper.S.Integers + + if have_mpfr: from .lib.symengine_wrapper import RealMPFR @@ -38,6 +47,12 @@ def lambdify(args, exprs, **kwargs): __version__ = "0.6.1" +# To not expose internals +del lib.symengine_wrapper +del lib +del wrapper + + def test(): import pytest import os diff --git a/symengine/tests/test_solve.py b/symengine/tests/test_solve.py index 8a1a65244..01eaaf04c 100644 --- a/symengine/tests/test_solve.py +++ b/symengine/tests/test_solve.py @@ -7,10 +7,10 @@ def test_solve(): x = Symbol("x") reals = Interval(-oo, oo) - assert solve(1, x, reals) == EmptySet() + assert solve(1, x, reals) == EmptySet assert solve(0, x, reals) == reals assert solve(x + 3, x, reals) == FiniteSet(-3) - assert solve(x + 3, x, Interval(0, oo)) == EmptySet() + assert solve(x + 3, x, Interval(0, oo)) == EmptySet assert solve(x, x, reals) == FiniteSet(0) assert solve(x**2 + 1, x) == FiniteSet(-I, I) assert solve(x**2 - 2*x + 1, x) == FiniteSet(1) From bca68422f72727114f9113db69e2d612f4df3f09 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Mon, 7 Dec 2020 22:02:09 +0100 Subject: [PATCH 038/314] Add is_positive_definite and is_negative_definite --- symengine/lib/symengine.pxd | 2 ++ symengine/lib/symengine_wrapper.pyx | 8 ++++++++ symengine/tests/test_matrices.py | 14 ++++++++++++++ symengine_version.txt | 2 +- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index b6b009c2c..a0727a988 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -827,6 +827,8 @@ cdef extern from "" namespace "SymEngine": int is_hermitian() nogil int is_weakly_diagonally_dominant() nogil int is_strictly_diagonally_dominant() nogil + int is_positive_definite() nogil + int is_negative_definite() nogil bool is_a_DenseMatrix "SymEngine::is_a"(const MatrixBase &b) nogil DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index d2075a2cc..f7f3a1d44 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3627,6 +3627,14 @@ cdef class DenseMatrixBase(MatrixBase): def is_strongly_diagonally_dominant(self): return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_strictly_diagonally_dominant()) + @property + def is_positive_definite(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_positive_definite()) + + @property + def is_negative_definite(self): + return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_negative_definite()) + @property def T(self): return self.transpose() diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 9e40658c9..6bba72137 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -385,6 +385,20 @@ def test_is_strongly_diagonally_dominant(): assert C.is_strongly_diagonally_dominant is None +def test_is_positive_definite(): + A = DenseMatrix(2, 2, [2, 1, 1, 2]) + assert A.is_positive_definite + C = DenseMatrix(3, 3, [Symbol('x'), 2, 0, 0, 4, 0, 0, 0, 4]) + assert C.is_positive_definite is None + + +def test_is_negative_definite(): + A = DenseMatrix(2, 2, [-2, -1, -1, -2]) + assert A.is_negative_definite + C = DenseMatrix(3, 3, [Symbol('x'), -2, 0, 0, -4, 0, 0, 0, -4]) + assert C.is_negative_definite is None + + def test_LU(): A = DenseMatrix(3, 3, [1, 3, 5, 2, 5, 6, 8, 3, 1]) L, U = A.LU() diff --git a/symengine_version.txt b/symengine_version.txt index e6b825d21..79a25bd25 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -44eb47e3bbfa7e06718f2f65f3f41a0a9d133b70 +41e9689c9ee4d383d09dcd0e352b46185d18c4f4 From e46379f187684e9a290657060ef1957ee4d64e3d Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Mon, 7 Dec 2020 22:09:54 +0100 Subject: [PATCH 039/314] Add Rationals --- symengine/__init__.py | 1 + symengine/lib/symengine.pxd | 4 ++++ symengine/lib/symengine_wrapper.pyx | 27 +++++++++++++++++++++++++++ symengine/tests/test_sets.py | 12 +++++++++--- symengine/tests/test_sympy_conv.py | 5 ++++- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index c8a26e26b..183651cd5 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -29,6 +29,7 @@ UniversalSet = wrapper.S.UniversalSet Reals = wrapper.S.Reals Integers = wrapper.S.Integers +Rationals = wrapper.S.Rationals if have_mpfr: diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index a0727a988..cce0068f7 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -302,6 +302,7 @@ cdef extern from "" namespace "SymEngine": bool is_a_Interval "SymEngine::is_a"(const Basic &b) nogil bool is_a_EmptySet "SymEngine::is_a"(const Basic &b) nogil bool is_a_Reals "SymEngine::is_a"(const Basic &b) nogil + bool is_a_Rationals "SymEngine::is_a"(const Basic &b) nogil bool is_a_Integers "SymEngine::is_a"(const Basic &b) nogil bool is_a_UniversalSet "SymEngine::is_a"(const Basic &b) nogil bool is_a_FiniteSet "SymEngine::is_a"(const Basic &b) nogil @@ -1056,6 +1057,8 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass Reals(Set): pass + cdef cppclass Rationals(Set): + pass cdef cppclass Integers(Set): pass cdef cppclass UniversalSet(Set): @@ -1074,6 +1077,7 @@ cdef extern from "" namespace "SymEngine": cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except + cdef RCP[const EmptySet] emptyset() nogil except + cdef RCP[const Reals] reals() nogil except + + cdef RCP[const Rationals] rationals() nogil except + cdef RCP[const Integers] integers() nogil except + cdef RCP[const UniversalSet] universalset() nogil except + cdef RCP[const Set] finiteset(set_basic &container) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index f7f3a1d44..26c1e3d5c 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -239,6 +239,8 @@ cdef object c2py(rcp_const_basic o): r = Set.__new__(Reals) elif (symengine.is_a_Integers(deref(o))): r = Set.__new__(Integers) + elif (symengine.is_a_Rationals(deref(o))): + r = Set.__new__(Rationals) elif (symengine.is_a_UniversalSet(deref(o))): r = Set.__new__(UniversalSet) elif (symengine.is_a_FiniteSet(deref(o))): @@ -451,6 +453,8 @@ def sympy2symengine(a, raise_error=False): return S.Reals elif a is sympy.S.Integers: return S.Integers + elif a is sympy.S.Rationals: + return S.Rationals elif isinstance(a, sympy.Interval): return interval(*(a.args)) elif a is sympy.S.EmptySet: @@ -669,6 +673,10 @@ class Singleton(object): def Integers(self): return integers_singleton + @property + def Rationals(self): + return rationals_singleton + @property def Reals(self): return reals_singleton @@ -3020,6 +3028,20 @@ class Reals(Set): return self.__class__ +class Rationals(Set): + + def __new__(self): + return rationals() + + def _sympy_(self): + import sympy + return sympy.S.Rationals + + @property + def func(self): + return self.__class__ + + class Integers(Set): def __new__(self): @@ -5185,6 +5207,10 @@ def reals(): return c2py((symengine.reals())) +def rationals(): + return c2py((symengine.rationals())) + + def integers(): return c2py((symengine.integers())) @@ -5299,6 +5325,7 @@ def imageset(sym, expr, base): universal_set_singleton = UniversalSet() integers_singleton = Integers() +rationals_singleton = Rationals() reals_singleton = Reals() empty_set_singleton = EmptySet() diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index c36f63e72..5ec8ce9e3 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -1,7 +1,7 @@ from symengine.utilities import raises from symengine.lib.symengine_wrapper import (Interval, EmptySet, UniversalSet, - FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, Integers, - And, Or, oo, Symbol, true, Ge, Eq, Gt) + FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, Rationals, + Integers, And, Or, oo, Symbol, true, Ge, Eq, Gt) def test_Interval(): @@ -38,7 +38,13 @@ def test_Reals(): assert R.contains(0) == true -def test_Reals(): +def test_Rationals(): + Q = Rationals() + assert Q.union(FiniteSet(2, 3)) == Q + assert Q.contains(0) == true + + +def test_Integers(): Z = Integers() assert Z.union(FiniteSet(2, 4)) == Z assert Z.contains(0) == true diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 9015cda14..0350784c9 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -9,7 +9,7 @@ KroneckerDelta, LeviCivita, erf, erfc, lowergamma, uppergamma, loggamma, beta, polygamma, sign, floor, ceiling, conjugate, And, Or, Not, Xor, Piecewise, Interval, EmptySet, FiniteSet, Contains, - Union, Complement, UniversalSet, Reals, Integers) + Union, Complement, UniversalSet, Reals, Rationals, Integers) import unittest # Note: We test _sympy_() for SymEngine -> SymPy conversion, as those are @@ -721,6 +721,9 @@ def test_sets(): assert sympify(sympy.S.Reals) == Reals() assert sympy.S.Reals == Reals()._sympy_() + assert sympify(sympy.S.Rationals) == Rationals() + assert sympy.S.Rationals == Rationals()._sympy_() + assert sympify(sympy.S.Integers) == Integers() assert sympy.S.Integers == Integers()._sympy_() From e72fcea665c1dd365d9f9317888de8b1e5d99149 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Tue, 26 Jan 2021 15:31:15 +0000 Subject: [PATCH 040/314] docs: Build scripts --- .gitignore | 5 +++ bin/install_travis.sh | 4 ++ docs/conf.py | 90 +++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 22 +++++++++++ 4 files changed, 121 insertions(+) create mode 100644 docs/conf.py create mode 100644 docs/index.rst diff --git a/.gitignore b/.gitignore index db4d60c66..fb54b321d 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,8 @@ symengine.egg-info/ # Temp files *~ .eggs/ + +# Docs +genDocs/ +docs/_build/ +docs/source/ diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 5b2bdf93f..02d105d54 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -16,6 +16,10 @@ if [[ "${WITH_SCIPY}" == "yes" ]]; then export conda_pkgs="${conda_pkgs} scipy"; fi +if [[ "${WITH_DOCS}" == "yes" ]]; then + export conda_pkgs="${conda_pkgs} sphinx recommonmark"; +fi + if [[ "${WITH_SAGE}" == "yes" ]]; then # This is split to avoid the 10 minute limit conda install -q sagelib=8.1 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..fd05636c3 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,90 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import os +import sys + +sys.path.insert(0, os.path.abspath("..")) + +import symengine + +# -- Project information ----------------------------------------------------- + +project = 'symengine' +copyright = '2021, SymEngine development team ' +author = 'SymEngine development team ' + +# The full version, including alpha/beta/rc tags +release = '0.6.1' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", # Consumes docstrings + "sphinx.ext.napoleon", # Allows for Google Style Docs + "sphinx.ext.viewcode", # Links to source code + "sphinx.ext.intersphinx", # Connects to other documentation + "sphinx.ext.todo", # Show TODO details + "sphinx.ext.imgconverter", # Handle svg images + "sphinx.ext.duration", # Shows times in the processing pipeline + "sphinx.ext.mathjax", # Need math support + "sphinx.ext.githubpages", # Puts the .nojekyll and CNAME files + "sphinxcontrib.apidoc", # Automatically sets up sphinx-apidoc + # "recommonmark", # Parses markdown + "m2r2", # Parses markdown in rst +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# API Doc settings +apidoc_module_dir = "../" +apidoc_output_dir = "source" +apidoc_excluded_paths = ["tests"] +apidoc_separate_modules = True + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_book_theme" +html_title = "Symengine Python Bindings" +# html_logo = "path/to/logo.png" +# html_favicon = "path/to/favicon.ico" +html_theme_options = { + "repository_url": "https://github.com/symengine/symengine.py", + "use_repository_button": True, + "use_issues_button": True, + "use_edit_page_button": True, + "path_to_docs": "docs", + "use_download_button": True, + "home_page_in_toc": True +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..9a47bd0a4 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +.. symengine documentation master file, created by + sphinx-quickstart on Tue Jan 26 09:42:30 2021. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Symengine Python API Documentation +=================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + source/modules + +.. mdinclude:: ../README.md + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From 8ea7f1a10143aa85f54debfdf2e33188a80c4581 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Tue, 2 Feb 2021 06:06:51 +0000 Subject: [PATCH 041/314] gha: Init documentation action --- .github/workflows/mkdocs.yaml | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/mkdocs.yaml diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml new file mode 100644 index 000000000..18f08952e --- /dev/null +++ b/.github/workflows/mkdocs.yaml @@ -0,0 +1,59 @@ +on: + push: + branches: + - main + - master + +name: Make Sphinx API Docs + +jobs: + mkdocs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build CPP Core + run: | + git clone https://github.com/symengine/symengine symengine-cpp + cd symengine-cpp + export SOURCE_DIR=`pwd` + git checkout `cat ../symengine_version.txt` + cd $SOURCE_DIR + source bin/install_travis.sh + cd $SOURCE_DIR + bin/test_travis.sh + env: + WITH_MPC: yes + WITH_MPFR: yes + WITH_FLINT: yes + WITH_SCIPY: yes + WITH_DOCS: yes + INTEGER_CLASS: flint + TEST_CPP: no + TEST_SYMPY: yes + MAKEFLAGS: -j2 + our_install_dir: $HOME/our_usr/ + - uses: s-weigand/setup-conda@v1 + - name: Build Bindings and Docs + run: | + export PYTHON_SOURCE_DIR=$GITHUB_WORKSPACE + cd $PYTHON_SOURCE_DIR + source bin/install_travis.sh + bin/test_travis.sh + pip install sphinx-autobuild m2r2 sphinxcontrib-apidoc sphinx-book-theme + sphinx-build docs/ genDocs/ + env: + WITH_MPC: yes + WITH_MPFR: yes + WITH_FLINT: yes + WITH_SCIPY: yes + WITH_DOCS: yes + INTEGER_CLASS: flint + TEST_CPP: no + TEST_SYMPY: yes + MAKEFLAGS: -j2 + our_install_dir: $HOME/our_usr/ + - name: Deploy Documentation + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./genDocs From a1dd147ea0f2c519bfdfbdc7991c482fe2dc1a56 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Tue, 2 Feb 2021 21:00:42 +0000 Subject: [PATCH 042/314] gha: Build always, deploy only for main or master --- .github/workflows/mkdocs.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml index 18f08952e..1d5cec520 100644 --- a/.github/workflows/mkdocs.yaml +++ b/.github/workflows/mkdocs.yaml @@ -1,8 +1,4 @@ -on: - push: - branches: - - main - - master +on: [push, pull_request] name: Make Sphinx API Docs @@ -53,6 +49,7 @@ jobs: MAKEFLAGS: -j2 our_install_dir: $HOME/our_usr/ - name: Deploy Documentation + if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }} uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} From a6cda095812ef5fc24f62a71192d9e3ce13fc254 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 14 Feb 2021 17:55:18 +0000 Subject: [PATCH 043/314] gha: Do not attempt deploys from PRs --- .github/workflows/mkdocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml index 1d5cec520..8848782b9 100644 --- a/.github/workflows/mkdocs.yaml +++ b/.github/workflows/mkdocs.yaml @@ -49,7 +49,7 @@ jobs: MAKEFLAGS: -j2 our_install_dir: $HOME/our_usr/ - name: Deploy Documentation - if: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }} + if: ${{ (github.ref == 'refs/heads/main' && github.repository == 'Symengine/symengine.py') || (github.ref == 'refs/heads/master' && github.repository == 'Symengine/symengine.py')}} uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} From 1e13e0b4a3f9fc6b86027d3cfa17d5a532f5381a Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Wed, 3 Mar 2021 16:32:00 +0000 Subject: [PATCH 044/314] docs: Fix warnings --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index d2075a2cc..e72b26f37 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4874,7 +4874,7 @@ cdef class LambdaDouble(_Lambdify): """ Returns a tuple with first element being a ctypes function with signature - void func(double * output, const double *input, void *user_data) + void func(double \*output, const double \*input, void \*user_data) and second element being a ctypes void pointer. This void pointer needs to be passed as input to the function as the third argument `user_data`. From e912481e347f1d93f463546af79209d2a5586f83 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Wed, 3 Mar 2021 17:16:56 +0000 Subject: [PATCH 045/314] version: Bump SymEngine --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index e6b825d21..1ed3c68e5 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -44eb47e3bbfa7e06718f2f65f3f41a0a9d133b70 +11bdb9bfb60d33d8bf48d4e81e9743fe732d9155 From 6c3d334dfe8ad1df6cd3cb2eec90b95b6ca7a862 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Thu, 4 Mar 2021 17:40:50 +0000 Subject: [PATCH 046/314] yml: Do not test symengine.py for docs --- .github/workflows/mkdocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml index 8848782b9..5305596ba 100644 --- a/.github/workflows/mkdocs.yaml +++ b/.github/workflows/mkdocs.yaml @@ -34,8 +34,8 @@ jobs: export PYTHON_SOURCE_DIR=$GITHUB_WORKSPACE cd $PYTHON_SOURCE_DIR source bin/install_travis.sh - bin/test_travis.sh pip install sphinx-autobuild m2r2 sphinxcontrib-apidoc sphinx-book-theme + python setup.py install build_ext --inplace --symengine-dir=$our_install_dir sphinx-build docs/ genDocs/ env: WITH_MPC: yes From 842e368300fc4db4cc75bc3cbe504d817818d5fd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 17:48:38 -0600 Subject: [PATCH 047/314] update symengine version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 1ed3c68e5..db498286c 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -11bdb9bfb60d33d8bf48d4e81e9743fe732d9155 +eb62270ce920c0118109b01b3702e0e503f39994 From f79014cbe4f2cafae5015969f68330ff258f0494 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 16:23:29 -0600 Subject: [PATCH 048/314] remove sending generator --- setup.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/setup.py b/setup.py index eb8ec3747..7da57ff11 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,6 @@ cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] -cmake_generator = [None] cmake_build_type = ["Release"] @@ -55,7 +54,6 @@ def get_build_dir(dist): global_user_options = [ ('symengine-dir=', None, 'path to symengine installation or build directory'), - ('generator=', None, 'cmake build generator'), ('build-type=', None, 'build type: Release or Debug'), ('define=', 'D', 'options to cmake :='), @@ -83,7 +81,6 @@ def initialize_options(self): _build_ext.initialize_options(self) self.define = None self.symengine_dir = None - self.generator = None self.build_type = "Release" def finalize_options(self): @@ -96,9 +93,6 @@ def finalize_options(self): if self.symengine_dir: cmake_opts.extend([('SymEngine_DIR', self.symengine_dir)]) - if self.generator: - cmake_generator[0] = self.generator - cmake_build_type[0] = self.build_type def cmake_build(self): @@ -112,8 +106,6 @@ def cmake_build(self): cmake_cmd = ["cmake", source_dir, "-DCMAKE_BUILD_TYPE=" + cmake_build_type[0]] cmake_cmd.extend(process_opts(cmake_opts)) - if not path.exists(path.join(build_dir, "CMakeCache.txt")): - cmake_cmd.extend(self.get_generator()) if subprocess.call(cmake_cmd, cwd=build_dir) != 0: raise EnvironmentError("error calling cmake") @@ -122,24 +114,6 @@ def cmake_build(self): cwd=build_dir) != 0: raise EnvironmentError("error building project") - def get_generator(self): - if cmake_generator[0]: - return ["-G", cmake_generator[0]] - else: - import platform - import sys - if (platform.system() == "Windows"): - compiler = str(self.compiler).lower() - if ("msys" in compiler): - return ["-G", "MSYS Makefiles"] - elif ("mingw" in compiler): - return ["-G", "MinGW Makefiles"] - elif sys.maxsize > 2**32: - return ["-G", "Visual Studio 14 2015 Win64"] - else: - return ["-G", "Visual Studio 14 2015"] - return [] - def run(self): self.cmake_build() # can't use super() here because @@ -156,7 +130,6 @@ def initialize_options(self): _install.initialize_options(self) self.define = None self.symengine_dir = None - self.generator = None self.build_type = "Release" def finalize_options(self): From 2ca3654304745e1611be6ec17a3e8c87b46089b9 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:14:35 -0600 Subject: [PATCH 049/314] skip python<3.6 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7da57ff11..c6929813a 100644 --- a/setup.py +++ b/setup.py @@ -204,7 +204,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", - python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,<4', + python_requires='>=3.6.*,<4', zip_safe=False, cmdclass = cmdclass, classifiers=[ From d5bd1200f9993252535bea4f9f70785112adb440 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:14:57 -0600 Subject: [PATCH 050/314] Require cmake>=2.8.12 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cabd8ed2..7fc92682a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(python_wrapper) set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH}) From 9ec2c52d26080471885623c29e6ae69f9388bb29 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:15:10 -0600 Subject: [PATCH 051/314] More info at the end of cmake --- CMakeLists.txt | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fc92682a..1d15fb235 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,15 +45,17 @@ foreach (PKG MPC MPFR PIRANHA FLINT LLVM) endif() endforeach() -message("CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}") -message("CMAKE_CXX_FLAGS : ${CMAKE_CXX_FLAGS}") -message("CMAKE_CXX_FLAGS_RELEASE : ${CMAKE_CXX_FLAGS_RELEASE}") -message("CMAKE_CXX_FLAGS_DEBUG : ${CMAKE_CXX_FLAGS_DEBUG}") -message("HAVE_SYMENGINE_MPFR : ${HAVE_SYMENGINE_MPFR}") -message("HAVE_SYMENGINE_MPC : ${HAVE_SYMENGINE_MPC}") -message("HAVE_SYMENGINE_PIRANHA : ${HAVE_SYMENGINE_PIRANHA}") -message("HAVE_SYMENGINE_FLINT : ${HAVE_SYMENGINE_FLINT}") -message("HAVE_SYMENGINE_LLVM : ${HAVE_SYMENGINE_LLVM}") +message("CMAKE_SYSTEM_PROCESSOR : ${CMAKE_SYSTEM_PROCESSOR}") +message("CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}") +message("CMAKE_CXX_FLAGS : ${CMAKE_CXX_FLAGS}") +message("CMAKE_CXX_FLAGS_RELEASE : ${CMAKE_CXX_FLAGS_RELEASE}") +message("CMAKE_CXX_FLAGS_DEBUG : ${CMAKE_CXX_FLAGS_DEBUG}") +message("HAVE_SYMENGINE_MPFR : ${HAVE_SYMENGINE_MPFR}") +message("HAVE_SYMENGINE_MPC : ${HAVE_SYMENGINE_MPC}") +message("HAVE_SYMENGINE_PIRANHA : ${HAVE_SYMENGINE_PIRANHA}") +message("HAVE_SYMENGINE_FLINT : ${HAVE_SYMENGINE_FLINT}") +message("HAVE_SYMENGINE_LLVM : ${HAVE_SYMENGINE_LLVM}") +message("HAVE_SYMENGINE_LLVM_LONG_DOUBLE : ${HAVE_SYMENGINE_LLVM_LONG_DOUBLE}") message("Copying source of python wrappers into: ${CMAKE_CURRENT_BINARY_DIR}") file(COPY symengine/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/symengine) From 7b013104733be87e65d50f597f278515ef8d8ded Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:15:29 -0600 Subject: [PATCH 052/314] Fix CMake dev warning --- cmake/FindPython.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index f4f8dd99e..4cb97cc50 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -66,7 +66,7 @@ set(PYTHON_EXTENSION_SOABI ${PYTHON_EXTENSION_SOABI_tmp} CACHE STRING "Suffix for python extensions") INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PYTHON DEFAULT_MSG PYTHON_LIBRARY PYTHON_INCLUDE_PATH PYTHON_INSTALL_PATH) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Python DEFAULT_MSG PYTHON_LIBRARY PYTHON_INCLUDE_PATH PYTHON_INSTALL_PATH) # Links a Python extension module. From 2a66ad8ac4121a02ea5440630d6bb0108b5b8fb2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:15:43 -0600 Subject: [PATCH 053/314] Fix Cython warning --- cmake/FindCython.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index e474bbcbc..b77d14ac1 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -6,7 +6,7 @@ # paths: find_program(CYTHON_BIN NAMES cython cython3 cython2) -SET(CYTHON_FLAGS --cplus --fast-fail) +SET(CYTHON_FLAGS --cplus --fast-fail -3) SET(Cython_FOUND FALSE) IF (CYTHON_BIN) From 3c10cdb45038fdd23c8a8599b177a3aed6783368 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 Mar 2021 22:13:44 -0600 Subject: [PATCH 054/314] update info about licenses --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 412a0ef32..484ad9ee5 100644 --- a/README.md +++ b/README.md @@ -71,8 +71,9 @@ symengine.py is MIT licensed and uses several LGPL, BSD-3 and MIT licensed libra Licenses for the dependencies of pip wheels are as follows, -pip wheels on Unix use GMP (LGPL v3), MPFR (LGPL v3), MPC (LGPL v3), LLVM (NCSA) and symengine (MIT + BSD-3). -pip wheels on Windows use MPIR (LGPL v3) instead of GMP above. -NumPy (BSD-3) and SymPy (BSD-3) are optional dependencies. +pip wheels on Unix use GMP (LGPL-3.0-or-later), MPFR (LGPL-3.0-or-later), +MPC (LGPL-3.0-or-later), LLVM (Apache-2.0), zlib (Zlib) and symengine (MIT AND BSD-3-Clause). +pip wheels on Windows use MPIR (LGPL-3.0-or-later) instead of GMP above. +NumPy (BSD-3-Clause) and SymPy (BSD-3-Clause) are optional dependencies. Sources for these binary dependencies can be found on https://github.com/symengine/symengine-wheels/releases From 79c3d1248ef817263dd7de6ebb1d8bcb6544f7cd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Mar 2021 13:32:01 -0600 Subject: [PATCH 055/314] Add an option to copy extension name --- CMakeLists.txt | 1 + symengine/lib/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d15fb235..4ee9d7937 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ message("HAVE_SYMENGINE_PIRANHA : ${HAVE_SYMENGINE_PIRANHA}") message("HAVE_SYMENGINE_FLINT : ${HAVE_SYMENGINE_FLINT}") message("HAVE_SYMENGINE_LLVM : ${HAVE_SYMENGINE_LLVM}") message("HAVE_SYMENGINE_LLVM_LONG_DOUBLE : ${HAVE_SYMENGINE_LLVM_LONG_DOUBLE}") +message("SYMENGINE_COPY_EXTENSION : ${SYMENGINE_COPY_EXTENSION}") message("Copying source of python wrappers into: ${CMAKE_CURRENT_BINARY_DIR}") file(COPY symengine/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/symengine) diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index 53247ea3f..33f813ff1 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -35,3 +35,16 @@ install(FILES __init__.py pywrapper.h DESTINATION ${PY_PATH} ) + +if (${SYMENGINE_COPY_EXTENSION}) + if ("${PYTHON_EXTENSION_SOABI}" MATCHES "ppc64le") + string(REPLACE "ppc64le" "powerpc64le" COPY_PYTHON_EXTENSION_SOABI "${PYTHON_EXTENSION_SOABI}") + endif () + if ("${PYTHON_EXTENSION_SOABI}" MATCHES "powerpc64le") + string(REPLACE "powerpc64le" "ppc64le" COPY_PYTHON_EXTENSION_SOABI "${PYTHON_EXTENSION_SOABI}") + endif () + message("${PYTHON_EXTENSION_SOABI} ${COPY_PYTHON_EXTENSION_SOABI}") + set(SOURCE_NAME "${PY_PATH}/symengine_wrapper${PYTHON_EXTENSION_SOABI}.so") + set(DEST_NAME "${PY_PATH}/symengine_wrapper${COPY_PYTHON_EXTENSION_SOABI}.so") + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${SOURCE_NAME} ${DEST_NAME})") +endif () From 6ea7333ff2986524f8ca4bb89e42319e8ec154f1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Mar 2021 14:08:40 -0600 Subject: [PATCH 056/314] mention pthreads-win32 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 484ad9ee5..ea43b2b28 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,8 @@ Licenses for the dependencies of pip wheels are as follows, pip wheels on Unix use GMP (LGPL-3.0-or-later), MPFR (LGPL-3.0-or-later), MPC (LGPL-3.0-or-later), LLVM (Apache-2.0), zlib (Zlib) and symengine (MIT AND BSD-3-Clause). -pip wheels on Windows use MPIR (LGPL-3.0-or-later) instead of GMP above. +pip wheels on Windows use MPIR (LGPL-3.0-or-later) instead of GMP above and +pthreads-win32 (LGPL-3.0-or-later) additionally. NumPy (BSD-3-Clause) and SymPy (BSD-3-Clause) are optional dependencies. Sources for these binary dependencies can be found on https://github.com/symengine/symengine-wheels/releases From 45428f4341c84e82873dfe2a510ce2f7dfa123f3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Mar 2021 16:55:42 -0600 Subject: [PATCH 057/314] Require symengine 0.7.0 --- CMakeLists.txt | 2 +- symengine_version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ee9d7937..c4b13eb70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.12) project(python_wrapper) set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH}) -find_package(SymEngine 0.6.0 REQUIRED CONFIG +find_package(SymEngine 0.7.0 REQUIRED CONFIG PATH_SUFFIXES lib/cmake/symengine cmake/symengine CMake/) message("SymEngine_DIR : " ${SymEngine_DIR}) message("SymEngine Version : " ${SymEngine_VERSION}) diff --git a/symengine_version.txt b/symengine_version.txt index db498286c..8b20e4852 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -eb62270ce920c0118109b01b3702e0e503f39994 +v0.7.0 From d4e6961613501800618e59afaaef0f423a3a358e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Mar 2021 17:53:11 -0600 Subject: [PATCH 058/314] Add Jialin, Rikard and Rohit to AUTHORS --- .mailmap | 1 + AUTHORS | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.mailmap b/.mailmap index 6918cbecd..b5cf86a6f 100644 --- a/.mailmap +++ b/.mailmap @@ -11,6 +11,7 @@ Ondřej Čertík Peter Brady Isuru Fernando +Isuru Fernando Alan Hu <31489167+alanlh@users.noreply.github.com> Shivam Vats Shikhar Jaiswal diff --git a/AUTHORS b/AUTHORS index 58f002dfe..d8863966f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,3 +26,6 @@ Alan Hu Richard Otis Erik Jansson Agnvall Simon Stelter +Jialin Ma +Rikard Nordgren +Rohit Goswami From 9032041e5ba3a8ad418ec203cc2f476769e1e59a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Mar 2021 17:57:08 -0600 Subject: [PATCH 059/314] Update tests for new python versions --- .travis.yml | 30 +++++++++++++++--------------- appveyor.yml | 14 +++++++------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45b935650..aa546b679 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,15 +24,15 @@ env: ## executed. matrix: # Debug builds: - - BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="2.7" TEST_SYMPY="yes" + - BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.7" TEST_SYMPY="yes" - BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.6" TEST_SYMPY="yes" # Release builds: - - PYTHON_VERSION="2.7" BUILD_SHARED_LIBS="yes" - - PYTHON_VERSION="2.7" WITH_MPFR="yes" INTEGER_CLASS="gmpxx" WITH_NUMPY="no" - - PYTHON_VERSION="3.7" WITH_MPC="yes" - - PYTHON_VERSION="3.7" WITH_MPFR="yes" - - PYTHON_VERSION="3.5" WITH_MPC="yes" + - PYTHON_VERSION="3.7" BUILD_SHARED_LIBS="yes" + - PYTHON_VERSION="3.7" WITH_MPFR="yes" INTEGER_CLASS="gmpxx" WITH_NUMPY="no" + - PYTHON_VERSION="3.8" WITH_MPC="yes" + - PYTHON_VERSION="3.8" WITH_MPFR="yes" + - PYTHON_VERSION="3.9" WITH_MPC="yes" - PYTHON_VERSION="3.6" WITH_MPC="yes" INTEGER_CLASS="flint" WITH_FLINT="yes" matrix: @@ -40,7 +40,7 @@ matrix: - compiler: clang - os: osx include: - - env: BUILD_TYPE="Debug" WITH_BFD="yes" WITH_PIRANHA="yes" PYTHON_VERSION="2.7" + - env: BUILD_TYPE="Debug" WITH_BFD="yes" WITH_PIRANHA="yes" PYTHON_VERSION="3.7" compiler: gcc os: linux addons: @@ -50,10 +50,10 @@ matrix: packages: - binutils-dev - g++-4.8 - - env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.5" BUILD_SHARED_LIBS="yes" + - env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.8" BUILD_SHARED_LIBS="yes" compiler: clang os: linux - - env: BUILD_TYPE="Release" PYTHON_VERSION="2.7" WITH_NUMPY="no" + - env: BUILD_TYPE="Release" PYTHON_VERSION="3.7" WITH_NUMPY="no" compiler: clang os: linux - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.6" WITH_SYMPY="no" WITH_LLVM="8.0" WITH_SCIPY="yes" CC="gcc-4.8" CXX="g++-4.8" @@ -69,23 +69,23 @@ matrix: - libstdc++-4.8-dev - binutils-dev - llvm-8-dev - - env: BUILD_TYPE="Debug" PYTHON_VERSION="2.7" WITH_LLVM="5.0" WITH_SCIPY="yes" + - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.7" WITH_LLVM="5.0" WITH_SCIPY="yes" compiler: clang os: osx - - env: BUILD_TYPE="Release" PYTHON_VERSION="3.5" WITH_NUMPY="no" + - env: BUILD_TYPE="Release" PYTHON_VERSION="3.9" WITH_NUMPY="no" compiler: clang os: osx - - env: BUILD_TYPE="Debug" PYTHON_VERSION="2.7" WITH_NUMPY="no" + - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.7" WITH_NUMPY="no" compiler: gcc os: osx - - env: BUILD_TYPE="Release" PYTHON_VERSION="3.5" + - env: BUILD_TYPE="Release" PYTHON_VERSION="3.6" compiler: gcc os: osx - - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="2.7" + - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="3.7" compiler: gcc os: linux allow_failures: - - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="2.7" + - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="3.7" before_install: - | diff --git a/appveyor.yml b/appveyor.yml index b0ddc7f3f..0d69c16d9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,22 +12,22 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "Win32" - PYTHON_VERSION: 27 - CONDA_INSTALL_LOCN: C:\\Miniconda35 + PYTHON_VERSION: 37 + CONDA_INSTALL_LOCN: C:\\Miniconda36 WITH_MPFR: yes WITH_MPC: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 35-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda35-x64 + PYTHON_VERSION: 36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 WITH_MPFR: yes WITH_MPC: yes WITH_LLVM: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 36-x64 + PYTHON_VERSION: 38-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 # - BUILD_TYPE: "Debug" # COMPILER: MinGW @@ -37,10 +37,10 @@ environment: # PYTHON_VERSION: 35 - BUILD_TYPE: "Release" COMPILER: MinGW-w64 - PYTHON_VERSION: 27-x64 + PYTHON_VERSION: 37-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 35-x64 + PYTHON_VERSION: 39-x64 WITH_NUMPY: no - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 From 9cf271cf0bc8f5f7ccd2343bb6bd250608234981 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 01:18:28 -0600 Subject: [PATCH 060/314] use pip to install sympy --- bin/install_travis.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 02d105d54..e70997f37 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -4,10 +4,6 @@ export conda_pkgs="python=${PYTHON_VERSION} pip cython pytest gmp mpfr" -if [[ "${WITH_SYMPY}" != "no" ]]; then - export conda_pkgs="${conda_pkgs} sympy"; -fi - if [[ "${WITH_NUMPY}" != "no" ]]; then export conda_pkgs="${conda_pkgs} numpy"; fi @@ -28,5 +24,10 @@ if [[ "${WITH_SAGE}" == "yes" ]]; then fi conda install -q ${conda_pkgs} + +if [[ "${WITH_SYMPY}" != "no" ]]; then + pip install sympy; +fi + conda clean --all source activate $our_install_dir; From b7370d9f0121192a80f3486ba3b42c2382a5975b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 01:32:07 -0600 Subject: [PATCH 061/314] Revert "remove sending generator" This reverts commit f79014cbe4f2cafae5015969f68330ff258f0494. --- setup.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/setup.py b/setup.py index c6929813a..9d2f1465e 100644 --- a/setup.py +++ b/setup.py @@ -37,6 +37,7 @@ cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] +cmake_generator = [None] cmake_build_type = ["Release"] @@ -54,6 +55,7 @@ def get_build_dir(dist): global_user_options = [ ('symengine-dir=', None, 'path to symengine installation or build directory'), + ('generator=', None, 'cmake build generator'), ('build-type=', None, 'build type: Release or Debug'), ('define=', 'D', 'options to cmake :='), @@ -81,6 +83,7 @@ def initialize_options(self): _build_ext.initialize_options(self) self.define = None self.symengine_dir = None + self.generator = None self.build_type = "Release" def finalize_options(self): @@ -93,6 +96,9 @@ def finalize_options(self): if self.symengine_dir: cmake_opts.extend([('SymEngine_DIR', self.symengine_dir)]) + if self.generator: + cmake_generator[0] = self.generator + cmake_build_type[0] = self.build_type def cmake_build(self): @@ -106,6 +112,8 @@ def cmake_build(self): cmake_cmd = ["cmake", source_dir, "-DCMAKE_BUILD_TYPE=" + cmake_build_type[0]] cmake_cmd.extend(process_opts(cmake_opts)) + if not path.exists(path.join(build_dir, "CMakeCache.txt")): + cmake_cmd.extend(self.get_generator()) if subprocess.call(cmake_cmd, cwd=build_dir) != 0: raise EnvironmentError("error calling cmake") @@ -114,6 +122,24 @@ def cmake_build(self): cwd=build_dir) != 0: raise EnvironmentError("error building project") + def get_generator(self): + if cmake_generator[0]: + return ["-G", cmake_generator[0]] + else: + import platform + import sys + if (platform.system() == "Windows"): + compiler = str(self.compiler).lower() + if ("msys" in compiler): + return ["-G", "MSYS Makefiles"] + elif ("mingw" in compiler): + return ["-G", "MinGW Makefiles"] + elif sys.maxsize > 2**32: + return ["-G", "Visual Studio 14 2015 Win64"] + else: + return ["-G", "Visual Studio 14 2015"] + return [] + def run(self): self.cmake_build() # can't use super() here because @@ -130,6 +156,7 @@ def initialize_options(self): _install.initialize_options(self) self.define = None self.symengine_dir = None + self.generator = None self.build_type = "Release" def finalize_options(self): From 382c376e9ddaa47f1b0e8d948823ce92a769bb82 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 01:33:17 -0600 Subject: [PATCH 062/314] Use NMake Makefiles --- setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 9d2f1465e..ba0d8641b 100644 --- a/setup.py +++ b/setup.py @@ -125,7 +125,7 @@ def cmake_build(self): def get_generator(self): if cmake_generator[0]: return ["-G", cmake_generator[0]] - else: + elif "CMAKE_GENERATOR" not in os.environ: import platform import sys if (platform.system() == "Windows"): @@ -134,10 +134,8 @@ def get_generator(self): return ["-G", "MSYS Makefiles"] elif ("mingw" in compiler): return ["-G", "MinGW Makefiles"] - elif sys.maxsize > 2**32: - return ["-G", "Visual Studio 14 2015 Win64"] else: - return ["-G", "Visual Studio 14 2015"] + return ["-G", "NMake Makefiles"] return [] def run(self): From 4c95e2b215ff2e9116d6cfa50f6a1c658e8bd950 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 01:59:02 -0600 Subject: [PATCH 063/314] set CMAKE_GENERATOR --- appveyor.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0d69c16d9..8ea096df6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -92,10 +92,14 @@ install: - mkdir build - cd build -- if [%COMPILER%]==[MSVC15] if [%PLATFORM%]==[Win32] cmake -G "Visual Studio 14 2015" -DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library .. -- if [%COMPILER%]==[MSVC15] if [%PLATFORM%]==[x64] cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library .. -- if [%COMPILER%]==[MinGW] cmake -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH=C:\MinGW -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. -- if [%COMPILER%]==[MinGW-w64] cmake -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH=C:\mingw64 -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. +- if [%COMPILER%]==[MSVC15] if [%PLATFORM%]==[Win32] set "CMAKE_GENERATOR=Visual Studio 14 2015" +- if [%COMPILER%]==[MSVC15] if [%PLATFORM%]==[x64] set "CMAKE_GENERATOR=Visual Studio 14 2015 Win64" +- if [%COMPILER%]==[MinGW] set "CMAKE_GENERATOR=MinGW Makefiles" +- if [%COMPILER%]==[MinGW-w64] set "CMAKE_GENERATOR=MinGW Makefiles" + +- if [%COMPILER%]==[MSVC15] cmake -DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library .. +- if [%COMPILER%]==[MinGW] cmake -DCMAKE_PREFIX_PATH=C:\MinGW -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. +- if [%COMPILER%]==[MinGW-w64] cmake -DCMAKE_PREFIX_PATH=C:\mingw64 -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. - if [%WITH_MPFR%]==[yes] cmake -DWITH_MPFR=yes .. - if [%WITH_MPC%]==[yes] cmake -DWITH_MPC=yes .. From b8f468cccee6ff62db1244992b6920d6eddbe4d4 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 02:17:12 -0600 Subject: [PATCH 064/314] move to github actions --- .github/workflows/ci.yml | 178 ++++++++++++++++++++++++++++++++++ .github/workflows/mkdocs.yaml | 56 ----------- .travis.yml | 128 ------------------------ bin/test_symengine_unix.sh | 22 +++++ 4 files changed, 200 insertions(+), 184 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/mkdocs.yaml delete mode 100644 .travis.yml create mode 100644 bin/test_symengine_unix.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..c09022a71 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,178 @@ +name: Build and test symengine +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.OS }} + strategy: + fail-fast: false + matrix: + include: + - BUILD_TYPE: Debug + WITH_BFD: yes + PYTHON_VERSION: 3.6 + TEST_SYMPY: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Debug + WITH_BFD: yes + PYTHON_VERSION: 3.9 + TEST_SYMPY: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.7 + BUILD_SHARED_LIBS: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.7 + WITH_MPFR: yes + INTEGER_CLASS: gmpxx + WITH_NUMPY: no + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.8 + WITH_MPC: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + WITH_MPFR: yes + PYTHON_VERSION: 3.8 + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.9 + WITH_MPC: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.6 + WITH_MPC: yes + INTEGER_CLASS: flint + WITH_FLINT: yes + OS: ubuntu-16.04 + CC: gcc + + - BUILD_TYPE: Debug + PYTHON_VERSION: 3.7 + WITH_BFD: yes + WITH_PIRANHA: yes + OS: ubuntu-16.04 + CC: gcc + EXTRA_APT_PACKAGES: "g++-4.8" + + - BUILD_TYPE: Debug + PYTHON_VERSION: 3.8 + WITH_BFD: yes + BUILD_SHARED_LIBS: yes + OS: ubuntu-16.04 + CC: clang + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.7 + WITH_NUMPY: yes + OS: ubuntu-16.04 + CC: clang + + - BUILD_TYPE: Debug + PYTHON_VERSION: 3.6 + WITH_SYMPY: yes + WITH_LLVM: 8.0 + WITH_SCIPY: yes + OS: ubuntu-16.04 + CC: gcc-4.8 + CXX: g++-4.8 + EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main' + EXTRA_APT_PACKAGES: 'g++-4.8 libstdc++-4.8-dev binutils-dev llvm-8-dev' + + - BUILD_TYPE: Debug + PYTHON_VERSION: 3.7 + WITH_SCIPY: yes + WITH_LLVM: 5.0 + OS: macos-latest + CC: clang + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.9 + WITH_NUMPY: no + OS: macos-latest + CC: clang + + - BUILD_TYPE: Debug + PYTHON_VERSION: 3.7 + WITH_NUMPY: no + OS: macos-latest + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.6 + OS: macos-latest + CC: gcc + + - BUILD_TYPE: Release + PYTHON_VERSION: 3.6 + OS: ubuntu-16.04 + WITH_MPC: yes + WITH_MPFR: yes + WITH_FLINT: yes + WITH_SCIPY: yes + WITH_DOCS: yes + INTEGER_CLASS: flint + TEST_SYMPY: yes + CC: gcc + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Build and test symengine + shell: bash + run: | + source bin/test_symengine_unix.sh + env: + USE_GLIBCXX_DEBUG: ${{ matrix.USE_GLIBCXX_DEBUG }} + WITH_MPFR: ${{ matrix.WITH_MPFR }} + BUILD_BENCHMARKS: ${{ matrix.BUILD_BENCHMARKS }} + WITH_LLVM: ${{ matrix.WITH_LLVM }} + WITH_BENCHMARKS_NONIUS: ${{ matrix.WITH_BENCHMARKS_NONIUS }} + WITH_SYMENGINE_RCP: ${{ matrix.WITH_SYMENGINE_RCP }} + TEST_IN_TREE: ${{ matrix.TEST_IN_TREE }} + WITH_SYMENGINE_THREAD_SAFE: ${{ matrix.WITH_SYMENGINE_THREAD_SAFE }} + WITH_PRIMESIEVE: ${{ matrix.WITH_PRIMESIEVE }} + INTEGER_CLASS: ${{ matrix.INTEGER_CLASS }} + WITH_ARB: ${{ matrix.WITH_ARB }} + WITH_PIRANHA: ${{ matrix.WITH_PIRANHA }} + WITH_GCC_6: ${{ matrix.WITH_GCC_6 }} + CONDA_ENV_FILE: ${{ matrix.CONDA_ENV_FILE }} + WITH_BFD: ${{ matrix.WITH_BFD }} + WITH_FLINT: ${{ matrix.WITH_FLINT }} + EXTRA_APT_REPOSITORY: ${{ matrix.EXTRA_APT_REPOSITORY }} + EXTRA_APT_PACKAGES: ${{ matrix.EXTRA_APT_PACKAGES }} + TEST_CLANG_FORMAT: ${{ matrix.TEST_CLANG_FORMAT }} + WITH_ECM: ${{ matrix.WITH_ECM }} + WITH_LATEST_GCC: ${{ matrix.WITH_LATEST_GCC }} + OS: ${{ matrix.OS }} + WITH_FLINT_DEV: ${{ matrix.WITH_FLINT_DEV }} + CC: ${{ matrix.CC }} + WITH_COVERAGE: ${{ matrix.WITH_COVERAGE }} + BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + WITH_SANITIZE: ${{ matrix.WITH_SANITIZE }} + WITH_MPC: ${{ matrix.WITH_MPC }} + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + BUILD_SHARED_LIBS: ${{ matrix.BUILD_SHARED_LIBS }} + + - name: Deploy Documentation + if: ${{ (github.ref == 'refs/heads/main' && github.repository == 'Symengine/symengine.py') || (github.ref == 'refs/heads/master' && github.repository == 'Symengine/symengine.py')}} + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./genDocs diff --git a/.github/workflows/mkdocs.yaml b/.github/workflows/mkdocs.yaml deleted file mode 100644 index 5305596ba..000000000 --- a/.github/workflows/mkdocs.yaml +++ /dev/null @@ -1,56 +0,0 @@ -on: [push, pull_request] - -name: Make Sphinx API Docs - -jobs: - mkdocs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build CPP Core - run: | - git clone https://github.com/symengine/symengine symengine-cpp - cd symengine-cpp - export SOURCE_DIR=`pwd` - git checkout `cat ../symengine_version.txt` - cd $SOURCE_DIR - source bin/install_travis.sh - cd $SOURCE_DIR - bin/test_travis.sh - env: - WITH_MPC: yes - WITH_MPFR: yes - WITH_FLINT: yes - WITH_SCIPY: yes - WITH_DOCS: yes - INTEGER_CLASS: flint - TEST_CPP: no - TEST_SYMPY: yes - MAKEFLAGS: -j2 - our_install_dir: $HOME/our_usr/ - - uses: s-weigand/setup-conda@v1 - - name: Build Bindings and Docs - run: | - export PYTHON_SOURCE_DIR=$GITHUB_WORKSPACE - cd $PYTHON_SOURCE_DIR - source bin/install_travis.sh - pip install sphinx-autobuild m2r2 sphinxcontrib-apidoc sphinx-book-theme - python setup.py install build_ext --inplace --symengine-dir=$our_install_dir - sphinx-build docs/ genDocs/ - env: - WITH_MPC: yes - WITH_MPFR: yes - WITH_FLINT: yes - WITH_SCIPY: yes - WITH_DOCS: yes - INTEGER_CLASS: flint - TEST_CPP: no - TEST_SYMPY: yes - MAKEFLAGS: -j2 - our_install_dir: $HOME/our_usr/ - - name: Deploy Documentation - if: ${{ (github.ref == 'refs/heads/main' && github.repository == 'Symengine/symengine.py') || (github.ref == 'refs/heads/master' && github.repository == 'Symengine/symengine.py')}} - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./genDocs diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index aa546b679..000000000 --- a/.travis.yml +++ /dev/null @@ -1,128 +0,0 @@ -language: cpp -compiler: - - gcc - - clang -os: - - linux - - osx -sudo: false -osx_image: xcode6.4 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - binutils-dev - - g++-4.7 - -env: - ## All these variables are sent into the bin/test_travis.sh script. See this - ## script to know how they are used. Most of them are just passed to cmake, - ## so if they are not set, cmake will use a default value. For the rest, the - ## bin/test_travis.sh script usually checks for either "yes" or "no" in an if - ## statement, so if the variable is not set, the other if branch will get - ## executed. - matrix: - # Debug builds: - - BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.7" TEST_SYMPY="yes" - - BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.6" TEST_SYMPY="yes" - - # Release builds: - - PYTHON_VERSION="3.7" BUILD_SHARED_LIBS="yes" - - PYTHON_VERSION="3.7" WITH_MPFR="yes" INTEGER_CLASS="gmpxx" WITH_NUMPY="no" - - PYTHON_VERSION="3.8" WITH_MPC="yes" - - PYTHON_VERSION="3.8" WITH_MPFR="yes" - - PYTHON_VERSION="3.9" WITH_MPC="yes" - - PYTHON_VERSION="3.6" WITH_MPC="yes" INTEGER_CLASS="flint" WITH_FLINT="yes" - -matrix: - exclude: - - compiler: clang - - os: osx - include: - - env: BUILD_TYPE="Debug" WITH_BFD="yes" WITH_PIRANHA="yes" PYTHON_VERSION="3.7" - compiler: gcc - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - binutils-dev - - g++-4.8 - - env: BUILD_TYPE="Debug" WITH_BFD="yes" PYTHON_VERSION="3.8" BUILD_SHARED_LIBS="yes" - compiler: clang - os: linux - - env: BUILD_TYPE="Release" PYTHON_VERSION="3.7" WITH_NUMPY="no" - compiler: clang - os: linux - - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.6" WITH_SYMPY="no" WITH_LLVM="8.0" WITH_SCIPY="yes" CC="gcc-4.8" CXX="g++-4.8" - compiler: gcc - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-8 - packages: - - g++-4.8 - - libstdc++-4.8-dev - - binutils-dev - - llvm-8-dev - - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.7" WITH_LLVM="5.0" WITH_SCIPY="yes" - compiler: clang - os: osx - - env: BUILD_TYPE="Release" PYTHON_VERSION="3.9" WITH_NUMPY="no" - compiler: clang - os: osx - - env: BUILD_TYPE="Debug" PYTHON_VERSION="3.7" WITH_NUMPY="no" - compiler: gcc - os: osx - - env: BUILD_TYPE="Release" PYTHON_VERSION="3.6" - compiler: gcc - os: osx - - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="3.7" - compiler: gcc - os: linux - allow_failures: - - env: BUILD_TYPE="Release" WITH_SAGE="yes" WITH_MPC="yes" PYTHON_VERSION="3.7" - -before_install: -- | - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then - command curl -sSL https://rvm.io/mpapis.asc | gpg --import -; - rvm get head || true - fi - -install: - - export PYTHON_SOURCE_DIR=`pwd` - - export TEST_CPP="no" - - export MAKEFLAGS="-j2" - - - git clone https://github.com/symengine/symengine symengine-cpp - - cd symengine-cpp - - export SOURCE_DIR=`pwd` - - git checkout `cat ../symengine_version.txt` - - cd .. - - # Setup travis for C++ library - - cd $SOURCE_DIR - - source bin/install_travis.sh - - # Setup travis for Python wrappers - - cd $PYTHON_SOURCE_DIR - - source bin/install_travis.sh - - # Build C++ library - - cd $SOURCE_DIR - - bin/test_travis.sh - - unset MAKEFLAGS - -script: - # Build Python wrappers and test - - cd $PYTHON_SOURCE_DIR - - bin/test_travis.sh - -notifications: - email: false - diff --git a/bin/test_symengine_unix.sh b/bin/test_symengine_unix.sh new file mode 100644 index 000000000..976f305d1 --- /dev/null +++ b/bin/test_symengine_unix.sh @@ -0,0 +1,22 @@ +export PYTHON_SOURCE_DIR=`pwd` +export TEST_CPP="no" +export MAKEFLAGS="-j2" + +git clone https://github.com/symengine/symengine symengine-cpp +cd symengine-cpp +export SOURCE_DIR=`pwd` +git checkout `cat ../symengine_version.txt` +cd .. + +# Setup travis for C++ library +cd $SOURCE_DIR +source bin/test_symengine_unix.sh + +# Setup travis for Python wrappers +cd $PYTHON_SOURCE_DIR +source bin/install_travis.sh + +# Build Python wrappers and test +cd $PYTHON_SOURCE_DIR +bin/test_travis.sh + From 49f64e6a78940c0e08d220d8051ef9f68109cf67 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 02:19:20 -0600 Subject: [PATCH 065/314] fix get_generator --- setup.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/setup.py b/setup.py index ba0d8641b..f2b43fb14 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,7 @@ import os import subprocess import sys +import platform from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build import build as _build @@ -125,17 +126,15 @@ def cmake_build(self): def get_generator(self): if cmake_generator[0]: return ["-G", cmake_generator[0]] - elif "CMAKE_GENERATOR" not in os.environ: - import platform - import sys - if (platform.system() == "Windows"): - compiler = str(self.compiler).lower() - if ("msys" in compiler): - return ["-G", "MSYS Makefiles"] - elif ("mingw" in compiler): - return ["-G", "MinGW Makefiles"] - else: - return ["-G", "NMake Makefiles"] + elif "CMAKE_GENERATOR" not in os.environ and platform.system() == "Windows": + compiler = str(self.compiler).lower() + if ("msys" in compiler): + return ["-G", "MSYS Makefiles"] + elif ("mingw" in compiler): + return ["-G", "MinGW Makefiles"] + else: + return ["-G", "NMake Makefiles"] + else: return [] def run(self): From 52034da38bba6a273a6035474aa763d2dae358ea Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 02:41:46 -0600 Subject: [PATCH 066/314] use conda activate --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 8ea096df6..a96f295ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -56,7 +56,7 @@ install: - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda create -n test --yes mpir=3.0.0 vc=14 -- if [%COMPILER%]==[MSVC15] call activate test +- if [%COMPILER%]==[MSVC15] conda activate test - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 - if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=3.9 From 9dbf688e4943065fe0f827ce8dd2c023ea7ed94c Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 03:32:58 -0600 Subject: [PATCH 067/314] use vs 2019 image for python39 --- appveyor.yml | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a96f295ba..b69ece969 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,21 +9,6 @@ environment: PLATFORMTOOLSET: "v140" matrix: - - BUILD_TYPE: "Release" - COMPILER: MSVC15 - PLATFORM: "Win32" - PYTHON_VERSION: 37 - CONDA_INSTALL_LOCN: C:\\Miniconda36 - WITH_MPFR: yes - WITH_MPC: yes - - BUILD_TYPE: "Release" - COMPILER: MSVC15 - PLATFORM: "x64" - PYTHON_VERSION: 36-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - WITH_MPFR: yes - WITH_MPC: yes - WITH_LLVM: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" @@ -42,10 +27,26 @@ environment: COMPILER: MinGW-w64 PYTHON_VERSION: 39-x64 WITH_NUMPY: no + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 PYTHON_VERSION: 36-x64 WITH_SYMPY: no + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "Win32" + PYTHON_VERSION: 37 + CONDA_INSTALL_LOCN: C:\\Miniconda36 + WITH_MPFR: yes + WITH_MPC: yes + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "x64" + PYTHON_VERSION: 36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + WITH_MPFR: yes + WITH_MPC: yes + WITH_LLVM: yes install: - set PYTHON_SOURCE_DIR=%CD% From 1ad3810a24a695c03903f224fbee92c62c86e7ba Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 03:33:13 -0600 Subject: [PATCH 068/314] more verbose error --- cmake/FindCython.cmake | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index b77d14ac1..318f58e48 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -14,8 +14,8 @@ IF (CYTHON_BIN) execute_process( COMMAND ${CYTHON_BIN} ${CYTHON_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cython_test.pyx RESULT_VARIABLE CYTHON_RESULT - OUTPUT_QUIET - ERROR_QUIET + OUTPUT_VARIABLE CYTHON_OUTPUT + ERROR_VARIABLE CYTHON_ERROR ) if (CYTHON_RESULT EQUAL 0) # Only if cython exits with the return code 0, we know that all is ok: @@ -38,7 +38,11 @@ ELSE (Cython_FOUND) # On Win the testing of Cython does not return any accessible value, so the test is not carried out. # Fresh Cython install was tested and works. IF(NOT MSVC) - MESSAGE(FATAL_ERROR "Your Cython version is too old. Please upgrade Cython.") + MESSAGE(FATAL_ERROR + "Your Cython version is too old. Please upgrade Cython." + "STDOUT: ${CYTHON_OUTPUT}" + "STDERROR: ${CYTHON_ERROR}" + ) ENDIF(NOT MSVC) else(Cython_Compilation_Failed) MESSAGE(FATAL_ERROR "Could not find Cython. Please install Cython.") From f6426b99113b24f0d31ee4af0e573661cef3e1b8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 04:00:11 -0600 Subject: [PATCH 069/314] use recent cython --- appveyor.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b69ece969..0c1e2e255 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,17 +9,6 @@ environment: PLATFORMTOOLSET: "v140" matrix: - - BUILD_TYPE: "Release" - COMPILER: MSVC15 - PLATFORM: "x64" - PYTHON_VERSION: 38-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 -# - BUILD_TYPE: "Debug" -# COMPILER: MinGW -# PYTHON_VERSION: 27 -# - BUILD_TYPE: "Release" -# COMPILER: MinGW -# PYTHON_VERSION: 35 - BUILD_TYPE: "Release" COMPILER: MinGW-w64 PYTHON_VERSION: 37-x64 @@ -28,6 +17,11 @@ environment: PYTHON_VERSION: 39-x64 WITH_NUMPY: no APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "x64" + PYTHON_VERSION: 38-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 PYTHON_VERSION: 36-x64 @@ -82,8 +76,7 @@ install: - set PATH=C:\Python%PYTHON_VERSION%;C:\Python%PYTHON_VERSION%\Scripts;%PATH% - pip install nose pytest -- if [%COMPILER%]==[MinGW-w64] pip install --install-option="--no-cython-compile" cython==0.26 -- if NOT [%COMPILER%]==[MinGW-w64] pip install --install-option="--no-cython-compile" cython +- pip install --install-option="--no-cython-compile" cython - if NOT [%WITH_NUMPY%]==[no] pip install numpy - if NOT [%WITH_SYMPY%]==[no] pip install sympy From ae70e5ebb8055775e06051887ac7ad9d44829e52 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 04:21:26 -0600 Subject: [PATCH 070/314] echo CONDA_PREFIX --- appveyor.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0c1e2e255..0a8d0de99 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,18 +10,18 @@ environment: matrix: - BUILD_TYPE: "Release" - COMPILER: MinGW-w64 - PYTHON_VERSION: 37-x64 + COMPILER: MSVC15 + PLATFORM: "x64" + PYTHON_VERSION: 38-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 PYTHON_VERSION: 39-x64 WITH_NUMPY: no APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: "Release" - COMPILER: MSVC15 - PLATFORM: "x64" - PYTHON_VERSION: 38-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + COMPILER: MinGW-w64 + PYTHON_VERSION: 37-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 PYTHON_VERSION: 36-x64 @@ -52,6 +52,7 @@ install: - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda create -n test --yes mpir=3.0.0 vc=14 - if [%COMPILER%]==[MSVC15] conda activate test +- if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 - if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=3.9 From 81ebc5d3468546f6e6279af8afc31e51323a8381 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 10:10:58 -0600 Subject: [PATCH 071/314] use base env for now --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0a8d0de99..820450715 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -50,8 +50,7 @@ install: - if [%COMPILER%]==[MSVC15] conda update --yes --quiet conda - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug -- if [%COMPILER%]==[MSVC15] conda create -n test --yes mpir=3.0.0 vc=14 -- if [%COMPILER%]==[MSVC15] conda activate test +- if [%COMPILER%]==[MSVC15] conda install mpir=3.0.0 vc=14 - if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 From 34b69c6f496a214fd20904bc406362d4490395cd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 10:22:15 -0600 Subject: [PATCH 072/314] add --yes --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 820450715..a6eaa8591 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -50,7 +50,7 @@ install: - if [%COMPILER%]==[MSVC15] conda update --yes --quiet conda - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug -- if [%COMPILER%]==[MSVC15] conda install mpir=3.0.0 vc=14 +- if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 - if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 From e3ce13e60407a91be333b3527ea5a1868a01044b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 10:48:46 -0600 Subject: [PATCH 073/314] Fix PATH --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a6eaa8591..5e35030f3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -52,6 +52,9 @@ install: - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 - if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% +- if [%COMPILER%]==[MSVC15] echo %PATH% +- if [%COMPILER%]==[MSVC15] set "PATH=%PATH%;%CONDA_PREFIX%\\Library\\bin;%CONDA_PREFIX%" +- if [%COMPILER%]==[MSVC15] echo %PATH% - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 - if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=3.9 From 3e4dbca2cdc2257286fac8faddb057042c1482a1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 15:13:37 -0600 Subject: [PATCH 074/314] Don't do python 3.9 on mingw-w64 --- appveyor.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5e35030f3..aa8686175 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,14 @@ environment: PLATFORMTOOLSET: "v140" matrix: + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "x64" + PYTHON_VERSION: 39 + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + WITH_MPFR: yes + WITH_MPC: yes + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" @@ -16,9 +24,8 @@ environment: CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 39-x64 + PYTHON_VERSION: 37-x64 WITH_NUMPY: no - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: "Release" COMPILER: MinGW-w64 PYTHON_VERSION: 37-x64 From 51d6d00b93aa9d4fc2d7696cfb5de6fd7551ea9d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 15:28:24 -0600 Subject: [PATCH 075/314] Fix python_version --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index aa8686175..0ccfc0164 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 39 + PYTHON_VERSION: 39-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 WITH_MPFR: yes WITH_MPC: yes From f89bd4179085fcaa79b6a6f4957745654d919be2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 15:53:14 -0600 Subject: [PATCH 076/314] Fix PATH --- appveyor.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0ccfc0164..634964d10 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -66,13 +66,13 @@ install: - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 - if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=3.9 -- if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH% +- if [%COMPILER%]==[MinGW] set "PATH=C:\MinGW\bin;%PATH%" - if [%COMPILER%]==[MinGW] mingw-get update # workaround for https://github.com/appveyor/ci/issues/996 - if [%COMPILER%]==[MinGW] mingw-get upgrade mingw32-libstdc++ - if [%COMPILER%]==[MinGW] mingw-get install mingw32-gmp -- if [%COMPILER%]==[MinGW-w64] set PATH=C:\mingw64\bin;%PATH% +- if [%COMPILER%]==[MinGW-w64] set "PATH=C:\mingw64\bin;%PATH%" - rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe" @@ -84,7 +84,8 @@ install: - if NOT [%COMPILER%]==[MSVC15] call symengine-cpp\bin\appveyor-download.cmd "https://raw.githubusercontent.com/symengine/dependencies/dcc10cce2133e2b57e61c5ced6120139bbcdfa20/python-libs-mingw32.7z" -FileName pylibs.7z - if NOT [%COMPILER%]==[MSVC15] 7z x -aoa -oC:\ pylibs.7z > NUL -- set PATH=C:\Python%PYTHON_VERSION%;C:\Python%PYTHON_VERSION%\Scripts;%PATH% +- set "PATH=C:\Python%PYTHON_VERSION%;C:\Python%PYTHON_VERSION%\Scripts;%PATH%" +- echo %PATH% - pip install nose pytest - pip install --install-option="--no-cython-compile" cython - if NOT [%WITH_NUMPY%]==[no] pip install numpy From 1ce68f40b34546eae3ab6d95f94213a1cf13e768 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 16:03:33 -0600 Subject: [PATCH 077/314] Fix PATH again --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 634964d10..c6f261c4b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -116,7 +116,8 @@ install: - cd ../../ build_script: -- set PATH=C:\symengine\bin\;%PATH% +- set "PATH=C:\symengine\bin\;%PATH%" +- echo %PATH% - if [%COMPILER%]==[MSVC15] python setup.py install build_ext --compiler=msvc --build-type=%BUILD_TYPE% - if [%COMPILER%]==[MinGW] python setup.py install build_ext --compiler=mingw --inplace - if [%COMPILER%]==[MinGW-w64] python setup.py install build_ext --compiler=mingw --inplace From 4a5a11c9b5c4fd7235a287ec48c5c77d26857a90 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 18:33:34 -0600 Subject: [PATCH 078/314] enable rdp --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c6f261c4b..a01839fbd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -130,5 +130,5 @@ test_script: # Enable this to be able to login to the build worker. You can use the # `remmina` program in Ubuntu, use the login information that the line below # prints into the log. -#on_finish: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +on_finish: +- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From bc5d2971b7164d5b8b3b4d677056dad5f60c52b3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 19:36:07 -0600 Subject: [PATCH 079/314] Fix for python>=3.8 --- appveyor.yml | 1 + symengine/__init__.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a01839fbd..34f88b050 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -117,6 +117,7 @@ install: build_script: - set "PATH=C:\symengine\bin\;%PATH%" +- set "SYMENGINE_PY_ADD_PATH_TO_SEARCH_DIRS=1" - echo %PATH% - if [%COMPILER%]==[MSVC15] python setup.py install build_ext --compiler=msvc --build-type=%BUILD_TYPE% - if [%COMPILER%]==[MinGW] python setup.py install build_ext --compiler=mingw --inplace diff --git a/symengine/__init__.py b/symengine/__init__.py index c8a26e26b..f71635def 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -1,3 +1,14 @@ +import os +import sys + +if sys.version_info >= (3, 8, 0) and sys.platform == 'win32' \ + and 'SYMENGINE_PY_ADD_PATH_TO_SEARCH_DIRS' in os.environ: + for directory in os.environ['PATH'].split(';'): + if os.path.isdir(directory): + os.add_dll_directory(directory) + +del os, sys + import symengine.lib.symengine_wrapper as wrapper from .lib.symengine_wrapper import ( From 6c66084b95f6eac2627dc87f9550fadf5b808ab7 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 19:36:34 -0600 Subject: [PATCH 080/314] Disable RDP --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 34f88b050..62adf2e1d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -131,5 +131,5 @@ test_script: # Enable this to be able to login to the build worker. You can use the # `remmina` program in Ubuntu, use the login information that the line below # prints into the log. -on_finish: -- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +# #on_finish: +#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From ddccf2fb7df8f59bc60ade10bb33b52cd39e24c0 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 19:38:51 -0600 Subject: [PATCH 081/314] Bump version to 0.7.0 --- docs/conf.py | 2 +- setup.py | 2 +- symengine/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index fd05636c3..8643d4630 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ author = 'SymEngine development team ' # The full version, including alpha/beta/rc tags -release = '0.6.1' +release = symengine.__version__ # -- General configuration --------------------------------------------------- diff --git a/setup.py b/setup.py index f2b43fb14..f4abaeb6b 100644 --- a/setup.py +++ b/setup.py @@ -220,7 +220,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.6.1", + version="0.7.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index f71635def..f63021cde 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.6.1" +__version__ = "0.7.0" # To not expose internals From 4ffaefeafebb279afa2930436b48c88a1ef3de41 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 19:39:08 -0600 Subject: [PATCH 082/314] Update classifiers --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index f4abaeb6b..126208374 100644 --- a/setup.py +++ b/setup.py @@ -238,10 +238,9 @@ def finalize_options(self): 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Scientific/Engineering :: Physics', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', ] ) From ac3aaa620e22ce988184cb3d31cda4f6abd46dab Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Thu, 25 Feb 2021 12:53:56 +0100 Subject: [PATCH 083/314] Remove support for python 2 and 3.5 --- benchmarks/expand1.py | 2 +- benchmarks/expand1_sage.py | 2 +- benchmarks/expand2_sage.py | 2 +- benchmarks/expand2b_sympy.py | 4 +- benchmarks/expand3.py | 2 +- benchmarks/expand4.py | 3 +- benchmarks/expand4_sage.py | 2 +- benchmarks/expand5.py | 2 +- benchmarks/kane.py | 20 +- benchmarks/kane_generate.py | 2 +- benchmarks/legendre1.py | 4 +- benchmarks/legendre1_sage.py | 8 +- cmake/get_suffix.py | 1 - setup.py | 14 +- symengine/CMakeLists.txt | 2 +- symengine/compatibility.py | 870 ---------------------------- symengine/lib/symengine_wrapper.pxd | 2 + symengine/lib/symengine_wrapper.pyx | 19 +- symengine/utilities.py | 42 +- 19 files changed, 77 insertions(+), 926 deletions(-) delete mode 100644 symengine/compatibility.py diff --git a/benchmarks/expand1.py b/benchmarks/expand1.py index 881dd4e92..fb910b31b 100644 --- a/benchmarks/expand1.py +++ b/benchmarks/expand1.py @@ -7,4 +7,4 @@ t1 = clock() g = e.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand1_sage.py b/benchmarks/expand1_sage.py index 9d1933153..a7b14ede7 100644 --- a/benchmarks/expand1_sage.py +++ b/benchmarks/expand1_sage.py @@ -5,4 +5,4 @@ t1 = clock() g = e.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand2_sage.py b/benchmarks/expand2_sage.py index fe2ebb673..9e0e04456 100644 --- a/benchmarks/expand2_sage.py +++ b/benchmarks/expand2_sage.py @@ -7,4 +7,4 @@ t1 = clock() g = f.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand2b_sympy.py b/benchmarks/expand2b_sympy.py index 28c585e9c..43dcd77b5 100644 --- a/benchmarks/expand2b_sympy.py +++ b/benchmarks/expand2b_sympy.py @@ -6,5 +6,5 @@ f = e*(e+w) t2 = clock() #print f -print "Total time:", t2-t1, "s" -print "number of terms:", len(f) +print("Total time:", t2-t1, "s") +print("number of terms:", len(f)) diff --git a/benchmarks/expand3.py b/benchmarks/expand3.py index 7288f3517..f8a3706f1 100644 --- a/benchmarks/expand3.py +++ b/benchmarks/expand3.py @@ -8,4 +8,4 @@ t1 = clock() g = f.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand4.py b/benchmarks/expand4.py index 3ff7b7d02..1bcdc6e7f 100644 --- a/benchmarks/expand4.py +++ b/benchmarks/expand4.py @@ -6,8 +6,7 @@ e = 1 for i in range(1, 351): e *= (i+x)**3 -#print e t1 = clock() f = e.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand4_sage.py b/benchmarks/expand4_sage.py index 0b900538e..1883b88fa 100644 --- a/benchmarks/expand4_sage.py +++ b/benchmarks/expand4_sage.py @@ -10,4 +10,4 @@ t1 = clock() f = e.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand5.py b/benchmarks/expand5.py index 047b17bfd..82ac0d59b 100644 --- a/benchmarks/expand5.py +++ b/benchmarks/expand5.py @@ -9,4 +9,4 @@ t1 = clock() g = f.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/kane.py b/benchmarks/kane.py index 4a624b234..fdefcf1f5 100644 --- a/benchmarks/kane.py +++ b/benchmarks/kane.py @@ -4,29 +4,29 @@ from symengine import var, sympify, function_symbol, Symbol import sympy s = open("expr.txt").read() -print "Converting to SymPy..." +printr("Converting to SymPy...") e = sympy.sympify(s) -print "Converting to SymEngine..." +print("Converting to SymEngine...") ce = sympify(e) -print " Done." -print "SymPy subs:" +print(" Done.") +print("SymPy subs:") t1 = clock() f = e.subs(sympy.Function("q5")(sympy.Symbol("t")), sympy.Symbol("sq5")) t2 = clock() -print "Total time:", t2-t1, "s" -print "SymEngine subs:" +print("Total time:", t2-t1, "s") +print("SymEngine subs:") t1 = clock() cf = ce.subs(function_symbol("q5", Symbol("t")), Symbol("sq5")) t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") print "SymPy diff:" t1 = clock() g = f.diff(sympy.Symbol("sq5")) t2 = clock() -print "Total time:", t2-t1, "s" -print "SymEngine diff:" +print("Total time:", t2-t1, "s") +print("SymEngine diff:") t1 = clock() cg = cf.diff(Symbol("sq5")) t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/kane_generate.py b/benchmarks/kane_generate.py index e849c1af2..dff13e573 100644 --- a/benchmarks/kane_generate.py +++ b/benchmarks/kane_generate.py @@ -253,7 +253,7 @@ def test_bicycle(): #import symengine #print "Converting to symengine..." #f = symengine.sympify(e) - print "Saving to expr.txt" + print("Saving to expr.txt") s = str(e) open("expr.txt", "w").write(s) return diff --git a/benchmarks/legendre1.py b/benchmarks/legendre1.py index 490b1f53b..6fa307397 100644 --- a/benchmarks/legendre1.py +++ b/benchmarks/legendre1.py @@ -20,9 +20,9 @@ def legendre(n, x): var("x") for n in range(10): - print n, legendre(n, x) + print(n, legendre(n, x)) t1 = clock() e = legendre(500, x) t2 = clock() -print "Total time for legendre(500, x):", t2-t1, "s" +print("Total time for legendre(500, x):", t2-t1, "s") diff --git a/benchmarks/legendre1_sage.py b/benchmarks/legendre1_sage.py index 1647dedc9..4cddc8436 100644 --- a/benchmarks/legendre1_sage.py +++ b/benchmarks/legendre1_sage.py @@ -1,7 +1,7 @@ -print "import..." +print("import...") from timeit import default_timer as clock from sage.all import var, Integer -print " done." +print(" done.") def fact(n): if n in [0, 1]: @@ -20,9 +20,9 @@ def legendre(n, x): var("x") for n in range(10): - print n, legendre(n, x) + print(n, legendre(n, x)) t1 = clock() e = legendre(500, x) t2 = clock() -print "Total time for legendre(500, x):", t2-t1, "s" +print("Total time for legendre(500, x):", t2-t1, "s") diff --git a/cmake/get_suffix.py b/cmake/get_suffix.py index 4871c489f..8fc5b1050 100644 --- a/cmake/get_suffix.py +++ b/cmake/get_suffix.py @@ -1,4 +1,3 @@ -from __future__ import print_function from distutils.sysconfig import get_config_var extsuffix = get_config_var('EXT_SUFFIX') if extsuffix is None: diff --git a/setup.py b/setup.py index 126208374..d3a09c9a1 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -from __future__ import print_function from os import getenv, path, makedirs import os import subprocess @@ -8,8 +7,8 @@ from distutils.command.build import build as _build # Make sure the system has the right Python version. -if sys.version_info[:2] < (2, 7): - print("SymEngine requires Python 2.7 or newer. " +if sys.version_info[:2] < (3, 6): + print("SymEngine requires Python 3.6 or newer. " "Python %d.%d detected" % sys.version_info[:2]) sys.exit(-1) @@ -139,8 +138,6 @@ def get_generator(self): def run(self): self.cmake_build() - # can't use super() here because - # _build_ext is an old style class in 2.7 _build_ext.run(self) @@ -165,8 +162,6 @@ def finalize_options(self): cmake_opts.extend(self.define) cmake_build_type[0] = self.build_type cmake_opts.extend([('PYTHON_INSTALL_PATH', path.join(os.getcwd(), self.install_platlib))]) - #cmake_opts.extend([('PYTHON_INSTALL_HEADER_PATH', - # path.join(os.getcwd(), self.install_headers))]) def cmake_install(self): source_dir = path.dirname(path.realpath(__file__)) @@ -189,7 +184,6 @@ def cmake_install(self): compileall.compile_dir(path.join(self.install_platlib, "symengine")) def run(self): - # can't use super() here because _install is an old style class in 2.7 _install.run(self) self.cmake_install() @@ -228,7 +222,11 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", +<<<<<<< HEAD python_requires='>=3.6.*,<4', +======= + python_requires='!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,<4', +>>>>>>> 916b786... Remove support for python 2 and 3.5 zip_safe=False, cmdclass = cmdclass, classifiers=[ diff --git a/symengine/CMakeLists.txt b/symengine/CMakeLists.txt index 224d1c99e..a666f7421 100644 --- a/symengine/CMakeLists.txt +++ b/symengine/CMakeLists.txt @@ -2,6 +2,6 @@ add_subdirectory(lib) add_subdirectory(tests) set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine) -install(FILES __init__.py utilities.py compatibility.py sympy_compat.py functions.py printing.py +install(FILES __init__.py utilities.py sympy_compat.py functions.py printing.py DESTINATION ${PY_PATH} ) diff --git a/symengine/compatibility.py b/symengine/compatibility.py deleted file mode 100644 index b28f64ada..000000000 --- a/symengine/compatibility.py +++ /dev/null @@ -1,870 +0,0 @@ -""" -Reimplementations of constructs introduced in later versions of Python than -we support. Also some functions that are needed SymPy-wide and are located -here for easy import. -""" -from __future__ import print_function, division - -import operator -from collections import defaultdict - -""" -Python 2 and Python 3 compatible imports - -String and Unicode compatible changes: - * `unicode()` removed in Python 3, import `unicode` for Python 2/3 - compatible function - * `unichr()` removed in Python 3, import `unichr` for Python 2/3 compatible - function - * Use `u()` for escaped unicode sequences (e.g. u'\u2020' -> u('\u2020')) - * Use `u_decode()` to decode utf-8 formatted unicode strings - * `string_types` gives str in Python 3, unicode and str in Python 2, - equivalent to basestring - -Integer related changes: - * `long()` removed in Python 3, import `long` for Python 2/3 compatible - function - * `integer_types` gives int in Python 3, int and long in Python 2 - -Types related changes: - * `class_types` gives type in Python 3, type and ClassType in Python 2 - -Renamed function attributes: - * Python 2 `.func_code`, Python 3 `.__func__`, access with - `get_function_code()` - * Python 2 `.func_globals`, Python 3 `.__globals__`, access with - `get_function_globals()` - * Python 2 `.func_name`, Python 3 `.__name__`, access with - `get_function_name()` - -Moved modules: - * `reduce()` - * `StringIO()` - * `cStringIO()` (same as `StingIO()` in Python 3) - * Python 2 `__builtins__`, access with Python 3 name, `builtins` - -Iterator/list changes: - * `xrange` removed in Python 3, import `xrange` for Python 2/3 compatible - iterator version of range - -exec: - * Use `exec_()`, with parameters `exec_(code, globs=None, locs=None)` - -Metaclasses: - * Use `with_metaclass()`, examples below - * Define class `Foo` with metaclass `Meta`, and no parent: - class Foo(with_metaclass(Meta)): - pass - * Define class `Foo` with metaclass `Meta` and parent class `Bar`: - class Foo(with_metaclass(Meta, Bar)): - pass -""" - -import sys -PY3 = sys.version_info[0] > 2 - -if PY3: - class_types = type, - integer_types = (int,) - string_types = (str,) - long = int - - # String / unicode compatibility - unicode = str - unichr = chr - def u(x): - return x - def u_decode(x): - return x - - Iterator = object - - # Moved definitions - get_function_code = operator.attrgetter("__code__") - get_function_globals = operator.attrgetter("__globals__") - get_function_name = operator.attrgetter("__name__") - - import builtins - from functools import reduce - from io import StringIO - cStringIO = StringIO - - exec_ = getattr(builtins, "exec") - - xrange = range -else: - import codecs - import types - - class_types = (type, types.ClassType) - integer_types = (int, long) - string_types = (str, unicode) - long = long - - # String / unicode compatibility - unicode = unicode - unichr = unichr - def u(x): - return codecs.unicode_escape_decode(x)[0] - def u_decode(x): - return x.decode('utf-8') - - class Iterator(object): - def next(self): - return type(self).__next__(self) - - # Moved definitions - get_function_code = operator.attrgetter("func_code") - get_function_globals = operator.attrgetter("func_globals") - get_function_name = operator.attrgetter("func_name") - - import __builtin__ as builtins - reduce = reduce - from StringIO import StringIO - from cStringIO import StringIO as cStringIO - - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("exec _code_ in _globs_, _locs_") - - xrange = xrange - -def with_metaclass(meta, *bases): - """ - Create a base class with a metaclass. - - For example, if you have the metaclass - - >>> class Meta(type): - ... pass - - Use this as the metaclass by doing - - >>> from symengine.compatibility import with_metaclass - >>> class MyClass(with_metaclass(Meta, object)): - ... pass - - This is equivalent to the Python 2:: - - class MyClass(object): - __metaclass__ = Meta - - or Python 3:: - - class MyClass(object, metaclass=Meta): - pass - - That is, the first argument is the metaclass, and the remaining arguments - are the base classes. Note that if the base class is just ``object``, you - may omit it. - - >>> MyClass.__mro__ - (, <... 'object'>) - >>> type(MyClass) - - - """ - class metaclass(meta): - __call__ = type.__call__ - __init__ = type.__init__ - def __new__(cls, name, this_bases, d): - if this_bases is None: - return type.__new__(cls, name, (), d) - return meta(name, bases, d) - return metaclass("NewBase", None, {}) - - -# These are in here because telling if something is an iterable just by calling -# hasattr(obj, "__iter__") behaves differently in Python 2 and Python 3. In -# particular, hasattr(str, "__iter__") is False in Python 2 and True in Python 3. -# I think putting them here also makes it easier to use them in the core. - -class NotIterable: - """ - Use this as mixin when creating a class which is not supposed to return - true when iterable() is called on its instances. I.e. avoid infinite loop - when calling e.g. list() on the instance - """ - pass - -def iterable(i, exclude=(string_types, dict, NotIterable)): - """ - Return a boolean indicating whether ``i`` is SymPy iterable. - True also indicates that the iterator is finite, i.e. you e.g. - call list(...) on the instance. - - When SymPy is working with iterables, it is almost always assuming - that the iterable is not a string or a mapping, so those are excluded - by default. If you want a pure Python definition, make exclude=None. To - exclude multiple items, pass them as a tuple. - - See also: is_sequence - - Examples - ======== - - >>> from sympy.utilities.iterables import iterable - >>> from sympy import Tuple - >>> things = [[1], (1,), set([1]), Tuple(1), (j for j in [1, 2]), {1:2}, '1', 1] - >>> for i in things: - ... print('%s %s' % (iterable(i), type(i))) - True <... 'list'> - True <... 'tuple'> - True <... 'set'> - True - True <... 'generator'> - False <... 'dict'> - False <... 'str'> - False <... 'int'> - - >>> iterable({}, exclude=None) - True - >>> iterable({}, exclude=str) - True - >>> iterable("no", exclude=str) - False - - """ - try: - iter(i) - except TypeError: - return False - if exclude: - return not isinstance(i, exclude) - return True - - -def is_sequence(i, include=None): - """ - Return a boolean indicating whether ``i`` is a sequence in the SymPy - sense. If anything that fails the test below should be included as - being a sequence for your application, set 'include' to that object's - type; multiple types should be passed as a tuple of types. - - Note: although generators can generate a sequence, they often need special - handling to make sure their elements are captured before the generator is - exhausted, so these are not included by default in the definition of a - sequence. - - See also: iterable - - Examples - ======== - - >>> from sympy.utilities.iterables import is_sequence - >>> from types import GeneratorType - >>> is_sequence([]) - True - >>> is_sequence(set()) - False - >>> is_sequence('abc') - False - >>> is_sequence('abc', include=str) - True - >>> generator = (c for c in 'abc') - >>> is_sequence(generator) - False - >>> is_sequence(generator, include=(str, GeneratorType)) - True - - """ - return (hasattr(i, '__getitem__') and - iterable(i) or - bool(include) and - isinstance(i, include)) - -try: - from functools import cmp_to_key -except ImportError: # <= Python 2.6 - def cmp_to_key(mycmp): - """ - Convert a cmp= function into a key= function - """ - class K(object): - def __init__(self, obj, *args): - self.obj = obj - - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - return K - -try: - from itertools import zip_longest -except ImportError: # <= Python 2.7 - from itertools import izip_longest as zip_longest - -try: - from itertools import combinations_with_replacement -except ImportError: # <= Python 2.6 - def combinations_with_replacement(iterable, r): - """Return r length subsequences of elements from the input iterable - allowing individual elements to be repeated more than once. - - Combinations are emitted in lexicographic sort order. So, if the - input iterable is sorted, the combination tuples will be produced - in sorted order. - - Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, the generated combinations - will also be unique. - - See also: combinations - - Examples - ======== - - >>> from sympy.core.compatibility import combinations_with_replacement - >>> list(combinations_with_replacement('AB', 2)) - [('A', 'A'), ('A', 'B'), ('B', 'B')] - """ - pool = tuple(iterable) - n = len(pool) - if not n and r: - return - indices = [0] * r - yield tuple(pool[i] for i in indices) - while True: - for i in reversed(range(r)): - if indices[i] != n - 1: - break - else: - return - indices[i:] = [indices[i] + 1] * (r - i) - yield tuple(pool[i] for i in indices) - - -def as_int(n): - """ - Convert the argument to a builtin integer. - - The return value is guaranteed to be equal to the input. ValueError is - raised if the input has a non-integral value. - - Examples - ======== - - >>> from sympy.core.compatibility import as_int - >>> from sympy import sqrt - >>> 3.0 - 3.0 - >>> as_int(3.0) # convert to int and test for equality - 3 - >>> int(sqrt(10)) - 3 - >>> as_int(sqrt(10)) - Traceback (most recent call last): - ... - ValueError: ... is not an integer - - """ - try: - result = int(n) - if result != n: - raise TypeError - except TypeError: - raise ValueError('%s is not an integer' % n) - return result - - -def default_sort_key(item, order=None): - """Return a key that can be used for sorting. - - The key has the structure: - - (class_key, (len(args), args), exponent.sort_key(), coefficient) - - This key is supplied by the sort_key routine of Basic objects when - ``item`` is a Basic object or an object (other than a string) that - sympifies to a Basic object. Otherwise, this function produces the - key. - - The ``order`` argument is passed along to the sort_key routine and is - used to determine how the terms *within* an expression are ordered. - (See examples below) ``order`` options are: 'lex', 'grlex', 'grevlex', - and reversed values of the same (e.g. 'rev-lex'). The default order - value is None (which translates to 'lex'). - - Examples - ======== - - >>> from sympy import S, I, default_sort_key - >>> from sympy.core.function import UndefinedFunction - >>> from sympy.abc import x - - The following are equivalent ways of getting the key for an object: - - >>> x.sort_key() == default_sort_key(x) - True - - Here are some examples of the key that is produced: - - >>> default_sort_key(UndefinedFunction('f')) - ((0, 0, 'UndefinedFunction'), (1, ('f',)), ((1, 0, 'Number'), - (0, ()), (), 1), 1) - >>> default_sort_key('1') - ((0, 0, 'str'), (1, ('1',)), ((1, 0, 'Number'), (0, ()), (), 1), 1) - >>> default_sort_key(S.One) - ((1, 0, 'Number'), (0, ()), (), 1) - >>> default_sort_key(2) - ((1, 0, 'Number'), (0, ()), (), 2) - - - While sort_key is a method only defined for SymPy objects, - default_sort_key will accept anything as an argument so it is - more robust as a sorting key. For the following, using key= - lambda i: i.sort_key() would fail because 2 doesn't have a sort_key - method; that's why default_sort_key is used. Note, that it also - handles sympification of non-string items likes ints: - - >>> a = [2, I, -I] - >>> sorted(a, key=default_sort_key) - [2, -I, I] - - The returned key can be used anywhere that a key can be specified for - a function, e.g. sort, min, max, etc...: - - >>> a.sort(key=default_sort_key); a[0] - 2 - >>> min(a, key=default_sort_key) - 2 - - Note - ---- - - The key returned is useful for getting items into a canonical order - that will be the same across platforms. It is not directly useful for - sorting lists of expressions: - - >>> a, b = x, 1/x - - Since ``a`` has only 1 term, its value of sort_key is unaffected by - ``order``: - - >>> a.sort_key() == a.sort_key('rev-lex') - True - - If ``a`` and ``b`` are combined then the key will differ because there - are terms that can be ordered: - - >>> eq = a + b - >>> eq.sort_key() == eq.sort_key('rev-lex') - False - >>> eq.as_ordered_terms() - [x, 1/x] - >>> eq.as_ordered_terms('rev-lex') - [1/x, x] - - But since the keys for each of these terms are independent of ``order``'s - value, they don't sort differently when they appear separately in a list: - - >>> sorted(eq.args, key=default_sort_key) - [1/x, x] - >>> sorted(eq.args, key=lambda i: default_sort_key(i, order='rev-lex')) - [1/x, x] - - The order of terms obtained when using these keys is the order that would - be obtained if those terms were *factors* in a product. - - See Also - ======== - - sympy.core.expr.as_ordered_factors, sympy.core.expr.as_ordered_terms - - """ - - from sympy.core import S, Basic - from sympy.core.sympify import sympify, SympifyError - from sympy.core.compatibility import iterable - - if isinstance(item, Basic): - return item.sort_key(order=order) - - if iterable(item, exclude=string_types): - if isinstance(item, dict): - args = item.items() - unordered = True - elif isinstance(item, set): - args = item - unordered = True - else: - # e.g. tuple, list - args = list(item) - unordered = False - - args = [default_sort_key(arg, order=order) for arg in args] - - if unordered: - # e.g. dict, set - args = sorted(args) - - cls_index, args = 10, (len(args), tuple(args)) - else: - if not isinstance(item, string_types): - try: - item = sympify(item) - except SympifyError: - # e.g. lambda x: x - pass - else: - if isinstance(item, Basic): - # e.g int -> Integer - return default_sort_key(item) - # e.g. UndefinedFunction - - # e.g. str - cls_index, args = 0, (1, (str(item),)) - - return (cls_index, 0, item.__class__.__name__ - ), args, S.One.sort_key(), S.One - - -def _nodes(e): - """ - A helper for ordered() which returns the node count of ``e`` which - for Basic objects is the number of Basic nodes in the expression tree - but for other objects is 1 (unless the object is an iterable or dict - for which the sum of nodes is returned). - """ - from .basic import Basic - - if isinstance(e, Basic): - return e.count(Basic) - elif iterable(e): - return 1 + sum(_nodes(ei) for ei in e) - elif isinstance(e, dict): - return 1 + sum(_nodes(k) + _nodes(v) for k, v in e.items()) - else: - return 1 - - -def ordered(seq, keys=None, default=True, warn=False): - """Return an iterator of the seq where keys are used to break ties in - a conservative fashion: if, after applying a key, there are no ties - then no other keys will be computed. - - Two default keys will be applied if 1) keys are not provided or 2) the - given keys don't resolve all ties (but only if `default` is True). The - two keys are `_nodes` (which places smaller expressions before large) and - `default_sort_key` which (if the `sort_key` for an object is defined - properly) should resolve any ties. - - If ``warn`` is True then an error will be raised if there were no - keys remaining to break ties. This can be used if it was expected that - there should be no ties between items that are not identical. - - Examples - ======== - - >>> from sympy.utilities.iterables import ordered - >>> from sympy import count_ops - >>> from sympy.abc import x, y - - The count_ops is not sufficient to break ties in this list and the first - two items appear in their original order (i.e. the sorting is stable): - - >>> list(ordered([y + 2, x + 2, x**2 + y + 3], - ... count_ops, default=False, warn=False)) - ... - [y + 2, x + 2, x**2 + y + 3] - - The default_sort_key allows the tie to be broken: - - >>> list(ordered([y + 2, x + 2, x**2 + y + 3])) - ... - [x + 2, y + 2, x**2 + y + 3] - - Here, sequences are sorted by length, then sum: - - >>> seq, keys = [[[1, 2, 1], [0, 3, 1], [1, 1, 3], [2], [1]], [ - ... lambda x: len(x), - ... lambda x: sum(x)]] - ... - >>> list(ordered(seq, keys, default=False, warn=False)) - [[1], [2], [1, 2, 1], [0, 3, 1], [1, 1, 3]] - - If ``warn`` is True, an error will be raised if there were not - enough keys to break ties: - - >>> list(ordered(seq, keys, default=False, warn=True)) - Traceback (most recent call last): - ... - ValueError: not enough keys to break ties - - - Notes - ===== - - The decorated sort is one of the fastest ways to sort a sequence for - which special item comparison is desired: the sequence is decorated, - sorted on the basis of the decoration (e.g. making all letters lower - case) and then undecorated. If one wants to break ties for items that - have the same decorated value, a second key can be used. But if the - second key is expensive to compute then it is inefficient to decorate - all items with both keys: only those items having identical first key - values need to be decorated. This function applies keys successively - only when needed to break ties. By yielding an iterator, use of the - tie-breaker is delayed as long as possible. - - This function is best used in cases when use of the first key is - expected to be a good hashing function; if there are no unique hashes - from application of a key then that key should not have been used. The - exception, however, is that even if there are many collisions, if the - first group is small and one does not need to process all items in the - list then time will not be wasted sorting what one was not interested - in. For example, if one were looking for the minimum in a list and - there were several criteria used to define the sort order, then this - function would be good at returning that quickly if the first group - of candidates is small relative to the number of items being processed. - - """ - d = defaultdict(list) - if keys: - if not isinstance(keys, (list, tuple)): - keys = [keys] - keys = list(keys) - f = keys.pop(0) - for a in seq: - d[f(a)].append(a) - else: - if not default: - raise ValueError('if default=False then keys must be provided') - d[None].extend(seq) - - for k in sorted(d.keys()): - if len(d[k]) > 1: - if keys: - d[k] = ordered(d[k], keys, default, warn) - elif default: - d[k] = ordered(d[k], (_nodes, default_sort_key,), - default=False, warn=warn) - elif warn: - from sympy.utilities.iterables import uniq - u = list(uniq(d[k])) - if len(u) > 1: - raise ValueError( - 'not enough keys to break ties: %s' % u) - for v in d[k]: - yield v - d.pop(k) - - -# check_output() is new in Python 2.7 -import os - -try: - try: - from subprocess import check_output - except ImportError: # <= Python 2.6 - from subprocess import CalledProcessError, check_call - def check_output(*args, **kwargs): - with open(os.devnull, 'w') as fh: - kwargs['stdout'] = fh - try: - return check_call(*args, **kwargs) - except CalledProcessError as e: - e.output = ("program output is not available for Python 2.6.x") - raise e -except ImportError: - # running on platform like App Engine, no subprocess at all - pass - - -# lru_cache compatible with py2.6->py3.2 copied directly from -# http://code.activestate.com/ -# recipes/578078-py26-and-py30-backport-of-python-33s-lru-cache/ -from collections import namedtuple -from functools import update_wrapper -from threading import RLock - -_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"]) - -class _HashedSeq(list): - __slots__ = 'hashvalue' - - def __init__(self, tup, hash=hash): - self[:] = tup - self.hashvalue = hash(tup) - - def __hash__(self): - return self.hashvalue - -def _make_key(args, kwds, typed, - kwd_mark = (object(),), - fasttypes = set((int, str, frozenset, type(None))), - sorted=sorted, tuple=tuple, type=type, len=len): - 'Make a cache key from optionally typed positional and keyword arguments' - key = args - if kwds: - sorted_items = sorted(kwds.items()) - key += kwd_mark - for item in sorted_items: - key += item - if typed: - key += tuple(type(v) for v in args) - if kwds: - key += tuple(type(v) for k, v in sorted_items) - elif len(key) == 1 and type(key[0]) in fasttypes: - return key[0] - return _HashedSeq(key) - -def lru_cache(maxsize=100, typed=False): - """Least-recently-used cache decorator. - - If *maxsize* is set to None, the LRU features are disabled and the cache - can grow without bound. - - If *typed* is True, arguments of different types will be cached separately. - For example, f(3.0) and f(3) will be treated as distinct calls with - distinct results. - - Arguments to the cached function must be hashable. - - View the cache statistics named tuple (hits, misses, maxsize, currsize) with - f.cache_info(). Clear the cache and statistics with f.cache_clear(). - Access the underlying function with f.__wrapped__. - - See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used - - """ - - # Users should only access the lru_cache through its public API: - # cache_info, cache_clear, and f.__wrapped__ - # The internals of the lru_cache are encapsulated for thread safety and - # to allow the implementation to change (including a possible C version). - - def decorating_function(user_function): - - cache = dict() - stats = [0, 0] # make statistics updateable non-locally - HITS, MISSES = 0, 1 # names for the stats fields - make_key = _make_key - cache_get = cache.get # bound method to lookup key or return None - _len = len # localize the global len() function - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - nonlocal_root = [root] # make updateable non-locally - PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - - if maxsize == 0: - - def wrapper(*args, **kwds): - # no caching, just do a statistics update after a successful call - result = user_function(*args, **kwds) - stats[MISSES] += 1 - return result - - elif maxsize is None: - - def wrapper(*args, **kwds): - # simple caching without ordering or size limit - key = make_key(args, kwds, typed) - result = cache_get(key, root) # root used here as a unique not-found sentinel - if result is not root: - stats[HITS] += 1 - return result - result = user_function(*args, **kwds) - cache[key] = result - stats[MISSES] += 1 - return result - - else: - - def wrapper(*args, **kwds): - # size limited caching that tracks accesses by recency - try: - key = make_key(args, kwds, typed) if kwds or typed else args - except TypeError: - stats[MISSES] += 1 - return user_function(*args, **kwds) - with lock: - link = cache_get(key) - if link is not None: - # record recent use of the key by moving it to the front of the list - root, = nonlocal_root - link_prev, link_next, key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - stats[HITS] += 1 - return result - result = user_function(*args, **kwds) - with lock: - root, = nonlocal_root - if key in cache: - # getting here means that this same key was added to the - # cache while the lock was released. since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif _len(cache) >= maxsize: - # use the old root to store the new key and result - oldroot = root - oldroot[KEY] = key - oldroot[RESULT] = result - # empty the oldest link and make it the new root - root = nonlocal_root[0] = oldroot[NEXT] - oldkey = root[KEY] - oldvalue = root[RESULT] - root[KEY] = root[RESULT] = None - # now update the cache dictionary for the new links - del cache[oldkey] - cache[key] = oldroot - else: - # put result in a new link at the front of the list - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - stats[MISSES] += 1 - return result - - def cache_info(): - """Report cache statistics""" - with lock: - return _CacheInfo(stats[HITS], stats[MISSES], maxsize, len(cache)) - - def cache_clear(): - """Clear the cache and cache statistics""" - with lock: - cache.clear() - root = nonlocal_root[0] - root[:] = [root, root, None, None] - stats[:] = [0, 0] - - wrapper.__wrapped__ = user_function - wrapper.cache_info = cache_info - wrapper.cache_clear = cache_clear - return update_wrapper(wrapper, user_function) - - return decorating_function -### End of backported lru_cache - -if sys.version_info[:2] >= (3, 3): - # 3.2 has an lru_cache with an incompatible API - from functools import lru_cache diff --git a/symengine/lib/symengine_wrapper.pxd b/symengine/lib/symengine_wrapper.pxd index 653854dc0..0728c42bd 100644 --- a/symengine/lib/symengine_wrapper.pxd +++ b/symengine/lib/symengine_wrapper.pxd @@ -1,3 +1,5 @@ +#cython: language_level=3 + cimport symengine from symengine cimport RCP, map_basic_basic, rcp_const_basic from libcpp.vector cimport vector diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index e72b26f37..32c576ac0 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -17,15 +17,11 @@ from operator import mul from functools import reduce import collections import warnings -from symengine.compatibility import is_sequence +from symengine.utilities import is_sequence import os import sys from cpython.pycapsule cimport PyCapsule_GetPointer - -if sys.version_info[0] == 2: - from collections import MutableMapping -else: - from collections.abc import MutableMapping +from collections.abc import MutableMapping try: import numpy as np @@ -872,13 +868,6 @@ cdef class Basic(object): if A is None or B is None: return NotImplemented return c2py(symengine.div(A.thisptr, B.thisptr)) - # This is for Python 2.7 compatibility only: - def __div__(a, b): - cdef Basic A = _sympify(a, False) - cdef Basic B = _sympify(b, False) - if A is None or B is None: return NotImplemented - return c2py(symengine.div(A.thisptr, B.thisptr)) - def __pow__(a, b, c): if c is not None: return powermod(a, b, c) @@ -2681,7 +2670,6 @@ class FunctionSymbol(Function): cdef RCP[const symengine.FunctionSymbol] X = \ symengine.rcp_static_cast_FunctionSymbol(self.thisptr) name = deref(X).get_name().decode("utf-8") - # In Python 2.7, function names cannot be unicode: return str(name) def _sympy_(self): @@ -3259,9 +3247,6 @@ cdef class DenseMatrixBase(MatrixBase): else: return NotImplemented - def __div__(a, b): - return div_matrices(a, b) - def __truediv__(a, b): return div_matrices(a, b) diff --git a/symengine/utilities.py b/symengine/utilities.py index e25c12b10..e3d85aa37 100644 --- a/symengine/utilities.py +++ b/symengine/utilities.py @@ -1,5 +1,4 @@ from .lib.symengine_wrapper import Symbol, Basic -from .compatibility import string_types from itertools import combinations, permutations, product, product as cartes import re as _re import string @@ -85,7 +84,7 @@ def symbols(names, **args): """ result = [] - if isinstance(names, string_types): + if isinstance(names, str): marker = 0 literals = ['\,', '\:', '\ '] for i in range(len(literals)): @@ -333,3 +332,42 @@ def __exit__(self, exc_type, exc_value, traceback): if exc_type is None: raise AssertionError("DID NOT RAISE") return issubclass(exc_type, self.expectedException) + + +class NotIterable: + """ + Use this as mixin when creating a class which is not supposed to return + true when iterable() is called on its instances. I.e. avoid infinite loop + when calling e.g. list() on the instance + """ + pass + + +def iterable(i, exclude=(str, dict, NotIterable)): + """ + Return a boolean indicating whether ``i`` is SymPy iterable. + True also indicates that the iterator is finite, i.e. you e.g. + call list(...) on the instance. + + When SymPy is working with iterables, it is almost always assuming + that the iterable is not a string or a mapping, so those are excluded + by default. If you want a pure Python definition, make exclude=None. To + exclude multiple items, pass them as a tuple. + """ + try: + iter(i) + except TypeError: + return False + if exclude: + return not isinstance(i, exclude) + return True + + +def is_sequence(i): + """ + Return a boolean indicating whether ``i`` is a sequence in the SymPy + sense. If anything that fails the test below should be included as + being a sequence for your application, set 'include' to that object's + type; multiple types should be passed as a tuple of types. + """ + return hasattr(i, '__getitem__') and iterable(i) From 1613329918a58b3569f6883d122be01be84a1d1a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 20:10:05 -0600 Subject: [PATCH 084/314] Fix bad merge conflict resolution --- setup.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.py b/setup.py index d3a09c9a1..6bbdda3e5 100644 --- a/setup.py +++ b/setup.py @@ -222,11 +222,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", -<<<<<<< HEAD python_requires='>=3.6.*,<4', -======= - python_requires='!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,<4', ->>>>>>> 916b786... Remove support for python 2 and 3.5 zip_safe=False, cmdclass = cmdclass, classifiers=[ From 38c97bc9341be469db04badf9713c72bca7d9b91 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 13 Mar 2021 22:17:24 -0600 Subject: [PATCH 085/314] Check for PYTHON_LIBRARY only on windows --- cmake/FindPython.cmake | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 4cb97cc50..16dc5af25 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -37,15 +37,17 @@ message(STATUS "Python version: ${PYTHON_VERSION}") string(REPLACE "." "" PYTHON_VERSION_WITHOUT_DOTS ${PYTHON_VERSION}) -FIND_LIBRARY(PYTHON_LIBRARY NAMES +if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + FIND_LIBRARY(PYTHON_LIBRARY NAMES python${PYTHON_VERSION} python${PYTHON_VERSION}m python${PYTHON_VERSION_WITHOUT_DOTS} - PATHS ${PYTHON_LIB_PATH} ${PYTHON_PREFIX_PATH}/lib ${PYTHON_PREFIX_PATH}/libs - PATH_SUFFIXES ${CMAKE_LIBRARY_ARCHITECTURE} - NO_DEFAULT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - ) + PATHS ${PYTHON_LIB_PATH} ${PYTHON_PREFIX_PATH}/lib ${PYTHON_PREFIX_PATH}/libs + PATH_SUFFIXES ${CMAKE_LIBRARY_ARCHITECTURE} + NO_DEFAULT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + ) +endif() execute_process( COMMAND ${PYTHON_BIN} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" @@ -66,7 +68,12 @@ set(PYTHON_EXTENSION_SOABI ${PYTHON_EXTENSION_SOABI_tmp} CACHE STRING "Suffix for python extensions") INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Python DEFAULT_MSG PYTHON_LIBRARY PYTHON_INCLUDE_PATH PYTHON_INSTALL_PATH) + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Python DEFAULT_MSG PYTHON_LIBRARY PYTHON_INCLUDE_PATH PYTHON_INSTALL_PATH) +else () + FIND_PACKAGE_HANDLE_STANDARD_ARGS(Python DEFAULT_MSG PYTHON_INCLUDE_PATH PYTHON_INSTALL_PATH) +endif () # Links a Python extension module. From ad210e3735baf1e0d494476949d3820a39d332f8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 15 Mar 2021 04:45:25 -0500 Subject: [PATCH 086/314] Release 0.7.0.post1 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6bbdda3e5..abe2a7a03 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.0", + version="0.7.0.post1", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index f63021cde..b14eaa15f 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.0" +__version__ = "0.7.0.post1" # To not expose internals From 140e036bddcc74e2e51a7f18c4681b4be13dfaf8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 16 Mar 2021 21:57:43 -0500 Subject: [PATCH 087/314] Update version to 0.7.0.post2 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index abe2a7a03..753ab802b 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.0.post1", + version="0.7.0.post2", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index b14eaa15f..823226bb7 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.0.post1" +__version__ = "0.7.0.post2" # To not expose internals From f738e3131f3f783d32862372cddde4094e687ebd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 20 Mar 2021 13:29:28 -0500 Subject: [PATCH 088/314] bump to v0.7.0.post3 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 753ab802b..9318a7d20 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.0.post2", + version="0.7.0.post3", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 823226bb7..8f2c44dca 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.0.post2" +__version__ = "0.7.0.post3" # To not expose internals From 9a2b4dfb750ac816129ca21cb5d11eac09f68b67 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 24 Mar 2021 15:56:58 -0500 Subject: [PATCH 089/314] Hide all symbols except PyInit_symengine_wrapper --- cmake/FindPython.cmake | 14 +++++++++++--- cmake/version_script.txt | 4 ++++ setup.py | 2 +- symengine/__init__.py | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 cmake/version_script.txt diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 16dc5af25..69fa6d492 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -112,12 +112,20 @@ macro(ADD_PYTHON_LIBRARY name) # and "-flat_namespace -undefined suppress" link flags, that we need # to add by hand: set_target_properties(${name} PROPERTIES - LINK_FLAGS "-flat_namespace -undefined suppress") - ELSE(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + LINK_FLAGS "-flat_namespace -undefined suppress -Wl,--exported_symbol,_PyInit_${name}") + ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # on Linux, we need to use the "-shared" gcc flag, which is what SHARED # does: + set(PYTHON_EXTENSION_NAME ${name}) add_library(${name} SHARED ${ARGN}) - ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + configure_file(${CMAKE_SOURCE_DIR}/cmake/version_script.txt + ${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt @ONLY) + set_target_properties(${name} PROPERTIES + LINK_FLAGS "-flat_namespace -undefined suppress " + "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") + ELSE + add_library(${name} SHARED ${ARGN}) + ENDIF() set_target_properties(${name} PROPERTIES PREFIX "") set_target_properties(${name} PROPERTIES OUTPUT_NAME "${name}${PYTHON_EXTENSION_SOABI}") IF(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") diff --git a/cmake/version_script.txt b/cmake/version_script.txt new file mode 100644 index 000000000..0b24ad9fa --- /dev/null +++ b/cmake/version_script.txt @@ -0,0 +1,4 @@ +{ + global: PyInit_@PYTHON_EXTENSION_NAME@; + local: *; +}; diff --git a/setup.py b/setup.py index 9318a7d20..7044c8f39 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.0.post3", + version="0.7.1", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 8f2c44dca..c15473d21 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.0.post3" +__version__ = "0.7.1" # To not expose internals From c7257c5d71b6115208530ddd39015f22ab147952 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 24 Mar 2021 16:17:27 -0500 Subject: [PATCH 090/314] Fix linux flags --- cmake/FindPython.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 69fa6d492..6a8f41c56 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -121,8 +121,7 @@ macro(ADD_PYTHON_LIBRARY name) configure_file(${CMAKE_SOURCE_DIR}/cmake/version_script.txt ${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt @ONLY) set_target_properties(${name} PROPERTIES - LINK_FLAGS "-flat_namespace -undefined suppress " - "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") ELSE add_library(${name} SHARED ${ARGN}) ENDIF() From 16690b7a756ced018177e7e0075956a79793d73b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 24 Mar 2021 16:35:15 -0500 Subject: [PATCH 091/314] Fix typo --- cmake/FindPython.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 6a8f41c56..2a1f97023 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -122,7 +122,7 @@ macro(ADD_PYTHON_LIBRARY name) ${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt @ONLY) set_target_properties(${name} PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") - ELSE + ELSE() add_library(${name} SHARED ${ARGN}) ENDIF() set_target_properties(${name} PROPERTIES PREFIX "") From 8a39a220355a9d544d946ec265abd34ae15d3ec3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 25 Mar 2021 21:53:33 -0500 Subject: [PATCH 092/314] Fix link flags --- cmake/FindPython.cmake | 8 ++++---- setup.py | 2 +- symengine/__init__.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 2a1f97023..287f52903 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -111,8 +111,8 @@ macro(ADD_PYTHON_LIBRARY name) add_library(${name} MODULE ${ARGN}) # and "-flat_namespace -undefined suppress" link flags, that we need # to add by hand: - set_target_properties(${name} PROPERTIES - LINK_FLAGS "-flat_namespace -undefined suppress -Wl,--exported_symbol,_PyInit_${name}") + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -flat_namespace -undefined suppress -Wl,-exported_symbol,_PyInit_${name}") ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # on Linux, we need to use the "-shared" gcc flag, which is what SHARED # does: @@ -120,8 +120,8 @@ macro(ADD_PYTHON_LIBRARY name) add_library(${name} SHARED ${ARGN}) configure_file(${CMAKE_SOURCE_DIR}/cmake/version_script.txt ${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt @ONLY) - set_target_properties(${name} PROPERTIES - LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") ELSE() add_library(${name} SHARED ${ARGN}) ENDIF() diff --git a/setup.py b/setup.py index 7044c8f39..8e64d9301 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.1", + version="0.7.2", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.19.1'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index c15473d21..1dfad11e6 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.1" +__version__ = "0.7.2" # To not expose internals From a65af1ce0aa436fcdd1aafea195e19a2deede2fa Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sun, 28 Mar 2021 20:45:49 +0200 Subject: [PATCH 093/314] Properly handle sympy matrix for Matrix constructor --- symengine/lib/symengine_wrapper.pyx | 2 +- symengine/tests/test_sympy_conv.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 32c576ac0..03584eb52 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3170,7 +3170,7 @@ cdef class DenseMatrixBase(MatrixBase): self.thisptr = new symengine.DenseMatrix(row, col) return if col is None: - v = row + v = sympify(row) row = 0 cdef symengine.vec_basic v_ cdef DenseMatrixBase A diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 9015cda14..913c78f47 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -783,3 +783,16 @@ def test_pynumber(): b = b / x assert isinstance(b, PyNumber) + + +@unittest.skipIf(not have_sympy, "SymPy not installed") +def test_construct_dense_matrix(): + # Test for issue #347 + A = sympy.Matrix([[1, 2], [3, 5]]) + B = DenseMatrix(A) + assert B.rows == 2 + assert B.cols == 2 + assert B[0, 0] == 1 + assert B[0, 1] == 2 + assert B[1, 0] == 3 + assert B[1, 1] == 5 From 803d00bd70f856828832bc664c16c25587430751 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Mon, 29 Mar 2021 20:31:43 +0200 Subject: [PATCH 094/314] Update symengine/tests/test_sympy_conv.py Co-authored-by: Isuru Fernando --- symengine/tests/test_sympy_conv.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 913c78f47..1234fcabc 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -790,9 +790,5 @@ def test_construct_dense_matrix(): # Test for issue #347 A = sympy.Matrix([[1, 2], [3, 5]]) B = DenseMatrix(A) - assert B.rows == 2 - assert B.cols == 2 - assert B[0, 0] == 1 - assert B[0, 1] == 2 - assert B[1, 0] == 3 - assert B[1, 1] == 5 + assert B.shape == (2, 2) + assert list(B) == [1, 2, 3, 5] From 4cafd8b3026e29a4591c3a974d91acfc8e2bb08d Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 6 May 2021 10:19:38 -0400 Subject: [PATCH 095/314] Add support for 32 and 16 bit numpy floats This commit adds support for 32 and 16 bit floats numpy as input types. Since it doesn't look like there is a native symengine type for working with single (or half) precision floats outside of using MPFR (which seemed like the wrong approach here, it might make sense for np.float128 in a follow up though) this implicitly casts the np.float16 and np.float32 types to doubles and just behaves as float/np.float64. Fixes #351 --- symengine/lib/symengine_wrapper.pyx | 8 ++++++++ symengine/tests/test_subs.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 03584eb52..0111da705 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -295,6 +295,10 @@ def sympy2symengine(a, raise_error=False): return RealDouble(float(str(a))) ELSE: return RealDouble(float(str(a))) + elif isinstance(a, np.float16): + return RealDouble(a) + elif isinstance(a, np.float32): + return RealDouble(a) elif a is sympy.I: return I elif a is sympy.E: @@ -558,6 +562,10 @@ def _sympify(a, raise_error=True): return Integer(a) elif isinstance(a, float): return RealDouble(a) + elif isinstance(a, np.float16): + return RealDouble(a) + elif isinstance(a, np.float32): + return RealDouble(a) elif isinstance(a, complex): return ComplexDouble(a) elif hasattr(a, '_symengine_'): diff --git a/symengine/tests/test_subs.py b/symengine/tests/test_subs.py index 2f762ddf6..f71fc2853 100644 --- a/symengine/tests/test_subs.py +++ b/symengine/tests/test_subs.py @@ -1,3 +1,5 @@ +import numpy as np + from symengine.utilities import raises from symengine import Symbol, sin, cos, sqrt, Add, function_symbol @@ -56,3 +58,15 @@ def test_xreplace(): y = Symbol("y") f = sin(cos(x)) assert f.xreplace({x: y}) == sin(cos(y)) + + +def test_float32(): + x = Symbol("x") + expr = x * 2 + assert expr.subs({x: np.float32(2)}) == 4.0 + + +def test_float16(): + x = Symbol("x") + expr = x * 2 + assert expr.subs({x: np.float16(2)}) == 4.0 From 57f66c6848f54dd8dc4704f3c5e8269ed451899e Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 6 May 2021 16:47:32 -0400 Subject: [PATCH 096/314] Fix support when building without numpy --- symengine/lib/symengine_wrapper.pyx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 0111da705..c950744ee 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -295,9 +295,7 @@ def sympy2symengine(a, raise_error=False): return RealDouble(float(str(a))) ELSE: return RealDouble(float(str(a))) - elif isinstance(a, np.float16): - return RealDouble(a) - elif isinstance(a, np.float32): + elif have_numpy and isinstance(a, (np.float16, np.float32)): return RealDouble(a) elif a is sympy.I: return I @@ -562,9 +560,7 @@ def _sympify(a, raise_error=True): return Integer(a) elif isinstance(a, float): return RealDouble(a) - elif isinstance(a, np.float16): - return RealDouble(a) - elif isinstance(a, np.float32): + elif have_numpy and isinstance(a, (np.float16, np.float32)): return RealDouble(a) elif isinstance(a, complex): return ComplexDouble(a) From 97ded0836bcaa81d2b527184d75598587c52d7d0 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 6 May 2021 17:01:27 -0400 Subject: [PATCH 097/314] Remove unecessary lines --- symengine/lib/symengine_wrapper.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c950744ee..4dde65317 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -295,8 +295,6 @@ def sympy2symengine(a, raise_error=False): return RealDouble(float(str(a))) ELSE: return RealDouble(float(str(a))) - elif have_numpy and isinstance(a, (np.float16, np.float32)): - return RealDouble(a) elif a is sympy.I: return I elif a is sympy.E: From 65ceced4a5f0a80cb1fe15b7ad09e056cf3c0b7e Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 6 May 2021 17:13:58 -0400 Subject: [PATCH 098/314] Skip tests if numpy is not installed --- symengine/tests/test_subs.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/symengine/tests/test_subs.py b/symengine/tests/test_subs.py index f71fc2853..bc03b1e39 100644 --- a/symengine/tests/test_subs.py +++ b/symengine/tests/test_subs.py @@ -1,7 +1,7 @@ -import numpy as np +import unittest from symengine.utilities import raises -from symengine import Symbol, sin, cos, sqrt, Add, function_symbol +from symengine import Symbol, sin, cos, sqrt, Add, function_symbol, have_numpy def test_basic(): @@ -60,13 +60,17 @@ def test_xreplace(): assert f.xreplace({x: y}) == sin(cos(y)) +@unittest.skipUnless(have_numpy, "Numpy not installed") def test_float32(): + import numpy as np x = Symbol("x") expr = x * 2 assert expr.subs({x: np.float32(2)}) == 4.0 +@unittest.skipUnless(have_numpy, "Numpy not installed") def test_float16(): + import numpy as np x = Symbol("x") expr = x * 2 assert expr.subs({x: np.float16(2)}) == 4.0 From 01b2f6255e05a808b14a9541b7a762277e409edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sat, 29 May 2021 19:37:04 +0200 Subject: [PATCH 099/314] Fix python_requires to unbreak installed package metadata The '>=3.6.*' entry in python_requires is invalid and results in broken metadata being installed. This in turn causes distlib to break. To reproduce: $ pip install distlib symengine $ python -c "import distlib.database; \ distlib.database.DistributionPath().get_distribution('symengine')" Traceback (most recent call last): File "/tmp/venv3/lib/python3.9/site-packages/distlib/metadata.py", line 677, in __init__ self._data = json.loads(data) File "/usr/lib/python3.9/json/__init__.py", line 346, in loads return _default_decoder.decode(s) File "/usr/lib/python3.9/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "", line 1, in File "/tmp/venv3/lib/python3.9/site-packages/distlib/database.py", line 240, in get_distribution self._generate_cache() File "/tmp/venv3/lib/python3.9/site-packages/distlib/database.py", line 167, in _generate_cache for dist in self._yield_distributions(): File "/tmp/venv3/lib/python3.9/site-packages/distlib/database.py", line 148, in _yield_distributions metadata = Metadata(fileobj=stream, scheme='legacy') File "/tmp/venv3/lib/python3.9/site-packages/distlib/metadata.py", line 686, in __init__ self._legacy = LegacyMetadata(fileobj=StringIO(data), File "/tmp/venv3/lib/python3.9/site-packages/distlib/metadata.py", line 261, in __init__ self.read_file(fileobj) File "/tmp/venv3/lib/python3.9/site-packages/distlib/metadata.py", line 359, in read_file self.set(field, value) File "/tmp/venv3/lib/python3.9/site-packages/distlib/metadata.py", line 459, in set if not scheme.is_valid_constraint_list(value): File "/tmp/venv3/lib/python3.9/site-packages/distlib/version.py", line 716, in is_valid_constraint_list return self.is_valid_matcher('dummy_name (%s)' % s) File "/tmp/venv3/lib/python3.9/site-packages/distlib/version.py", line 703, in is_valid_matcher self.matcher(s) File "/tmp/venv3/lib/python3.9/site-packages/distlib/version.py", line 115, in __init__ raise ValueError('\'.*\' not allowed for ' ValueError: '.*' not allowed for '>=' constraints --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 8e64d9301..7b2a2d7bc 100644 --- a/setup.py +++ b/setup.py @@ -222,7 +222,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", - python_requires='>=3.6.*,<4', + python_requires='>=3.6,<4', zip_safe=False, cmdclass = cmdclass, classifiers=[ From c969732f5213afd5f527f21977d8ddf9d7d221ef Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 8 Jun 2021 17:25:15 -0500 Subject: [PATCH 100/314] wrap LUdecomposition --- symengine/lib/symengine.pxd | 4 +++- symengine/lib/symengine_wrapper.pyx | 11 +++++++++++ symengine/tests/test_matrices.py | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index b6b009c2c..0c8686b90 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -832,7 +832,6 @@ cdef extern from "" namespace "SymEngine": DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) void inverse_FFLU "SymEngine::inverse_fraction_free_LU"(const DenseMatrix &A, DenseMatrix &B) nogil except + - void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[int] &P) nogil except + void pivoted_LU_solve (const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) nogil except + void inverse_GJ "SymEngine::inverse_gauss_jordan"(const DenseMatrix &A, DenseMatrix &B) nogil except + @@ -857,6 +856,9 @@ cdef extern from "" namespace "SymEngine": void dot(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &C) nogil void cross(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &C) nogil +cdef extern from "": + void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[pair[int, int]] &P) nogil except + + cdef extern from "" namespace "SymEngine": int probab_prime_p(const Integer &a, int reps) RCP[const Integer] nextprime (const Integer &a) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4dde65317..0d624cac0 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3678,6 +3678,17 @@ cdef class DenseMatrixBase(MatrixBase): deref(self.thisptr).LU(deref(L.thisptr), deref(U.thisptr)) return L, U + def LUdecomposition(self): + cdef DenseMatrixBase L = self.__class__(self.nrows(), self.ncols()) + cdef DenseMatrixBase U = self.__class__(self.nrows(), self.ncols()) + cdef vector[pair[int, int]] perm + symengine.pivoted_LU( + deref(symengine.static_cast_DenseMatrix(self.thisptr)), + deref(symengine.static_cast_DenseMatrix(L.thisptr)), + deref(symengine.static_cast_DenseMatrix(U.thisptr)), + perm) + return L, U, perm + def LDL(self): cdef DenseMatrixBase L = self.__class__(self.nrows(), self.ncols()) cdef DenseMatrixBase D = self.__class__(self.nrows(), self.ncols()) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 9e40658c9..3b53443d7 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -685,3 +685,15 @@ def test_atoms(): b = Symbol("b") X = DenseMatrix([[a, 2], [b, 4]]) assert X.atoms(Symbol) == set([a, b]) + + +def test_LUdecomp(): + testmat = DenseMatrix([[0, 2, 5, 3], + [3, 3, 7, 4], + [8, 4, 0, 2], + [-2, 6, 3, 4]]) + L, U, p = testmat.LUdecomposition() + res = L*U + for orig, new in p: + res.row_swap(orig, new) + assert res - testmat == zeros(4) From 9ea40f34d6a9d9727dbf5c8a099cb45511769d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 22 Jun 2021 10:09:12 +0200 Subject: [PATCH 101/314] prime sieve has moved to new header in latest symengine master --- .gitignore | 1 + symengine/lib/symengine.pxd | 1 + symengine_version.txt | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fb54b321d..1ef1e18ed 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ symengine.egg-info/ genDocs/ docs/_build/ docs/source/ +symengine/lib/version_script_symengine_wrapper.txt diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 0c8686b90..9a1cd818f 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -910,6 +910,7 @@ cdef extern from "" namespace "SymEngine": void powermod_list(vec_integer &powm, RCP[const Integer] a, RCP[const Number] b, RCP[const Integer] m) nogil +cdef extern from "" namespace "SymEngine": void sieve_generate_primes "SymEngine::Sieve::generate_primes"(vector[unsigned] &primes, unsigned limit) nogil cdef cppclass sieve_iterator "SymEngine::Sieve::iterator": diff --git a/symengine_version.txt b/symengine_version.txt index 8b20e4852..9b927f803 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.7.0 +24c9d19b43eee3e4e76bbd3b7fab18dfe5ad00ca From 41b9411610e2e246586ccbf6b4aec81eec7ebced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 22 Jun 2021 13:44:59 +0200 Subject: [PATCH 102/314] Tweak CI scripts --- bin/test_travis.sh | 7 ++++--- symengine_version.txt | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bin/test_travis.sh b/bin/test_travis.sh index 74dabbaab..6d0f636ca 100755 --- a/bin/test_travis.sh +++ b/bin/test_travis.sh @@ -6,12 +6,13 @@ set -e set -x # Build inplace so that nosetests can be run inside source directory -python setup.py install build_ext --inplace --symengine-dir=$our_install_dir +python3 setup.py install build_ext --inplace --symengine-dir=$our_install_dir # Test python wrappers -py.test -s -v $PYTHON_SOURCE_DIR/symengine/tests/test_*.py +python3 -m pip install pytest +python3 -m pytest -s -v $PYTHON_SOURCE_DIR/symengine/tests/test_*.py mkdir -p empty && cd empty -python $PYTHON_SOURCE_DIR/bin/test_python.py +python3 $PYTHON_SOURCE_DIR/bin/test_python.py cd .. if [[ "${TRIGGER_FEEDSTOCK}" == "yes" ]]; then diff --git a/symengine_version.txt b/symengine_version.txt index 9b927f803..57f392b76 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -24c9d19b43eee3e4e76bbd3b7fab18dfe5ad00ca +bb386f47369500d76cda07e6e9f014bfe6339f64 From 4dce246049396658a0af53e6df0e6addeecabb32 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 26 Jun 2021 15:27:27 -0500 Subject: [PATCH 103/314] Throw if matrix is non-square --- symengine/lib/symengine_wrapper.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 0d624cac0..22d7cc3d7 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3679,6 +3679,8 @@ cdef class DenseMatrixBase(MatrixBase): return L, U def LUdecomposition(self): + if self.rows != self.cols: + raise NotImplementedError("LU decomposition not implemented for non-square matrices yet.") cdef DenseMatrixBase L = self.__class__(self.nrows(), self.ncols()) cdef DenseMatrixBase U = self.__class__(self.nrows(), self.ncols()) cdef vector[pair[int, int]] perm From d025f576375ffc148c27a23b7150724bf69ec3b9 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Wed, 18 Aug 2021 21:19:58 +0200 Subject: [PATCH 104/314] Update README.md Update required version of Python --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea43b2b28..268d6b8dc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ optionally, you may choose to install an early [developer preview](https://githu Install prerequisites. CMake >= 2.8.7 - Python2 >= 2.7 or Python3 >= 3.4 + Python3 >= 3.6 Cython >= 0.19.1 SymEngine >= 0.4.0 From d1e7adc56ebe670122ab584841c0a7ec2ced18d3 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Mon, 23 Aug 2021 19:45:00 +0200 Subject: [PATCH 105/314] Update CI Stop testing using Python 3.6 Test on Ubuntu 20.04 Update to latest version of symengine --- .github/workflows/ci.yml | 52 ++++++++++++++++------------------------ symengine_version.txt | 2 +- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c09022a71..519228689 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,24 +8,17 @@ jobs: fail-fast: false matrix: include: - - BUILD_TYPE: Debug - WITH_BFD: yes - PYTHON_VERSION: 3.6 - TEST_SYMPY: yes - OS: ubuntu-16.04 - CC: gcc - - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: 3.9 TEST_SYMPY: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: 3.7 BUILD_SHARED_LIBS: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release @@ -33,66 +26,63 @@ jobs: WITH_MPFR: yes INTEGER_CLASS: gmpxx WITH_NUMPY: no - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: 3.8 WITH_MPC: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release WITH_MPFR: yes PYTHON_VERSION: 3.8 - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: 3.9 WITH_MPC: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.6 + PYTHON_VERSION: 3.9 WITH_MPC: yes INTEGER_CLASS: flint WITH_FLINT: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Debug - PYTHON_VERSION: 3.7 + PYTHON_VERSION: 3.9 WITH_BFD: yes WITH_PIRANHA: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: gcc - EXTRA_APT_PACKAGES: "g++-4.8" - BUILD_TYPE: Debug PYTHON_VERSION: 3.8 WITH_BFD: yes BUILD_SHARED_LIBS: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: clang - BUILD_TYPE: Release PYTHON_VERSION: 3.7 WITH_NUMPY: yes - OS: ubuntu-16.04 + OS: ubuntu-20.04 CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: 3.6 + PYTHON_VERSION: 3.8 WITH_SYMPY: yes - WITH_LLVM: 8.0 + WITH_LLVM: 13 WITH_SCIPY: yes - OS: ubuntu-16.04 - CC: gcc-4.8 - CXX: g++-4.8 - EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main' - EXTRA_APT_PACKAGES: 'g++-4.8 libstdc++-4.8-dev binutils-dev llvm-8-dev' + OS: ubuntu-20.04 + EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main' + EXTRA_APT_PACKAGES: 'llvm-13' - BUILD_TYPE: Debug PYTHON_VERSION: 3.7 @@ -114,13 +104,13 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.6 + PYTHON_VERSION: 3.8 OS: macos-latest CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.6 - OS: ubuntu-16.04 + PYTHON_VERSION: 3.8 + OS: ubuntu-20.04 WITH_MPC: yes WITH_MPFR: yes WITH_FLINT: yes @@ -148,7 +138,7 @@ jobs: TEST_IN_TREE: ${{ matrix.TEST_IN_TREE }} WITH_SYMENGINE_THREAD_SAFE: ${{ matrix.WITH_SYMENGINE_THREAD_SAFE }} WITH_PRIMESIEVE: ${{ matrix.WITH_PRIMESIEVE }} - INTEGER_CLASS: ${{ matrix.INTEGER_CLASS }} + INTEGER_CLASS: ${{ matrix.gNTEGER_CLASS }} WITH_ARB: ${{ matrix.WITH_ARB }} WITH_PIRANHA: ${{ matrix.WITH_PIRANHA }} WITH_GCC_6: ${{ matrix.WITH_GCC_6 }} diff --git a/symengine_version.txt b/symengine_version.txt index 5e9087c83..936c631b6 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -bb386f47369500d76cda07e6e9f014bfe6339f64 \ No newline at end of file +b104685091b4b84a26ac3ab75b8c51943390eb05 From b209fdeda198dcb10e9d6c7d0dc544fa9471a06d Mon Sep 17 00:00:00 2001 From: Garming Sam Date: Fri, 30 Jul 2021 02:24:12 +0000 Subject: [PATCH 106/314] tests: Add tests for differentiation This ensures that the zero-th derivative returns the correct answer. The sympy python library returns the 'correct' answer. There are still some other deviations which are documented further in the next commit. Signed-off-by: Garming Sam --- symengine/tests/test_functions.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 2086394ce..848b0aeba 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -62,6 +62,8 @@ def test_derivative(): assert f.diff(y) == 0 assert f.diff(x).args == (f, x) assert f.diff(x).diff(x).args == (f, x, x) + assert f.diff(x, 0) == f + assert f.diff(x, 0) == Derivative(function_symbol("f", x), x, 0) g = function_symbol("f", y) assert g.diff(x) == 0 @@ -84,6 +86,17 @@ def test_derivative(): assert g == fxy.diff(y, 1, x, 2) assert g == fxy.diff(y, x, 2) + h = Derivative(Function("f")(x, y), x, 0, y, 1) + assert h == fxy.diff(x, 0, y) + assert h == fxy.diff(y, x, 0) + + i = Derivative(Function("f")(x, y), x, 0, y, 1, x, 1) + assert i == fxy.diff(x, 0, y, x, 1) + assert i == fxy.diff(x, 0, y, x) + assert i == fxy.diff(y, x) + assert i == fxy.diff(y, 1, x, 1) + assert i == fxy.diff(y, 1, x) + def test_abs(): x = Symbol("x") From d5277383168fcfbd0b7608c200ed141f67d6d769 Mon Sep 17 00:00:00 2001 From: Garming Sam Date: Fri, 30 Jul 2021 02:20:59 +0000 Subject: [PATCH 107/314] symengine_wrapper.pyx: Calculate the zero-th derivative This is useful for more general, albeit sometimes inefficient, summation code. Just copying some taylor expansion code from the internet worked with sympy but not symengine due to the following error: Traceback (most recent call last): File "example.py", line 32, in taylor(symengine.sympify('1/(1-x-x^2)'), 0, 15) File "example.py", line 27, in taylor p = p + (function.diff(x, i).subs(x, x0))/(factorial(i))*(x - x0)**i File "symengine_wrapper.pyx", line 923, in symengine.lib.symengine_wrapper.Basic.diff File "symengine_wrapper.pyx", line 4020, in symengine.lib.symengine_wrapper.diff OverflowError: can't convert negative value to size_t There are a number of inconsistencies compared to the regular sympy library: 1. Takes no argument: >>> symengine.sympify('x**2').diff() 2*x This actually seems helpful, except when you have #2 misleading you. This is not accepted in sympy, but doesn't necessarily need a fix. 2. Takes a standalone integer argument and returns a nonsense answer: >>> symengine.sympify('x**2').diff(1) x**2 This is simply not accepted in the regular sympy library. 3. Takes multiple integer arguments and aggregates: diff(x, 1, 1) == diff(x, 2) This does not occur with the sympy library, and does not seem useful. It can easily be replaced with diff(x, x), if repetition was necessary. 4. Takes only integer arguments > 1: diff(x, 0) returns integer overflow This is accepted in sympy. In this patch, 2-4 are all fixed. #1 seems like a potentially useful (and likely used) feature. Signed-off-by: Garming Sam --- symengine/lib/symengine_wrapper.pyx | 47 ++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1eb5fabc0..69628cf9a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4056,18 +4056,55 @@ atexit.register(module_cleanup) def diff(ex, *args): ex = sympify(ex) - prev = 0 + prev = None cdef Basic b cdef size_t i - for x in args: + length = len(args) + + if not length: + return ex + + l = 0 + x = args[l] + b = sympify(x) + l += 1 + + while l <= length: + # Assume symbol 'x' or 'y' currently in b + # Pointer to next arg l is either derivative order or a separate symbol + + prev = b + + if l == length: + # No next argument, differentiate with no integer argument + if isinstance(b, Integer): + raise ValueError("Unexpected integer argument") + ex = ex._diff(b) + break + + x = args[l] b = sympify(x) + # Check if the next arg was derivative order if isinstance(b, Integer): - i = int(b) - 1 + i = int(b) for j in range(i): ex = ex._diff(prev) + + # Move forward to point at next symbol + l += 1 + if l == length: + break + + x = args[l] + b = sympify(x) + if isinstance(b, Integer): + raise ValueError("Unexpected double integer argument") else: - ex = ex._diff(b) - prev = b + # Separate symbol and no derivative order, differentiate now + ex = ex._diff(prev) + + l += 1 + return ex def expand(x, deep=True): From 7fa2091ad06e88bc4abccc42886cb2464b30d474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Thu, 26 Aug 2021 09:27:31 +0200 Subject: [PATCH 108/314] Latest Cython might avoid deprecated Python C-API --- README.md | 8 ++++---- setup.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 268d6b8dc..66b24f013 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ optionally, you may choose to install an early [developer preview](https://githu Install prerequisites. - CMake >= 2.8.7 - Python3 >= 3.6 - Cython >= 0.19.1 - SymEngine >= 0.4.0 + CMake >= 2.8.12 + Python3 >= 3.7 + Cython >= 0.29.24 + SymEngine >= 0.7.0 For SymEngine, only a specific commit/tag (see symengine_version.txt) is supported. Latest git master branch may not work as there may be breaking changes in SymEngine. diff --git a/setup.py b/setup.py index 7b2a2d7bc..46274dbaf 100644 --- a/setup.py +++ b/setup.py @@ -216,7 +216,7 @@ def finalize_options(self): setup(name="symengine", version="0.7.2", description="Python library providing wrappers to SymEngine", - setup_requires=['cython>=0.19.1'], + setup_requires=['cython>=0.29.24'], long_description=long_description, author="SymEngine development team", author_email="symengine@googlegroups.com", From cc478b29f071bcd75bdfc62f4c34d5ef6bf240db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Thu, 26 Aug 2021 15:55:29 +0200 Subject: [PATCH 109/314] Add support for Python's matrix multiplication operator --- symengine/lib/symengine_wrapper.pyx | 11 +++++++++-- symengine/tests/test_matrices.py | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1eb5fabc0..162f45e0a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3271,6 +3271,13 @@ cdef class DenseMatrixBase(MatrixBase): else: return NotImplemented + def __matmul__(a, b): + a = _sympify(a, False) + b = _sympify(b, False) + if (a.ncols() != b.nrows()): + raise ShapeError("Invalid shapes for matrix multiplication. Got %s %s" % (a.shape, b.shape)) + return a.mul_matrix(b) + def __truediv__(a, b): return div_matrices(a, b) @@ -4889,7 +4896,7 @@ cdef class LambdaDouble(_Lambdify): c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) cpdef as_scipy_low_level_callable(self): from ctypes import c_double, c_void_p, c_int, cast, POINTER, CFUNCTYPE @@ -5135,7 +5142,7 @@ def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', raise ValueError("Long double not supported on this platform") else: raise ValueError("Unknown numpy dtype.") - + if as_scipy: return ret.as_scipy_low_level_callable() return ret diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 7538a4474..f01c10b0e 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -229,6 +229,8 @@ def test_mul_matrix(): assert A.mul_matrix(B) == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) assert A * B == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) + assert A @ B == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) + assert (A @ DenseMatrix(2, 1, [0]*4)).shape == (2, 1) C = DenseMatrix(2, 3, [1, 2, 3, 2, 3, 4]) D = DenseMatrix(3, 2, [3, 4, 4, 5, 5, 6]) From 71ab90cb460e9ca2505b9c467020240bfe37a815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Thu, 26 Aug 2021 19:51:51 +0200 Subject: [PATCH 110/314] raise an exception if conflicting shape is given to DenseMatrix at construction --- symengine/lib/symengine_wrapper.pyx | 2 ++ symengine/tests/test_matrices.py | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 162f45e0a..2c8777131 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3230,6 +3230,8 @@ cdef class DenseMatrixBase(MatrixBase): raise ValueError("sizes don't match.") else: self.thisptr = new symengine.DenseMatrix(0, 0, v_) + elif col is not None and (row*col != v_.size()): + raise ValueError("Number of elements should equal rows*columns.") else: self.thisptr = new symengine.DenseMatrix(row, v_.size() / row, v_) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index f01c10b0e..0b5fb39c9 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -12,6 +12,10 @@ HAVE_NUMPY = False +def test_init(): + raises(ValueError, DenseMatrix(2, 1, [0]*4)) + + def test_get(): A = DenseMatrix([[1, 2], [3, 4]]) @@ -230,7 +234,7 @@ def test_mul_matrix(): assert A.mul_matrix(B) == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) assert A * B == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) assert A @ B == DenseMatrix(2, 2, [a + b, 0, c + d, 0]) - assert (A @ DenseMatrix(2, 1, [0]*4)).shape == (2, 1) + assert (A @ DenseMatrix(2, 1, [0]*2)).shape == (2, 1) C = DenseMatrix(2, 3, [1, 2, 3, 2, 3, 4]) D = DenseMatrix(3, 2, [3, 4, 4, 5, 5, 6]) From fc36776e0d412e9f70138ba5f7fc757e0aeb7e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 27 Aug 2021 09:42:54 +0200 Subject: [PATCH 111/314] forgot a lambda in raises (fixup) --- symengine/tests/test_matrices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 0b5fb39c9..901c4e2de 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -13,7 +13,7 @@ def test_init(): - raises(ValueError, DenseMatrix(2, 1, [0]*4)) + raises(ValueError, lambda: DenseMatrix(2, 1, [0]*4)) def test_get(): From 5d25f2f000b0202bc43d03b6cec528e56b2b1ee6 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Fri, 27 Aug 2021 09:50:22 +0200 Subject: [PATCH 112/314] Fix typo --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 519228689..db74652bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -138,7 +138,7 @@ jobs: TEST_IN_TREE: ${{ matrix.TEST_IN_TREE }} WITH_SYMENGINE_THREAD_SAFE: ${{ matrix.WITH_SYMENGINE_THREAD_SAFE }} WITH_PRIMESIEVE: ${{ matrix.WITH_PRIMESIEVE }} - INTEGER_CLASS: ${{ matrix.gNTEGER_CLASS }} + INTEGER_CLASS: ${{ matrix.INTEGER_CLASS }} WITH_ARB: ${{ matrix.WITH_ARB }} WITH_PIRANHA: ${{ matrix.WITH_PIRANHA }} WITH_GCC_6: ${{ matrix.WITH_GCC_6 }} From b61e6deeea13a31693251e30783fdb8931f7f72b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 6 Sep 2021 17:49:54 -0500 Subject: [PATCH 113/314] install newer cython --- bin/install_travis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/install_travis.sh b/bin/install_travis.sh index e70997f37..581354a06 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -2,7 +2,7 @@ # symengine's bin/install_travis.sh will install miniconda -export conda_pkgs="python=${PYTHON_VERSION} pip cython pytest gmp mpfr" +export conda_pkgs="python=${PYTHON_VERSION} pip 'cython>=0.29.24' pytest gmp mpfr" if [[ "${WITH_NUMPY}" != "no" ]]; then export conda_pkgs="${conda_pkgs} numpy"; From 42cf3700c21955570f739a222a95a8198e6a2c25 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 7 Sep 2021 00:31:17 -0500 Subject: [PATCH 114/314] Refactor and use cdef --- symengine/lib/symengine_wrapper.pyx | 61 +++++++++++------------------ symengine/tests/test_functions.py | 4 ++ 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 69628cf9a..1f91acd47 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4054,58 +4054,43 @@ def module_cleanup(): import atexit atexit.register(module_cleanup) -def diff(ex, *args): - ex = sympify(ex) - prev = None +def diff(expr, *args): + cdef Basic ex = sympify(expr) + cdef Basic prev cdef Basic b cdef size_t i - length = len(args) + cdef size_t length = len(args) if not length: return ex - l = 0 - x = args[l] - b = sympify(x) - l += 1 + cdef size_t l = 0 + cdef Basic cur_arg, next_arg + cur_arg = sympify(args[l]) - while l <= length: - # Assume symbol 'x' or 'y' currently in b - # Pointer to next arg l is either derivative order or a separate symbol + while l < length: + if isinstance(cur_arg, Integer): + raise ValueError("Unexpected integer argument") - prev = b - - if l == length: + if l + 1 == length: # No next argument, differentiate with no integer argument - if isinstance(b, Integer): - raise ValueError("Unexpected integer argument") - ex = ex._diff(b) - break + return ex._diff(cur_arg) - x = args[l] - b = sympify(x) + next_arg = sympify(args[l + 1]) # Check if the next arg was derivative order - if isinstance(b, Integer): - i = int(b) - for j in range(i): - ex = ex._diff(prev) - - # Move forward to point at next symbol - l += 1 + if isinstance(next_arg, Integer): + i = int(next_arg) + for _ in range(i): + ex = ex._diff(cur_arg) + l += 2 if l == length: - break - - x = args[l] - b = sympify(x) - if isinstance(b, Integer): - raise ValueError("Unexpected double integer argument") + return ex + cur_arg = sympify(args[l]) else: - # Separate symbol and no derivative order, differentiate now - ex = ex._diff(prev) - - l += 1 + ex = ex._diff(cur_arg) + l += 1 + cur_arg = next_arg - return ex def expand(x, deep=True): return sympify(x).expand(deep) diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 848b0aeba..0a0388cfd 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -5,6 +5,7 @@ loggamma, beta, polygamma, digamma, trigamma, sign, floor, ceiling, conjugate, nan, Float, UnevaluatedExpr ) +from symengine.utilities import raises import unittest @@ -64,6 +65,9 @@ def test_derivative(): assert f.diff(x).diff(x).args == (f, x, x) assert f.diff(x, 0) == f assert f.diff(x, 0) == Derivative(function_symbol("f", x), x, 0) + raises(ValueError, lambda: f.diff(0)) + raises(ValueError, lambda: f.diff(x, 0, 0)) + raises(ValueError, lambda: f.diff(x, y, 0, 0, x)) g = function_symbol("f", y) assert g.diff(x) == 0 From d19e3aeb419a168cb846e4240aba3b11de0fd9ea Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 7 Sep 2021 23:18:50 -0500 Subject: [PATCH 115/314] update C++ version --- CMakeLists.txt | 2 +- symengine_version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4b13eb70..6bb764968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.12) project(python_wrapper) set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH}) -find_package(SymEngine 0.7.0 REQUIRED CONFIG +find_package(SymEngine 0.8.1 REQUIRED CONFIG PATH_SUFFIXES lib/cmake/symengine cmake/symengine CMake/) message("SymEngine_DIR : " ${SymEngine_DIR}) message("SymEngine Version : " ${SymEngine_VERSION}) diff --git a/symengine_version.txt b/symengine_version.txt index 936c631b6..85f7059bb 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -b104685091b4b84a26ac3ab75b8c51943390eb05 +v0.8.1 From 6243d01d8a022a01a3ca8eaced832ee1e70fd7ca Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 7 Sep 2021 23:20:27 -0500 Subject: [PATCH 116/314] Update version to 0.8.0 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 46274dbaf..c12b0d439 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.7.2", + version="0.8.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 1d7c6bdbd..ae213f386 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -56,7 +56,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.7.2" +__version__ = "0.8.0" # To not expose internals From 6819df90209f04a0a0b34cafd30edcd02764139b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 7 Sep 2021 23:22:11 -0500 Subject: [PATCH 117/314] =?UTF-8?q?Add=20Matthew,=20Micha=C5=82,=20Garming?= =?UTF-8?q?=20to=20AUTHORS.=20Welcome=20to=20SymEngine!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .mailmap | 1 + AUTHORS | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.mailmap b/.mailmap index b5cf86a6f..efc30bd6d 100644 --- a/.mailmap +++ b/.mailmap @@ -19,3 +19,4 @@ Sumith Kulal Sushant Hiray Abhinav Agarwal Nilay Pochhi +Björn Dahlgren diff --git a/AUTHORS b/AUTHORS index d8863966f..26e4df59c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -29,3 +29,6 @@ Simon Stelter Jialin Ma Rikard Nordgren Rohit Goswami +Matthew Treinish +Michał Górny +Garming Sam From 018ecee7cd63a6fe842b331ad69f7e25c926a826 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 8 Sep 2021 17:06:23 -0500 Subject: [PATCH 118/314] Fix Matrix.diff --- symengine/lib/symengine_wrapper.pyx | 11 +++++------ symengine/tests/test_matrices.py | 6 ++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 9a12efa2b..619ea5def 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4064,14 +4064,13 @@ import atexit atexit.register(module_cleanup) def diff(expr, *args): - cdef Basic ex = sympify(expr) cdef Basic prev cdef Basic b cdef size_t i cdef size_t length = len(args) if not length: - return ex + return expr cdef size_t l = 0 cdef Basic cur_arg, next_arg @@ -4083,20 +4082,20 @@ def diff(expr, *args): if l + 1 == length: # No next argument, differentiate with no integer argument - return ex._diff(cur_arg) + return expr._diff(cur_arg) next_arg = sympify(args[l + 1]) # Check if the next arg was derivative order if isinstance(next_arg, Integer): i = int(next_arg) for _ in range(i): - ex = ex._diff(cur_arg) + expr = expr._diff(cur_arg) l += 2 if l == length: - return ex + return expr cur_arg = sympify(args[l]) else: - ex = ex._diff(cur_arg) + expr = expr._diff(cur_arg) l += 1 cur_arg = next_arg diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 901c4e2de..31dd13011 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -655,6 +655,12 @@ def test_cross(): DenseMatrix(1, 2, [1, 1]).cross(DenseMatrix(1, 2, [1, 1]))) +def test_diff(): + x = symbols("x") + M = DenseMatrix(1, 2, [x**2, x]) + assert M.diff(x) == DenseMatrix(1, 2, [2*x, 1]) + + def test_immutablematrix(): A = ImmutableMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) assert A.shape == (3, 3) From ded8a6c532507f0e599b0a43a23aa2ea0c77b32d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 8 Sep 2021 17:25:18 -0500 Subject: [PATCH 119/314] sympify exprs except matrices --- symengine/lib/symengine_wrapper.pyx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 619ea5def..c4736db5a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4063,7 +4063,16 @@ def module_cleanup(): import atexit atexit.register(module_cleanup) + def diff(expr, *args): + if isinstance(expr, MatrixBase): + # Don't sympify matrices so that mutable matrices + # return mutable matrices + return _diff(expr, *args) + return _diff(sympify(expr, *args)) + + +def _diff(expr, *args): cdef Basic prev cdef Basic b cdef size_t i From 185a4c5ee5bb47c7662ba117a2b8a8bf4a985b9b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 8 Sep 2021 17:27:19 -0500 Subject: [PATCH 120/314] test that mutable returns mutable --- symengine/lib/symengine_wrapper.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c4736db5a..499413114 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -930,7 +930,7 @@ cdef class Basic(object): if (len(f) != 1): raise RuntimeError("Variable w.r.t should be given") return self._diff(f.pop()) - return diff(self, *args) + return _diff(self, *args) def subs_dict(Basic self not None, *args): warnings.warn("subs_dict() is deprecated. Use subs() instead", DeprecationWarning) @@ -3687,7 +3687,7 @@ cdef class DenseMatrixBase(MatrixBase): return R def diff(self, *args): - return diff(self, *args) + return _diff(self, *args) #TODO: implement this in C++ def subs(self, *args): From 95e5321818b05862c998ab1eaa1050786e86fca2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 8 Sep 2021 17:35:09 -0500 Subject: [PATCH 121/314] Fix sympify --- symengine/lib/symengine_wrapper.pyx | 2 +- symengine/tests/test_matrices.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 499413114..d178afe53 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4069,7 +4069,7 @@ def diff(expr, *args): # Don't sympify matrices so that mutable matrices # return mutable matrices return _diff(expr, *args) - return _diff(sympify(expr, *args)) + return _diff(sympify(expr), *args) def _diff(expr, *args): diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 31dd13011..ea2a8d72e 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -658,7 +658,9 @@ def test_cross(): def test_diff(): x = symbols("x") M = DenseMatrix(1, 2, [x**2, x]) - assert M.diff(x) == DenseMatrix(1, 2, [2*x, 1]) + result = M.diff(x) + assert isinstance(result, DenseMatrix) + assert result == DenseMatrix(1, 2, [2*x, 1]) def test_immutablematrix(): From d0db511a89b68a9baa46d6821a2c3c689a8c4e15 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 8 Sep 2021 20:23:29 -0500 Subject: [PATCH 122/314] Update version to 0.8.1 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index c12b0d439..5f15b696a 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.8.0", + version="0.8.1", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index ae213f386..5085641d1 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -56,7 +56,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.8.0" +__version__ = "0.8.1" # To not expose internals From 1dee729aa347d6c41d4f6baa626a450ec6bb884d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 9 Sep 2021 11:27:55 -0500 Subject: [PATCH 123/314] package missing files from cmake directory --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 5ff1ff6bd..c5d457e29 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ include CMakeLists.txt LICENSE README.md symengine_version.txt recursive-include symengine *.cpp *.h *.hpp CMakeLists.txt *.in *.cmake *.pyx *.pxd *.py *.pxi -recursive-include cmake *.cpp *.in *.cmake *.pyx +recursive-include cmake *.cpp *.in *.cmake *.pyx *.py *.txt From 8b8ed55cca796669f08a5637a23c8de7f99acc8a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 9 Sep 2021 12:23:46 -0500 Subject: [PATCH 124/314] check sdist --- bin/test_travis.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/test_travis.sh b/bin/test_travis.sh index 6d0f636ca..31599d2f8 100755 --- a/bin/test_travis.sh +++ b/bin/test_travis.sh @@ -5,6 +5,12 @@ set -e # Echo each command set -x +python setup.py sdist +mkdir dist-extract +cd dist-extract +tar -xvf ../dist/symengine-*.tar.gz +cd symengine-* + # Build inplace so that nosetests can be run inside source directory python3 setup.py install build_ext --inplace --symengine-dir=$our_install_dir @@ -13,10 +19,3 @@ python3 -m pip install pytest python3 -m pytest -s -v $PYTHON_SOURCE_DIR/symengine/tests/test_*.py mkdir -p empty && cd empty python3 $PYTHON_SOURCE_DIR/bin/test_python.py -cd .. - -if [[ "${TRIGGER_FEEDSTOCK}" == "yes" ]]; then - cd $PYTHON_SOURCE_DIR - ./bin/trigger_feedstock.sh -fi - From 6a8ae4c7f9fa038c2ac9c1b94d49dd893ad13d6a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 9 Sep 2021 13:13:42 -0500 Subject: [PATCH 125/314] Set PYTHON_SOURCE_DIR to the new directory --- bin/test_travis.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/test_travis.sh b/bin/test_travis.sh index 31599d2f8..764fc91d3 100755 --- a/bin/test_travis.sh +++ b/bin/test_travis.sh @@ -10,6 +10,7 @@ mkdir dist-extract cd dist-extract tar -xvf ../dist/symengine-*.tar.gz cd symengine-* +export PYTHON_SOURCE_DIR=$PWD # Build inplace so that nosetests can be run inside source directory python3 setup.py install build_ext --inplace --symengine-dir=$our_install_dir From 2c5ed3063c737db6ebc55eabd6f7509e6e3ff4cf Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 9 Sep 2021 13:20:28 -0500 Subject: [PATCH 126/314] Fix inplace tests --- bin/test_travis.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/test_travis.sh b/bin/test_travis.sh index 764fc91d3..d83b27db5 100755 --- a/bin/test_travis.sh +++ b/bin/test_travis.sh @@ -10,13 +10,12 @@ mkdir dist-extract cd dist-extract tar -xvf ../dist/symengine-*.tar.gz cd symengine-* -export PYTHON_SOURCE_DIR=$PWD # Build inplace so that nosetests can be run inside source directory python3 setup.py install build_ext --inplace --symengine-dir=$our_install_dir # Test python wrappers python3 -m pip install pytest -python3 -m pytest -s -v $PYTHON_SOURCE_DIR/symengine/tests/test_*.py +python3 -m pytest -s -v $PWD/symengine/tests/test_*.py mkdir -p empty && cd empty python3 $PYTHON_SOURCE_DIR/bin/test_python.py From 941640cb92f555cd6faf23002d275218875b075f Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 13 Sep 2021 00:17:30 -0500 Subject: [PATCH 127/314] Fix a bug in converting C++ Dummy objects to Python --- symengine/lib/symengine_wrapper.pyx | 2 +- symengine/tests/test_symbol.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index d178afe53..714bfbd25 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -71,7 +71,7 @@ cdef object c2py(rcp_const_basic o): return S.ImaginaryUnit r = Complex.__new__(Complex) elif (symengine.is_a_Dummy(deref(o))): - r = Symbol.__new__(Dummy) + r = Dummy.__new__(Dummy) elif (symengine.is_a_Symbol(deref(o))): if (symengine.is_a_PySymbol(deref(o))): return (deref(symengine.rcp_static_cast_PySymbol(o)).get_py_object()) diff --git a/symengine/tests/test_symbol.py b/symengine/tests/test_symbol.py index ad9d923b9..fc9fafc7c 100644 --- a/symengine/tests/test_symbol.py +++ b/symengine/tests/test_symbol.py @@ -159,6 +159,7 @@ def test_dummy(): assert x1 == x2 assert x1 != xdummy1 + assert xdummy1 == (xdummy1 + 1) - 1 assert xdummy1 != xdummy2 assert Dummy() != Dummy() assert Dummy('x') != Dummy('x') From 8ef62a01139cd33e7e89248e6ffad0e7ee7ce41f Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 24 Sep 2021 23:17:24 +0200 Subject: [PATCH 128/314] add _repr_latex_ to DenseMatrix --- symengine/lib/symengine_wrapper.pyx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 714bfbd25..05ff4cb76 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3241,6 +3241,34 @@ cdef class DenseMatrixBase(MatrixBase): def __str__(self): return deref(self.thisptr).__str__().decode("utf-8") + def _repr_latex_(self): + MAX_NUMBER_OF_ROWS = 24 + MAX_NUMBER_OF_COLUMNS = 16 + + values = list(self) + ncols=self.shape[1] + nrows = self.shape[0] + if nrows > MAX_NUMBER_OF_ROWS: + nrows_display = MAX_NUMBER_OF_ROWS - 2 + else: + nrows_display= nrows + ncols_display = min(ncols, MAX_NUMBER_OF_COLUMNS) + latex = r'$\displaystyle \left[\begin{matrix}' + + newline = r'\\' + if ncols_display Date: Fri, 24 Sep 2021 23:24:14 +0200 Subject: [PATCH 129/314] whitespace --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 05ff4cb76..c417825f3 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3241,7 +3241,7 @@ cdef class DenseMatrixBase(MatrixBase): def __str__(self): return deref(self.thisptr).__str__().decode("utf-8") - def _repr_latex_(self): + def _repr_latex_(self): MAX_NUMBER_OF_ROWS = 24 MAX_NUMBER_OF_COLUMNS = 16 From 60448660caa3498d716eba33703759536f9a8022 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 24 Sep 2021 23:28:46 +0200 Subject: [PATCH 130/314] add test --- symengine/tests/test_matrices.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index ea2a8d72e..3f853ada4 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -725,3 +725,9 @@ def test_LUdecomp(): for orig, new in p: res.row_swap(orig, new) assert res - testmat == zeros(4) + +def test_repr_latex(): + testmat = DenseMatrix([[0, 2]]) + latex_string = testmat._repr_latex_() + assert isinstance(latex_string, str) + \ No newline at end of file From 3c32620fced59ce6cc547705cbe43000e47345dd Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 25 Sep 2021 00:07:19 +0200 Subject: [PATCH 131/314] fix import error --- symengine/printing.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/symengine/printing.py b/symengine/printing.py index c6a06ef91..465ba1707 100644 --- a/symengine/printing.py +++ b/symengine/printing.py @@ -1,5 +1,4 @@ -from symengine.lib.symengine_wrapper import ccode, sympify, Basic -import symengine.lib.symengine_wrapper +from symengine.lib.symengine_wrapper import ccode, sympify, Basic, repr_latex class CCodePrinter: @@ -29,6 +28,6 @@ def init_printing(pretty_print=True, use_latex=True): if pretty_print: if not use_latex: raise RuntimeError("Only latex is supported for pretty printing") - symengine.lib.symengine_wrapper.repr_latex[0] = True + repr_latex[0] = True else: - symengine.lib.symengine_wrapper.repr_latex[0] = False + repr_latex[0] = False From 0dd160bcee7df30acd2198b3c11e949c12c9a264 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 25 Sep 2021 00:10:20 +0200 Subject: [PATCH 132/314] remove del statement --- symengine/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 5085641d1..7baaed3f9 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -60,7 +60,6 @@ def lambdify(args, exprs, **kwargs): # To not expose internals -del lib.symengine_wrapper del lib del wrapper From 9270217f3bb40b46bc1fa6adc1052eba1a2af2d1 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 25 Sep 2021 00:13:08 +0200 Subject: [PATCH 133/314] add test for init_printing --- symengine/tests/test_printing.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/symengine/tests/test_printing.py b/symengine/tests/test_printing.py index 2365dbc98..feea3650e 100644 --- a/symengine/tests/test_printing.py +++ b/symengine/tests/test_printing.py @@ -1,6 +1,6 @@ from symengine import (ccode, Symbol, sqrt, Pow, Max, sin, Integer, MutableDenseMatrix) from symengine.utilities import raises -from symengine.printing import CCodePrinter +from symengine.printing import CCodePrinter, init_printing def test_ccode(): x = Symbol("x") @@ -24,3 +24,9 @@ def test_CCodePrinter(): assert myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]), "larry") == "larry[0] = x;\nlarry[1] = y;" raises(TypeError, lambda: myprinter.doprint(sin(x), Integer)) raises(RuntimeError, lambda: myprinter.doprint(MutableDenseMatrix(1, 2, [x, y]))) + +def test_init_printing(): + x = Symbol("x") + assert x._repr_latex_() is None + init_printing() + assert x._repr_latex_() == '$x$' From ab9e998cecfbf3fb1078a9e7b12ed28d0040ef7b Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 25 Sep 2021 20:16:34 +0200 Subject: [PATCH 134/314] Update symengine/printing.py Co-authored-by: Isuru Fernando --- symengine/printing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/printing.py b/symengine/printing.py index 465ba1707..e095689b7 100644 --- a/symengine/printing.py +++ b/symengine/printing.py @@ -1,4 +1,4 @@ -from symengine.lib.symengine_wrapper import ccode, sympify, Basic, repr_latex +from .lib.symengine_wrapper import ccode, sympify, Basic, repr_latex class CCodePrinter: From ed739fee3043004b68ec7bfdcd7745a5f54f121f Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sun, 26 Sep 2021 11:06:19 +0200 Subject: [PATCH 135/314] hide internals --- symengine/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/symengine/__init__.py b/symengine/__init__.py index 7baaed3f9..5085641d1 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -60,6 +60,7 @@ def lambdify(args, exprs, **kwargs): # To not expose internals +del lib.symengine_wrapper del lib del wrapper From 8d5e646ff0689357a5a7fd0aa46db1a7c2a9c001 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 26 Sep 2021 15:42:14 -0500 Subject: [PATCH 136/314] Hide repr_latex --- symengine/printing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/symengine/printing.py b/symengine/printing.py index e095689b7..6cec481a6 100644 --- a/symengine/printing.py +++ b/symengine/printing.py @@ -1,4 +1,4 @@ -from .lib.symengine_wrapper import ccode, sympify, Basic, repr_latex +from .lib.symengine_wrapper import ccode, sympify, Basic, repr_latex as _repr_latex class CCodePrinter: @@ -28,6 +28,6 @@ def init_printing(pretty_print=True, use_latex=True): if pretty_print: if not use_latex: raise RuntimeError("Only latex is supported for pretty printing") - repr_latex[0] = True + _repr_latex[0] = True else: - repr_latex[0] = False + _repr_latex[0] = False From d1840daf5f79c3b37b81aa7c175b8cade6e471ed Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 27 Sep 2021 08:53:12 +0200 Subject: [PATCH 137/314] trigger build From 4e5464487b2e23405c9f12f45922052ded556f7e Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Wed, 29 Sep 2021 12:46:40 +0200 Subject: [PATCH 138/314] use c++ latex rendering --- symengine/lib/symengine_wrapper.pyx | 36 ++++++++--------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index c417825f3..e08ca254f 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3242,32 +3242,10 @@ cdef class DenseMatrixBase(MatrixBase): return deref(self.thisptr).__str__().decode("utf-8") def _repr_latex_(self): - MAX_NUMBER_OF_ROWS = 24 - MAX_NUMBER_OF_COLUMNS = 16 - - values = list(self) - ncols=self.shape[1] - nrows = self.shape[0] - if nrows > MAX_NUMBER_OF_ROWS: - nrows_display = MAX_NUMBER_OF_ROWS - 2 + if repr_latex[0]: + return latex(deref(self.thisptr)).decode("utf-8") else: - nrows_display= nrows - ncols_display = min(ncols, MAX_NUMBER_OF_COLUMNS) - latex = r'$\displaystyle \left[\begin{matrix}' - - newline = r'\\' - if ncols_display Date: Fri, 1 Oct 2021 19:25:07 -0700 Subject: [PATCH 139/314] Fix getting string representation of sage objects --- symengine/lib/pywrapper.cpp | 17 ++++++----------- symengine/lib/symengine_wrapper.pyx | 9 ++++++--- symengine/tests/test_sage.py | 10 +++------- symengine/tests/test_sympy_conv.py | 1 + 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index ca7b7c109..c321ea39f 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -175,17 +175,12 @@ RCP PyNumber::eval(long bits) const { } std::string PyNumber::__str__() const { - PyObject* temp; - std::string str; -#if PY_MAJOR_VERSION > 2 - temp = PyUnicode_AsUTF8String(pyobject_); - str = std::string(PyBytes_AsString(temp)); -#else - temp = PyObject_Str(pyobject_); - str = std::string(PyString_AsString(temp)); -#endif - Py_XDECREF(temp); - return str; + Py_ssize_t size; + PyObject *pystr = PyObject_Str(pyobject_); + const char* data = PyUnicode_AsUTF8AndSize(pystr, &size); + std::string result = std::string(data, size); + Py_XDECREF(pystr); + return result; } // PyFunctionClass diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 714bfbd25..f9e5d3c6a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -2690,7 +2690,7 @@ class FunctionSymbol(Function): def _sage_(self): import sage.all as sage name = self.get_name() - return sage.function(name, *self.args_as_sage()) + return sage.function(name)(*self.args_as_sage()) def func(self, *values): name = self.get_name() @@ -2711,7 +2711,7 @@ cdef rcp_const_basic pynumber_to_symengine(PyObject* o1): cdef PyObject* symengine_to_sage(rcp_const_basic o1): import sage.all as sage - t = sage.SR(c2py(o1)._sage_()) + t = c2py(o1)._sage_() Py_XINCREF(t) return (t) @@ -2765,7 +2765,10 @@ cdef class PyNumber(Number): def _sage_(self): import sage.all as sage - return sage.SR(self.pyobject()) + res = self.pyobject() + if hasattr(res, '_sage_'): + return res._sage_() + return res def pyobject(self): return deref(symengine.rcp_static_cast_PyNumber(self.thisptr)).get_py_object() diff --git a/symengine/tests/test_sage.py b/symengine/tests/test_sage.py index 3b994abba..e364bd6d9 100644 --- a/symengine/tests/test_sage.py +++ b/symengine/tests/test_sage.py @@ -66,9 +66,9 @@ def test_sage_conversions(): assert cos(x1)._sage_() == sage.cos(x) assert cos(x1) == sympify(sage.cos(x)) - assert function_symbol('f', x1, y1)._sage_() == sage.function('f', x, y) + assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y) assert (function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == - sage.function('f', 2 * x, x + y).diff(x)) + sage.function('f')(2 * x, x + y).diff(x)) assert LambertW(x1) == LambertW(x) assert LambertW(x1)._sage_() == sage.lambert_w(x) @@ -142,11 +142,7 @@ def test_sage_conversions(): b = b + 8 assert isinstance(b, PyNumber) assert b._sage_() == a - - a = a + x - b = b + x - assert isinstance(b, Add) - assert b._sage_() == a + assert str(a) == str(b) # Sage Function e = x1 + wrap_sage_function(sage.log_gamma(x)) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 3f8b152be..ee070a818 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -760,6 +760,7 @@ def test_pynumber(): assert isinstance(b, PyNumber) assert b == a # Check equality via SymEngine assert a == b # Check equality via SymPy + assert str(a) == str(b) a = 1 - a b = 1 - b From 1c90da19ba95a316a5cba8224adf6a1e5310117c Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Thu, 7 Oct 2021 20:00:51 +0200 Subject: [PATCH 140/314] Mul and Add of immutable and dense matrices gives immutable --- symengine/lib/symengine_wrapper.pyx | 18 +++++++++++++++--- symengine/tests/test_matrices.py | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1eb5fabc0..2c2c47e46 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3558,19 +3558,31 @@ cdef class DenseMatrixBase(MatrixBase): def add_matrix(self, A): cdef MatrixBase A_ = sympify(A) - cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) + if isinstance(A, ImmutableDenseMatrix): + cls = A.__class__ + else: + cls = self.__class__ + cdef DenseMatrixBase result = cls(self.nrows(), self.ncols()) deref(self.thisptr).add_matrix(deref(A_.thisptr), deref(result.thisptr)) return result def mul_matrix(self, A): cdef MatrixBase A_ = sympify(A) - cdef DenseMatrixBase result = self.__class__(self.nrows(), A.ncols()) + if isinstance(A, ImmutableDenseMatrix): + cls = A.__class__ + else: + cls = self.__class__ + cdef DenseMatrixBase result = cls(self.nrows(), A.ncols()) deref(self.thisptr).mul_matrix(deref(A_.thisptr), deref(result.thisptr)) return result def multiply_elementwise(self, A): cdef MatrixBase A_ = sympify(A) - cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols()) + if isinstance(A, ImmutableDenseMatrix): + cls = A.__class__ + else: + cls = self.__class__ + cdef DenseMatrixBase result = cls(self.nrows(), self.ncols()) deref(self.thisptr).elementwise_mul_matrix(deref(A_.thisptr), deref(result.thisptr)) return result diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 7538a4474..d427fab99 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -694,6 +694,15 @@ def test_immutablematrix(): assert isinstance(Z, ImmutableMatrix) assert Z == ImmutableMatrix([[1, 2], [3, 4], [5, 6]]) + # Operations of one immutable and one mutable matrix should give immutable result + X = ImmutableMatrix([1]) + Y = DenseMatrix([1]) + assert type(X + Y) == ImmutableMatrix + assert type(Y + X) == ImmutableMatrix + assert type(X * Y) == ImmutableMatrix + assert type(Y * X) == ImmutableMatrix + + def test_atoms(): a = Symbol("a") b = Symbol("b") From 9d2dc7ad7b52a5d88681faf76a04913ef6cf07d7 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Thu, 14 Oct 2021 15:20:18 +0530 Subject: [PATCH 141/314] Fix leading underscore in converted dummy name by slicing --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index f9e5d3c6a..2a1dff702 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1262,7 +1262,7 @@ cdef class Dummy(Symbol): def _sympy_(self): import sympy - return sympy.Dummy(str(self)) + return sympy.Dummy(str(self)[1:]) @property def is_Dummy(self): From 419b09dbef1751fdcb81237d274b81efd9b36968 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 28 Oct 2021 14:45:11 -0500 Subject: [PATCH 142/314] Update symengine_version.txt --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 85f7059bb..845dbe7f9 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.8.1 +23abf31763620463500d5fad114d855afd66d011 From a59635b024c6f08eca9c519f22bdb58cd9ee0c0b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 7 Nov 2021 11:39:35 -0600 Subject: [PATCH 143/314] Fix cdef --- symengine/lib/symengine_wrapper.pyx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index e08ca254f..4b94e93af 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5418,11 +5418,13 @@ def cse(exprs): return (vec_pair_to_list(replacements), vec_basic_to_list(reduced_exprs)) def latex(expr): + cdef symengine.DenseMatrix expr_ + cdef Basic expr_ if isinstance(expr, DenseMatrixBase): - cdef symengine.DenseMatrix expr_ = sympify(expr) - return symengine.latex(deref(expr_.thisptr)).decode("utf-8") + mat_expr_ = sympify(expr) + return symengine.latex(deref(mat_expr_.thisptr)).decode("utf-8") else: - cdef Basic expr_ = sympify(expr) + expr_ = sympify(expr) return symengine.latex(deref(expr_.thisptr)).decode("utf-8") cdef _flattened_vec(symengine.vec_basic &vec, exprs): From b505c642373fccc546b4e99e115c49131feb6103 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 8 Nov 2021 10:52:28 +0100 Subject: [PATCH 144/314] fix name clash --- symengine/lib/symengine_wrapper.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4b94e93af..87f797389 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5418,14 +5418,14 @@ def cse(exprs): return (vec_pair_to_list(replacements), vec_basic_to_list(reduced_exprs)) def latex(expr): - cdef symengine.DenseMatrix expr_ - cdef Basic expr_ + cdef symengine.DenseMatrix mat_expr + cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): mat_expr_ = sympify(expr) return symengine.latex(deref(mat_expr_.thisptr)).decode("utf-8") else: - expr_ = sympify(expr) - return symengine.latex(deref(expr_.thisptr)).decode("utf-8") + basic_expr = sympify(expr) + return symengine.latex(deref(basic_expr.thisptr)).decode("utf-8") cdef _flattened_vec(symengine.vec_basic &vec, exprs): cdef Basic b From d84d32aa6422bdb30081c074d764aad6d042ca60 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 10 Nov 2021 13:44:22 -0600 Subject: [PATCH 145/314] Fix typo --- symengine/lib/symengine_wrapper.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 87f797389..9337323ae 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5421,8 +5421,8 @@ def latex(expr): cdef symengine.DenseMatrix mat_expr cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): - mat_expr_ = sympify(expr) - return symengine.latex(deref(mat_expr_.thisptr)).decode("utf-8") + mat_expr = expr + return symengine.latex(deref(mat_expr.thisptr)).decode("utf-8") else: basic_expr = sympify(expr) return symengine.latex(deref(basic_expr.thisptr)).decode("utf-8") From 91c77c32efe16ebeed77fa68a503355895214c2c Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 16 Nov 2021 18:05:22 -0600 Subject: [PATCH 146/314] dont use flat_namespace as it is evil --- cmake/FindPython.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 287f52903..52539cb79 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -109,10 +109,9 @@ macro(ADD_PYTHON_LIBRARY name) # on Mac, we need to use the "-bundle" gcc flag, which is what MODULE # does: add_library(${name} MODULE ${ARGN}) - # and "-flat_namespace -undefined suppress" link flags, that we need - # to add by hand: + # and "-undefined dynamic_lookup" link flags, that we need to add by hand: set_property(TARGET ${name} APPEND_STRING PROPERTY - LINK_FLAGS " -flat_namespace -undefined suppress -Wl,-exported_symbol,_PyInit_${name}") + LINK_FLAGS " -undefined dynamic_lookup -Wl,-exported_symbol,_PyInit_${name}") ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") # on Linux, we need to use the "-shared" gcc flag, which is what SHARED # does: From f5ed1cd60e32a08749568a0a2e83dd598f4cb4dd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 16 Nov 2021 18:06:56 -0600 Subject: [PATCH 147/314] Fix repr_latex --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 9337323ae..30e5c6eeb 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3243,7 +3243,7 @@ cdef class DenseMatrixBase(MatrixBase): def _repr_latex_(self): if repr_latex[0]: - return latex(deref(self.thisptr)).decode("utf-8") + return "${}$".format(latex(self)) else: return None From f63e77ac3a3239373c0903a9551a43e3ff0adff9 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 06:15:38 -0600 Subject: [PATCH 148/314] Fix type error --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 30e5c6eeb..191e2a16e 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5418,7 +5418,7 @@ def cse(exprs): return (vec_pair_to_list(replacements), vec_basic_to_list(reduced_exprs)) def latex(expr): - cdef symengine.DenseMatrix mat_expr + cdef DenseMatrix mat_expr cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): mat_expr = expr From 3d89207f08feaf74cdce2f43520434679d638acd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 09:38:05 -0600 Subject: [PATCH 149/314] Fix type again --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 191e2a16e..728ba7fc8 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5418,7 +5418,7 @@ def cse(exprs): return (vec_pair_to_list(replacements), vec_basic_to_list(reduced_exprs)) def latex(expr): - cdef DenseMatrix mat_expr + cdef DenseMatrixBase mat_expr cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): mat_expr = expr From c7d6a49803b6708dcf7704621fb104b4ef0da7d2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 11:37:29 -0600 Subject: [PATCH 150/314] Add overloaded latex definition --- symengine/lib/symengine.pxd | 1 + 1 file changed, 1 insertion(+) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 5803344d3..9d86d9831 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -1099,6 +1099,7 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + + string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) nogil except + ## Defined in 'symengine/cwrapper.cpp' cdef struct CRCPBasic: From 18777f0c0603c1c44dd0254ee9ad340076a54458 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 11:38:03 -0600 Subject: [PATCH 151/314] set default values for max rows and cols --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 728ba7fc8..4c4acbf24 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5422,7 +5422,7 @@ def latex(expr): cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): mat_expr = expr - return symengine.latex(deref(mat_expr.thisptr)).decode("utf-8") + return symengine.latex(deref(mat_expr.thisptr), 20, 12).decode("utf-8") else: basic_expr = sympify(expr) return symengine.latex(deref(basic_expr.thisptr)).decode("utf-8") From dc8273a27fc6d49aaf0baecdd3b59afbec58e4fb Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 11:51:35 -0600 Subject: [PATCH 152/314] cast to DenseMatrix --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4c4acbf24..9048f2e66 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5422,7 +5422,7 @@ def latex(expr): cdef Basic basic_expr if isinstance(expr, DenseMatrixBase): mat_expr = expr - return symengine.latex(deref(mat_expr.thisptr), 20, 12).decode("utf-8") + return symengine.latex(deref(symengine.static_cast_DenseMatrix(mat_expr.thisptr)), 20, 12).decode("utf-8") else: basic_expr = sympify(expr) return symengine.latex(deref(basic_expr.thisptr)).decode("utf-8") From dae7f131d76a85a5e373796b9dac0fce43ae48dd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 12:02:52 -0600 Subject: [PATCH 153/314] Fix test --- symengine/tests/test_matrices.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 3f853ada4..901bcc37c 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -1,4 +1,4 @@ -from symengine import symbols +from symengine import symbols, init_printing from symengine.lib.symengine_wrapper import (DenseMatrix, Symbol, Integer, Rational, function_symbol, I, NonSquareMatrixError, ShapeError, zeros, ones, eye, ImmutableMatrix) @@ -728,6 +728,7 @@ def test_LUdecomp(): def test_repr_latex(): testmat = DenseMatrix([[0, 2]]) + init_printing(True) latex_string = testmat._repr_latex_() assert isinstance(latex_string, str) - \ No newline at end of file + init_printing(False) From 4fa1db064f1e2db3f4a0edd0f54d63c0bb977a4e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 14:09:56 -0600 Subject: [PATCH 154/314] fix appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 62adf2e1d..69028741b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -54,7 +54,7 @@ install: - git clone https://github.com/sympy/symengine symengine-cpp - if [%COMPILER%]==[MSVC15] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat -- if [%COMPILER%]==[MSVC15] conda update --yes --quiet conda +- if [%COMPILER%]==[MSVC15] conda install --yes --quiet conda python=3.6 - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 From b85a0baaf0d1464c9fe0edec11fb5e1d4e29e8ec Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 26 Nov 2021 15:39:28 -0600 Subject: [PATCH 155/314] Support pickling of Basic objects --- symengine/lib/symengine.pxd | 3 +++ symengine/lib/symengine_wrapper.pyx | 8 ++++++++ symengine/tests/test_pickling.py | 11 ++++++++++- symengine_version.txt | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 9d86d9831..5ef0fc1e7 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -183,6 +183,8 @@ cdef extern from "" namespace "SymEngine": unsigned int hash() nogil except + vec_basic get_args() nogil int __cmp__(const Basic &o) nogil + string dumps() nogil except + + ctypedef RCP[const Number] rcp_const_number "SymEngine::RCP" ctypedef unordered_map[int, rcp_const_basic] umap_int_basic "SymEngine::umap_int_basic" ctypedef unordered_map[int, rcp_const_basic].iterator umap_int_basic_iterator "SymEngine::umap_int_basic::iterator" @@ -193,6 +195,7 @@ cdef extern from "" namespace "SymEngine": bool eq(const Basic &a, const Basic &b) nogil except + bool neq(const Basic &a, const Basic &b) nogil except + + RCP[const Basic] loads "SymEngine::Basic::loads"(const string &) nogil except + RCP[const Symbol] rcp_static_cast_Symbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index d66af0584..10c5f06ff 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -826,6 +826,10 @@ cdef list vec_pair_to_list(symengine.vec_pair& vec): return result +def load_basic(bytes s): + return c2py(symengine.loads(s)) + + repr_latex=[False] cdef class Basic(object): @@ -836,6 +840,10 @@ cdef class Basic(object): def __repr__(self): return self.__str__() + def __reduce__(self): + cdef bytes s = deref(self.thisptr).dumps() + return (load_basic, (s,)) + def _repr_latex_(self): if repr_latex[0]: return "${}$".format(latex(self)) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index b7f14a181..75c353b60 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,7 +1,16 @@ -from symengine import symbols, sin, sinh, have_numpy, have_llvm +from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos import pickle import unittest + +def test_basic(): + x, y, z = symbols('x y z') + expr = sin(cos(x + y)/z)**2 + s = pickle.dumps(expr) + expr2 = pickle.loads(s) + assert expr == expr2 + + @unittest.skipUnless(have_llvm, "No LLVM support") @unittest.skipUnless(have_numpy, "Numpy not installed") def test_llvm_double(): diff --git a/symengine_version.txt b/symengine_version.txt index 845dbe7f9..f4d17b3e7 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -23abf31763620463500d5fad114d855afd66d011 +4b841d144bbc1ecd4367e4bd7dd4e7c6be8fac05 From f096b4e4e3de30615d78873e85558c72eafaea65 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 30 Nov 2021 23:43:54 -0800 Subject: [PATCH 156/314] support serializing and deserializing pysymbol --- symengine/lib/pywrapper.cpp | 77 +++++++++++++++++++++++++++++ symengine/lib/pywrapper.h | 3 ++ symengine/lib/symengine.pxd | 6 +-- symengine/lib/symengine_wrapper.pyx | 10 +++- symengine/tests/test_pickling.py | 20 +++++++- 5 files changed, 109 insertions(+), 7 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index c321ea39f..dc714ea69 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -1,4 +1,5 @@ #include "pywrapper.h" +#include #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong @@ -269,4 +270,80 @@ int PyFunction::compare(const Basic &o) const { return unified_compare(get_vec(), s.get_vec()); } +inline PyObject* get_pickle_module() { + static PyObject *module = NULL; + if (module == NULL) { + module = PyImport_ImportModule("pickle"); + } + return module; +} + +RCP load_basic(cereal::PortableBinaryInputArchive &ar, RCP &) +{ + bool is_pysymbol; + std::string name; + ar(is_pysymbol); + ar(name); + if (is_pysymbol) { + std::string pickle_str; + ar(pickle_str); + PyObject *module = get_pickle_module(); + PyObject *pickle_bytes = PyBytes_FromStringAndSize(pickle_str.data(), pickle_str.size()); + PyObject *obj = PyObject_CallMethod(module, "loads", "O", pickle_bytes); + RCP result = make_rcp(name, obj); + Py_XDECREF(pickle_bytes); + return result; + } else { + return symbol(name); + } +} + +void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) +{ + bool is_pysymbol = is_a_sub(b); + ar(is_pysymbol); + ar(b.__str__()); + if (is_pysymbol) { + RCP p = rcp_static_cast(b.rcp_from_this()); + PyObject *module = get_pickle_module(); + PyObject *pickle_bytes = PyObject_CallMethod(module, "dumps", "O", p->get_py_object()); + Py_ssize_t size; + char* buffer; + PyBytes_AsStringAndSize(pickle_bytes, &buffer, &size); + std::string pickle_str(buffer, size); + ar(pickle_str); + Py_XDECREF(pickle_bytes); + } +} + +std::string wrapper_dumps(const Basic &x) +{ + std::cout << "qwe" << std::endl; + std::ostringstream oss; + unsigned short major = SYMENGINE_MAJOR_VERSION; + unsigned short minor = SYMENGINE_MINOR_VERSION; + cereal::PortableBinaryOutputArchive{oss}(major, minor, + x.rcp_from_this()); + return oss.str(); +} + +RCP wrapper_loads(const std::string &serialized) +{ + unsigned short major, minor; + RCP obj; + std::istringstream iss(serialized); + cereal::PortableBinaryInputArchive iarchive{iss}; + iarchive(major, minor); + if (major != SYMENGINE_MAJOR_VERSION or minor != SYMENGINE_MINOR_VERSION) { + throw SerializationError(StreamFmt() + << "SymEngine-" << SYMENGINE_MAJOR_VERSION + << "." << SYMENGINE_MINOR_VERSION + << " was asked to deserialize an object " + << "created using SymEngine-" << major << "." + << minor << "."); + } + iarchive(obj); + return obj; +} + } // SymEngine diff --git a/symengine/lib/pywrapper.h b/symengine/lib/pywrapper.h index ba5fe70a8..175cc763c 100644 --- a/symengine/lib/pywrapper.h +++ b/symengine/lib/pywrapper.h @@ -195,6 +195,9 @@ class PyFunction : public FunctionWrapper { virtual hash_t __hash__() const; }; +std::string wrapper_dumps(const Basic &x); +RCP wrapper_loads(const std::string &s); + } #endif //SYMENGINE_PYWRAPPER_H diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 5ef0fc1e7..10a3b33c7 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -183,7 +183,6 @@ cdef extern from "" namespace "SymEngine": unsigned int hash() nogil except + vec_basic get_args() nogil int __cmp__(const Basic &o) nogil - string dumps() nogil except + ctypedef RCP[const Number] rcp_const_number "SymEngine::RCP" ctypedef unordered_map[int, rcp_const_basic] umap_int_basic "SymEngine::umap_int_basic" @@ -195,8 +194,6 @@ cdef extern from "" namespace "SymEngine": bool eq(const Basic &a, const Basic &b) nogil except + bool neq(const Basic &a, const Basic &b) nogil except + - RCP[const Basic] loads "SymEngine::Basic::loads"(const string &) nogil except + - RCP[const Symbol] rcp_static_cast_Symbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Integer] rcp_static_cast_Integer "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil @@ -373,6 +370,9 @@ cdef extern from "pywrapper.h" namespace "SymEngine": PySymbol(string name, PyObject* pyobj) PyObject* get_py_object() + string wrapper_dumps(const Basic &x) nogil except + + rcp_const_basic wrapper_loads(const string &s) nogil except + + cdef extern from "" namespace "SymEngine": cdef cppclass Integer(Number): Integer(int i) nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 10c5f06ff..5c5fb669c 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -827,7 +827,7 @@ cdef list vec_pair_to_list(symengine.vec_pair& vec): def load_basic(bytes s): - return c2py(symengine.loads(s)) + return c2py(symengine.wrapper_loads(s)) repr_latex=[False] @@ -841,7 +841,7 @@ cdef class Basic(object): return self.__str__() def __reduce__(self): - cdef bytes s = deref(self.thisptr).dumps() + cdef bytes s = symengine.wrapper_dumps(deref(self.thisptr)) return (load_basic, (s,)) def _repr_latex_(self): @@ -1231,6 +1231,12 @@ cdef class Symbol(Expr): import sympy return sympy.Symbol(str(self)) + def __reduce__(self): + if type(self) == Symbol: + return Basic.__reduce__(self) + else: + raise NotImplementedError("pickling for Symbol subclass not implemented") + def _sage_(self): import sage.all as sage return sage.SR.symbol(str(self)) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index 75c353b60..6e75f133d 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,4 +1,4 @@ -from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos +from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos, Symbol import pickle import unittest @@ -11,6 +11,23 @@ def test_basic(): assert expr == expr2 +class MySymbol(Symbol): + def __init__(self, name, attr): + super().__init__(name=name) + self.attr = attr + + def __reduce__(self): + return (self.__class__, (self.name, self.attr)) + + +def test_pysymbol(): + a = MySymbol("hello", attr=1) + b = pickle.loads(pickle.dumps(a)) + assert b.attr == 1 + a._unsafe_reset() + b._unsafe_reset() + + @unittest.skipUnless(have_llvm, "No LLVM support") @unittest.skipUnless(have_numpy, "Numpy not installed") def test_llvm_double(): @@ -23,4 +40,3 @@ def test_llvm_double(): ll = pickle.loads(ss) inp = [1, 2, 3] assert np.allclose(l(inp), ll(inp)) - From 322f2f4f3a096495fcdef545edf8c08a57f50e30 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 00:01:37 -0800 Subject: [PATCH 157/314] handle errors gracefully --- symengine/lib/pywrapper.cpp | 9 +++++++++ symengine/tests/test_pickling.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index dc714ea69..077bd1ede 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -275,6 +275,9 @@ inline PyObject* get_pickle_module() { if (module == NULL) { module = PyImport_ImportModule("pickle"); } + if (module == NULL) { + throw SymEngineException("error importing pickle module.") + } return module; } @@ -290,6 +293,9 @@ RCP load_basic(cereal::PortableBinaryInputArchive &ar, RCP result = make_rcp(name, obj); Py_XDECREF(pickle_bytes); return result; @@ -307,6 +313,9 @@ void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) RCP p = rcp_static_cast(b.rcp_from_this()); PyObject *module = get_pickle_module(); PyObject *pickle_bytes = PyObject_CallMethod(module, "dumps", "O", p->get_py_object()); + if (pickle_bytes == NULL) { + throw SymEngineException("error when pickling symbol subclass object"); + } Py_ssize_t size; char* buffer; PyBytes_AsStringAndSize(pickle_bytes, &buffer, &size); diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index 6e75f133d..7c814ea63 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,4 +1,5 @@ from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos, Symbol +from symengine.utilities import raises import pickle import unittest @@ -11,22 +12,28 @@ def test_basic(): assert expr == expr2 -class MySymbol(Symbol): +class MySymbolBase(Symbol): def __init__(self, name, attr): super().__init__(name=name) self.attr = attr + +class MySymbol(MySymbolBase): def __reduce__(self): return (self.__class__, (self.name, self.attr)) def test_pysymbol(): a = MySymbol("hello", attr=1) - b = pickle.loads(pickle.dumps(a)) + b = pickle.loads(pickle.dumps(a + 2)) - 2 assert b.attr == 1 a._unsafe_reset() b._unsafe_reset() + a = MySymbolBase("hello", attr=1) + raises(NotImplementedError, lambda: pickle.dumps(a + 2)) + a._unsafe_reset() + @unittest.skipUnless(have_llvm, "No LLVM support") @unittest.skipUnless(have_numpy, "Numpy not installed") From 6aa316b4e55a57e4215b265b793b9a6c03df20d8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 00:22:17 -0800 Subject: [PATCH 158/314] improve tests --- symengine/tests/test_pickling.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index 7c814ea63..4e70c0a63 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -17,6 +17,11 @@ def __init__(self, name, attr): super().__init__(name=name) self.attr = attr + def __eq__(self, other): + if not isinstance(other, MySymbolBase): + return False + return self.name == other.name and self.attr == other.attr + class MySymbol(MySymbolBase): def __reduce__(self): @@ -26,13 +31,18 @@ def __reduce__(self): def test_pysymbol(): a = MySymbol("hello", attr=1) b = pickle.loads(pickle.dumps(a + 2)) - 2 - assert b.attr == 1 - a._unsafe_reset() - b._unsafe_reset() + try: + assert a == b + finally: + a._unsafe_reset() + b._unsafe_reset() a = MySymbolBase("hello", attr=1) - raises(NotImplementedError, lambda: pickle.dumps(a + 2)) - a._unsafe_reset() + try: + raises(NotImplementedError, lambda: pickle.dumps(a)) + raises(NotImplementedError, lambda: pickle.dumps(a + 2)) + finally: + a._unsafe_reset() @unittest.skipUnless(have_llvm, "No LLVM support") From 80b6a6eb48a6872e9c5d8cbac0dff9ae4993f368 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 00:51:17 -0800 Subject: [PATCH 159/314] bump symengine version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index f4d17b3e7..37b09f412 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -4b841d144bbc1ecd4367e4bd7dd4e7c6be8fac05 +36ac51d06e248657d828bfa4859cff32ab5f03ba From 782eef341da16067b1d0cc1257a8bd93820c2912 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 00:54:11 -0800 Subject: [PATCH 160/314] remove debug line --- symengine/lib/pywrapper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index 077bd1ede..a45a7d237 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -327,7 +327,6 @@ void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) std::string wrapper_dumps(const Basic &x) { - std::cout << "qwe" << std::endl; std::ostringstream oss; unsigned short major = SYMENGINE_MAJOR_VERSION; unsigned short minor = SYMENGINE_MINOR_VERSION; From b6366236a01f77385f13f933566c27134d7cba8c Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 00:55:15 -0800 Subject: [PATCH 161/314] fix typo --- symengine/lib/pywrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index a45a7d237..234c481a6 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -276,7 +276,7 @@ inline PyObject* get_pickle_module() { module = PyImport_ImportModule("pickle"); } if (module == NULL) { - throw SymEngineException("error importing pickle module.") + throw SymEngineException("error importing pickle module."); } return module; } From 1ca9c70ac72fe8807d656d39dca4c8bab9a6283b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Dec 2021 16:12:37 -0600 Subject: [PATCH 162/314] Throw SerializationError instead of SymEngineException --- symengine/lib/pywrapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index 234c481a6..aaf128d28 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -294,7 +294,7 @@ RCP load_basic(cereal::PortableBinaryInputArchive &ar, RCP result = make_rcp(name, obj); Py_XDECREF(pickle_bytes); @@ -314,7 +314,7 @@ void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) PyObject *module = get_pickle_module(); PyObject *pickle_bytes = PyObject_CallMethod(module, "dumps", "O", p->get_py_object()); if (pickle_bytes == NULL) { - throw SymEngineException("error when pickling symbol subclass object"); + throw SerializationError("error when pickling symbol subclass object"); } Py_ssize_t size; char* buffer; From 423148edb6b448f97ecb863bbb497be2ea25ec93 Mon Sep 17 00:00:00 2001 From: richardotis Date: Thu, 2 Dec 2021 15:57:09 +0000 Subject: [PATCH 163/314] FIX: API compatib th sympy for Interval objects --- symengine/lib/symengine_wrapper.pyx | 19 +++++++++++++++++-- symengine/tests/test_sets.py | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 5c5fb669c..4bba5f5f5 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -2999,8 +2999,23 @@ cdef class Set(Expr): class Interval(Set): - def __new__(self, *args): - return interval(*args) + def __new__(self, *args, left_open=None, right_open=None): + list_args = list(args) + if ((left_open is not None) and (right_open is None)) or ((left_open is None) and (right_open is not None)): + raise ValueError("Both (or neither) keyword arguments for Interval should be specified") + if left_open is not None: + list_args.append(left_open) + if right_open is not None: + list_args.append(right_open) + return interval(*list_args) + + @property + def start(self): + return self.args[0] + + @property + def end(self): + return self.args[1] def _sympy_(self): import sympy diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index 5ec8ce9e3..971f96283 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -6,7 +6,9 @@ def test_Interval(): assert Interval(0, oo) == Interval(0, oo, False, True) + assert Interval(0, oo) == Interval(0, oo, left_open=False, right_open=True) assert Interval(-oo, 0) == Interval(-oo, 0, True, False) + assert Interval(-oo, 0) == Interval(-oo, 0, left_open=True, right_open=False) assert Interval(oo, -oo) == EmptySet() assert Interval(oo, oo) == EmptySet() assert Interval(-oo, -oo) == EmptySet() @@ -18,6 +20,9 @@ def test_Interval(): assert Interval(1, 1, True, True) == EmptySet() assert Interval(1, 2).union(Interval(2, 3)) == Interval(1, 3) + assert Interval(-oo, 0).start == -oo + assert Interval(-oo, 0).end == 0 + def test_EmptySet(): E = EmptySet() From 52daf3bd052e11048f89bf9302eba02daa9b7b51 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sat, 1 Jan 2022 22:17:18 +0100 Subject: [PATCH 164/314] Add unicode function --- symengine/__init__.py | 3 ++- symengine/lib/symengine.pxd | 1 + symengine/lib/symengine_wrapper.pyx | 5 +++++ symengine/tests/test_printing.py | 8 +++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 5085641d1..d26436027 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -29,7 +29,8 @@ FunctionSymbol as AppliedUndef, golden_ratio as GoldenRatio, catalan as Catalan, - eulergamma as EulerGamma + eulergamma as EulerGamma, + unicode ) from .utilities import var, symbols from .functions import * diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 10a3b33c7..14576130d 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -1103,6 +1103,7 @@ cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) nogil except + + string unicode(const Basic &x) nogil except + ## Defined in 'symengine/cwrapper.cpp' cdef struct CRCPBasic: diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4bba5f5f5..61fbef34c 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5471,6 +5471,11 @@ def latex(expr): basic_expr = sympify(expr) return symengine.latex(deref(basic_expr.thisptr)).decode("utf-8") +def unicode(expr): + cdef Basic basic_expr + basic_expr = sympify(expr) + return symengine.unicode(deref(basic_expr.thisptr)).decode("utf-8") + cdef _flattened_vec(symengine.vec_basic &vec, exprs): cdef Basic b if is_sequence(exprs): diff --git a/symengine/tests/test_printing.py b/symengine/tests/test_printing.py index feea3650e..f33ce5a77 100644 --- a/symengine/tests/test_printing.py +++ b/symengine/tests/test_printing.py @@ -1,4 +1,4 @@ -from symengine import (ccode, Symbol, sqrt, Pow, Max, sin, Integer, MutableDenseMatrix) +from symengine import (ccode, unicode, Symbol, sqrt, Pow, Max, sin, Integer, MutableDenseMatrix) from symengine.utilities import raises from symengine.printing import CCodePrinter, init_printing @@ -30,3 +30,9 @@ def test_init_printing(): assert x._repr_latex_() is None init_printing() assert x._repr_latex_() == '$x$' + + +def test_unicode(): + x = Symbol("x") + y = Integer(2) + assert unicode(x / y) == "x\n―\n2" From ab53be7f396cc5bd28035781fd88a828a3c543ec Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sun, 2 Jan 2022 15:30:38 +0100 Subject: [PATCH 165/314] Update symengine/tests/test_printing.py Co-authored-by: Isuru Fernando --- symengine/tests/test_printing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/tests/test_printing.py b/symengine/tests/test_printing.py index f33ce5a77..6c5ec7307 100644 --- a/symengine/tests/test_printing.py +++ b/symengine/tests/test_printing.py @@ -35,4 +35,4 @@ def test_init_printing(): def test_unicode(): x = Symbol("x") y = Integer(2) - assert unicode(x / y) == "x\n―\n2" + assert unicode(x / 2) == "x\n―\n2" From 31fa4dc8d1aef516154066fbf529c6b6f4e8c649 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 16 Feb 2022 17:01:04 -0600 Subject: [PATCH 166/314] Add Pieter and Ayush to AUTHORS. Welcome to SymEngine!! --- .mailmap | 1 + AUTHORS | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index efc30bd6d..71840613b 100644 --- a/.mailmap +++ b/.mailmap @@ -20,3 +20,4 @@ Sushant Hiray Abhinav Agarwal Nilay Pochhi Björn Dahlgren +Richard Otis richardotis diff --git a/AUTHORS b/AUTHORS index 26e4df59c..651e06ec7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,3 +32,5 @@ Rohit Goswami Matthew Treinish Michał Górny Garming Sam +Pieter Eendebak +Ayush Kumar From 7c57599552cf552523195bc92b61f862e0301b3d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 16 Feb 2022 17:07:06 -0600 Subject: [PATCH 167/314] update symengine commit --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 37b09f412..f979adec6 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -36ac51d06e248657d828bfa4859cff32ab5f03ba +v0.9.0 From b5c329c96ab20e086d24c14e9593490f890844da Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 16 Feb 2022 20:07:15 -0600 Subject: [PATCH 168/314] Update version and METADATA --- appveyor.yml | 4 ++-- setup.py | 10 +++++----- symengine/__init__.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 69028741b..ceb246aab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,7 @@ environment: PYTHON_VERSION: 37-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 36-x64 + PYTHON_VERSION: 310-x64 WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 @@ -43,7 +43,7 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 36-x64 + PYTHON_VERSION: 310-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 WITH_MPFR: yes WITH_MPC: yes diff --git a/setup.py b/setup.py index 5f15b696a..a77d038b9 100644 --- a/setup.py +++ b/setup.py @@ -7,8 +7,8 @@ from distutils.command.build import build as _build # Make sure the system has the right Python version. -if sys.version_info[:2] < (3, 6): - print("SymEngine requires Python 3.6 or newer. " +if sys.version_info[:2] < (3, 7): + print("SymEngine requires Python 3.7 or newer. " "Python %d.%d detected" % sys.version_info[:2]) sys.exit(-1) @@ -214,7 +214,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.8.1", + version="0.9.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, @@ -222,7 +222,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", - python_requires='>=3.6,<4', + python_requires='>=3.7,<4', zip_safe=False, cmdclass = cmdclass, classifiers=[ @@ -232,9 +232,9 @@ def finalize_options(self): 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Scientific/Engineering :: Physics', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ] ) diff --git a/symengine/__init__.py b/symengine/__init__.py index 5085641d1..f443f2d74 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -56,7 +56,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.8.1" +__version__ = "0.9.0" # To not expose internals From 5d871a9c8b307c837b51a8613855a43799541628 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 16 Feb 2022 20:17:46 -0600 Subject: [PATCH 169/314] remove failing CI for now it's not a package issue, but CI infrastructure issue --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db74652bf..4e2c5444b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,12 +55,12 @@ jobs: OS: ubuntu-20.04 CC: gcc - - BUILD_TYPE: Debug - PYTHON_VERSION: 3.9 - WITH_BFD: yes - WITH_PIRANHA: yes - OS: ubuntu-20.04 - CC: gcc + #- BUILD_TYPE: Debug + # PYTHON_VERSION: 3.9 + # WITH_BFD: yes + # WITH_PIRANHA: yes + # OS: ubuntu-20.04 + # CC: gcc - BUILD_TYPE: Debug PYTHON_VERSION: 3.8 From c54301b638dd1699d1d7c2ecd4be219f62db7523 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 17 Feb 2022 01:44:42 -0600 Subject: [PATCH 170/314] Need newer image for 3.10 --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ceb246aab..5da4ab24d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,6 +32,7 @@ environment: - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 PYTHON_VERSION: 310-x64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 @@ -45,6 +46,7 @@ environment: PLATFORM: "x64" PYTHON_VERSION: 310-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 WITH_MPFR: yes WITH_MPC: yes WITH_LLVM: yes From df6baf4bd2f2bbb3b0881fdef1a0368f84930dc3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 17 Feb 2022 10:52:41 -0600 Subject: [PATCH 171/314] no 3.10 for mingw as .a is not there --- appveyor.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5da4ab24d..17e2e7e27 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 39-x64 + PYTHON_VERSION: 310-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 WITH_MPFR: yes WITH_MPC: yes @@ -31,8 +31,7 @@ environment: PYTHON_VERSION: 37-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 310-x64 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PYTHON_VERSION: 39-x64 WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 From d0aa12448c28b539f4b2e252ac1f2f29e2f79073 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 17 Feb 2022 12:01:34 -0600 Subject: [PATCH 172/314] only 3.7 with mingw --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 17e2e7e27..30da13f3a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,7 @@ environment: PYTHON_VERSION: 37-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 39-x64 + PYTHON_VERSION: 37-x64 WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 From c9e9aa89e50b5d58c41d3074ec1263704a281d34 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 17 Feb 2022 15:28:47 -0600 Subject: [PATCH 173/314] use build_ext from setuptools --- setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a77d038b9..eef028590 100644 --- a/setup.py +++ b/setup.py @@ -3,8 +3,6 @@ import subprocess import sys import platform -from distutils.command.build_ext import build_ext as _build_ext -from distutils.command.build import build as _build # Make sure the system has the right Python version. if sys.version_info[:2] < (3, 7): @@ -28,12 +26,16 @@ try: from setuptools import setup from setuptools.command.install import install as _install + from setuptools.command.build_ext import build_ext as _build_ext + from setuptools.command.build import build as _build except ImportError: use_setuptools = False if not use_setuptools: from distutils.core import setup from distutils.command.install import install as _install + from distutils.command.build_ext import build_ext as _build_ext + from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] From b6d2d5a9a6a5719c0cf1a44e2a52d53448590dfe Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 19 Feb 2022 02:47:58 -0600 Subject: [PATCH 174/314] Use build from distutils --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index eef028590..bac05f989 100644 --- a/setup.py +++ b/setup.py @@ -22,12 +22,13 @@ print("Value {} for USE_DISTUTILS treated as False". format(use_distutils)) +from distutils.command.build import build as _build + if use_setuptools: try: from setuptools import setup from setuptools.command.install import install as _install from setuptools.command.build_ext import build_ext as _build_ext - from setuptools.command.build import build as _build except ImportError: use_setuptools = False @@ -35,7 +36,6 @@ from distutils.core import setup from distutils.command.install import install as _install from distutils.command.build_ext import build_ext as _build_ext - from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] From 9d36b49627b0224e9ce4f88ced095a83ff72db71 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sat, 19 Feb 2022 19:59:17 +0100 Subject: [PATCH 175/314] Faster rational creation --- symengine/lib/symengine.pxd | 3 +++ symengine/lib/symengine_wrapper.pyx | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 14576130d..ef94aa19e 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -379,6 +379,7 @@ cdef extern from "" namespace "SymEngine": Integer(integer_class i) nogil int compare(const Basic &o) nogil integer_class as_integer_class() nogil + RCP[Number] divint(const Integer &other) nogil cdef long mp_get_si(integer_class &i) nogil cdef double mp_get_d(integer_class &i) nogil cdef RCP[const Integer] integer(int i) nogil @@ -390,6 +391,8 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": cdef cppclass Rational(Number): rational_class as_rational_class() nogil + @staticmethod + RCP[const Number] from_two_ints(const long n, const long d) nogil cdef double mp_get_d(rational_class &i) nogil cdef RCP[const Number] from_mpq "SymEngine::Rational::from_mpq"(rational_class r) nogil cdef void get_num_den(const Rational &rat, const Ptr[RCP[Integer]] &num, diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 61fbef34c..b6473b16d 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1664,7 +1664,25 @@ cdef class Number(Expr): class Rational(Number): def __new__(cls, p, q): - return Integer(p)/q + p = int(p) + q = int(q) + cdef int p_ + cdef int q_ + cdef symengine.integer_class p__ + cdef symengine.integer_class q__ + cdef string tmp + try: + # Try to convert p and q to int + p_ = p + q_ = q + return c2py(symengine.Rational.from_two_ints(p_, q_)); + except OverflowError: + # Too big, need to use mpz + tmp = str(p).encode("utf-8") + p__ = symengine.integer_class(tmp) + tmp = str(q).encode("utf-8") + q__ = symengine.integer_class(tmp) + return c2py(symengine.Integer(p__).divint(symengine.Integer(q__))) @property def is_Rational(self): From 3603878ff5b0bef288d0f158e0cc5dff647f5577 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 7 Mar 2022 13:19:44 +0100 Subject: [PATCH 176/314] fix escape warnings --- symengine/utilities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/utilities.py b/symengine/utilities.py index e3d85aa37..a16aa0a46 100644 --- a/symengine/utilities.py +++ b/symengine/utilities.py @@ -9,7 +9,7 @@ def symbols(names, **args): - """ + r""" Transform strings into instances of :class:`Symbol` class. :func:`symbols` function returns a sequence of symbols with names taken from ``names`` argument, which can be a comma or whitespace delimited @@ -86,7 +86,7 @@ def symbols(names, **args): if isinstance(names, str): marker = 0 - literals = ['\,', '\:', '\ '] + literals = [r'\,', r'\:', r'\ '] for i in range(len(literals)): lit = literals.pop(0) if lit in names: From adee9c40230acc84dd0fb520f76e66ab08bfee95 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 7 Mar 2022 16:39:26 -0600 Subject: [PATCH 177/314] Update version to 0.9.2 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index bac05f989..346e1db03 100644 --- a/setup.py +++ b/setup.py @@ -216,7 +216,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.9.0", + version="0.9.2", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 75e302513..f05422c62 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -57,7 +57,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.9.0" +__version__ = "0.9.2" # To not expose internals From 6c9d44fbe894c702cef5db48083e0f3ba86a009d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 2 Apr 2022 15:17:28 -0500 Subject: [PATCH 178/314] Fix converting doubles --- symengine/lib/symengine_wrapper.pyx | 6 +++--- symengine/tests/test_sympy_conv.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index b6473b16d..2e7ea2075 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -294,9 +294,9 @@ def sympy2symengine(a, raise_error=False): if a._prec > 53: return RealMPFR(str(a), a._prec) else: - return RealDouble(float(str(a))) + return RealDouble(float(a)) ELSE: - return RealDouble(float(str(a))) + return RealDouble(float(a)) elif a is sympy.I: return I elif a is sympy.E: @@ -1902,7 +1902,7 @@ class RealDouble(Float): def _sympy_(Basic self): import sympy - return sympy.Float(deref(self.thisptr).__str__().decode("utf-8")) + return sympy.Float(float(self)) def _sage_(Basic self): import sage.all as sage diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index ee070a818..edf8eafc6 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -3,7 +3,7 @@ exp, gamma, have_mpfr, have_mpc, DenseMatrix, sin, cos, tan, cot, csc, sec, asin, acos, atan, acot, acsc, asec, sinh, cosh, tanh, coth, asinh, acosh, atanh, acoth, Add, Mul, Pow, diff, GoldenRatio, - Catalan, EulerGamma, UnevaluatedExpr) + Catalan, EulerGamma, UnevaluatedExpr, RealDouble) from symengine.lib.symengine_wrapper import (Subs, Derivative, RealMPFR, ComplexMPC, PyNumber, Function, LambertW, zeta, dirichlet_eta, KroneckerDelta, LeviCivita, erf, erfc, lowergamma, uppergamma, @@ -515,7 +515,7 @@ def test_zeta(): e1 = sympy.zeta(sympy.Symbol("x"), sympy.Symbol("y")) e2 = zeta(x, y) assert sympify(e1) == e2 - assert e2._sympy_() == e1 + assert e2._sympy_() == e1 @unittest.skipIf(not have_sympy, "SymPy not installed") @@ -796,3 +796,13 @@ def test_construct_dense_matrix(): B = DenseMatrix(A) assert B.shape == (2, 2) assert list(B) == [1, 2, 3, 5] + + +@unittest.skipIf(not have_sympy, "SymPy not installed") +def test_conv_doubles(): + f = 4.347249999999999 + a = sympify() + assert isinstance(a, RealDouble) + assert sympify(a._sympy_()) == a + assert float(a) == f + assert float(a._sympy_()) == f From 987e665e71cf92d1b021d7d573a1b9733408eecf Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 2 Apr 2022 15:43:00 -0500 Subject: [PATCH 179/314] Fix for latest setuptools --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 346e1db03..33365e5b2 100644 --- a/setup.py +++ b/setup.py @@ -226,6 +226,7 @@ def finalize_options(self): url="https://github.com/symengine/symengine.py", python_requires='>=3.7,<4', zip_safe=False, + packages=['symengine'], cmdclass = cmdclass, classifiers=[ 'License :: OSI Approved :: MIT License', From d1f3aa96aa33edcfa6b39849e9d2cd962b96f635 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 2 Apr 2022 15:52:35 -0500 Subject: [PATCH 180/314] fix typo --- symengine/tests/test_sympy_conv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index edf8eafc6..67253637b 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -801,7 +801,7 @@ def test_construct_dense_matrix(): @unittest.skipIf(not have_sympy, "SymPy not installed") def test_conv_doubles(): f = 4.347249999999999 - a = sympify() + a = sympify(f) assert isinstance(a, RealDouble) assert sympify(a._sympy_()) == a assert float(a) == f From bbd1435ddc6de70d40918d57f0c729942a68ea8e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 18 Apr 2022 16:13:42 -0500 Subject: [PATCH 181/314] Raise TypeError for bool(Booleans) except true, false --- symengine/lib/symengine_wrapper.pyx | 7 +++++++ symengine/tests/test_logic.py | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 2e7ea2075..5b2858be5 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1419,6 +1419,9 @@ cdef class Boolean(Expr): def logical_not(self): return c2py((deref(symengine.rcp_static_cast_Boolean(self.thisptr)).logical_not())) + def __bool__(self): + raise TypeError("cannot determine truth value of Boolean") + cdef class BooleanAtom(Boolean): @@ -1524,6 +1527,10 @@ class Relational(Boolean): def is_Relational(self): return True + def __bool__(self): + raise TypeError("cannot determine truth value of Relational") + + Rel = Relational diff --git a/symengine/tests/test_logic.py b/symengine/tests/test_logic.py index 0a64de6fa..669f7c217 100644 --- a/symengine/tests/test_logic.py +++ b/symengine/tests/test_logic.py @@ -44,6 +44,7 @@ def test_And(): assert And(True, False) == false assert And(False, False) == false assert And(True, True, True) == true + assert raises(TypeError, lambda: x < y and y < 1) def test_Or(): @@ -54,6 +55,7 @@ def test_Or(): assert Or(True, False) == true assert Or(False, False) == false assert Or(True, False, False) == true + assert raises(TypeError, lambda: x < y or y < 1) def test_Nor(): @@ -116,4 +118,4 @@ def test_Contains(): assert Contains(x, Interval(1, 1)) != false assert Contains(oo, Interval(-oo, oo)) == false assert Contains(-oo, Interval(-oo, oo)) == false - \ No newline at end of file + From cf9ff1e76972c1ebc99f84b414ccaf467b6d2ef6 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 18 Apr 2022 23:32:29 -0500 Subject: [PATCH 182/314] Don't assert raises --- symengine/tests/test_logic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/tests/test_logic.py b/symengine/tests/test_logic.py index 669f7c217..2fb2e0a16 100644 --- a/symengine/tests/test_logic.py +++ b/symengine/tests/test_logic.py @@ -44,7 +44,7 @@ def test_And(): assert And(True, False) == false assert And(False, False) == false assert And(True, True, True) == true - assert raises(TypeError, lambda: x < y and y < 1) + raises(TypeError, lambda: x < y and y < 1) def test_Or(): @@ -55,7 +55,7 @@ def test_Or(): assert Or(True, False) == true assert Or(False, False) == false assert Or(True, False, False) == true - assert raises(TypeError, lambda: x < y or y < 1) + raises(TypeError, lambda: x < y or y < 1) def test_Nor(): From 59056f8efc3e6b90d60685ecf5db8c90b36145bd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 19 Apr 2022 15:05:36 -0500 Subject: [PATCH 183/314] Fix wrong test --- symengine/tests/test_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/tests/test_eval.py b/symengine/tests/test_eval.py index 1ea2b51f0..c1cca41f4 100644 --- a/symengine/tests/test_eval.py +++ b/symengine/tests/test_eval.py @@ -16,7 +16,7 @@ def test_eval_double2(): x = Symbol("x") e = sin(x)**2 + sqrt(2) raises(RuntimeError, lambda: e.n(real=True)) - assert abs(e.n() - x**2 - 1.414) < 1e-3 + assert abs(e.n() - sin(x)**2.0 - 1.414) < 1e-3 def test_n(): x = Symbol("x") From bc84086d60de038eb381c9e37c8b552a6c246ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 May 2022 09:24:45 +0200 Subject: [PATCH 184/314] Fix build to avoid duplicate files in wheel Fix the build system to package pure Python files via distutils/setuptools, and limit CMake to installing the compiled extension. The prior logic has installed some of the .py files both via setuptools and via CMake, to different build directories. As a result, the resulting wheel contained duplicate files, e.g.: 2170 05-02-2022 07:08 symengine/__init__.py 2170 05-02-2022 07:08 symengine-0.9.2.data/purelib/symengine/__init__.py Duplicate files cause the wheel to be rejected by the installer package. After the change, a correct wheel is generated. Installation works both via PEP517/wheel and via legacy `setup.py install`. --- setup.py | 2 +- symengine/CMakeLists.txt | 6 ------ symengine/lib/CMakeLists.txt | 2 +- symengine/tests/CMakeLists.txt | 25 ------------------------- 4 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 symengine/tests/CMakeLists.txt diff --git a/setup.py b/setup.py index 33365e5b2..808dac93f 100644 --- a/setup.py +++ b/setup.py @@ -226,7 +226,7 @@ def finalize_options(self): url="https://github.com/symengine/symengine.py", python_requires='>=3.7,<4', zip_safe=False, - packages=['symengine'], + packages=['symengine', 'symengine.lib', 'symengine.tests'], cmdclass = cmdclass, classifiers=[ 'License :: OSI Approved :: MIT License', diff --git a/symengine/CMakeLists.txt b/symengine/CMakeLists.txt index a666f7421..3ea7a4199 100644 --- a/symengine/CMakeLists.txt +++ b/symengine/CMakeLists.txt @@ -1,7 +1 @@ add_subdirectory(lib) -add_subdirectory(tests) - -set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine) -install(FILES __init__.py utilities.py sympy_compat.py functions.py printing.py - DESTINATION ${PY_PATH} - ) diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index 33f813ff1..87b1ab9d4 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -28,7 +28,7 @@ install(TARGETS symengine_wrapper ARCHIVE DESTINATION ${PY_PATH} LIBRARY DESTINATION ${PY_PATH} ) -install(FILES __init__.py +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.pxi symengine.pxd symengine_wrapper.pxd diff --git a/symengine/tests/CMakeLists.txt b/symengine/tests/CMakeLists.txt deleted file mode 100644 index ebd4dfaa2..000000000 --- a/symengine/tests/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine/tests) -install(FILES __init__.py - test_arit.py - test_dict_basic.py - test_eval.py - test_expr.py - test_functions.py - test_number.py - test_matrices.py - test_ntheory.py - test_printing.py - test_sage.py - test_series_expansion.py - test_sets.py - test_solve.py - test_subs.py - test_symbol.py - test_sympify.py - test_sympy_conv.py - test_var.py - test_lambdify.py - test_sympy_compat.py - test_logic.py - DESTINATION ${PY_PATH} - ) From 1830662d5ae74d2054a549fea37a836d0467af81 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 4 May 2022 16:16:21 -0700 Subject: [PATCH 185/314] Add workaround for symbol class leak --- symengine/lib/pywrapper.cpp | 50 ++++++++++++++++++----------- symengine/lib/pywrapper.h | 27 +++++++++++++--- symengine/lib/symengine.pxd | 8 ++--- symengine/lib/symengine_wrapper.pyx | 20 ++++++++++-- 4 files changed, 75 insertions(+), 30 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index aaf128d28..4f45a0b7d 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -281,29 +281,49 @@ inline PyObject* get_pickle_module() { return module; } +PyObject* pickle_loads(const std::string &pickle_str) { + PyObject *module = get_pickle_module(); + PyObject *pickle_bytes = PyBytes_FromStringAndSize(pickle_str.data(), pickle_str.size()); + PyObject *obj = PyObject_CallMethod(module, "loads", "O", pickle_bytes); + Py_XDECREF(pickle_bytes); + if (obj == NULL) { + throw SerializationError("error when loading pickled symbol subclass object"); + } + return obj; +} + RCP load_basic(cereal::PortableBinaryInputArchive &ar, RCP &) { bool is_pysymbol; + bool store_pickle; std::string name; ar(is_pysymbol); ar(name); if (is_pysymbol) { std::string pickle_str; ar(pickle_str); - PyObject *module = get_pickle_module(); - PyObject *pickle_bytes = PyBytes_FromStringAndSize(pickle_str.data(), pickle_str.size()); - PyObject *obj = PyObject_CallMethod(module, "loads", "O", pickle_bytes); - if (obj == NULL) { - throw SerializationError("error when loading pickled symbol subclass object"); - } - RCP result = make_rcp(name, obj); - Py_XDECREF(pickle_bytes); + ar(store_pickle); + PyObject *obj = pickle_loads(pickle_str); + RCP result = make_rcp(name, obj, store_pickle); + Py_XDECREF(obj); return result; } else { return symbol(name); } } +std::string pickle_dumps(const PyObject * obj) { + PyObject *module = get_pickle_module(); + PyObject *pickle_bytes = PyObject_CallMethod(module, "dumps", "O", obj); + if (pickle_bytes == NULL) { + throw SerializationError("error when pickling symbol subclass object"); + } + Py_ssize_t size; + char* buffer; + PyBytes_AsStringAndSize(pickle_bytes, &buffer, &size); + return std::string(buffer, size); +} + void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) { bool is_pysymbol = is_a_sub(b); @@ -311,17 +331,11 @@ void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) ar(b.__str__()); if (is_pysymbol) { RCP p = rcp_static_cast(b.rcp_from_this()); - PyObject *module = get_pickle_module(); - PyObject *pickle_bytes = PyObject_CallMethod(module, "dumps", "O", p->get_py_object()); - if (pickle_bytes == NULL) { - throw SerializationError("error when pickling symbol subclass object"); - } - Py_ssize_t size; - char* buffer; - PyBytes_AsStringAndSize(pickle_bytes, &buffer, &size); - std::string pickle_str(buffer, size); + PyObject *obj = p->get_py_object(); + std::string pickle_str = pickle_dumps(obj); ar(pickle_str); - Py_XDECREF(pickle_bytes); + ar(p->store_pickle); + Py_XDECREF(obj); } } diff --git a/symengine/lib/pywrapper.h b/symengine/lib/pywrapper.h index 175cc763c..20a6dbee4 100644 --- a/symengine/lib/pywrapper.h +++ b/symengine/lib/pywrapper.h @@ -8,6 +8,9 @@ namespace SymEngine { +std::string pickle_dumps(const PyObject *); +PyObject* pickle_loads(const std::string &); + /* * PySymbol is a subclass of Symbol that keeps a reference to a Python object. * When subclassing a Symbol from Python, the information stored in subclassed @@ -27,16 +30,30 @@ namespace SymEngine { class PySymbol : public Symbol { private: PyObject* obj; + std::string bytes; public: - PySymbol(const std::string& name, PyObject* obj) : Symbol(name), obj(obj) { - Py_INCREF(obj); + const bool store_pickle; + PySymbol(const std::string& name, PyObject* obj, bool store_pickle) : + Symbol(name), obj(obj), store_pickle(store_pickle) { + if (store_pickle) { + bytes = pickle_dumps(obj); + } else { + Py_INCREF(obj); + } } PyObject* get_py_object() const { - return obj; + if (store_pickle) { + return pickle_loads(bytes); + } else { + Py_INCREF(obj); + return obj; + } } virtual ~PySymbol() { - // TODO: This is never called because of the cyclic reference. - Py_DECREF(obj); + if (not store_pickle) { + // TODO: This is never called because of the cyclic reference. + Py_DECREF(obj); + } } }; diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index ef94aa19e..06353c258 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -195,7 +195,7 @@ cdef extern from "" namespace "SymEngine": bool neq(const Basic &a, const Basic &b) nogil except + RCP[const Symbol] rcp_static_cast_Symbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil - RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil + RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil except + RCP[const Integer] rcp_static_cast_Integer "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Rational] rcp_static_cast_Rational "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Complex] rcp_static_cast_Complex "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil @@ -367,8 +367,8 @@ cdef extern from "pywrapper.h" namespace "SymEngine": cdef extern from "pywrapper.h" namespace "SymEngine": cdef cppclass PySymbol(Symbol): - PySymbol(string name, PyObject* pyobj) - PyObject* get_py_object() + PySymbol(string name, PyObject* pyobj, bool use_pickle) except + + PyObject* get_py_object() except + string wrapper_dumps(const Basic &x) nogil except + rcp_const_basic wrapper_loads(const string &s) nogil except + @@ -477,7 +477,7 @@ cdef extern from "" namespace "SymEngine": rcp_const_basic make_rcp_Symbol "SymEngine::make_rcp"(string name) nogil rcp_const_basic make_rcp_Dummy "SymEngine::make_rcp"() nogil rcp_const_basic make_rcp_Dummy "SymEngine::make_rcp"(string name) nogil - rcp_const_basic make_rcp_PySymbol "SymEngine::make_rcp"(string name, PyObject * pyobj) nogil + rcp_const_basic make_rcp_PySymbol "SymEngine::make_rcp"(string name, PyObject * pyobj, bool use_pickle) except + rcp_const_basic make_rcp_Constant "SymEngine::make_rcp"(string name) nogil rcp_const_basic make_rcp_Infty "SymEngine::make_rcp"(RCP[const Number] i) nogil rcp_const_basic make_rcp_NaN "SymEngine::make_rcp"() nogil diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 5b2858be5..09ec7e46b 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -46,6 +46,7 @@ cpdef void assign_to_capsule(object capsule, object value): cdef object c2py(rcp_const_basic o): cdef Basic r + cdef PyObject *obj if (symengine.is_a_Add(deref(o))): r = Expr.__new__(Add) elif (symengine.is_a_Mul(deref(o))): @@ -74,7 +75,10 @@ cdef object c2py(rcp_const_basic o): r = Dummy.__new__(Dummy) elif (symengine.is_a_Symbol(deref(o))): if (symengine.is_a_PySymbol(deref(o))): - return (deref(symengine.rcp_static_cast_PySymbol(o)).get_py_object()) + obj = deref(symengine.rcp_static_cast_PySymbol(o)).get_py_object() + result = (obj) + Py_XDECREF(obj); + return result r = Symbol.__new__(Symbol) elif (symengine.is_a_Constant(deref(o))): r = S.Pi @@ -1216,16 +1220,26 @@ cdef class Expr(Basic): cdef class Symbol(Expr): - """ Symbol is a class to store a symbolic variable with a given name. + Subclassing Symbol leads to a memory leak due to a cycle in reference counting. + To avoid this with a performance penalty, set the kwarg store_pickle=True + in the constructor and support the pickle protocol in the subclass by + implmenting __reduce__. """ def __init__(Basic self, name, *args, **kwargs): + cdef cppbool store_pickle; if type(self) == Symbol: self.thisptr = symengine.make_rcp_Symbol(name.encode("utf-8")) else: - self.thisptr = symengine.make_rcp_PySymbol(name.encode("utf-8"), self) + store_pickle = kwargs.pop("store_pickle", False) + if store_pickle: + # First set the pointer to a regular symbol so that when pickle.dumps + # is called when the PySymbol is created, methods like name works. + self.thisptr = symengine.make_rcp_Symbol(name.encode("utf-8")) + self.thisptr = symengine.make_rcp_PySymbol(name.encode("utf-8"), self, + store_pickle) def _sympy_(self): import sympy From 05c02a1bc824f38128dce34645af733c6862d63b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 27 Jun 2022 11:41:30 -0500 Subject: [PATCH 186/314] Add an option --- CMakeLists.txt | 1 + setup.py | 4 +++- symengine/CMakeLists.txt | 9 +++++++++ symengine/lib/CMakeLists.txt | 4 ++++ symengine/tests/CMakeLists.txt | 25 +++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 symengine/tests/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bb764968..920b504ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ foreach (PKG MPC MPFR PIRANHA FLINT LLVM) set(HAVE_SYMENGINE_${PKG} False) endif() endforeach() +option(SYMENGINE_INSTALL_PY_FILES "Install python files" ON) message("CMAKE_SYSTEM_PROCESSOR : ${CMAKE_SYSTEM_PROCESSOR}") message("CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}") diff --git a/setup.py b/setup.py index 808dac93f..5da07e1b7 100644 --- a/setup.py +++ b/setup.py @@ -112,7 +112,9 @@ def cmake_build(self): os.remove("CMakeCache.txt") cmake_cmd = ["cmake", source_dir, - "-DCMAKE_BUILD_TYPE=" + cmake_build_type[0]] + "-DCMAKE_BUILD_TYPE=" + cmake_build_type[0], + "-DSYMENGINE_INSTALL_PY_FILES=OFF", + ] cmake_cmd.extend(process_opts(cmake_opts)) if not path.exists(path.join(build_dir, "CMakeCache.txt")): cmake_cmd.extend(self.get_generator()) diff --git a/symengine/CMakeLists.txt b/symengine/CMakeLists.txt index 3ea7a4199..907e6f648 100644 --- a/symengine/CMakeLists.txt +++ b/symengine/CMakeLists.txt @@ -1 +1,10 @@ add_subdirectory(lib) + +if (SYMENGINE_INSTALL_PY_FILES) + add_subdirectory(tests) + + set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine) + install(FILES __init__.py utilities.py sympy_compat.py functions.py printing.py + DESTINATION ${PY_PATH} + ) +endif () diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index 87b1ab9d4..bf5cc9f80 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -36,6 +36,10 @@ install(FILES DESTINATION ${PY_PATH} ) +if (SYMENGINE_INSTALL_PY_FILES) + install(FILES __init__.py DESTINATION ${PY_PATH}) +endif () + if (${SYMENGINE_COPY_EXTENSION}) if ("${PYTHON_EXTENSION_SOABI}" MATCHES "ppc64le") string(REPLACE "ppc64le" "powerpc64le" COPY_PYTHON_EXTENSION_SOABI "${PYTHON_EXTENSION_SOABI}") diff --git a/symengine/tests/CMakeLists.txt b/symengine/tests/CMakeLists.txt new file mode 100644 index 000000000..ebd4dfaa2 --- /dev/null +++ b/symengine/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine/tests) +install(FILES __init__.py + test_arit.py + test_dict_basic.py + test_eval.py + test_expr.py + test_functions.py + test_number.py + test_matrices.py + test_ntheory.py + test_printing.py + test_sage.py + test_series_expansion.py + test_sets.py + test_solve.py + test_subs.py + test_symbol.py + test_sympify.py + test_sympy_conv.py + test_var.py + test_lambdify.py + test_sympy_compat.py + test_logic.py + DESTINATION ${PY_PATH} + ) From a44442961ad9bc8673ce264f51c02baaa4e22622 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 26 Aug 2022 20:15:45 +0200 Subject: [PATCH 187/314] move test functions to a separate file --- symengine/tests/test_arit.py | 2 +- symengine/tests/test_dict_basic.py | 2 +- symengine/tests/test_eval.py | 2 +- symengine/tests/test_expr.py | 4 +- symengine/tests/test_functions.py | 2 +- symengine/tests/test_lambdify.py | 3 +- symengine/tests/test_logic.py | 2 +- symengine/tests/test_matrices.py | 2 +- symengine/tests/test_ntheory.py | 2 +- symengine/tests/test_number.py | 2 +- symengine/tests/test_pickling.py | 2 +- symengine/tests/test_printing.py | 2 +- symengine/tests/test_series_expansion.py | 2 +- symengine/tests/test_sets.py | 2 +- symengine/tests/test_solve.py | 2 +- symengine/tests/test_subs.py | 2 +- symengine/tests/test_symbol.py | 2 +- symengine/tests/test_sympify.py | 2 +- symengine/tests/test_sympy_compat.py | 2 +- symengine/tests/test_var.py | 2 +- symengine/utilities.py | 93 ------------------------ 21 files changed, 21 insertions(+), 115 deletions(-) diff --git a/symengine/tests/test_arit.py b/symengine/tests/test_arit.py index 65f8062e4..2beacb83b 100644 --- a/symengine/tests/test_arit.py +++ b/symengine/tests/test_arit.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import (Symbol, Integer, Add, Mul, Pow, Rational, sqrt, symbols, S, I, count_ops) diff --git a/symengine/tests/test_dict_basic.py b/symengine/tests/test_dict_basic.py index 7a399a25a..9c2ada68b 100644 --- a/symengine/tests/test_dict_basic.py +++ b/symengine/tests/test_dict_basic.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import symbols, DictBasic, sin, Integer diff --git a/symengine/tests/test_eval.py b/symengine/tests/test_eval.py index c1cca41f4..24b062f11 100644 --- a/symengine/tests/test_eval.py +++ b/symengine/tests/test_eval.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import (Symbol, sin, cos, Integer, Add, I, RealDouble, ComplexDouble, sqrt) from unittest.case import SkipTest diff --git a/symengine/tests/test_expr.py b/symengine/tests/test_expr.py index 8c46f1d8c..f69099a56 100644 --- a/symengine/tests/test_expr.py +++ b/symengine/tests/test_expr.py @@ -1,5 +1,5 @@ -from symengine import Add, Mul, Symbol, Integer -from symengine.utilities import raises +from symengine import Symbol, Integer +from symengine.test_utilities import raises def test_as_coefficients_dict(): diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 0a0388cfd..267506daa 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -5,7 +5,7 @@ loggamma, beta, polygamma, digamma, trigamma, sign, floor, ceiling, conjugate, nan, Float, UnevaluatedExpr ) -from symengine.utilities import raises +from symengine.test_utilities import raises import unittest diff --git a/symengine/tests/test_lambdify.py b/symengine/tests/test_lambdify.py index b2ad57c0a..d0e386987 100644 --- a/symengine/tests/test_lambdify.py +++ b/symengine/tests/test_lambdify.py @@ -8,10 +8,9 @@ import itertools from operator import mul import math -import sys import symengine as se -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import have_numpy import unittest from unittest.case import SkipTest diff --git a/symengine/tests/test_logic.py b/symengine/tests/test_logic.py index 2fb2e0a16..7c01f8e9b 100644 --- a/symengine/tests/test_logic.py +++ b/symengine/tests/test_logic.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine.lib.symengine_wrapper import (true, false, Eq, Ne, Ge, Gt, Le, Lt, Symbol, I, And, Or, Not, Nand, Nor, Xor, Xnor, Piecewise, Contains, Interval, FiniteSet, oo, log) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 7115513de..a79fa746d 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -2,7 +2,7 @@ from symengine.lib.symengine_wrapper import (DenseMatrix, Symbol, Integer, Rational, function_symbol, I, NonSquareMatrixError, ShapeError, zeros, ones, eye, ImmutableMatrix) -from symengine.utilities import raises +from symengine.test_utilities import raises try: diff --git a/symengine/tests/test_ntheory.py b/symengine/tests/test_ntheory.py index 1b5435fe1..68b9a23f1 100644 --- a/symengine/tests/test_ntheory.py +++ b/symengine/tests/test_ntheory.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine.lib.symengine_wrapper import (isprime, nextprime, gcd, lcm, gcd_ext, mod, quotient, quotient_mod, mod_inverse, crt, fibonacci, diff --git a/symengine/tests/test_number.py b/symengine/tests/test_number.py index 0f3ca872f..14b20af42 100644 --- a/symengine/tests/test_number.py +++ b/symengine/tests/test_number.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import Integer, I, S, Symbol, pi, Rational from symengine.lib.symengine_wrapper import (perfect_power, is_square, integer_nthroot) diff --git a/symengine/tests/test_pickling.py b/symengine/tests/test_pickling.py index 4e70c0a63..5ae64a75a 100644 --- a/symengine/tests/test_pickling.py +++ b/symengine/tests/test_pickling.py @@ -1,5 +1,5 @@ from symengine import symbols, sin, sinh, have_numpy, have_llvm, cos, Symbol -from symengine.utilities import raises +from symengine.test_utilities import raises import pickle import unittest diff --git a/symengine/tests/test_printing.py b/symengine/tests/test_printing.py index 6c5ec7307..e0c428169 100644 --- a/symengine/tests/test_printing.py +++ b/symengine/tests/test_printing.py @@ -1,5 +1,5 @@ from symengine import (ccode, unicode, Symbol, sqrt, Pow, Max, sin, Integer, MutableDenseMatrix) -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine.printing import CCodePrinter, init_printing def test_ccode(): diff --git a/symengine/tests/test_series_expansion.py b/symengine/tests/test_series_expansion.py index ed1dee518..651e36302 100644 --- a/symengine/tests/test_series_expansion.py +++ b/symengine/tests/test_series_expansion.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine.lib.symengine_wrapper import (series, have_piranha, have_flint, Symbol, Integer, sin, cos, exp, sqrt, E) diff --git a/symengine/tests/test_sets.py b/symengine/tests/test_sets.py index 971f96283..bfa4ecd4e 100644 --- a/symengine/tests/test_sets.py +++ b/symengine/tests/test_sets.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine.lib.symengine_wrapper import (Interval, EmptySet, UniversalSet, FiniteSet, Union, Complement, ImageSet, ConditionSet, Reals, Rationals, Integers, And, Or, oo, Symbol, true, Ge, Eq, Gt) diff --git a/symengine/tests/test_solve.py b/symengine/tests/test_solve.py index 01eaaf04c..675f1a9fe 100644 --- a/symengine/tests/test_solve.py +++ b/symengine/tests/test_solve.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import (Interval, EmptySet, FiniteSet, I, oo, Eq, Symbol, linsolve) from symengine.lib.symengine_wrapper import solve diff --git a/symengine/tests/test_subs.py b/symengine/tests/test_subs.py index bc03b1e39..4d8c6f0a4 100644 --- a/symengine/tests/test_subs.py +++ b/symengine/tests/test_subs.py @@ -1,6 +1,6 @@ import unittest -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import Symbol, sin, cos, sqrt, Add, function_symbol, have_numpy diff --git a/symengine/tests/test_symbol.py b/symengine/tests/test_symbol.py index fc9fafc7c..a441cf0e9 100644 --- a/symengine/tests/test_symbol.py +++ b/symengine/tests/test_symbol.py @@ -1,5 +1,5 @@ from symengine import Symbol, symbols, symarray, has_symbol, Dummy -from symengine.utilities import raises +from symengine.test_utilities import raises import unittest import platform diff --git a/symengine/tests/test_sympify.py b/symengine/tests/test_sympify.py index 09dcc759e..9ecf57b09 100644 --- a/symengine/tests/test_sympify.py +++ b/symengine/tests/test_sympify.py @@ -1,4 +1,4 @@ -from symengine.utilities import raises +from symengine.test_utilities import raises from symengine import (Symbol, Integer, sympify, SympifyError, true, false, pi, nan, oo, zoo, E, I, GoldenRatio, Catalan, Rational, sqrt, Eq) diff --git a/symengine/tests/test_sympy_compat.py b/symengine/tests/test_sympy_compat.py index 0d1bf50e3..0e69aa1a6 100644 --- a/symengine/tests/test_sympy_compat.py +++ b/symengine/tests/test_sympy_compat.py @@ -1,7 +1,7 @@ from symengine.sympy_compat import (Integer, Rational, S, Basic, Add, Mul, Pow, symbols, Symbol, log, sin, cos, sech, csch, zeros, atan2, nan, Number, Float, Min, Max, RealDouble, have_mpfr, Abs) -from symengine.utilities import raises +from symengine.test_utilities import raises def test_Integer(): diff --git a/symengine/tests/test_var.py b/symengine/tests/test_var.py index 35498c47a..d82d4fab1 100644 --- a/symengine/tests/test_var.py +++ b/symengine/tests/test_var.py @@ -1,7 +1,7 @@ # Tests for var are in their own file, because var pollutes global namespace. from symengine import Symbol, var -from symengine.utilities import raises +from symengine.test_utilities import raises # make z1 with call-depth = 1 diff --git a/symengine/utilities.py b/symengine/utilities.py index a16aa0a46..a64ea15e3 100644 --- a/symengine/utilities.py +++ b/symengine/utilities.py @@ -241,99 +241,6 @@ def traverse(symbols, frame): return syms -try: - import py - from py.test import skip, raises - USE_PYTEST = getattr(sys, '_running_pytest', False) -except ImportError: - USE_PYTEST = False - -if not USE_PYTEST: - def raises(expectedException, code=None): - """ - Tests that ``code`` raises the exception ``expectedException``. - - ``code`` may be a callable, such as a lambda expression or function - name. - - If ``code`` is not given or None, ``raises`` will return a context - manager for use in ``with`` statements; the code to execute then - comes from the scope of the ``with``. - - ``raises()`` does nothing if the callable raises the expected - exception, otherwise it raises an AssertionError. - - Examples - ======== - - >>> from symengine.pytest import raises - - >>> raises(ZeroDivisionError, lambda: 1/0) - >>> raises(ZeroDivisionError, lambda: 1/2) - Traceback (most recent call last): - ... - AssertionError: DID NOT RAISE - - >>> with raises(ZeroDivisionError): - ... n = 1/0 - >>> with raises(ZeroDivisionError): - ... n = 1/2 - Traceback (most recent call last): - ... - AssertionError: DID NOT RAISE - - Note that you cannot test multiple statements via - ``with raises``: - - >>> with raises(ZeroDivisionError): - ... n = 1/0 # will execute and raise, aborting the ``with`` - ... n = 9999/0 # never executed - - This is just what ``with`` is supposed to do: abort the - contained statement sequence at the first exception and let - the context manager deal with the exception. - - To test multiple statements, you'll need a separate ``with`` - for each: - - >>> with raises(ZeroDivisionError): - ... n = 1/0 # will execute and raise - >>> with raises(ZeroDivisionError): - ... n = 9999/0 # will also execute and raise - - """ - if code is None: - return RaisesContext(expectedException) - elif callable(code): - try: - code() - except expectedException: - return - raise AssertionError("DID NOT RAISE") - elif isinstance(code, str): - raise TypeError( - '\'raises(xxx, "code")\' has been phased out; ' - 'change \'raises(xxx, "expression")\' ' - 'to \'raises(xxx, lambda: expression)\', ' - '\'raises(xxx, "statement")\' ' - 'to \'with raises(xxx): statement\'') - else: - raise TypeError( - 'raises() expects a callable for the 2nd argument.') - - class RaisesContext(object): - def __init__(self, expectedException): - self.expectedException = expectedException - - def __enter__(self): - return None - - def __exit__(self, exc_type, exc_value, traceback): - if exc_type is None: - raise AssertionError("DID NOT RAISE") - return issubclass(exc_type, self.expectedException) - - class NotIterable: """ Use this as mixin when creating a class which is not supposed to return From 40ae6a121834daafe3291ad5b8cca0a7bca85877 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 26 Aug 2022 20:19:45 +0200 Subject: [PATCH 188/314] add new test_utitilies.py file --- symengine/test_utilities.py | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 symengine/test_utilities.py diff --git a/symengine/test_utilities.py b/symengine/test_utilities.py new file mode 100644 index 000000000..7c1487848 --- /dev/null +++ b/symengine/test_utilities.py @@ -0,0 +1,93 @@ +try: + import py + from py.test import skip, raises + USE_PYTEST = getattr(sys, '_running_pytest', False) +except ImportError: + USE_PYTEST = False + +if not USE_PYTEST: + def raises(expectedException, code=None): + """ + Tests that ``code`` raises the exception ``expectedException``. + + ``code`` may be a callable, such as a lambda expression or function + name. + + If ``code`` is not given or None, ``raises`` will return a context + manager for use in ``with`` statements; the code to execute then + comes from the scope of the ``with``. + + ``raises()`` does nothing if the callable raises the expected + exception, otherwise it raises an AssertionError. + + Examples + ======== + + >>> from symengine.pytest import raises + + >>> raises(ZeroDivisionError, lambda: 1/0) + >>> raises(ZeroDivisionError, lambda: 1/2) + Traceback (most recent call last): + ... + AssertionError: DID NOT RAISE + + >>> with raises(ZeroDivisionError): + ... n = 1/0 + >>> with raises(ZeroDivisionError): + ... n = 1/2 + Traceback (most recent call last): + ... + AssertionError: DID NOT RAISE + + Note that you cannot test multiple statements via + ``with raises``: + + >>> with raises(ZeroDivisionError): + ... n = 1/0 # will execute and raise, aborting the ``with`` + ... n = 9999/0 # never executed + + This is just what ``with`` is supposed to do: abort the + contained statement sequence at the first exception and let + the context manager deal with the exception. + + To test multiple statements, you'll need a separate ``with`` + for each: + + >>> with raises(ZeroDivisionError): + ... n = 1/0 # will execute and raise + >>> with raises(ZeroDivisionError): + ... n = 9999/0 # will also execute and raise + + """ + if code is None: + return RaisesContext(expectedException) + elif callable(code): + try: + code() + except expectedException: + return + raise AssertionError("DID NOT RAISE") + elif isinstance(code, str): + raise TypeError( + '\'raises(xxx, "code")\' has been phased out; ' + 'change \'raises(xxx, "expression")\' ' + 'to \'raises(xxx, lambda: expression)\', ' + '\'raises(xxx, "statement")\' ' + 'to \'with raises(xxx): statement\'') + else: + raise TypeError( + 'raises() expects a callable for the 2nd argument.') + + class RaisesContext(object): + def __init__(self, expectedException): + self.expectedException = expectedException + + def __enter__(self): + return None + + def __exit__(self, exc_type, exc_value, traceback): + if exc_type is None: + raise AssertionError("DID NOT RAISE") + return issubclass(exc_type, self.expectedException) + + From ae1a0e0a450c05cb0227cde0621632ccc1869800 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 26 Aug 2022 20:28:42 +0200 Subject: [PATCH 189/314] add missing import --- symengine/test_utilities.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/symengine/test_utilities.py b/symengine/test_utilities.py index 7c1487848..dd394b065 100644 --- a/symengine/test_utilities.py +++ b/symengine/test_utilities.py @@ -1,3 +1,5 @@ +import sys + try: import py from py.test import skip, raises From fbac0d485100bc278648e011e31a970ae0e79b38 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 9 Oct 2022 06:30:56 +0200 Subject: [PATCH 190/314] Upgrade GitHub Action to v3 https://github.com/actions/checkout/releases --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e2c5444b..e9d043275 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build and test symengine shell: bash From b01e6310b4fcc3c068f4461a843ce7c6568a541b Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 9 Oct 2022 23:49:02 +0200 Subject: [PATCH 191/314] Use print() function in both Python 2 and 3 --- benchmarks/expand2_sage.py | 3 ++- benchmarks/expand3.py | 3 ++- benchmarks/expand3_sage.py | 5 +++-- benchmarks/expand4_sage.py | 7 ++++--- benchmarks/expand5.py | 3 ++- benchmarks/expand5_sage.py | 5 +++-- benchmarks/kane.py | 3 ++- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/benchmarks/expand2_sage.py b/benchmarks/expand2_sage.py index 9e0e04456..2af846a63 100644 --- a/benchmarks/expand2_sage.py +++ b/benchmarks/expand2_sage.py @@ -1,9 +1,10 @@ +from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z w") e = (x+y+z+w)**15 f = e*(e+w) -print f +print(f) t1 = clock() g = f.expand() t2 = clock() diff --git a/benchmarks/expand3.py b/benchmarks/expand3.py index f8a3706f1..f9fcbf98f 100644 --- a/benchmarks/expand3.py +++ b/benchmarks/expand3.py @@ -1,10 +1,11 @@ +from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock from symengine import var var("x y z") f = (x**y + y**z + z**x)**100 -print f +print(f) t1 = clock() g = f.expand() t2 = clock() diff --git a/benchmarks/expand3_sage.py b/benchmarks/expand3_sage.py index 85587001a..4be0ecf5f 100644 --- a/benchmarks/expand3_sage.py +++ b/benchmarks/expand3_sage.py @@ -1,9 +1,10 @@ +from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z") f = (x**y + y**z + z**x)**100 -print f +print(f) t1 = clock() g = f.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/expand4_sage.py b/benchmarks/expand4_sage.py index 1883b88fa..bd8e391e6 100644 --- a/benchmarks/expand4_sage.py +++ b/benchmarks/expand4_sage.py @@ -1,12 +1,13 @@ -print "import..." +from __future__ import print_function +print("import...") from timeit import default_timer as clock from sage.all import var var("x") e = 1 -print "constructing expression..." +print("constructing expression...") for i in range(1, 351): e *= (i+x)**3 -print "running benchmark..." +print("running benchmark...") t1 = clock() f = e.expand() t2 = clock() diff --git a/benchmarks/expand5.py b/benchmarks/expand5.py index 82ac0d59b..d6fda8f54 100644 --- a/benchmarks/expand5.py +++ b/benchmarks/expand5.py @@ -1,3 +1,4 @@ +from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock @@ -5,7 +6,7 @@ var("x y z") e = (x+y+z+1)**15 f = e*(e+1) -print f +print(f) t1 = clock() g = f.expand() t2 = clock() diff --git a/benchmarks/expand5_sage.py b/benchmarks/expand5_sage.py index 2153a1d46..91a153908 100644 --- a/benchmarks/expand5_sage.py +++ b/benchmarks/expand5_sage.py @@ -1,10 +1,11 @@ +from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z") e = (x+y+z+1)**15 f = e*(e+1) -print f +print(f) t1 = clock() g = f.expand() t2 = clock() -print "Total time:", t2-t1, "s" +print("Total time:", t2-t1, "s") diff --git a/benchmarks/kane.py b/benchmarks/kane.py index fdefcf1f5..a0fa715ef 100644 --- a/benchmarks/kane.py +++ b/benchmarks/kane.py @@ -1,3 +1,4 @@ +from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock @@ -20,7 +21,7 @@ t2 = clock() print("Total time:", t2-t1, "s") -print "SymPy diff:" +print("SymPy diff:") t1 = clock() g = f.diff(sympy.Symbol("sq5")) t2 = clock() From 0d01148c3d9902ad378b6931020728b9e6a22bfb Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 10 Oct 2022 13:12:19 +0200 Subject: [PATCH 192/314] pyupgrade --py37-plus **/*.py --- benchmarks/expand2_sage.py | 1 - benchmarks/expand3.py | 1 - benchmarks/expand3_sage.py | 1 - benchmarks/expand4_sage.py | 1 - benchmarks/expand5.py | 1 - benchmarks/expand5_sage.py | 1 - benchmarks/heterogeneous_output_Lambdify.py | 2 +- benchmarks/kane.py | 1 - benchmarks/kane_generate.py | 8 ++++---- setup.py | 8 ++++---- symengine/printing.py | 6 +++--- symengine/test_utilities.py | 2 +- symengine/tests/test_arit.py | 16 ++++++++-------- symengine/tests/test_dict_basic.py | 6 +++--- symengine/tests/test_lambdify.py | 4 ---- symengine/tests/test_matrices.py | 2 +- symengine/tests/test_symbol.py | 8 ++++---- symengine/tests/test_sympify.py | 2 +- symengine/tests/test_sympy_compat.py | 2 +- 19 files changed, 31 insertions(+), 42 deletions(-) diff --git a/benchmarks/expand2_sage.py b/benchmarks/expand2_sage.py index 2af846a63..f29f55ddd 100644 --- a/benchmarks/expand2_sage.py +++ b/benchmarks/expand2_sage.py @@ -1,4 +1,3 @@ -from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z w") diff --git a/benchmarks/expand3.py b/benchmarks/expand3.py index f9fcbf98f..18f0a9cb8 100644 --- a/benchmarks/expand3.py +++ b/benchmarks/expand3.py @@ -1,4 +1,3 @@ -from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock diff --git a/benchmarks/expand3_sage.py b/benchmarks/expand3_sage.py index 4be0ecf5f..75872fa4b 100644 --- a/benchmarks/expand3_sage.py +++ b/benchmarks/expand3_sage.py @@ -1,4 +1,3 @@ -from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z") diff --git a/benchmarks/expand4_sage.py b/benchmarks/expand4_sage.py index bd8e391e6..961f5d3b5 100644 --- a/benchmarks/expand4_sage.py +++ b/benchmarks/expand4_sage.py @@ -1,4 +1,3 @@ -from __future__ import print_function print("import...") from timeit import default_timer as clock from sage.all import var diff --git a/benchmarks/expand5.py b/benchmarks/expand5.py index d6fda8f54..25ab7e7a3 100644 --- a/benchmarks/expand5.py +++ b/benchmarks/expand5.py @@ -1,4 +1,3 @@ -from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock diff --git a/benchmarks/expand5_sage.py b/benchmarks/expand5_sage.py index 91a153908..8fb7ab455 100644 --- a/benchmarks/expand5_sage.py +++ b/benchmarks/expand5_sage.py @@ -1,4 +1,3 @@ -from __future__ import print_function from timeit import default_timer as clock from sage.all import var var("x y z") diff --git a/benchmarks/heterogeneous_output_Lambdify.py b/benchmarks/heterogeneous_output_Lambdify.py index 7c493c0c8..f54d7ab1b 100644 --- a/benchmarks/heterogeneous_output_Lambdify.py +++ b/benchmarks/heterogeneous_output_Lambdify.py @@ -9,7 +9,7 @@ import warnings src = os.path.join(os.path.dirname(__file__), '6_links_rhs.txt') -serial = open(src, 'tr').read() +serial = open(src).read() parsed = parse_expr(serial, transformations=standard_transformations) vec = sp.Matrix(1, 14, parsed) args = tuple(sorted(vec.free_symbols, key=lambda arg: arg.name)) diff --git a/benchmarks/kane.py b/benchmarks/kane.py index a0fa715ef..96d5fb66b 100644 --- a/benchmarks/kane.py +++ b/benchmarks/kane.py @@ -1,4 +1,3 @@ -from __future__ import print_function import sys sys.path.append("..") from timeit import default_timer as clock diff --git a/benchmarks/kane_generate.py b/benchmarks/kane_generate.py index dff13e573..b3c81284f 100644 --- a/benchmarks/kane_generate.py +++ b/benchmarks/kane_generate.py @@ -188,11 +188,11 @@ def test_bicycle(): PaperForkCgZ = 0.7 FrameLength = evalf.N(PaperWb*sin(HTA)-(rake-(PaperRadFront-PaperRadRear)*cos(HTA))) FrameCGNorm = evalf.N((PaperFrameCgZ - PaperRadRear-(PaperFrameCgX/sin(HTA))*cos(HTA))*sin(HTA)) - FrameCGPar = evalf.N((PaperFrameCgX / sin(HTA) + (PaperFrameCgZ - PaperRadRear - PaperFrameCgX / sin(HTA) * cos(HTA)) * cos(HTA))) - tempa = evalf.N((PaperForkCgZ - PaperRadFront)) - tempb = evalf.N((PaperWb-PaperForkCgX)) + FrameCGPar = evalf.N(PaperFrameCgX / sin(HTA) + (PaperFrameCgZ - PaperRadRear - PaperFrameCgX / sin(HTA) * cos(HTA)) * cos(HTA)) + tempa = evalf.N(PaperForkCgZ - PaperRadFront) + tempb = evalf.N(PaperWb-PaperForkCgX) tempc = evalf.N(sqrt(tempa**2+tempb**2)) - PaperForkL = evalf.N((PaperWb*cos(HTA)-(PaperRadFront-PaperRadRear)*sin(HTA))) + PaperForkL = evalf.N(PaperWb*cos(HTA)-(PaperRadFront-PaperRadRear)*sin(HTA)) ForkCGNorm = evalf.N(rake+(tempc * sin(pi/2-HTA-acos(tempa/tempc)))) ForkCGPar = evalf.N(tempc * cos((pi/2-HTA)-acos(tempa/tempc))-PaperForkL) diff --git a/setup.py b/setup.py index 5da07e1b7..bbaf54cb4 100644 --- a/setup.py +++ b/setup.py @@ -119,12 +119,12 @@ def cmake_build(self): if not path.exists(path.join(build_dir, "CMakeCache.txt")): cmake_cmd.extend(self.get_generator()) if subprocess.call(cmake_cmd, cwd=build_dir) != 0: - raise EnvironmentError("error calling cmake") + raise OSError("error calling cmake") if subprocess.call(["cmake", "--build", ".", "--config", cmake_build_type[0]], cwd=build_dir) != 0: - raise EnvironmentError("error building project") + raise OSError("error building project") def get_generator(self): if cmake_generator[0]: @@ -176,13 +176,13 @@ def cmake_install(self): # CMake has to be called here to update PYTHON_INSTALL_PATH # if build and install were called separately by the user if subprocess.call(cmake_cmd, cwd=build_dir) != 0: - raise EnvironmentError("error calling cmake") + raise OSError("error calling cmake") if subprocess.call(["cmake", "--build", ".", "--config", cmake_build_type[0], "--target", "install"], cwd=build_dir) != 0: - raise EnvironmentError("error installing") + raise OSError("error installing") import compileall compileall.compile_dir(path.join(self.install_platlib, "symengine")) diff --git a/symengine/printing.py b/symengine/printing.py index 6cec481a6..4d16d0f26 100644 --- a/symengine/printing.py +++ b/symengine/printing.py @@ -4,7 +4,7 @@ class CCodePrinter: def doprint(self, expr, assign_to=None): if not isinstance(assign_to, (Basic, type(None), str)): - raise TypeError("{0} cannot assign to object of type {1}".format( + raise TypeError("{} cannot assign to object of type {}".format( type(self).__name__, type(assign_to))) expr = sympify(expr) @@ -15,11 +15,11 @@ def doprint(self, expr, assign_to=None): assign_to = str(assign_to) if not expr.is_Matrix: - return "{} = {};".format(assign_to, ccode(expr)) + return f"{assign_to} = {ccode(expr)};" code_lines = [] for i, element in enumerate(expr): - code_line = '{}[{}] = {};'.format(assign_to, i, element) + code_line = f'{assign_to}[{i}] = {element};' code_lines.append(code_line) return '\n'.join(code_lines) diff --git a/symengine/test_utilities.py b/symengine/test_utilities.py index dd394b065..cd3eeaa4c 100644 --- a/symengine/test_utilities.py +++ b/symengine/test_utilities.py @@ -80,7 +80,7 @@ def raises(expectedException, code=None): raise TypeError( 'raises() expects a callable for the 2nd argument.') - class RaisesContext(object): + class RaisesContext: def __init__(self, expectedException): self.expectedException = expectedException diff --git a/symengine/tests/test_arit.py b/symengine/tests/test_arit.py index 2beacb83b..b81165145 100644 --- a/symengine/tests/test_arit.py +++ b/symengine/tests/test_arit.py @@ -133,27 +133,27 @@ def test_args(): y = Symbol("y") assert (x**2).args == (x, 2) assert (x**2 + 5).args == (5, x**2) - assert set((x**2 + 2*x*y + 5).args) == set((x**2, 2*x*y, Integer(5))) + assert set((x**2 + 2*x*y + 5).args) == {x**2, 2*x*y, Integer(5)} assert (2*x**2).args == (2, x**2) - assert set((2*x**2*y).args) == set((Integer(2), x**2, y)) + assert set((2*x**2*y).args) == {Integer(2), x**2, y} def test_atoms(): x = Symbol("x") y = Symbol("y") z = Symbol("z") - assert (x**2).atoms() == set([x]) - assert (x**2).atoms(Symbol) == set([x]) - assert (x ** y + z).atoms() == set([x, y, z]) - assert (x**y + z).atoms(Symbol) == set([x, y, z]) + assert (x**2).atoms() == {x} + assert (x**2).atoms(Symbol) == {x} + assert (x ** y + z).atoms() == {x, y, z} + assert (x**y + z).atoms(Symbol) == {x, y, z} def test_free_symbols(): x = Symbol("x") y = Symbol("y") z = Symbol("z") - assert (x**2).free_symbols == set([x]) - assert (x**y + z).free_symbols == set([x, y, z]) + assert (x**2).free_symbols == {x} + assert (x**y + z).free_symbols == {x, y, z} def test_as_numer_denom(): diff --git a/symengine/tests/test_dict_basic.py b/symengine/tests/test_dict_basic.py index 9c2ada68b..d1e5ab633 100644 --- a/symengine/tests/test_dict_basic.py +++ b/symengine/tests/test_dict_basic.py @@ -18,11 +18,11 @@ def test_DictBasic(): assert d[2*z] == x if 2*z not in d: assert False - assert set(d.items()) == set([(2*z, x), (x, Integer(2)), (y, z)]) + assert set(d.items()) == {(2*z, x), (x, Integer(2)), (y, z)} del d[x] - assert set(d.keys()) == set([2*z, y]) - assert set(d.values()) == set([x, z]) + assert set(d.keys()) == {2*z, y} + assert set(d.values()) == {x, z} e = y + sin(2*z) assert e.subs(d) == z + sin(x) diff --git a/symengine/tests/test_lambdify.py b/symengine/tests/test_lambdify.py index d0e386987..fa628a363 100644 --- a/symengine/tests/test_lambdify.py +++ b/symengine/tests/test_lambdify.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, print_function) - - import array import cmath from functools import reduce diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index a79fa746d..55ebd0464 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -721,7 +721,7 @@ def test_atoms(): a = Symbol("a") b = Symbol("b") X = DenseMatrix([[a, 2], [b, 4]]) - assert X.atoms(Symbol) == set([a, b]) + assert X.atoms(Symbol) == {a, b} def test_LUdecomp(): diff --git a/symengine/tests/test_symbol.py b/symengine/tests/test_symbol.py index a441cf0e9..498259141 100644 --- a/symengine/tests/test_symbol.py +++ b/symengine/tests/test_symbol.py @@ -48,7 +48,7 @@ def test_symbols(): assert symbols(('x', 'y', 'z')) == (x, y, z) assert symbols(['x', 'y', 'z']) == [x, y, z] - assert symbols(set(['x', 'y', 'z'])) == set([x, y, z]) + assert symbols({'x', 'y', 'z'}) == {x, y, z} raises(ValueError, lambda: symbols('')) raises(ValueError, lambda: symbols(',')) @@ -104,13 +104,13 @@ def sym(s): assert sym('a0:4') == '(a0, a1, a2, a3)' assert sym('a2:4,b1:3') == '(a2, a3, b1, b2)' assert sym('a1(2:4)') == '(a12, a13)' - assert sym(('a0:2.0:2')) == '(a0.0, a0.1, a1.0, a1.1)' - assert sym(('aa:cz')) == '(aaz, abz, acz)' + assert sym('a0:2.0:2') == '(a0.0, a0.1, a1.0, a1.1)' + assert sym('aa:cz') == '(aaz, abz, acz)' assert sym('aa:c0:2') == '(aa0, aa1, ab0, ab1, ac0, ac1)' assert sym('aa:ba:b') == '(aaa, aab, aba, abb)' assert sym('a:3b') == '(a0b, a1b, a2b)' assert sym('a-1:3b') == '(a-1b, a-2b)' - assert sym('a:2\,:2' + chr(0)) == '(a0,0%s, a0,1%s, a1,0%s, a1,1%s)' % ( + assert sym(r'a:2\,:2' + chr(0)) == '(a0,0%s, a0,1%s, a1,0%s, a1,1%s)' % ( (chr(0),)*4) assert sym('x(:a:3)') == '(x(a0), x(a1), x(a2))' assert sym('x(:c):1') == '(xa0, xb0, xc0)' diff --git a/symengine/tests/test_sympify.py b/symengine/tests/test_sympify.py index 9ecf57b09..86c59785c 100644 --- a/symengine/tests/test_sympify.py +++ b/symengine/tests/test_sympify.py @@ -44,7 +44,7 @@ def test_S(): def test_sympify_error1a(): - class Test(object): + class Test: pass raises(SympifyError, lambda: sympify(Test())) diff --git a/symengine/tests/test_sympy_compat.py b/symengine/tests/test_sympy_compat.py index 0e69aa1a6..6316d548f 100644 --- a/symengine/tests/test_sympy_compat.py +++ b/symengine/tests/test_sympy_compat.py @@ -183,7 +183,7 @@ def __new__(cls, name, extra_attribute): return Symbol.__new__(cls, name) def __init__(self, name, extra_attribute): - super(Wrapper, self).__init__(name) + super().__init__(name) self.extra_attribute = extra_attribute # Instantiate the subclass From 08412c1062f94324c1f2a2b61fb937b8189712e1 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Mon, 10 Oct 2022 13:43:06 +0200 Subject: [PATCH 193/314] Add Python 3.10 to the testing `"3.10"` ___must___ be quoted in yaml. https://dev.to/hugovk/the-python-3-1-problem-85g --- .github/workflows/ci.yml | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9d043275..a99708a11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,19 +10,26 @@ jobs: include: - BUILD_TYPE: Debug WITH_BFD: yes - PYTHON_VERSION: 3.9 + PYTHON_VERSION: '3.10' + TEST_SYMPY: yes + OS: ubuntu-20.04 + CC: gcc + + - BUILD_TYPE: Debug + WITH_BFD: yes + PYTHON_VERSION: '3.9' TEST_SYMPY: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.7 + PYTHON_VERSION: '3.7' BUILD_SHARED_LIBS: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.7 + PYTHON_VERSION: '3.7' WITH_MPFR: yes INTEGER_CLASS: gmpxx WITH_NUMPY: no @@ -30,25 +37,25 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' WITH_MPC: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release WITH_MPFR: yes - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.9 + PYTHON_VERSION: '3.9' WITH_MPC: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.9 + PYTHON_VERSION: '3.9' WITH_MPC: yes INTEGER_CLASS: flint WITH_FLINT: yes @@ -56,27 +63,27 @@ jobs: CC: gcc #- BUILD_TYPE: Debug - # PYTHON_VERSION: 3.9 + # PYTHON_VERSION: '3.9' # WITH_BFD: yes # WITH_PIRANHA: yes # OS: ubuntu-20.04 # CC: gcc - BUILD_TYPE: Debug - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' WITH_BFD: yes BUILD_SHARED_LIBS: yes OS: ubuntu-20.04 CC: clang - BUILD_TYPE: Release - PYTHON_VERSION: 3.7 + PYTHON_VERSION: '3.7' WITH_NUMPY: yes OS: ubuntu-20.04 CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' WITH_SYMPY: yes WITH_LLVM: 13 WITH_SCIPY: yes @@ -85,31 +92,31 @@ jobs: EXTRA_APT_PACKAGES: 'llvm-13' - BUILD_TYPE: Debug - PYTHON_VERSION: 3.7 + PYTHON_VERSION: '3.7' WITH_SCIPY: yes WITH_LLVM: 5.0 OS: macos-latest CC: clang - BUILD_TYPE: Release - PYTHON_VERSION: 3.9 + PYTHON_VERSION: '3.9' WITH_NUMPY: no OS: macos-latest CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: 3.7 + PYTHON_VERSION: '3.7' WITH_NUMPY: no OS: macos-latest CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' OS: macos-latest CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: 3.8 + PYTHON_VERSION: '3.8' OS: ubuntu-20.04 WITH_MPC: yes WITH_MPFR: yes From 75f0bf7e0d62f9b8c7597a048e83ae75e8ad8335 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 14 Oct 2022 01:33:11 -0500 Subject: [PATCH 194/314] fix conversion of large integers --- symengine/lib/symengine.pxd | 2 ++ symengine/lib/symengine_wrapper.pyx | 18 ++++++++++-------- symengine/tests/test_sympy_conv.py | 9 +++++++++ symengine_version.txt | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index ef94aa19e..9b7da674d 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -24,6 +24,8 @@ cdef extern from 'symengine/mp_class.h' namespace "SymEngine": integer_class(const string &s) except + mpz_t get_mpz_t(integer_class &a) const mpz_t get_mpz_t(const integer_class &a) + string mp_get_hex_str(const integer_class &a) + void mp_set_str(integer_class &a, const string &s) cdef cppclass rational_class: rational_class() rational_class(mpq_t) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 5b2858be5..a77f5bb4a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1685,10 +1685,10 @@ class Rational(Number): return c2py(symengine.Rational.from_two_ints(p_, q_)); except OverflowError: # Too big, need to use mpz - tmp = str(p).encode("utf-8") - p__ = symengine.integer_class(tmp) - tmp = str(q).encode("utf-8") - q__ = symengine.integer_class(tmp) + tmp = hex(p).encode("utf-8") + symengine.mp_set_str(p__, tmp) + tmp = hex(q).encode("utf-8") + symengine.mp_set_str(q__, tmp) return c2py(symengine.Integer(p__).divint(symengine.Integer(q__))) @property @@ -1756,8 +1756,8 @@ class Integer(Rational): except OverflowError: # Too big, need to use mpz int_ok = False - tmp = str(i).encode("utf-8") - i__ = symengine.integer_class(tmp) + tmp = hex(i).encode("utf-8") + symengine.mp_set_str(i__, tmp) # Note: all other exceptions are left intact if int_ok: return c2py(symengine.integer(i_)) @@ -1817,7 +1817,7 @@ class Integer(Rational): def _sympy_(Basic self): import sympy - return sympy.Integer(deref(self.thisptr).__str__().decode("utf-8")) + return sympy.Integer(int(self)) def _sage_(Basic self): try: @@ -1828,7 +1828,9 @@ class Integer(Rational): return sage.Integer(str(self)) def __int__(Basic self): - return int(str(self)) + cdef string s = symengine.mp_get_hex_str( + deref(symengine.rcp_static_cast_Integer(self.thisptr)).as_integer_class()) + return int(s.decode("utf-8"), base=16) @property def p(self): diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 67253637b..7692ad716 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -806,3 +806,12 @@ def test_conv_doubles(): assert sympify(a._sympy_()) == a assert float(a) == f assert float(a._sympy_()) == f + +def test_conv_large_integers(): + a = Integer(10)**10000 + # check that convert to python int does not throw + b = int(a) + # check that convert to sympy int does not throw + if have_sympy: + c = a._sympy_() + d = sympify(c) diff --git a/symengine_version.txt b/symengine_version.txt index f979adec6..08007dd19 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.9.0 +5a9d4fa8c769b2dc8d7904ec16d7ea76328c4565 From 3ae6fad34ebca5db34b85cd0ad37c7130944fbf3 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 10 Nov 2022 11:45:37 +0100 Subject: [PATCH 195/314] ci: Add Python 3.11 to the testing --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a99708a11..709c12fe6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,13 @@ jobs: fail-fast: false matrix: include: + - BUILD_TYPE: Debug + WITH_BFD: yes + PYTHON_VERSION: '3.11' + TEST_SYMPY: yes + OS: ubuntu-20.04 + CC: gcc + - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: '3.10' From 560bafb9eb4623800f8caa4df72033ecb6f6b21a Mon Sep 17 00:00:00 2001 From: Bjorn Date: Mon, 16 Jan 2023 08:57:59 +0100 Subject: [PATCH 196/314] Add boostmp to test matrix, also bump llvm version tested. (#428) * Add boostmp to test matrix, also bump llvm version tested. * handle tribool explicitly (bool -> tribool) * boost: skip test integer_nthroot (does not complete in 6h) --- .github/workflows/ci.yml | 13 ++++--- symengine/lib/symengine.pxd | 43 +++++++++++++++-------- symengine/lib/symengine_wrapper.pyx | 54 ++++++++++++++++------------- symengine_version.txt | 2 +- 4 files changed, 66 insertions(+), 46 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 709c12fe6..4916921cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,13 +90,15 @@ jobs: CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.10' WITH_SYMPY: yes - WITH_LLVM: 13 + WITH_LLVM: 14 WITH_SCIPY: yes - OS: ubuntu-20.04 - EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main' - EXTRA_APT_PACKAGES: 'llvm-13' + INTEGER_CLASS: 'boostmp' + PYTEST_ADDOPTS: '-k "not integer_nthroot"' + OS: ubuntu-22.04 + EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main' + EXTRA_APT_PACKAGES: 'llvm-14' - BUILD_TYPE: Debug PYTHON_VERSION: '3.7' @@ -143,6 +145,7 @@ jobs: run: | source bin/test_symengine_unix.sh env: + PYTEST_ADDOPTS: ${{ matrix.PYTEST_ADDOPTS }} USE_GLIBCXX_DEBUG: ${{ matrix.USE_GLIBCXX_DEBUG }} WITH_MPFR: ${{ matrix.WITH_MPFR }} BUILD_BENCHMARKS: ${{ matrix.BUILD_BENCHMARKS }} diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 9b7da674d..674ff56f9 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -350,12 +350,12 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass NumberWrapper(Basic): pass - cdef int is_zero(const Basic &x) nogil - cdef int is_positive(const Basic &x) nogil - cdef int is_negative(const Basic &x) nogil - cdef int is_nonnegative(const Basic &x) nogil - cdef int is_nonpositive(const Basic &x) nogil - cdef int is_real(const Basic &x) nogil + cdef tribool is_zero(const Basic &x) nogil + cdef tribool is_positive(const Basic &x) nogil + cdef tribool is_negative(const Basic &x) nogil + cdef tribool is_nonnegative(const Basic &x) nogil + cdef tribool is_nonpositive(const Basic &x) nogil + cdef tribool is_real(const Basic &x) nogil cdef extern from "pywrapper.h" namespace "SymEngine": cdef cppclass PyNumber(NumberWrapper): @@ -829,15 +829,15 @@ cdef extern from "" namespace "SymEngine": void row_del(unsigned k) nogil void col_del(unsigned k) nogil rcp_const_basic trace() nogil - int is_zero() nogil - int is_real() nogil - int is_diagonal() nogil - int is_symmetric() nogil - int is_hermitian() nogil - int is_weakly_diagonally_dominant() nogil - int is_strictly_diagonally_dominant() nogil - int is_positive_definite() nogil - int is_negative_definite() nogil + tribool is_zero() nogil + tribool is_real() nogil + tribool is_diagonal() nogil + tribool is_symmetric() nogil + tribool is_hermitian() nogil + tribool is_weakly_diagonally_dominant() nogil + tribool is_strictly_diagonally_dominant() nogil + tribool is_positive_definite() nogil + tribool is_negative_definite() nogil bool is_a_DenseMatrix "SymEngine::is_a"(const MatrixBase &b) nogil DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) @@ -1104,6 +1104,19 @@ cdef extern from "" namespace "SymEngine": cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym, RCP[const Set] &domain) nogil except + cdef vec_basic linsolve(const vec_basic &eqs, const vec_sym &syms) nogil except + +cdef extern from "symengine/tribool.h" namespace "SymEngine": + cdef cppclass tribool: + pass # tribool is an enum class + + cdef bool is_true(tribool) nogil + cdef bool is_false(tribool) nogil + cdef bool is_indeterminate(tribool) nogil + +cdef extern from "symengine/tribool.h" namespace "SymEngine::tribool": + cdef tribool indeterminate + cdef tribool trifalse + cdef tribool tritrue + cdef extern from "" namespace "SymEngine": string ccode(const Basic &x) nogil except + string latex(const Basic &x) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index a77f5bb4a..7cbf148cf 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3,7 +3,7 @@ cimport symengine from symengine cimport (RCP, pair, map_basic_basic, umap_int_basic, umap_int_basic_iterator, umap_basic_num, umap_basic_num_iterator, rcp_const_basic, std_pair_short_rcp_const_basic, - rcp_const_seriescoeffinterface, CRCPBasic) + rcp_const_seriescoeffinterface, CRCPBasic, tribool, is_indeterminate, is_true, is_false) from libcpp cimport bool as cppbool from libcpp.string cimport string from libcpp.vector cimport vector @@ -3696,39 +3696,39 @@ cdef class DenseMatrixBase(MatrixBase): @property def is_zero_matrix(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_zero()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_zero()) @property def is_real_matrix(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_real()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_real()) @property def is_diagonal(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_diagonal()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_diagonal()) @property def is_symmetric(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_symmetric()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_symmetric()) @property def is_hermitian(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_hermitian()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_hermitian()) @property def is_weakly_diagonally_dominant(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_weakly_diagonally_dominant()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_weakly_diagonally_dominant()) @property def is_strongly_diagonally_dominant(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_strictly_diagonally_dominant()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_strictly_diagonally_dominant()) @property def is_positive_definite(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_positive_definite()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_positive_definite()) @property def is_negative_definite(self): - return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_negative_definite()) + return tribool_py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_negative_definite()) @property def T(self): @@ -5347,47 +5347,51 @@ def contains(expr, sset): return c2py((symengine.contains(expr_.thisptr, s))) -def tribool(value): - if value == -1: +cdef tribool_py(tribool value): + if is_indeterminate(value): return None + elif is_true(value): + return True + elif is_false(value): + return False else: - return bool(value) + raise RuntimeError("Internal error in symengine.py, tribool got a fourth value.") def is_zero(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_zero(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_zero(deref(expr_.thisptr)) + return tribool_py(tbool) def is_positive(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_positive(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_positive(deref(expr_.thisptr)) + return tribool_py(tbool) def is_negative(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_negative(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_negative(deref(expr_.thisptr)) + return tribool_py(tbool) def is_nonpositive(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_nonpositive(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_nonpositive(deref(expr_.thisptr)) + return tribool_py(tbool) def is_nonnegative(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_nonnegative(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_nonnegative(deref(expr_.thisptr)) + return tribool_py(tbool) def is_real(expr): cdef Basic expr_ = sympify(expr) - cdef int tbool = symengine.is_real(deref(expr_.thisptr)) - return tribool(tbool) + cdef tribool tbool = symengine.is_real(deref(expr_.thisptr)) + return tribool_py(tbool) def set_union(*args): diff --git a/symengine_version.txt b/symengine_version.txt index 08007dd19..9628dc6a4 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -5a9d4fa8c769b2dc8d7904ec16d7ea76328c4565 +fcef5c7d6cc848e3f6c0b9ecc5a22d30e5e98f99 From 4cfa839ae57af1d83aa8f4bbddf3a38daf0aaa11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Sun, 12 Feb 2023 10:01:08 +0100 Subject: [PATCH 197/314] Change lambdify's default for backend to llvm when available --- symengine/lib/symengine_wrapper.pyx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 7cbf148cf..558b64fdb 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5203,7 +5203,7 @@ def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', Whether datatype is ``double`` (``double complex`` otherwise). backend : str 'llvm' or 'lambda'. When ``None`` the environment variable - 'SYMENGINE_LAMBDIFY_BACKEND' is used (taken as 'lambda' if unset). + 'SYMENGINE_LAMBDIFY_BACKEND' is used (taken as 'llvm' if available, otherwise 'lambda'). order : 'C' or 'F' C- or Fortran-contiguous memory layout. Note that this affects broadcasting: e.g. a (m, n) matrix taking 3 arguments and given a @@ -5235,7 +5235,11 @@ def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', """ if backend is None: - backend = os.getenv('SYMENGINE_LAMBDIFY_BACKEND', "lambda") + IF HAVE_SYMENGINE_LLVM: + backend_default = 'llvm' + ELSE: + backend_default = 'lambda' + backend = os.getenv('SYMENGINE_LAMBDIFY_BACKEND', backend_default) if backend == "llvm": IF HAVE_SYMENGINE_LLVM: if dtype == None: From 7cccac0816695291bb0182aea99e488025a5c4b8 Mon Sep 17 00:00:00 2001 From: Bjorn Date: Tue, 14 Feb 2023 19:18:50 +0100 Subject: [PATCH 198/314] Update symengine/lib/symengine_wrapper.pyx Co-authored-by: Isuru Fernando --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 558b64fdb..3184c7d5a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5235,7 +5235,7 @@ def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', """ if backend is None: - IF HAVE_SYMENGINE_LLVM: + IF HAVE_SYMENGINE_LLVM and real: backend_default = 'llvm' ELSE: backend_default = 'lambda' From 721312ee9e41691c32cfbda97c5673fb4f983b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 14 Feb 2023 19:58:30 +0100 Subject: [PATCH 199/314] avoid using Cython compile-time 'IF' --- symengine/lib/symengine_wrapper.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 3184c7d5a..4c5f0f82f 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -5235,8 +5235,8 @@ def Lambdify(args, *exprs, cppbool real=True, backend=None, order='C', """ if backend is None: - IF HAVE_SYMENGINE_LLVM and real: - backend_default = 'llvm' + IF HAVE_SYMENGINE_LLVM: + backend_default = 'llvm' if real else 'lambda' ELSE: backend_default = 'lambda' backend = os.getenv('SYMENGINE_LAMBDIFY_BACKEND', backend_default) From 0b0acb6a0094b59282047fa176acec597bb81f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 14 Feb 2023 21:02:49 +0100 Subject: [PATCH 200/314] Add a lambdify func. that throws ModuleNotFoundError when numpy missing --- symengine/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index f05422c62..bc6a1b214 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -55,7 +55,9 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) - +else: + def lambdify(args, exprs, **kwargs): + raise ModuleNotFoundError("Cannot import numpy, which is required for `lambdify` to work") __version__ = "0.9.2" From d3e590bacb3a6723c3455d3c662445802be7877d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 14 Feb 2023 21:21:11 +0100 Subject: [PATCH 201/314] prefer __getattr__ --- symengine/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index bc6a1b214..656d80f2d 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -56,8 +56,10 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) else: - def lambdify(args, exprs, **kwargs): - raise ModuleNotFoundError("Cannot import numpy, which is required for `lambdify` to work") + def __getattr__(name): + if name == 'lambdify': + raise AttributeError("Cannot import numpy, which is required for `lambdify` to work") + raise AttributeError __version__ = "0.9.2" From 10241a4657354b14e7d526a5e3c9dd67596ac4ab Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 13:49:50 -0500 Subject: [PATCH 202/314] Fix converting atan2 to sympy --- symengine/lib/symengine_wrapper.pyx | 8 ++++++++ symengine/tests/test_sympy_conv.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 7cbf148cf..52c65d6c3 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -2635,6 +2635,14 @@ class atan2(Function): cdef Basic Y = sympify(y) return c2py(symengine.atan2(X.thisptr, Y.thisptr)) + def _sympy_(self): + import sympy + return sympy.atan2(*self.args_as_sympy()) + + def _sage_(self): + import sage.all as sage + return sage.atan2(*self.args_as_sage()) + # For backwards compatibility Sin = sin diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 7692ad716..e9fbe0bd7 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -171,6 +171,7 @@ def test_conv7(): assert acot(x/3) == acot(sympy.Symbol("x") / 3) assert acsc(x/3) == acsc(sympy.Symbol("x") / 3) assert asec(x/3) == asec(sympy.Symbol("x") / 3) + assert atan2(x/3, y) == atan2(sympy.Symbol("x") / 3, sympy.Symbol("y")) assert sin(x/3)._sympy_() == sympy.sin(sympy.Symbol("x") / 3) assert sin(x/3)._sympy_() != sympy.cos(sympy.Symbol("x") / 3) @@ -185,6 +186,22 @@ def test_conv7(): assert acot(x/3)._sympy_() == sympy.acot(sympy.Symbol("x") / 3) assert acsc(x/3)._sympy_() == sympy.acsc(sympy.Symbol("x") / 3) assert asec(x/3)._sympy_() == sympy.asec(sympy.Symbol("x") / 3) + assert atan2(x/3, y)._sympy_() == sympy.atan2(sympy.Symbol("x") / 3, sympy.Symbol("y")) + + assert sympy.sympify(sin(x/3)) == sympy.sin(sympy.Symbol("x") / 3) + assert sympy.sympify(sin(x/3)) != sympy.cos(sympy.Symbol("x") / 3) + assert sympy.sympify(cos(x/3)) == sympy.cos(sympy.Symbol("x") / 3) + assert sympy.sympify(tan(x/3)) == sympy.tan(sympy.Symbol("x") / 3) + assert sympy.sympify(cot(x/3)) == sympy.cot(sympy.Symbol("x") / 3) + assert sympy.sympify(csc(x/3)) == sympy.csc(sympy.Symbol("x") / 3) + assert sympy.sympify(sec(x/3)) == sympy.sec(sympy.Symbol("x") / 3) + assert sympy.sympify(asin(x/3)) == sympy.asin(sympy.Symbol("x") / 3) + assert sympy.sympify(acos(x/3)) == sympy.acos(sympy.Symbol("x") / 3) + assert sympy.sympify(atan(x/3)) == sympy.atan(sympy.Symbol("x") / 3) + assert sympy.sympify(acot(x/3)) == sympy.acot(sympy.Symbol("x") / 3) + assert sympy.sympify(acsc(x/3)) == sympy.acsc(sympy.Symbol("x") / 3) + assert sympy.sympify(asec(x/3)) == sympy.asec(sympy.Symbol("x") / 3) + assert sympy.sympify(atan2(x/3, y)) == sympy.atan2(sympy.Symbol("x") / 3, sympy.Symbol("y")) @unittest.skipIf(not have_sympy, "SymPy not installed") @@ -204,6 +221,7 @@ def test_conv7b(): assert sympify(sympy.acot(x/3)) == acot(Symbol("x") / 3) assert sympify(sympy.acsc(x/3)) == acsc(Symbol("x") / 3) assert sympify(sympy.asec(x/3)) == asec(Symbol("x") / 3) + assert sympify(sympy.atan2(x/3, y)) == atan2(Symbol("x") / 3, Symbol("y")) @unittest.skipIf(not have_sympy, "SymPy not installed") From f0047f3764d3b8bca8a2ae82b9db8c63d0f961cd Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:11:01 -0500 Subject: [PATCH 203/314] check latest symengine master --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 9628dc6a4..59d512b60 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -fcef5c7d6cc848e3f6c0b9ecc5a22d30e5e98f99 +4f9fad1bfc068f072e238f5e195371ca4946aa9a From 2cb84e59227734eb6bca86e1f4890e92a90b5f69 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:11:45 -0500 Subject: [PATCH 204/314] bump version to 0.10.0 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index bbaf54cb4..6242769df 100644 --- a/setup.py +++ b/setup.py @@ -218,7 +218,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.9.2", + version="0.10.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index f05422c62..a58817148 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -57,7 +57,7 @@ def lambdify(args, exprs, **kwargs): return Lambdify(args, *exprs, **kwargs) -__version__ = "0.9.2" +__version__ = "0.10.0" # To not expose internals From c0c6ca0498736c6921980fee1bb4ea4ca3f1d385 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:12:57 -0500 Subject: [PATCH 205/314] Add Christian to AUTHORS. Welcome to SymEngine!! --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 651e06ec7..b0719fd56 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,3 +34,4 @@ Michał Górny Garming Sam Pieter Eendebak Ayush Kumar +Christian Clauss From eb78901bfbb6b37c15e03d73fb2420a47aa44909 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:21:00 -0500 Subject: [PATCH 206/314] import atan2 --- symengine/tests/test_sympy_conv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index e9fbe0bd7..5d173dc4f 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -2,7 +2,7 @@ function_symbol, I, E, pi, oo, zoo, nan, true, false, exp, gamma, have_mpfr, have_mpc, DenseMatrix, sin, cos, tan, cot, csc, sec, asin, acos, atan, acot, acsc, asec, sinh, cosh, tanh, coth, - asinh, acosh, atanh, acoth, Add, Mul, Pow, diff, GoldenRatio, + asinh, acosh, atanh, acoth, atan2, Add, Mul, Pow, diff, GoldenRatio, Catalan, EulerGamma, UnevaluatedExpr, RealDouble) from symengine.lib.symengine_wrapper import (Subs, Derivative, RealMPFR, ComplexMPC, PyNumber, Function, LambertW, zeta, dirichlet_eta, From fcd7cd5a2a607ec6e2dc906014786ce4c6c4f3a0 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:09:40 -0500 Subject: [PATCH 207/314] Update error message --- symengine/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/__init__.py b/symengine/__init__.py index 656d80f2d..c65d41437 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -59,7 +59,7 @@ def lambdify(args, exprs, **kwargs): def __getattr__(name): if name == 'lambdify': raise AttributeError("Cannot import numpy, which is required for `lambdify` to work") - raise AttributeError + raise AttributeError(f"module 'symengine' has no attribute '{name}'") __version__ = "0.9.2" From eba314ac0e29de79554ac5f3717730169dbbb5bc Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:30:02 -0500 Subject: [PATCH 208/314] Use setuptools.command.build if available --- setup.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6242769df..88f2d1c7b 100644 --- a/setup.py +++ b/setup.py @@ -22,8 +22,6 @@ print("Value {} for USE_DISTUTILS treated as False". format(use_distutils)) -from distutils.command.build import build as _build - if use_setuptools: try: from setuptools import setup @@ -31,11 +29,17 @@ from setuptools.command.build_ext import build_ext as _build_ext except ImportError: use_setuptools = False + else: + try: + from setuptools.command.build import build as _build + except ImportError: + from distutils.command.build import build as _build if not use_setuptools: from distutils.core import setup from distutils.command.install import install as _install from distutils.command.build_ext import build_ext as _build_ext + from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] From 5d89eb80f994f02ce7b826ccb223df83a274810b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:32:48 -0500 Subject: [PATCH 209/314] use symengine v0.10.0 --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 59d512b60..bf057dbfd 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -4f9fad1bfc068f072e238f5e195371ca4946aa9a +v0.10.0 From 9550a2bbffc60bd30b59988c9888b33f1a857ced Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sat, 26 Feb 2022 18:46:16 +0100 Subject: [PATCH 210/314] Better compatibility with sympy ImmutableMatrix (fixes #363) simplify Immutable to new Immutable sympy.sympify matrices to Immutable --- symengine/lib/symengine_wrapper.pyx | 14 ++++++++++++-- symengine/tests/test_matrices.py | 5 +++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 4c5f0f82f..5e93dc9ac 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3895,7 +3895,7 @@ cdef class DenseMatrixBase(MatrixBase): l.append(c2py(A.get(i, j))._sympy_()) s.append(l) import sympy - return sympy.Matrix(s) + return sympy.ImmutableMatrix(s) def _sage_(self): s = [] @@ -3906,7 +3906,7 @@ cdef class DenseMatrixBase(MatrixBase): l.append(c2py(A.get(i, j))._sage_()) s.append(l) import sage.all as sage - return sage.Matrix(s) + return sage.ImmutableMatrix(s) def dump_real(self, double[::1] out): cdef size_t ri, ci, nr, nc @@ -4046,6 +4046,16 @@ cdef class ImmutableDenseMatrix(DenseMatrixBase): def __setitem__(self, key, value): raise TypeError("Cannot set values of {}".format(self.__class__)) + def _applyfunc(self, f): + cdef int nr = self.nrows() + cdef int nc = self.ncols() + temp = DenseMatrix(self) + for i in range(nr): + for j in range(nc): + temp._set(i, j, f(temp._get(i, j))) + return ImmutableDenseMatrix(temp) + + ImmutableMatrix = ImmutableDenseMatrix diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 55ebd0464..e90e0d02d 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -741,3 +741,8 @@ def test_repr_latex(): latex_string = testmat._repr_latex_() assert isinstance(latex_string, str) init_printing(False) + + +def test_simplify(): + A = ImmutableMatrix([1]) + assert type(A.simplify()) == type(A) From f1ec18a43ece598373f6b3b93b7c54778604c311 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sat, 26 Feb 2022 19:54:03 +0100 Subject: [PATCH 211/314] Update symengine/lib/symengine_wrapper.pyx Co-authored-by: Isuru Fernando --- symengine/lib/symengine_wrapper.pyx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 5e93dc9ac..35265144a 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4047,13 +4047,9 @@ cdef class ImmutableDenseMatrix(DenseMatrixBase): raise TypeError("Cannot set values of {}".format(self.__class__)) def _applyfunc(self, f): - cdef int nr = self.nrows() - cdef int nc = self.ncols() - temp = DenseMatrix(self) - for i in range(nr): - for j in range(nc): - temp._set(i, j, f(temp._get(i, j))) - return ImmutableDenseMatrix(temp) + res = DenseMatrix(self) + res._applyfunc(f) + return ImmutableDenseMatrix(res) ImmutableMatrix = ImmutableDenseMatrix From e9e06d8f31a74fb46a81b654fbc2acb1d4af4d25 Mon Sep 17 00:00:00 2001 From: Rikard Nordgren Date: Sun, 27 Feb 2022 07:51:40 +0100 Subject: [PATCH 212/314] Update symengine/lib/symengine_wrapper.pyx Co-authored-by: Isuru Fernando --- symengine/lib/symengine_wrapper.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 35265144a..b38eb0809 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -3906,7 +3906,7 @@ cdef class DenseMatrixBase(MatrixBase): l.append(c2py(A.get(i, j))._sage_()) s.append(l) import sage.all as sage - return sage.ImmutableMatrix(s) + return sage.Matrix(s, immutable=True) def dump_real(self, double[::1] out): cdef size_t ri, ci, nr, nc From 967d49e1766cd69b075501247ad496294ab16882 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:35:43 -0500 Subject: [PATCH 213/314] Skip test if sympy not found --- symengine/tests/test_matrices.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index e90e0d02d..42cfa07d3 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -10,6 +10,15 @@ HAVE_NUMPY = True except ImportError: HAVE_NUMPY = False + +try: + import sympy + from sympy.core.cache import clear_cache + import atexit + atexit.register(clear_cache) + have_sympy = True +except ImportError: + have_sympy = False def test_init(): @@ -742,7 +751,7 @@ def test_repr_latex(): assert isinstance(latex_string, str) init_printing(False) - +@unittest.skipIf(not have_sympy, "SymPy not installed") def test_simplify(): A = ImmutableMatrix([1]) assert type(A.simplify()) == type(A) From b586d4114f3210052b0b55d276570361da2c3faa Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 17:31:28 -0500 Subject: [PATCH 214/314] Import and use unittest --- symengine/tests/test_matrices.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index 42cfa07d3..de9975299 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -3,13 +3,14 @@ Rational, function_symbol, I, NonSquareMatrixError, ShapeError, zeros, ones, eye, ImmutableMatrix) from symengine.test_utilities import raises +import unittest try: import numpy as np - HAVE_NUMPY = True + have_numpy = True except ImportError: - HAVE_NUMPY = False + have_numpy = False try: import sympy @@ -529,10 +530,8 @@ def test_reshape(): assert C != A -# @pytest.mark.skipif(not HAVE_NUMPY, reason='requires numpy') +@unittest.skipIf(not have_numpy, 'requires numpy') def test_dump_real(): - if not HAVE_NUMPY: # nosetests work-around - return ref = [1, 2, 3, 4] A = DenseMatrix(2, 2, ref) out = np.empty(4) @@ -540,10 +539,9 @@ def test_dump_real(): assert np.allclose(out, ref) -# @pytest.mark.skipif(not HAVE_NUMPY, reason='requires numpy') + +@unittest.skipIf(not have_numpy, 'requires numpy') def test_dump_complex(): - if not HAVE_NUMPY: # nosetests work-around - return ref = [1j, 2j, 3j, 4j] A = DenseMatrix(2, 2, ref) out = np.empty(4, dtype=np.complex128) From 03bc25378d27c8163bcb9b69abd9aef92646462a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:11:01 -0500 Subject: [PATCH 215/314] check latest symengine master --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 9628dc6a4..59d512b60 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -fcef5c7d6cc848e3f6c0b9ecc5a22d30e5e98f99 +4f9fad1bfc068f072e238f5e195371ca4946aa9a From 33b49706f505cfc1b623db2a009f754d2e1c6514 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:11:45 -0500 Subject: [PATCH 216/314] bump version to 0.10.0 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index bbaf54cb4..6242769df 100644 --- a/setup.py +++ b/setup.py @@ -218,7 +218,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.9.2", + version="0.10.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index c65d41437..57b658017 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -61,7 +61,7 @@ def __getattr__(name): raise AttributeError("Cannot import numpy, which is required for `lambdify` to work") raise AttributeError(f"module 'symengine' has no attribute '{name}'") -__version__ = "0.9.2" +__version__ = "0.10.0" # To not expose internals From 9ea5b7b48bbf0ce10ff4a9d6f1101b75f7264f46 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 14:12:57 -0500 Subject: [PATCH 217/314] Add Christian to AUTHORS. Welcome to SymEngine!! --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 651e06ec7..b0719fd56 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,3 +34,4 @@ Michał Górny Garming Sam Pieter Eendebak Ayush Kumar +Christian Clauss From 64b134e216f3d780b163b3ac7e086ce851be07a5 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:30:02 -0500 Subject: [PATCH 218/314] Use setuptools.command.build if available --- setup.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6242769df..88f2d1c7b 100644 --- a/setup.py +++ b/setup.py @@ -22,8 +22,6 @@ print("Value {} for USE_DISTUTILS treated as False". format(use_distutils)) -from distutils.command.build import build as _build - if use_setuptools: try: from setuptools import setup @@ -31,11 +29,17 @@ from setuptools.command.build_ext import build_ext as _build_ext except ImportError: use_setuptools = False + else: + try: + from setuptools.command.build import build as _build + except ImportError: + from distutils.command.build import build as _build if not use_setuptools: from distutils.core import setup from distutils.command.install import install as _install from distutils.command.build_ext import build_ext as _build_ext + from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] From 0680b4296c9a68537d9f6f4fd87f7dbb67f01d49 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 20 Mar 2023 16:32:48 -0500 Subject: [PATCH 219/314] use symengine v0.10.0 --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 59d512b60..bf057dbfd 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -4f9fad1bfc068f072e238f5e195371ca4946aa9a +v0.10.0 From ce8743c9122c20b466f71b53f427f0d8a9c86cc3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 21 Mar 2023 10:34:03 -0500 Subject: [PATCH 220/314] Fix building with LLVM 16 --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 920b504ea..0cf3c25c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,15 @@ cmake_minimum_required(VERSION 2.8.12) + +if (POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) # needed for llvm >= 16 +endif () + project(python_wrapper) set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH}) + +include(GNUInstallDirs) + find_package(SymEngine 0.8.1 REQUIRED CONFIG PATH_SUFFIXES lib/cmake/symengine cmake/symengine CMake/) message("SymEngine_DIR : " ${SymEngine_DIR}) From fc6cf308cd2bb73e8f3cb7e95ed113963e423937 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 23 Mar 2023 14:08:06 -0500 Subject: [PATCH 221/314] bump c++ version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index bf057dbfd..c91125db5 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.10.0 +v0.10.1 From 4e31fac07e018b28f528aa79f984fa24561aded2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 23 Mar 2023 14:12:03 -0500 Subject: [PATCH 222/314] update README with new LLVM dependencies --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66b24f013..f6fc3742f 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ symengine.py is MIT licensed and uses several LGPL, BSD-3 and MIT licensed libra Licenses for the dependencies of pip wheels are as follows, pip wheels on Unix use GMP (LGPL-3.0-or-later), MPFR (LGPL-3.0-or-later), -MPC (LGPL-3.0-or-later), LLVM (Apache-2.0), zlib (Zlib) and symengine (MIT AND BSD-3-Clause). +MPC (LGPL-3.0-or-later), LLVM (Apache-2.0), zlib (Zlib), libxml2 (MIT), +zstd (BSD-3-Clause) and symengine (MIT AND BSD-3-Clause). pip wheels on Windows use MPIR (LGPL-3.0-or-later) instead of GMP above and pthreads-win32 (LGPL-3.0-or-later) additionally. NumPy (BSD-3-Clause) and SymPy (BSD-3-Clause) are optional dependencies. From e385e2fc12944733f7b3429f79e1de9edb57c823 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 4 May 2023 13:10:58 -0500 Subject: [PATCH 223/314] Add as_powers_dict --- symengine/lib/symengine_wrapper.pyx | 37 +++++++++++++++++++++++++++++ symengine/tests/test_expr.py | 15 +++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 24b52c0e7..f3cd0417c 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -1169,6 +1169,11 @@ cdef class Basic(object): raise TypeError("Can't convert expression to float") return complex(f) + def as_powers_dict(self): + d = collections.defaultdict(int) + d[self] = 1 + return d + def series(ex, x=None, x0=0, n=6, as_deg_coef_pair=False): # TODO: check for x0 an infinity, see sympy/core/expr.py @@ -1345,6 +1350,11 @@ cdef class ImaginaryUnit(Complex): def __cinit__(Basic self): self.thisptr = symengine.I + def as_powers_dict(self): + d = collections.defaultdict(int) + d[minus_one] = half + return d + I = ImaginaryUnit() @@ -2078,6 +2088,13 @@ cdef class NegativeInfinity(Number): import sage.all as sage return -sage.oo + def as_powers_dict(self): + d = collections.defaultdict(int) + d[minus_one] = 1 + d[oo] = 1 + return d + + minus_oo = NegativeInfinity() @@ -2276,6 +2293,21 @@ class Mul(AssocOp): c2py(deref(X).get_coef()) return d + def as_powers_dict(Basic self): + cdef RCP[const symengine.Mul] X = symengine.rcp_static_cast_Mul(self.thisptr) + cdef rcp_const_basic coef = (deref(X).get_coef()) + cdef map_basic_basic m = deref(X).get_dict() + d = c2py(coef).as_powers_dict() + + it = m.begin() + it_end = m.end() + while it != it_end: + d[c2py((deref(it).first))] =\ + c2py((deref(it).second)) + inc(it) + + return d + class Pow(Expr): @@ -2319,6 +2351,11 @@ class Pow(Expr): def func(self): return self.__class__ + def as_powers_dict(self): + d = collections.defaultdict(int) + d[self.base] = self.exp + return d + class Function(Expr): diff --git a/symengine/tests/test_expr.py b/symengine/tests/test_expr.py index f69099a56..e75e3d4cf 100644 --- a/symengine/tests/test_expr.py +++ b/symengine/tests/test_expr.py @@ -1,4 +1,4 @@ -from symengine import Symbol, Integer +from symengine import Symbol, Integer, oo from symengine.test_utilities import raises @@ -12,3 +12,16 @@ def test_as_coefficients_dict(): [0, 0, 3, 0] assert (3.0*x*y).as_coefficients_dict()[3.0*x*y] == 0 assert (3.0*x*y).as_coefficients_dict()[x*y] == 3.0 + + +def test_as_powers_dict(): + x = Symbol('x') + y = Symbol('y') + + assert (2*x**y).as_coefficients_dict() == {2: 1, x: y} + assert (2*x**2*y**3).as_coefficients_dict() == {2: 1, x: 2, y: 3} + assert (-oo).as_coefficients_dict() == {-1: 1, oo: 1} + assert (x**y).as_coefficients_dict() == {x: y} + assert ((1/Integer(2))**y).as_coefficients_dict() == {2: -y} + assert (2**y).as_coefficients_dict() == {2: y} + assert (2**-y).as_coefficients_dict() == {2: -y} From dc8fd64296da7924646a4cec46946c630fb947ab Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 4 May 2023 17:55:22 -0500 Subject: [PATCH 224/314] Fix rational and mul --- symengine/lib/symengine_wrapper.pyx | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index f3cd0417c..1210a171d 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -2295,15 +2295,22 @@ class Mul(AssocOp): def as_powers_dict(Basic self): cdef RCP[const symengine.Mul] X = symengine.rcp_static_cast_Mul(self.thisptr) - cdef rcp_const_basic coef = (deref(X).get_coef()) cdef map_basic_basic m = deref(X).get_dict() - d = c2py(coef).as_powers_dict() + coef = c2py((deref(X).get_coef())) + if coef == 1: + d = collections.defaultdict(int) + else: + d = coef.as_powers_dict() it = m.begin() it_end = m.end() while it != it_end: - d[c2py((deref(it).first))] =\ - c2py((deref(it).second)) + base = c2py((deref(it).first)) + exp = c2py((deref(it).second)) + if base.is_Rational and base.p < base.q and base.p > 0: + d[1/base] -= exp + else: + d[base] += exp inc(it) return d @@ -2351,9 +2358,13 @@ class Pow(Expr): def func(self): return self.__class__ - def as_powers_dict(self): + def as_powers_dict(Basic self): d = collections.defaultdict(int) - d[self.base] = self.exp + base, exp = self.as_base_exp() + if base.is_Rational and base.p < base.q and base.p > 0: + d[1/base] = -exp + else: + d[base] = exp return d From 0c1111c720829afea5d03b9b3f1ff7aec374d0f2 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 4 May 2023 18:07:24 -0500 Subject: [PATCH 225/314] Fix tests --- symengine/tests/test_expr.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/symengine/tests/test_expr.py b/symengine/tests/test_expr.py index e75e3d4cf..8cbf4ab7b 100644 --- a/symengine/tests/test_expr.py +++ b/symengine/tests/test_expr.py @@ -18,10 +18,11 @@ def test_as_powers_dict(): x = Symbol('x') y = Symbol('y') - assert (2*x**y).as_coefficients_dict() == {2: 1, x: y} - assert (2*x**2*y**3).as_coefficients_dict() == {2: 1, x: 2, y: 3} - assert (-oo).as_coefficients_dict() == {-1: 1, oo: 1} - assert (x**y).as_coefficients_dict() == {x: y} - assert ((1/Integer(2))**y).as_coefficients_dict() == {2: -y} - assert (2**y).as_coefficients_dict() == {2: y} - assert (2**-y).as_coefficients_dict() == {2: -y} + assert (2*x**y).as_powers_dict() == {2: 1, x: y} + assert (2*x**2*y**3).as_powers_dict() == {2: 1, x: 2, y: 3} + assert (-oo).as_powers_dict() == {Integer(-1): 1, oo: 1} + assert (x**y).as_powers_dict() == {x: y} + assert ((1/Integer(2))**y).as_powers_dict() == {Integer(2): -y} + assert (x*(1/Integer(2))**y).as_powers_dict() == {x: Integer(1), Integer(2): -y} + assert (2**y).as_powers_dict() == {2: y} + assert (2**-y).as_powers_dict() == {2: -y} From 625004b50186945fa01b9a0c87b58281ac645a11 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 11 May 2023 14:39:27 -0500 Subject: [PATCH 226/314] Define __floor__, __mod__, __divmod__ for basic --- symengine/lib/symengine_wrapper.pyx | 19 ++++++++++--------- symengine/tests/test_arit.py | 13 ++++++++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 1210a171d..b6a34e600 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -890,6 +890,16 @@ cdef class Basic(object): if A is None or B is None: return NotImplemented return c2py(symengine.div(A.thisptr, B.thisptr)) + def __floordiv__(x, y): + return floor(x/y) + + def __mod__(x, y): + return x - y * floor(x/y) + + def __divmod__(x, y): + f = floor(x/y) + return f, x - y * f + def __pow__(a, b, c): if c is not None: return powermod(a, b, c) @@ -1830,15 +1840,6 @@ class Integer(Rational): else: return NotImplemented - def __floordiv__(x, y): - return quotient(x, y) - - def __mod__(x, y): - return mod(x, y) - - def __divmod__(x, y): - return quotient_mod(x, y) - def _sympy_(Basic self): import sympy return sympy.Integer(int(self)) diff --git a/symengine/tests/test_arit.py b/symengine/tests/test_arit.py index b81165145..e6ff192b7 100644 --- a/symengine/tests/test_arit.py +++ b/symengine/tests/test_arit.py @@ -1,7 +1,7 @@ from symengine.test_utilities import raises from symengine import (Symbol, Integer, Add, Mul, Pow, Rational, sqrt, - symbols, S, I, count_ops) + symbols, S, I, count_ops, floor) def test_arit1(): @@ -165,12 +165,23 @@ def test_as_numer_denom(): assert x == Integer(-5) assert y == Integer(1) + +def test_floor(): + exprs = [Symbol("x"), Symbol("y"), Integer(2), Rational(-3, 5), Integer(-3)] + + for x in exprs: + for y in exprs: + assert x // y == floor(x / y) + assert x == y * (x // y) + x % y + + def test_as_real_imag(): x, y = (5 + 6 * I).as_real_imag() assert x == 5 assert y == 6 + def test_from_args(): x = Symbol("x") y = Symbol("y") From 4fba9a6db38a268666903c724a5a15e7d7cb2264 Mon Sep 17 00:00:00 2001 From: Bjorn Date: Sat, 24 Jun 2023 12:14:28 +0200 Subject: [PATCH 227/314] Tentative fix of .has for FunctionSymbol (#446) * Tentative fix of .has for FunctionSymbol * SymEngine supports FunctionSymbol in has_symbol --- CMakeLists.txt | 3 +++ symengine/__init__.py | 3 ++- symengine/lib/symengine.pxd | 2 +- symengine/lib/symengine_wrapper.pyx | 5 ++--- symengine/tests/test_functions.py | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf3c25c1..418b6704c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ cmake_minimum_required(VERSION 2.8.12) if (POLICY CMP0057) cmake_policy(SET CMP0057 NEW) # needed for llvm >= 16 endif () +if (POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) # allow user to set *_ROOT variables +endif() project(python_wrapper) diff --git a/symengine/__init__.py b/symengine/__init__.py index 19c0d69be..fa72ded4f 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -26,7 +26,7 @@ Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot, isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet, linsolve, - FunctionSymbol as AppliedUndef, + FunctionSymbol, golden_ratio as GoldenRatio, catalan as Catalan, eulergamma as EulerGamma, @@ -37,6 +37,7 @@ from .printing import init_printing +AppliedUndef = FunctionSymbol # an alias EmptySet = wrapper.S.EmptySet UniversalSet = wrapper.S.UniversalSet Reals = wrapper.S.Reals diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 449ffc01b..ff5cd7728 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -930,7 +930,7 @@ cdef extern from "" namespace "SymEngine": unsigned next_prime() nogil cdef extern from "" namespace "SymEngine": - bool has_symbol(const Basic &b, const Symbol &x) nogil except + + bool has_symbol(const Basic &b, const Basic &x) nogil except + rcp_const_basic coeff(const Basic &b, const Basic &x, const Basic &n) nogil except + set_basic free_symbols(const Basic &b) nogil except + set_basic free_symbols(const MatrixBase &b) nogil except + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index b6a34e600..de90b2cb8 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -4846,12 +4846,11 @@ def powermod_list(a, b, m): def has_symbol(obj, symbol=None): cdef Basic b = _sympify(obj) cdef Basic s = _sympify(symbol) - require(s, Symbol) + require(s, (Symbol, FunctionSymbol)) if (not symbol): return not b.free_symbols.empty() else: - return symengine.has_symbol(deref(b.thisptr), - deref(symengine.rcp_static_cast_Symbol(s.thisptr))) + return symengine.has_symbol(deref(b.thisptr), deref(s.thisptr)) cdef class _Lambdify(object): diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 267506daa..3a19b122c 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -85,6 +85,7 @@ def test_derivative(): assert s.variables == (x,) fxy = Function("f")(x, y) + assert (1+fxy).has(fxy) g = Derivative(Function("f")(x, y), x, 2, y, 1) assert g == fxy.diff(x, x, y) assert g == fxy.diff(y, 1, x, 2) From 4f168559c28852f7d0eaa6f664d270e91fcb0800 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 09:44:54 -0500 Subject: [PATCH 228/314] cython 3 compatibility --- symengine/lib/symengine.pxd | 407 +++++++++++++++--------------------- 1 file changed, 163 insertions(+), 244 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index ff5cd7728..b70b7a0d6 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -4,6 +4,8 @@ from libcpp.map cimport map from libcpp.vector cimport vector from cpython.ref cimport PyObject from libcpp.pair cimport pair +from libcpp.set cimport multiset, set +from libcpp.unordered_map cimport unordered_map include "config.pxi" @@ -31,94 +33,6 @@ cdef extern from 'symengine/mp_class.h' namespace "SymEngine": rational_class(mpq_t) const mpq_t get_mpq_t(const rational_class &a) -cdef extern from "" namespace "std": -# Cython's libcpp.set does not support two template arguments to set. -# Methods to declare and iterate a set with a custom compare are given here - cdef cppclass set[T, U]: - cppclass iterator: - T& operator*() - iterator operator++() nogil - iterator operator--() nogil - bint operator==(iterator) nogil - bint operator!=(iterator) nogil - iterator begin() nogil - iterator end() nogil - iterator insert(T&) nogil - - cdef cppclass multiset[T, U]: - cppclass iterator: - T& operator*() - iterator operator++() nogil - iterator operator--() nogil - bint operator==(iterator) nogil - bint operator!=(iterator) nogil - iterator begin() nogil - iterator end() nogil - iterator insert(T&) nogil - -cdef extern from "" namespace "std" nogil: - cdef cppclass unordered_map[T, U]: - cppclass iterator: - pair[T, U]& operator*() - iterator operator++() - iterator operator--() - bint operator==(iterator) - bint operator!=(iterator) - cppclass reverse_iterator: - pair[T, U]& operator*() - iterator operator++() - iterator operator--() - bint operator==(reverse_iterator) - bint operator!=(reverse_iterator) - cppclass const_iterator(iterator): - pass - cppclass const_reverse_iterator(reverse_iterator): - pass - unordered_map() except + - unordered_map(unordered_map&) except + - #unordered_map(key_compare&) - U& operator[](T&) - #unordered_map& operator=(unordered_map&) - bint operator==(unordered_map&, unordered_map&) - bint operator!=(unordered_map&, unordered_map&) - bint operator<(unordered_map&, unordered_map&) - bint operator>(unordered_map&, unordered_map&) - bint operator<=(unordered_map&, unordered_map&) - bint operator>=(unordered_map&, unordered_map&) - U& at(T&) - iterator begin() - const_iterator const_begin "begin"() - void clear() - size_t count(T&) - bint empty() - iterator end() - const_iterator const_end "end"() - pair[iterator, iterator] equal_range(T&) - #pair[const_iterator, const_iterator] equal_range(key_type&) - void erase(iterator) - void erase(iterator, iterator) - size_t erase(T&) - iterator find(T&) - const_iterator const_find "find"(T&) - pair[iterator, bint] insert(pair[T, U]) # XXX pair[T,U]& - iterator insert(iterator, pair[T, U]) # XXX pair[T,U]& - #void insert(input_iterator, input_iterator) - #key_compare key_comp() - iterator lower_bound(T&) - const_iterator const_lower_bound "lower_bound"(T&) - size_t max_size() - reverse_iterator rbegin() - const_reverse_iterator const_rbegin "rbegin"() - reverse_iterator rend() - const_reverse_iterator const_rend "rend"() - size_t size() - void swap(unordered_map&) - iterator upper_bound(T&) - const_iterator const_upper_bound "upper_bound"(T&) - #value_compare value_comp() - void max_load_factor(float) - float max_load_factor() - cdef extern from "" namespace "SymEngine": cdef enum ENull: null @@ -126,17 +40,22 @@ cdef extern from "" namespace "SymEngine": cdef cppclass RCP[T]: T& operator*() nogil # Not yet supported in Cython: -# RCP[T]& operator=(RCP[T] &r_ptr) nogil except + - void reset() nogil except + +# RCP[T]& operator=(RCP[T] &r_ptr) except+ nogil + void reset() except+ nogil cdef cppclass Ptr[T]: - T& operator*() nogil except + + T& operator*() except+ nogil void print_stack_on_segfault() nogil cdef extern from "" namespace "SymEngine": ctypedef Basic const_Basic "const SymEngine::Basic" - ctypedef RCP[const Basic] rcp_const_basic "SymEngine::RCP" + # RCP[const_Basic] instead of RCP[const Basic] is because of https://github.com/cython/cython/issues/5478 + ctypedef RCP[const_Basic] rcp_const_basic "SymEngine::RCP" + #cdef cppclass rcp_const_basic "SymEngine::RCP": + # Basic& operator*() nogil + # void reset() except+ nogil + # pass # Cython has broken support for the following: # ctypedef map[rcp_const_basic, rcp_const_basic] map_basic_basic # So instead we replicate the map features we need here @@ -178,11 +97,11 @@ cdef extern from "" namespace "SymEngine": ctypedef map[RCP[Integer], unsigned] map_integer_uint "SymEngine::map_integer_uint" cdef struct RCPIntegerKeyLess cdef struct RCPBasicKeyLess - ctypedef set[rcp_const_basic, RCPBasicKeyLess] set_basic "SymEngine::set_basic" - ctypedef multiset[rcp_const_basic, RCPBasicKeyLess] multiset_basic "SymEngine::multiset_basic" + ctypedef set[rcp_const_basic] set_basic "SymEngine::set_basic" + ctypedef multiset[rcp_const_basic] multiset_basic "SymEngine::multiset_basic" cdef cppclass Basic: - string __str__() nogil except + - unsigned int hash() nogil except + + string __str__() except+ nogil + unsigned int hash() except+ nogil vec_basic get_args() nogil int __cmp__(const Basic &o) nogil @@ -193,11 +112,11 @@ cdef extern from "" namespace "SymEngine": ctypedef unordered_map[rcp_const_basic, rcp_const_number].iterator umap_basic_num_iterator "SymEngine::umap_basic_num::iterator" ctypedef vector[pair[rcp_const_basic, rcp_const_basic]] vec_pair "SymEngine::vec_pair" - bool eq(const Basic &a, const Basic &b) nogil except + - bool neq(const Basic &a, const Basic &b) nogil except + + bool eq(const Basic &a, const Basic &b) except+ nogil + bool neq(const Basic &a, const Basic &b) except+ nogil RCP[const Symbol] rcp_static_cast_Symbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil - RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil except + + RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) except+ nogil RCP[const Integer] rcp_static_cast_Integer "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Rational] rcp_static_cast_Rational "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Complex] rcp_static_cast_Complex "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil @@ -319,10 +238,10 @@ cdef extern from "" namespace "SymEngine": bool is_a_Not "SymEngine::is_a"(const Basic &b) nogil bool is_a_Or "SymEngine::is_a"(const Basic &b) nogil bool is_a_Xor "SymEngine::is_a"(const Basic &b) nogil - rcp_const_basic expand(rcp_const_basic &o, bool deep) nogil except + + rcp_const_basic expand(rcp_const_basic &o, bool deep) except+ nogil void as_numer_denom(rcp_const_basic &x, const Ptr[RCP[Basic]] &numer, const Ptr[RCP[Basic]] &denom) nogil void as_real_imag(rcp_const_basic &x, const Ptr[RCP[Basic]] &real, const Ptr[RCP[Basic]] &imag) nogil - void cse(vec_pair &replacements, vec_basic &reduced_exprs, const vec_basic &exprs) nogil except + + void cse(vec_pair &replacements, vec_basic &reduced_exprs, const vec_basic &exprs) except+ nogil cdef extern from "" namespace "SymEngine": rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) nogil @@ -330,7 +249,7 @@ cdef extern from "" namespace "SymEngine": rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) nogil cdef extern from "" namespace "SymEngine": - rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) nogil except + + rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) except+ nogil cdef extern from "" namespace "SymEngine": cdef cppclass Symbol(Basic): @@ -372,8 +291,8 @@ cdef extern from "pywrapper.h" namespace "SymEngine": PySymbol(string name, PyObject* pyobj, bool use_pickle) except + PyObject* get_py_object() except + - string wrapper_dumps(const Basic &x) nogil except + - rcp_const_basic wrapper_loads(const string &s) nogil except + + string wrapper_dumps(const Basic &x) except+ nogil + rcp_const_basic wrapper_loads(const string &s) except+ nogil cdef extern from "" namespace "SymEngine": cdef cppclass Integer(Number): @@ -443,9 +362,9 @@ cdef extern from "" namespace "SymEngine": pass cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic add(rcp_const_basic &a, rcp_const_basic &b) nogil except+ - cdef rcp_const_basic sub(rcp_const_basic &a, rcp_const_basic &b) nogil except+ - cdef rcp_const_basic add(const vec_basic &a) nogil except+ + cdef rcp_const_basic add(rcp_const_basic &a, rcp_const_basic &b) except+ nogil + cdef rcp_const_basic sub(rcp_const_basic &a, rcp_const_basic &b) except+ nogil + cdef rcp_const_basic add(const vec_basic &a) except+ nogil cdef cppclass Add(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) @@ -453,10 +372,10 @@ cdef extern from "" namespace "SymEngine": const umap_basic_num &get_dict() cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic mul(rcp_const_basic &a, rcp_const_basic &b) nogil except+ - cdef rcp_const_basic div(rcp_const_basic &a, rcp_const_basic &b) nogil except+ - cdef rcp_const_basic neg(rcp_const_basic &a) nogil except+ - cdef rcp_const_basic mul(const vec_basic &a) nogil except+ + cdef rcp_const_basic mul(rcp_const_basic &a, rcp_const_basic &b) except+ nogil + cdef rcp_const_basic div(rcp_const_basic &a, rcp_const_basic &b) except+ nogil + cdef rcp_const_basic neg(rcp_const_basic &a) except+ nogil + cdef rcp_const_basic mul(const vec_basic &a) except+ nogil cdef cppclass Mul(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) @@ -465,9 +384,9 @@ cdef extern from "" namespace "SymEngine": cdef RCP[const Mul] mul_from_dict "SymEngine::Mul::from_dict"(RCP[const Number] coef, map_basic_basic &&d) nogil cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic pow(rcp_const_basic &a, rcp_const_basic &b) nogil except+ - cdef rcp_const_basic sqrt(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic exp(rcp_const_basic &x) nogil except+ + cdef rcp_const_basic pow(rcp_const_basic &a, rcp_const_basic &b) except+ nogil + cdef rcp_const_basic sqrt(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic exp(rcp_const_basic &x) except+ nogil cdef cppclass Pow(Basic): rcp_const_basic get_base() nogil @@ -491,9 +410,9 @@ cdef extern from "" namespace "SymEngine": void (*dec_ref)(void *), int (*comp)(void *, void *)) nogil rcp_const_basic make_rcp_RealDouble "SymEngine::make_rcp"(double x) nogil rcp_const_basic make_rcp_ComplexDouble "SymEngine::make_rcp"(double complex x) nogil - RCP[const PyModule] make_rcp_PyModule "SymEngine::make_rcp"(PyObject* (*) (rcp_const_basic x), \ - rcp_const_basic (*)(PyObject*), RCP[const Number] (*)(PyObject*, long bits), - rcp_const_basic (*)(PyObject*, rcp_const_basic)) nogil + RCP[const PyModule] make_rcp_PyModule "SymEngine::make_rcp"(PyObject* (*) (rcp_const_basic x) except +, \ + rcp_const_basic (*)(PyObject*) except +, RCP[const Number] (*)(PyObject*, long bits) except +, + rcp_const_basic (*)(PyObject*, rcp_const_basic) except +) except + rcp_const_basic make_rcp_PyNumber "SymEngine::make_rcp"(PyObject*, RCP[const PyModule] x) nogil RCP[const PyFunctionClass] make_rcp_PyFunctionClass "SymEngine::make_rcp"(PyObject* pyobject, string name, RCP[const PyModule] pymodule) nogil @@ -501,58 +420,58 @@ cdef extern from "" namespace "SymEngine": RCP[const PyFunctionClass] pyfunc_class, const PyObject* pyobject) nogil cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic sin(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic cos(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic tan(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic cot(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic csc(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic sec(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic asin(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acos(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic atan(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acot(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acsc(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic asec(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic sinh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic cosh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic tanh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic coth(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic csch(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic sech(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic asinh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acosh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic atanh(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acoth(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic acsch(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic asech(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic function_symbol(string name, const vec_basic &arg) nogil except+ - cdef rcp_const_basic abs(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic max(const vec_basic &arg) nogil except+ - cdef rcp_const_basic min(const vec_basic &arg) nogil except+ - cdef rcp_const_basic gamma(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic atan2(rcp_const_basic &num, rcp_const_basic &den) nogil except+ - cdef rcp_const_basic lambertw(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic zeta(rcp_const_basic &s) nogil except+ - cdef rcp_const_basic zeta(rcp_const_basic &s, rcp_const_basic &a) nogil except+ - cdef rcp_const_basic dirichlet_eta(rcp_const_basic &s) nogil except+ - cdef rcp_const_basic kronecker_delta(rcp_const_basic &i, rcp_const_basic &j) nogil except+ - cdef rcp_const_basic levi_civita(const vec_basic &arg) nogil except+ - cdef rcp_const_basic erf(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic erfc(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic lowergamma(rcp_const_basic &s, rcp_const_basic &x) nogil except+ - cdef rcp_const_basic uppergamma(rcp_const_basic &s, rcp_const_basic &x) nogil except+ - cdef rcp_const_basic loggamma(rcp_const_basic &arg) nogil except+ - cdef rcp_const_basic beta(rcp_const_basic &x, rcp_const_basic &y) nogil except+ - cdef rcp_const_basic polygamma(rcp_const_basic &n, rcp_const_basic &x) nogil except+ - cdef rcp_const_basic digamma(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic trigamma(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic sign(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic floor(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic ceiling(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic conjugate(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic log(rcp_const_basic &x) nogil except+ - cdef rcp_const_basic log(rcp_const_basic &x, rcp_const_basic &y) nogil except+ - cdef rcp_const_basic unevaluated_expr(rcp_const_basic &x) nogil except+ + cdef rcp_const_basic sin(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic cos(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic tan(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic cot(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic csc(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic sec(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic asin(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acos(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic atan(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acot(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acsc(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic asec(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic sinh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic cosh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic tanh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic coth(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic csch(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic sech(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic asinh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acosh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic atanh(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acoth(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic acsch(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic asech(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic function_symbol(string name, const vec_basic &arg) except+ nogil + cdef rcp_const_basic abs(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic max(const vec_basic &arg) except+ nogil + cdef rcp_const_basic min(const vec_basic &arg) except+ nogil + cdef rcp_const_basic gamma(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic atan2(rcp_const_basic &num, rcp_const_basic &den) except+ nogil + cdef rcp_const_basic lambertw(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic zeta(rcp_const_basic &s) except+ nogil + cdef rcp_const_basic zeta(rcp_const_basic &s, rcp_const_basic &a) except+ nogil + cdef rcp_const_basic dirichlet_eta(rcp_const_basic &s) except+ nogil + cdef rcp_const_basic kronecker_delta(rcp_const_basic &i, rcp_const_basic &j) except+ nogil + cdef rcp_const_basic levi_civita(const vec_basic &arg) except+ nogil + cdef rcp_const_basic erf(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic erfc(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic lowergamma(rcp_const_basic &s, rcp_const_basic &x) except+ nogil + cdef rcp_const_basic uppergamma(rcp_const_basic &s, rcp_const_basic &x) except+ nogil + cdef rcp_const_basic loggamma(rcp_const_basic &arg) except+ nogil + cdef rcp_const_basic beta(rcp_const_basic &x, rcp_const_basic &y) except+ nogil + cdef rcp_const_basic polygamma(rcp_const_basic &n, rcp_const_basic &x) except+ nogil + cdef rcp_const_basic digamma(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic trigamma(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic sign(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic floor(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic ceiling(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic conjugate(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic log(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic log(rcp_const_basic &x, rcp_const_basic &y) except+ nogil + cdef rcp_const_basic unevaluated_expr(rcp_const_basic &x) except+ nogil cdef cppclass Function(Basic): pass @@ -792,7 +711,7 @@ cdef extern from "" namespace "SymEngine": const unsigned ncols() nogil rcp_const_basic get(unsigned i, unsigned j) nogil rcp_const_basic set(unsigned i, unsigned j, rcp_const_basic e) nogil - string __str__() nogil except+ + string __str__() except+ nogil bool eq(const MatrixBase &) nogil rcp_const_basic det() nogil void inv(MatrixBase &) @@ -842,20 +761,20 @@ cdef extern from "" namespace "SymEngine": bool is_a_DenseMatrix "SymEngine::is_a"(const MatrixBase &b) nogil DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) void inverse_FFLU "SymEngine::inverse_fraction_free_LU"(const DenseMatrix &A, - DenseMatrix &B) nogil except + - void pivoted_LU_solve (const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) nogil except + + DenseMatrix &B) except+ nogil + void pivoted_LU_solve (const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) except+ nogil void inverse_GJ "SymEngine::inverse_gauss_jordan"(const DenseMatrix &A, - DenseMatrix &B) nogil except + + DenseMatrix &B) except+ nogil void FFLU_solve "SymEngine::fraction_free_LU_solve"(const DenseMatrix &A, - const DenseMatrix &b, DenseMatrix &x) nogil except + + const DenseMatrix &b, DenseMatrix &x) except+ nogil void FFGJ_solve "SymEngine::fraction_free_gauss_jordan_solve"(const DenseMatrix &A, - const DenseMatrix &b, DenseMatrix &x) nogil except + + const DenseMatrix &b, DenseMatrix &x) except+ nogil void LDL_solve "SymEngine::LDL_solve"(const DenseMatrix &A, const DenseMatrix &b, - DenseMatrix &x) nogil except + + DenseMatrix &x) except+ nogil void jacobian "SymEngine::sjacobian"(const DenseMatrix &A, - const DenseMatrix &x, DenseMatrix &result) nogil except + + const DenseMatrix &x, DenseMatrix &result) except+ nogil void diff "SymEngine::sdiff"(const DenseMatrix &A, - rcp_const_basic &x, DenseMatrix &result) nogil except + + rcp_const_basic &x, DenseMatrix &result) except+ nogil void eye (DenseMatrix &A, int k) nogil void diag(DenseMatrix &A, vec_basic &v, int k) nogil void ones(DenseMatrix &A) nogil @@ -868,7 +787,7 @@ cdef extern from "" namespace "SymEngine": void cross(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &C) nogil cdef extern from "": - void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[pair[int, int]] &P) nogil except + + void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[pair[int, int]] &P) except+ nogil cdef extern from "" namespace "SymEngine": int probab_prime_p(const Integer &a, int reps) @@ -877,10 +796,10 @@ cdef extern from "" namespace "SymEngine": RCP[const Integer] lcm(const Integer &a, const Integer &b) nogil void gcd_ext(const Ptr[RCP[Integer]] &g, const Ptr[RCP[Integer]] &s, const Ptr[RCP[Integer]] &t, const Integer &a, const Integer &b) nogil - RCP[const Integer] mod "SymEngine::mod_f"(const Integer &n, const Integer &d) nogil except + - RCP[const Integer] quotient "SymEngine::quotient_f"(const Integer &n, const Integer &d) nogil except + + RCP[const Integer] mod "SymEngine::mod_f"(const Integer &n, const Integer &d) except+ nogil + RCP[const Integer] quotient "SymEngine::quotient_f"(const Integer &n, const Integer &d) except+ nogil void quotient_mod "SymEngine::quotient_mod_f"(const Ptr[RCP[Integer]] &q, const Ptr[RCP[Integer]] &mod, - const Integer &n, const Integer &d) nogil except + + const Integer &n, const Integer &d) except+ nogil int mod_inverse(const Ptr[RCP[Integer]] &b, const Integer &a, const Integer &m) nogil bool crt(const Ptr[RCP[Integer]] &R, const vec_integer &rem, @@ -900,9 +819,9 @@ cdef extern from "" namespace "SymEngine": unsigned B, unsigned retries) nogil int factor_pollard_rho_method(const Ptr[RCP[Integer]] &f, const Integer &n, unsigned retries) nogil - void prime_factors(vec_integer &primes, const Integer &n) nogil except + - void prime_factor_multiplicities(map_integer_uint &primes, const Integer &n) nogil except + - RCP[const Number] bernoulli(unsigned long n) nogil except + + void prime_factors(vec_integer &primes, const Integer &n) except+ nogil + void prime_factor_multiplicities(map_integer_uint &primes, const Integer &n) except+ nogil + RCP[const Number] bernoulli(unsigned long n) except+ nogil bool primitive_root(const Ptr[RCP[Integer]] &g, const Integer &n) nogil void primitive_root_list(vec_integer &roots, const Integer &n) nogil RCP[const Integer] totient(RCP[const Integer] n) nogil @@ -930,15 +849,15 @@ cdef extern from "" namespace "SymEngine": unsigned next_prime() nogil cdef extern from "" namespace "SymEngine": - bool has_symbol(const Basic &b, const Basic &x) nogil except + - rcp_const_basic coeff(const Basic &b, const Basic &x, const Basic &n) nogil except + - set_basic free_symbols(const Basic &b) nogil except + - set_basic free_symbols(const MatrixBase &b) nogil except + + bool has_symbol(const Basic &b, const Basic &x) except+ nogil + rcp_const_basic coeff(const Basic &b, const Basic &x, const Basic &n) except+ nogil + set_basic free_symbols(const Basic &b) except+ nogil + set_basic free_symbols(const MatrixBase &b) except+ nogil unsigned count_ops(const vec_basic &a) nogil cdef extern from "" namespace "SymEngine": cdef cppclass Boolean(Basic): - RCP[const Boolean] logical_not() nogil except+ + RCP[const Boolean] logical_not() except+ nogil cdef cppclass BooleanAtom(Boolean): bool get_val() nogil cdef cppclass Relational(Boolean): @@ -967,25 +886,25 @@ cdef extern from "" namespace "SymEngine": rcp_const_basic boolTrue rcp_const_basic boolFalse bool is_a_Relational(const Basic &b) nogil - cdef RCP[const Boolean] Eq(rcp_const_basic &lhs) nogil except+ - cdef RCP[const Boolean] Eq(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ - cdef RCP[const Boolean] Ne(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ - cdef RCP[const Boolean] Ge(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ - cdef RCP[const Boolean] Gt(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ - cdef RCP[const Boolean] Le(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ - cdef RCP[const Boolean] Lt(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except+ + cdef RCP[const Boolean] Eq(rcp_const_basic &lhs) except+ nogil + cdef RCP[const Boolean] Eq(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Ne(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Ge(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Gt(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Le(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Lt(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil ctypedef Boolean const_Boolean "const SymEngine::Boolean" ctypedef vector[pair[rcp_const_basic, RCP[const_Boolean]]] PiecewiseVec; ctypedef vector[RCP[Boolean]] vec_boolean "SymEngine::vec_boolean" - ctypedef set[RCP[Boolean], RCPBasicKeyLess] set_boolean "SymEngine::set_boolean" - cdef RCP[const Boolean] logical_and(set_boolean &s) nogil except+ - cdef RCP[const Boolean] logical_nand(set_boolean &s) nogil except+ - cdef RCP[const Boolean] logical_or(set_boolean &s) nogil except+ - cdef RCP[const Boolean] logical_not(RCP[const Boolean] &s) nogil except+ - cdef RCP[const Boolean] logical_nor(set_boolean &s) nogil except+ - cdef RCP[const Boolean] logical_xor(vec_boolean &s) nogil except+ - cdef RCP[const Boolean] logical_xnor(vec_boolean &s) nogil except+ - cdef rcp_const_basic piecewise(PiecewiseVec vec) nogil except + + ctypedef set[RCP[Boolean]] set_boolean "SymEngine::set_boolean" + cdef RCP[const Boolean] logical_and(set_boolean &s) except+ nogil + cdef RCP[const Boolean] logical_nand(set_boolean &s) except+ nogil + cdef RCP[const Boolean] logical_or(set_boolean &s) except+ nogil + cdef RCP[const Boolean] logical_not(RCP[const Boolean] &s) except+ nogil + cdef RCP[const Boolean] logical_nor(set_boolean &s) except+ nogil + cdef RCP[const Boolean] logical_xor(vec_boolean &s) except+ nogil + cdef RCP[const Boolean] logical_xnor(vec_boolean &s) except+ nogil + cdef rcp_const_basic piecewise(PiecewiseVec vec) except+ nogil cdef RCP[const Boolean] contains(rcp_const_basic &expr, RCP[const Set] &set) nogil @@ -1004,26 +923,26 @@ cdef extern from "" namespace "SymEngine": cdef EvalfDomain EvalfComplex "SymEngine::EvalfDomain::Complex" cdef EvalfDomain EvalfReal "SymEngine::EvalfDomain::Real" cdef EvalfDomain EvalfSymbolic "SymEngine::EvalfDomain::Symbolic" - rcp_const_basic evalf(const Basic &b, unsigned long bits, EvalfDomain domain) nogil except + + rcp_const_basic evalf(const Basic &b, unsigned long bits, EvalfDomain domain) except+ nogil cdef extern from "" namespace "SymEngine": - double eval_double(const Basic &b) nogil except + - double complex eval_complex_double(const Basic &b) nogil except + + double eval_double(const Basic &b) except+ nogil + double complex eval_complex_double(const Basic &b) except+ nogil cdef extern from "" namespace "SymEngine": cdef cppclass LambdaRealDoubleVisitor: LambdaRealDoubleVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except + + void init(const vec_basic &x, const vec_basic &b, bool cse) except+ nogil void call(double *r, const double *x) nogil cdef cppclass LambdaComplexDoubleVisitor: LambdaComplexDoubleVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except + + void init(const vec_basic &x, const vec_basic &b, bool cse) except+ nogil void call(double complex *r, const double complex *x) nogil cdef extern from "" namespace "SymEngine": cdef cppclass LLVMVisitor: LLVMVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse, int opt_level) nogil except + + void init(const vec_basic &x, const vec_basic &b, bool cse, int opt_level) except+ nogil const string& dumps() nogil void loads(const string&) nogil @@ -1039,29 +958,29 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": cdef cppclass SeriesCoeffInterface: - rcp_const_basic as_basic() nogil except + - umap_int_basic as_dict() nogil except + - rcp_const_basic get_coeff(int) nogil except + + rcp_const_basic as_basic() except+ nogil + umap_int_basic as_dict() except+ nogil + rcp_const_basic get_coeff(int) except+ nogil ctypedef RCP[const SeriesCoeffInterface] rcp_const_seriescoeffinterface "SymEngine::RCP" - rcp_const_seriescoeffinterface series "SymEngine::series"(rcp_const_basic &ex, RCP[const Symbol] &var, unsigned int prec) nogil except + + rcp_const_seriescoeffinterface series "SymEngine::series"(rcp_const_basic &ex, RCP[const Symbol] &var, unsigned int prec) except+ nogil IF HAVE_SYMENGINE_MPFR: cdef extern from "" namespace "SymEngine": - void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) nogil except + + void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil IF HAVE_SYMENGINE_MPC: cdef extern from "" namespace "SymEngine": - void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) nogil except + + void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil cdef extern from "" namespace "SymEngine": - rcp_const_basic parse(const string &n) nogil except + + rcp_const_basic parse(const string &n) except+ nogil cdef extern from "" namespace "SymEngine": cdef cppclass Set(Basic): - RCP[const Set] set_intersection(RCP[const Set] &o) nogil except + - RCP[const Set] set_union(RCP[const Set] &o) nogil except + - RCP[const Set] set_complement(RCP[const Set] &o) nogil except + - RCP[const Boolean] contains(rcp_const_basic &a) nogil except + + RCP[const Set] set_intersection(RCP[const Set] &o) except+ nogil + RCP[const Set] set_union(RCP[const Set] &o) except+ nogil + RCP[const Set] set_complement(RCP[const Set] &o) except+ nogil + RCP[const Boolean] contains(rcp_const_basic &a) except+ nogil cdef cppclass Interval(Set): pass cdef cppclass EmptySet(Set): @@ -1084,25 +1003,25 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass ImageSet(Set): pass - ctypedef set[RCP[Set], RCPBasicKeyLess] set_set "SymEngine::set_set" - cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except + - cdef RCP[const EmptySet] emptyset() nogil except + - cdef RCP[const Reals] reals() nogil except + - cdef RCP[const Rationals] rationals() nogil except + - cdef RCP[const Integers] integers() nogil except + - cdef RCP[const UniversalSet] universalset() nogil except + - cdef RCP[const Set] finiteset(set_basic &container) nogil except + - cdef RCP[const Set] set_union(set_set &a) nogil except + - cdef RCP[const Set] set_intersection(set_set &a) nogil except + - cdef RCP[const Set] set_complement_helper(RCP[const Set] &container, RCP[const Set] &universe) nogil except + - cdef RCP[const Set] set_complement(RCP[const Set] &universe, RCP[const Set] &container) nogil except + - cdef RCP[const Set] conditionset(rcp_const_basic &sym, RCP[const Boolean] &condition) nogil except + - cdef RCP[const Set] imageset(rcp_const_basic &sym, rcp_const_basic &expr, RCP[const Set] &base) nogil except + + ctypedef set[RCP[Set]] set_set "SymEngine::set_set" + cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) except+ nogil + cdef RCP[const EmptySet] emptyset() except+ nogil + cdef RCP[const Reals] reals() except+ nogil + cdef RCP[const Rationals] rationals() except+ nogil + cdef RCP[const Integers] integers() except+ nogil + cdef RCP[const UniversalSet] universalset() except+ nogil + cdef RCP[const Set] finiteset(set_basic &container) except+ nogil + cdef RCP[const Set] set_union(set_set &a) except+ nogil + cdef RCP[const Set] set_intersection(set_set &a) except+ nogil + cdef RCP[const Set] set_complement_helper(RCP[const Set] &container, RCP[const Set] &universe) except+ nogil + cdef RCP[const Set] set_complement(RCP[const Set] &universe, RCP[const Set] &container) except+ nogil + cdef RCP[const Set] conditionset(rcp_const_basic &sym, RCP[const Boolean] &condition) except+ nogil + cdef RCP[const Set] imageset(rcp_const_basic &sym, rcp_const_basic &expr, RCP[const Set] &base) except+ nogil cdef extern from "" namespace "SymEngine": - cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym) nogil except + - cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym, RCP[const Set] &domain) nogil except + - cdef vec_basic linsolve(const vec_basic &eqs, const vec_sym &syms) nogil except + + cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym) except+ nogil + cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym, RCP[const Set] &domain) except+ nogil + cdef vec_basic linsolve(const vec_basic &eqs, const vec_sym &syms) except+ nogil cdef extern from "symengine/tribool.h" namespace "SymEngine": cdef cppclass tribool: @@ -1118,10 +1037,10 @@ cdef extern from "symengine/tribool.h" namespace "SymEngine::tribool": cdef tribool tritrue cdef extern from "" namespace "SymEngine": - string ccode(const Basic &x) nogil except + - string latex(const Basic &x) nogil except + - string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) nogil except + - string unicode(const Basic &x) nogil except + + string ccode(const Basic &x) except+ nogil + string latex(const Basic &x) except+ nogil + string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) except+ nogil + string unicode(const Basic &x) except+ nogil ## Defined in 'symengine/cwrapper.cpp' cdef struct CRCPBasic: From f09fb79def999451476f1dce77d3f4c0e9494e06 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 10:04:08 -0500 Subject: [PATCH 229/314] reversed methods for cython 3 --- symengine/lib/symengine_wrapper.pyx | 115 ++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index de90b2cb8..8d24fb432 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -870,6 +870,12 @@ cdef class Basic(object): cdef Basic B = B_ return c2py(symengine.add(A.thisptr, B.thisptr)) + def __radd__(Basic self, b): + B_ = _sympify(b, False) + if B_ is None or isinstance(B_, MatrixBase): return NotImplemented + cdef Basic B = B_ + return c2py(symengine.add(B.thisptr, self.thisptr)) + def __sub__(a, b): cdef Basic A = _sympify(a, False) B_ = _sympify(b, False) @@ -877,6 +883,12 @@ cdef class Basic(object): cdef Basic B = B_ return c2py(symengine.sub(A.thisptr, B.thisptr)) + def __rsub__(Basic self, b): + B_ = _sympify(b, False) + if B_ is None or isinstance(B_, MatrixBase): return NotImplemented + cdef Basic B = B_ + return c2py(symengine.sub(B.thisptr, self.thisptr)) + def __mul__(a, b): cdef Basic A = _sympify(a, False) B_ = _sympify(b, False) @@ -884,22 +896,45 @@ cdef class Basic(object): cdef Basic B = B_ return c2py(symengine.mul(A.thisptr, B.thisptr)) + def __rmul__(Basic self, b): + B_ = _sympify(b, False) + if B_ is None or isinstance(B_, MatrixBase): return NotImplemented + cdef Basic B = B_ + return c2py(symengine.mul(B.thisptr, self.thisptr)) + def __truediv__(a, b): cdef Basic A = _sympify(a, False) - cdef Basic B = _sympify(b, False) - if A is None or B is None: return NotImplemented + B_ = _sympify(b, False) + if A is None or B_ is None or isinstance(B_, MatrixBase): return NotImplemented + cdef Basic B = B_ return c2py(symengine.div(A.thisptr, B.thisptr)) + def __rtruediv__(Basic self, b): + B_ = _sympify(b, False) + if B_ is None or isinstance(B_, MatrixBase): return NotImplemented + cdef Basic B = B_ + return c2py(symengine.div(B.thisptr, self.thisptr)) + def __floordiv__(x, y): return floor(x/y) + def __rfloordiv__(y, x): + return floor(x/y) + def __mod__(x, y): return x - y * floor(x/y) + def __rmod__(y, x): + return x - y * floor(x/y) + def __divmod__(x, y): f = floor(x/y) return f, x - y * f + def __rdivmod__(y, x): + f = floor(x/y) + return f, x - y * f + def __pow__(a, b, c): if c is not None: return powermod(a, b, c) @@ -908,6 +943,11 @@ cdef class Basic(object): if A is None or B is None: return NotImplemented return c2py(symengine.pow(A.thisptr, B.thisptr)) + def __rpow__(Basic self, b): + cdef Basic B = _sympify(b, False) + if B is None: return NotImplemented + return c2py(symengine.pow(B.thisptr, self.thisptr)) + def __neg__(Basic self not None): return c2py(symengine.neg(self.thisptr)) @@ -3392,6 +3432,19 @@ cdef class DenseMatrixBase(MatrixBase): raise ShapeError("Invalid shapes for matrix addition. Got %s %s" % (a_.shape, b_.shape)) return a_.add_matrix(b_) + def __radd__(MatrixBase self, a): + a = _sympify(a, False) + if not isinstance(a, MatrixBase): + return NotImplemented + cdef MatrixBase a_ = a + if (a_.shape == (0, 0)): + return self + if (self.shape == (0, 0)): + return a_ + if (self.shape != a_.shape): + raise ShapeError("Invalid shapes for matrix addition. Got %s %s" % (a_.shape, self.shape)) + return a_.add_matrix(self) + def __mul__(a, b): a = _sympify(a, False) b = _sympify(b, False) @@ -3409,6 +3462,17 @@ cdef class DenseMatrixBase(MatrixBase): else: return NotImplemented + def __rmul__(Basic self, a): + a = _sympify(a, False) + if isinstance(a, MatrixBase): + if (a.ncols() != self.nrows()): + raise ShapeError("Invalid shapes for matrix multiplication. Got %s %s" % (a.shape, self.shape)) + return a.mul_matrix(self) + elif isinstance(a, Basic): + return self.mul_scalar(a) + else: + return NotImplemented + def __matmul__(a, b): a = _sympify(a, False) b = _sympify(b, False) @@ -3416,8 +3480,31 @@ cdef class DenseMatrixBase(MatrixBase): raise ShapeError("Invalid shapes for matrix multiplication. Got %s %s" % (a.shape, b.shape)) return a.mul_matrix(b) + def __rmatmul__(Basic self, a): + a = _sympify(a, False) + if (a.ncols() != self.nrows()): + raise ShapeError("Invalid shapes for matrix multiplication. Got %s %s" % (a.shape, self.shape)) + return a.mul_matrix(self) + def __truediv__(a, b): - return div_matrices(a, b) + a = _sympify(a, False) + b = _sympify(b, False) + if isinstance(a, MatrixBase): + if isinstance(b, MatrixBase): + return a.mul_matrix(b.inv()) + elif isinstance(b, Basic): + return a.mul_scalar(1/b) + else: + return NotImplemented + else: + return NotImplemented + + def __rtruediv__(Basic self, a): + a = _sympify(a, False) + if isinstance(a, MatrixBase): + return a.mul_matrix(self.inv()) + else: + return NotImplemented def __sub__(a, b): a = _sympify(a, False) @@ -3430,6 +3517,15 @@ cdef class DenseMatrixBase(MatrixBase): raise ShapeError("Invalid shapes for matrix subtraction. Got %s %s" % (a.shape, b.shape)) return a_.add_matrix(-b_) + def __rsub__(MatrixBase self, a): + a = _sympify(a, False) + if not isinstance(a, MatrixBase): + return NotImplemented + cdef MatrixBase a_ = a + if (a_.shape != self.shape): + raise ShapeError("Invalid shapes for matrix subtraction. Got %s %s" % (a.shape, self.shape)) + return a_.add_matrix(-self) + def __neg__(self): return self.mul_scalar(-1) @@ -4038,19 +4134,6 @@ cdef class DenseMatrixBase(MatrixBase): return self.applyfunc(lambda x : x.expand(*args, **kwargs)) -def div_matrices(a, b): - a = _sympify(a, False) - b = _sympify(b, False) - if isinstance(a, MatrixBase): - if isinstance(b, MatrixBase): - return a.mul_matrix(b.inv()) - elif isinstance(b, Basic): - return a.mul_scalar(1/b) - else: - return NotImplemented - else: - return NotImplemented - class DenseMatrixBaseIter(object): def __init__(self, d): From a73e5c370eeec7586e823a7ab47f9e1cec3cf04b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 10:20:07 -0500 Subject: [PATCH 230/314] bring back multiset --- symengine/lib/symengine.pxd | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index b70b7a0d6..01478860e 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -4,11 +4,24 @@ from libcpp.map cimport map from libcpp.vector cimport vector from cpython.ref cimport PyObject from libcpp.pair cimport pair -from libcpp.set cimport multiset, set +from libcpp.set cimport set from libcpp.unordered_map cimport unordered_map include "config.pxi" +cdef extern from "" namespace "std": + # Cython's libcpp.set does not support multiset in 0.29.x + cdef cppclass multiset[T]: + cppclass iterator: + T& operator*() + iterator operator++() nogil + iterator operator--() nogil + bint operator==(iterator) nogil + bint operator!=(iterator) nogil + iterator begin() nogil + iterator end() nogil + iterator insert(T&) nogil + cdef extern from 'symengine/mp_class.h' namespace "SymEngine": ctypedef unsigned long mp_limb_t ctypedef struct __mpz_struct: From 42887ce09ffdcf1de515d8c227a076ee404b0d4b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 10:48:12 -0500 Subject: [PATCH 231/314] remove some IF statements --- symengine/lib/symengine.pxd | 134 +++++++++++++++++------------------- 1 file changed, 62 insertions(+), 72 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 01478860e..47894daf3 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -655,68 +655,62 @@ cdef extern from "" namespace "SymEngine": cdef cppclass Log(Function): pass -IF HAVE_SYMENGINE_MPFR: - cdef extern from "mpfr.h": - ctypedef struct __mpfr_struct: - pass - ctypedef __mpfr_struct mpfr_t[1] - ctypedef __mpfr_struct* mpfr_ptr - ctypedef const __mpfr_struct* mpfr_srcptr - ctypedef long mpfr_prec_t - ctypedef enum mpfr_rnd_t: - MPFR_RNDN - MPFR_RNDZ - MPFR_RNDU - MPFR_RNDD - MPFR_RNDA - MPFR_RNDF - MPFR_RNDNA - - cdef extern from "" namespace "SymEngine": - cdef cppclass mpfr_class: - mpfr_class() nogil - mpfr_class(mpfr_prec_t prec) nogil - mpfr_class(string s, mpfr_prec_t prec, unsigned base) nogil - mpfr_class(mpfr_t m) nogil - mpfr_ptr get_mpfr_t() nogil - - cdef cppclass RealMPFR(Number): - RealMPFR(mpfr_class) nogil - mpfr_class as_mpfr() nogil - mpfr_prec_t get_prec() nogil - - RCP[const RealMPFR] real_mpfr(mpfr_class t) nogil -ELSE: - cdef extern from "" namespace "SymEngine": - cdef cppclass RealMPFR(Number): - pass - -IF HAVE_SYMENGINE_MPC: - cdef extern from "mpc.h": - ctypedef struct __mpc_struct: - pass - ctypedef __mpc_struct mpc_t[1] - ctypedef __mpc_struct* mpc_ptr - ctypedef const __mpc_struct* mpc_srcptr - - cdef extern from "" namespace "SymEngine": - cdef cppclass mpc_class: - mpc_class() nogil - mpc_class(mpfr_prec_t prec) nogil - mpc_class(mpc_t m) nogil - mpc_ptr get_mpc_t() nogil - mpc_class(string s, mpfr_prec_t prec, unsigned base) nogil - - cdef cppclass ComplexMPC(ComplexBase): - ComplexMPC(mpc_class) nogil - mpc_class as_mpc() nogil - mpfr_prec_t get_prec() nogil - - RCP[const ComplexMPC] complex_mpc(mpc_class t) nogil -ELSE: - cdef extern from "" namespace "SymEngine": - cdef cppclass ComplexMPC(Number): - pass +cdef extern from "": + # These come from mpfr.h, but don't include mpfr.h to not break + # builds without mpfr + ctypedef struct __mpfr_struct: + pass + ctypedef __mpfr_struct mpfr_t[1] + ctypedef __mpfr_struct* mpfr_ptr + ctypedef const __mpfr_struct* mpfr_srcptr + ctypedef long mpfr_prec_t + ctypedef enum mpfr_rnd_t: + MPFR_RNDN + MPFR_RNDZ + MPFR_RNDU + MPFR_RNDD + MPFR_RNDA + MPFR_RNDF + MPFR_RNDNA + +cdef extern from "" namespace "SymEngine": + cdef cppclass mpfr_class: + mpfr_class() nogil + mpfr_class(mpfr_prec_t prec) nogil + mpfr_class(string s, mpfr_prec_t prec, unsigned base) nogil + mpfr_class(mpfr_t m) nogil + mpfr_ptr get_mpfr_t() nogil + + cdef cppclass RealMPFR(Number): + RealMPFR(mpfr_class) nogil + mpfr_class as_mpfr() nogil + mpfr_prec_t get_prec() nogil + + RCP[const RealMPFR] real_mpfr(mpfr_class t) nogil + +cdef extern from "": + # These come from mpc.h, but don't include mpc.h to not break + # builds without mpc + ctypedef struct __mpc_struct: + pass + ctypedef __mpc_struct mpc_t[1] + ctypedef __mpc_struct* mpc_ptr + ctypedef const __mpc_struct* mpc_srcptr + +cdef extern from "" namespace "SymEngine": + cdef cppclass mpc_class: + mpc_class() nogil + mpc_class(mpfr_prec_t prec) nogil + mpc_class(mpc_t m) nogil + mpc_ptr get_mpc_t() nogil + mpc_class(string s, mpfr_prec_t prec, unsigned base) nogil + + cdef cppclass ComplexMPC(ComplexBase): + ComplexMPC(mpc_class) nogil + mpc_class as_mpc() nogil + mpfr_prec_t get_prec() nogil + + RCP[const ComplexMPC] complex_mpc(mpc_class t) nogil cdef extern from "" namespace "SymEngine": cdef cppclass MatrixBase: @@ -923,10 +917,8 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "std": cdef integer_class std_move_mpz "std::move" (integer_class) nogil - IF HAVE_SYMENGINE_MPFR: - cdef mpfr_class std_move_mpfr "std::move" (mpfr_class) nogil - IF HAVE_SYMENGINE_MPC: - cdef mpc_class std_move_mpc "std::move" (mpc_class) nogil + cdef mpfr_class std_move_mpfr "std::move" (mpfr_class) nogil + cdef mpc_class std_move_mpc "std::move" (mpc_class) nogil cdef map_basic_basic std_move_map_basic_basic "std::move" (map_basic_basic) nogil cdef PiecewiseVec std_move_PiecewiseVec "std::move" (PiecewiseVec) nogil @@ -977,13 +969,11 @@ cdef extern from "" namespace "SymEngine": ctypedef RCP[const SeriesCoeffInterface] rcp_const_seriescoeffinterface "SymEngine::RCP" rcp_const_seriescoeffinterface series "SymEngine::series"(rcp_const_basic &ex, RCP[const Symbol] &var, unsigned int prec) except+ nogil -IF HAVE_SYMENGINE_MPFR: - cdef extern from "" namespace "SymEngine": - void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil +cdef extern from "" namespace "SymEngine": + void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil -IF HAVE_SYMENGINE_MPC: - cdef extern from "" namespace "SymEngine": - void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil +cdef extern from "" namespace "SymEngine": + void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil cdef extern from "" namespace "SymEngine": rcp_const_basic parse(const string &n) except+ nogil From d1d4de804004151694e29742578cfd777bc8ab6e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 10:56:46 -0500 Subject: [PATCH 232/314] rename file --- symengine/lib/{symengine_wrapper.pyx => symengine_wrapper.in.pyx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename symengine/lib/{symengine_wrapper.pyx => symengine_wrapper.in.pyx} (100%) diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.in.pyx similarity index 100% rename from symengine/lib/symengine_wrapper.pyx rename to symengine/lib/symengine_wrapper.in.pyx From 1d63ae406c2788b52a6e99156c93873ea091ac0c Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 8 Jun 2023 13:05:48 -0500 Subject: [PATCH 233/314] Replace the use of conditional statements by a preprocessing program --- .gitignore | 2 + cmake/FindCython.cmake | 23 ++-------- cmake/preprocess.py | 38 +++++++++++++++ symengine/lib/CMakeLists.txt | 46 +++++++++++++++---- symengine/lib/config.pxi.in | 1 + symengine/lib/symengine.pxd | 4 +- ...e_wrapper.pxd => symengine_wrapper.in.pxd} | 2 - symengine/lib/symengine_wrapper.in.pyx | 2 +- 8 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 cmake/preprocess.py rename symengine/lib/{symengine_wrapper.pxd => symengine_wrapper.in.pxd} (99%) diff --git a/.gitignore b/.gitignore index 1ef1e18ed..f93c02277 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ cython_test.cpp *.vcxproj *.filters symengine/lib/symengine_wrapper.cpp +symengine/lib/symengine_wrapper.pyx +symengine/lib/symengine_wrapper.pxd # Config Files symengine/lib/config.pxi diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 318f58e48..073e561d1 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -63,26 +63,13 @@ if(NOT CYTHON_INCLUDE_DIRECTORIES) endif(NOT CYTHON_INCLUDE_DIRECTORIES) # Cythonizes the .pyx files into .cpp file (but doesn't compile it) -macro(CYTHON_ADD_MODULE_PYX name) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) - set(DEPENDS ${name}.pyx ${name}.pxd) - else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) - set(DEPENDS ${name}.pyx) - endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pxd) +macro(CYTHON_ADD_MODULE_PYX name filename) # Allow the user to specify dependencies as optional arguments set(DEPENDS ${DEPENDS} ${ARGN}) add_custom_command( - OUTPUT ${name}.cpp + OUTPUT ${name} COMMAND ${CYTHON_BIN} - ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${name}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${name}.pyx - DEPENDS ${DEPENDS} - COMMENT "Cythonizing ${name}.pyx") + ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${name} ${filename} + DEPENDS ${DEPENDS} ${filename} + COMMENT "Cythonizing ${filename}") endmacro(CYTHON_ADD_MODULE_PYX) - -# Cythonizes and compiles a .pyx file -macro(CYTHON_ADD_MODULE name) - CYTHON_ADD_MODULE_PYX(${name}) - # We need Python for this: - find_package(Python REQUIRED) - add_python_library(${name} ${name}.cpp ${ARGN}) -endmacro(CYTHON_ADD_MODULE) diff --git a/cmake/preprocess.py b/cmake/preprocess.py new file mode 100644 index 000000000..a99d24898 --- /dev/null +++ b/cmake/preprocess.py @@ -0,0 +1,38 @@ +import sys + + +def main(input_name, output_name, replacements): + replacements = dict((item.split("=")[0], item.split("=")[1] == "True") for item in replacements) + with open(input_name, "r") as inp: + text = inp.readlines() + + new_text = [] + in_cond = [True] + nspaces = [0] + for i, line in enumerate(text): + if line.strip().startswith("IF"): + s = len(line) - len(line.lstrip()) + while s <= nspaces[-1] and len(in_cond) > 1: + in_cond = in_cond[:-1] + nspaces = nspaces[:-1] + + cond = line.lstrip()[3:-2] + in_cond.append(replacements[cond]) + nspaces.append(s) + elif line.strip().startswith("ELSE"): + in_cond[-1] = not in_cond[-1] and in_cond[-2] + + if len(line) > 1 and not line.strip().startswith(("IF", "ELSE")): + while len(in_cond) > 1 and (len(line) <= nspaces[-1] or not line.startswith(" "*nspaces[-1]) or line[nspaces[-1]] != " "): + in_cond = in_cond[:-1] + nspaces = nspaces[:-1] + if len(line) == 1: + new_text.append(line) + elif in_cond[-1] and not line.strip().startswith(("IF", "ELSE")): + new_text.append(line[4*(len(in_cond) - 1):]) + + with open(output_name, "w") as out: + out.writelines(new_text) + +if __name__ == "__main__": + main(sys.argv[1], sys.argv[2], sys.argv[3:]) diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index bf5cc9f80..d37d94dca 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -1,13 +1,46 @@ set(SRC - symengine_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.cpp pywrapper.cpp ) -configure_file(config.pxi.in config.pxi) +include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) -include_directories(BEFORE ${python_wrapper_BINARY_DIR}/symengine/lib) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pxd + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd + ${PROJECT_SOURCE_DIR}/cmake/preprocess.py + COMMAND ${PYTHON_BIN} ${PROJECT_SOURCE_DIR}/cmake/preprocess.py + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.pxd + HAVE_SYMENGINE_MPFR=${HAVE_SYMENGINE_MPFR} + HAVE_SYMENGINE_MPC=${HAVE_SYMENGINE_MPC} + HAVE_SYMENGINE_PIRANHA=${HAVE_SYMENGINE_PIRANHA} + HAVE_SYMENGINE_FLINT=${HAVE_SYMENGINE_FLINT} + HAVE_SYMENGINE_LLVM=${HAVE_SYMENGINE_LLVM} + HAVE_SYMENGINE_LLVM_LONG_DOUBLE=${HAVE_SYMENGINE_LLVM_LONG_DOUBLE} + COMMENT "Preprocessing symengine_wrapper.in.pxd" +) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pyx + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pyx + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd + ${PROJECT_SOURCE_DIR}/cmake/preprocess.py + COMMAND ${PYTHON_BIN} ${PROJECT_SOURCE_DIR}/cmake/preprocess.py + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pyx + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.pyx + HAVE_SYMENGINE_MPFR=${HAVE_SYMENGINE_MPFR} + HAVE_SYMENGINE_MPC=${HAVE_SYMENGINE_MPC} + HAVE_SYMENGINE_PIRANHA=${HAVE_SYMENGINE_PIRANHA} + HAVE_SYMENGINE_FLINT=${HAVE_SYMENGINE_FLINT} + HAVE_SYMENGINE_LLVM=${HAVE_SYMENGINE_LLVM} + HAVE_SYMENGINE_LLVM_LONG_DOUBLE=${HAVE_SYMENGINE_LLVM_LONG_DOUBLE} + COMMENT "Preprocessing symengine_wrapper.in.pyx" +) -cython_add_module_pyx(symengine_wrapper symengine.pxd) +cython_add_module_pyx(symengine_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pyx + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pxd + ${CMAKE_CURRENT_SOURCE_DIR}/symengine.pxd) add_python_library(symengine_wrapper ${SRC}) target_link_libraries(symengine_wrapper ${SYMENGINE_LIBRARIES}) if (CMAKE_CXX_COMPILER_ID MATCHES GNU|Clang) @@ -18,10 +51,6 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU|Clang) ) endif() -add_custom_target(cython - COMMAND cython symengine_wrapper.pyx - ) - set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine/lib) install(TARGETS symengine_wrapper RUNTIME DESTINATION ${PY_PATH} @@ -29,7 +58,6 @@ install(TARGETS symengine_wrapper LIBRARY DESTINATION ${PY_PATH} ) install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/config.pxi symengine.pxd symengine_wrapper.pxd pywrapper.h diff --git a/symengine/lib/config.pxi.in b/symengine/lib/config.pxi.in index 26a33012e..5ae5675f2 100644 --- a/symengine/lib/config.pxi.in +++ b/symengine/lib/config.pxi.in @@ -4,3 +4,4 @@ DEF HAVE_SYMENGINE_PIRANHA = ${HAVE_SYMENGINE_PIRANHA} DEF HAVE_SYMENGINE_FLINT = ${HAVE_SYMENGINE_FLINT} DEF HAVE_SYMENGINE_LLVM = ${HAVE_SYMENGINE_LLVM} DEF HAVE_SYMENGINE_LLVM_LONG_DOUBLE = ${HAVE_SYMENGINE_LLVM_LONG_DOUBLE} +DEF ENDIF = 1 diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 47894daf3..94a667599 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -7,8 +7,6 @@ from libcpp.pair cimport pair from libcpp.set cimport set from libcpp.unordered_map cimport unordered_map -include "config.pxi" - cdef extern from "" namespace "std": # Cython's libcpp.set does not support multiset in 0.29.x cdef cppclass multiset[T]: @@ -394,7 +392,7 @@ cdef extern from "" namespace "SymEngine": void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) RCP[const Number] get_coef() const map_basic_basic &get_dict() - cdef RCP[const Mul] mul_from_dict "SymEngine::Mul::from_dict"(RCP[const Number] coef, map_basic_basic &&d) nogil + cdef RCP[const Mul] mul_from_dict "SymEngine::Mul::from_dict"(RCP[const Number] coef, map_basic_basic &d) nogil cdef extern from "" namespace "SymEngine": cdef rcp_const_basic pow(rcp_const_basic &a, rcp_const_basic &b) except+ nogil diff --git a/symengine/lib/symengine_wrapper.pxd b/symengine/lib/symengine_wrapper.in.pxd similarity index 99% rename from symengine/lib/symengine_wrapper.pxd rename to symengine/lib/symengine_wrapper.in.pxd index 0728c42bd..3712e17ce 100644 --- a/symengine/lib/symengine_wrapper.pxd +++ b/symengine/lib/symengine_wrapper.in.pxd @@ -6,8 +6,6 @@ from libcpp.vector cimport vector from libcpp.string cimport string from libcpp cimport bool as cppbool -include "config.pxi" - cdef class Basic(object): cdef rcp_const_basic thisptr diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 8d24fb432..7ea7f1de9 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -30,7 +30,7 @@ try: except ImportError: have_numpy = False -include "config.pxi" +# include "config.pxi" class SympifyError(Exception): pass From 07f7342884809f9947a246e0d5db502884e4d0d1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 12 Jun 2023 16:13:48 -0500 Subject: [PATCH 234/314] use is_a template function --- symengine/lib/symengine.pxd | 98 +------------- symengine/lib/symengine_wrapper.in.pyx | 180 ++++++++++++------------- 2 files changed, 96 insertions(+), 182 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 94a667599..2b9cfc3b3 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -110,6 +110,7 @@ cdef extern from "" namespace "SymEngine": cdef struct RCPBasicKeyLess ctypedef set[rcp_const_basic] set_basic "SymEngine::set_basic" ctypedef multiset[rcp_const_basic] multiset_basic "SymEngine::multiset_basic" + cdef cppclass Basic: string __str__() except+ nogil unsigned int hash() except+ nogil @@ -159,96 +160,8 @@ cdef extern from "" namespace "SymEngine": Ptr[RCP[Basic]] outArg(rcp_const_basic &arg) nogil Ptr[RCP[Integer]] outArg_Integer "SymEngine::outArg>"(RCP[const Integer] &arg) nogil - bool is_a_Add "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Mul "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Pow "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Integer "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Rational "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Complex "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Symbol "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Dummy "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Constant "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Infty "SymEngine::is_a"(const Basic &b) nogil - bool is_a_NaN "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Sin "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Cos "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Tan "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Cot "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Csc "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Sec "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ASin "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACos "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ATan "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACot "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACsc "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ASec "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Sinh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Cosh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Tanh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Coth "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Csch "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Sech "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ASinh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACosh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ATanh "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACoth "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ACsch "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ASech "SymEngine::is_a"(const Basic &b) nogil - bool is_a_FunctionSymbol "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Abs "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Max "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Min "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Gamma "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Derivative "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Subs "SymEngine::is_a"(const Basic &b) nogil - bool is_a_PyFunction "SymEngine::is_a"(const Basic &b) nogil - bool is_a_RealDouble "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ComplexDouble "SymEngine::is_a"(const Basic &b) nogil - bool is_a_RealMPFR "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ComplexMPC "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Log "SymEngine::is_a"(const Basic &b) nogil - bool is_a_BooleanAtom "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Equality "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Unequality "SymEngine::is_a"(const Basic &b) nogil - bool is_a_LessThan "SymEngine::is_a"(const Basic &b) nogil - bool is_a_StrictLessThan "SymEngine::is_a"(const Basic &b) nogil - bool is_a_PyNumber "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ATan2 "SymEngine::is_a"(const Basic &b) nogil - bool is_a_LambertW "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Zeta "SymEngine::is_a"(const Basic &b) nogil - bool is_a_DirichletEta "SymEngine::is_a"(const Basic &b) nogil - bool is_a_KroneckerDelta "SymEngine::is_a"(const Basic &b) nogil - bool is_a_LeviCivita "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Erf "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Erfc "SymEngine::is_a"(const Basic &b) nogil - bool is_a_LowerGamma "SymEngine::is_a"(const Basic &b) nogil - bool is_a_UpperGamma "SymEngine::is_a"(const Basic &b) nogil - bool is_a_LogGamma "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Beta "SymEngine::is_a"(const Basic &b) nogil - bool is_a_PolyGamma "SymEngine::is_a"(const Basic &b) nogil - bool is_a_PySymbol "SymEngine::is_a_sub"(const Basic &b) nogil - bool is_a_Sign "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Floor "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Ceiling "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Conjugate "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Interval "SymEngine::is_a"(const Basic &b) nogil - bool is_a_EmptySet "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Reals "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Rationals "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Integers "SymEngine::is_a"(const Basic &b) nogil - bool is_a_UniversalSet "SymEngine::is_a"(const Basic &b) nogil - bool is_a_FiniteSet "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Union "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Complement "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ConditionSet "SymEngine::is_a"(const Basic &b) nogil - bool is_a_ImageSet "SymEngine::is_a"(const Basic &b) nogil - bool is_a_UnevaluatedExpr "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Piecewise "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Contains "SymEngine::is_a"(const Basic &b) nogil - bool is_a_And "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Not "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Or "SymEngine::is_a"(const Basic &b) nogil - bool is_a_Xor "SymEngine::is_a"(const Basic &b) nogil + bool is_a[T] (const Basic &b) nogil + bool is_a_sub[T] (const Basic &b) nogil rcp_const_basic expand(rcp_const_basic &o, bool deep) except+ nogil void as_numer_denom(rcp_const_basic &x, const Ptr[RCP[Basic]] &numer, const Ptr[RCP[Basic]] &denom) nogil void as_real_imag(rcp_const_basic &x, const Ptr[RCP[Basic]] &real, const Ptr[RCP[Basic]] &imag) nogil @@ -650,6 +563,9 @@ cdef extern from "" namespace "SymEngine": cdef cppclass Conjugate(OneArgFunction): pass + cdef cppclass UnevaluatedExpr(OneArgFunction): + pass + cdef cppclass Log(Function): pass @@ -763,7 +679,6 @@ cdef extern from "" namespace "SymEngine": tribool is_positive_definite() nogil tribool is_negative_definite() nogil - bool is_a_DenseMatrix "SymEngine::is_a"(const MatrixBase &b) nogil DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) void inverse_FFLU "SymEngine::inverse_fraction_free_LU"(const DenseMatrix &A, DenseMatrix &B) except+ nogil @@ -890,7 +805,6 @@ cdef extern from "" namespace "SymEngine": rcp_const_basic boolTrue rcp_const_basic boolFalse - bool is_a_Relational(const Basic &b) nogil cdef RCP[const Boolean] Eq(rcp_const_basic &lhs) except+ nogil cdef RCP[const Boolean] Eq(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil cdef RCP[const Boolean] Ne(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 7ea7f1de9..325033e43 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -47,13 +47,13 @@ cpdef void assign_to_capsule(object capsule, object value): cdef object c2py(rcp_const_basic o): cdef Basic r cdef PyObject *obj - if (symengine.is_a_Add(deref(o))): + if (symengine.is_a[symengine.Add](deref(o))): r = Expr.__new__(Add) - elif (symengine.is_a_Mul(deref(o))): + elif (symengine.is_a[symengine.Mul](deref(o))): r = Expr.__new__(Mul) - elif (symengine.is_a_Pow(deref(o))): + elif (symengine.is_a[symengine.Pow](deref(o))): r = Expr.__new__(Pow) - elif (symengine.is_a_Integer(deref(o))): + elif (symengine.is_a[symengine.Integer](deref(o))): if (deref(symengine.rcp_static_cast_Integer(o)).is_zero()): return S.Zero elif (deref(symengine.rcp_static_cast_Integer(o)).is_one()): @@ -61,26 +61,26 @@ cdef object c2py(rcp_const_basic o): elif (deref(symengine.rcp_static_cast_Integer(o)).is_minus_one()): return S.NegativeOne r = Number.__new__(Integer) - elif (symengine.is_a_Rational(deref(o))): + elif (symengine.is_a[symengine.Rational](deref(o))): r = S.Half if (symengine.eq(deref(o), deref(r.thisptr))): return S.Half r = Number.__new__(Rational) - elif (symengine.is_a_Complex(deref(o))): + elif (symengine.is_a[symengine.Complex](deref(o))): r = S.ImaginaryUnit if (symengine.eq(deref(o), deref(r.thisptr))): return S.ImaginaryUnit r = Complex.__new__(Complex) - elif (symengine.is_a_Dummy(deref(o))): + elif (symengine.is_a[symengine.Dummy](deref(o))): r = Dummy.__new__(Dummy) - elif (symengine.is_a_Symbol(deref(o))): - if (symengine.is_a_PySymbol(deref(o))): + elif (symengine.is_a[symengine.Symbol](deref(o))): + if (symengine.is_a_sub[symengine.PySymbol](deref(o))): obj = deref(symengine.rcp_static_cast_PySymbol(o)).get_py_object() result = (obj) Py_XDECREF(obj); return result r = Symbol.__new__(Symbol) - elif (symengine.is_a_Constant(deref(o))): + elif (symengine.is_a[symengine.Constant](deref(o))): r = S.Pi if (symengine.eq(deref(o), deref(r.thisptr))): return S.Pi @@ -97,171 +97,171 @@ cdef object c2py(rcp_const_basic o): if (symengine.eq(deref(o), deref(r.thisptr))): return S.EulerGamma r = Constant.__new__(Constant) - elif (symengine.is_a_Infty(deref(o))): + elif (symengine.is_a[symengine.Infty](deref(o))): if (deref(symengine.rcp_static_cast_Infty(o)).is_positive()): return S.Infinity elif (deref(symengine.rcp_static_cast_Infty(o)).is_negative()): return S.NegativeInfinity return S.ComplexInfinity - elif (symengine.is_a_NaN(deref(o))): + elif (symengine.is_a[symengine.NaN](deref(o))): return S.NaN - elif (symengine.is_a_PyFunction(deref(o))): + elif (symengine.is_a[symengine.PyFunction](deref(o))): r = PyFunction.__new__(PyFunction) - elif (symengine.is_a_FunctionSymbol(deref(o))): + elif (symengine.is_a[symengine.FunctionSymbol](deref(o))): r = FunctionSymbol.__new__(FunctionSymbol) - elif (symengine.is_a_Abs(deref(o))): + elif (symengine.is_a[symengine.Abs](deref(o))): r = Function.__new__(Abs) - elif (symengine.is_a_Max(deref(o))): + elif (symengine.is_a[symengine.Max](deref(o))): r = Function.__new__(Max) - elif (symengine.is_a_Min(deref(o))): + elif (symengine.is_a[symengine.Min](deref(o))): r = Function.__new__(Min) - elif (symengine.is_a_BooleanAtom(deref(o))): + elif (symengine.is_a[symengine.BooleanAtom](deref(o))): if (deref(symengine.rcp_static_cast_BooleanAtom(o)).get_val()): return S.true return S.false - elif (symengine.is_a_Equality(deref(o))): + elif (symengine.is_a[symengine.Equality](deref(o))): r = Relational.__new__(Equality) - elif (symengine.is_a_Unequality(deref(o))): + elif (symengine.is_a[symengine.Unequality](deref(o))): r = Relational.__new__(Unequality) - elif (symengine.is_a_LessThan(deref(o))): + elif (symengine.is_a[symengine.LessThan](deref(o))): r = Relational.__new__(LessThan) - elif (symengine.is_a_StrictLessThan(deref(o))): + elif (symengine.is_a[symengine.StrictLessThan](deref(o))): r = Relational.__new__(StrictLessThan) - elif (symengine.is_a_Gamma(deref(o))): + elif (symengine.is_a[symengine.Gamma](deref(o))): r = Function.__new__(Gamma) - elif (symengine.is_a_Derivative(deref(o))): + elif (symengine.is_a[symengine.Derivative](deref(o))): r = Expr.__new__(Derivative) - elif (symengine.is_a_Subs(deref(o))): + elif (symengine.is_a[symengine.Subs](deref(o))): r = Expr.__new__(Subs) - elif (symengine.is_a_RealDouble(deref(o))): + elif (symengine.is_a[symengine.RealDouble](deref(o))): r = Number.__new__(RealDouble) - elif (symengine.is_a_ComplexDouble(deref(o))): + elif (symengine.is_a[symengine.ComplexDouble](deref(o))): r = ComplexDouble.__new__(ComplexDouble) - elif (symengine.is_a_RealMPFR(deref(o))): + elif (symengine.is_a[symengine.RealMPFR](deref(o))): r = Number.__new__(RealMPFR) - elif (symengine.is_a_ComplexMPC(deref(o))): + elif (symengine.is_a[symengine.ComplexMPC](deref(o))): r = ComplexMPC.__new__(ComplexMPC) - elif (symengine.is_a_Log(deref(o))): + elif (symengine.is_a[symengine.Log](deref(o))): r = Function.__new__(Log) - elif (symengine.is_a_Sin(deref(o))): + elif (symengine.is_a[symengine.Sin](deref(o))): r = Function.__new__(Sin) - elif (symengine.is_a_Cos(deref(o))): + elif (symengine.is_a[symengine.Cos](deref(o))): r = Function.__new__(Cos) - elif (symengine.is_a_Tan(deref(o))): + elif (symengine.is_a[symengine.Tan](deref(o))): r = Function.__new__(Tan) - elif (symengine.is_a_Cot(deref(o))): + elif (symengine.is_a[symengine.Cot](deref(o))): r = Function.__new__(Cot) - elif (symengine.is_a_Csc(deref(o))): + elif (symengine.is_a[symengine.Csc](deref(o))): r = Function.__new__(Csc) - elif (symengine.is_a_Sec(deref(o))): + elif (symengine.is_a[symengine.Sec](deref(o))): r = Function.__new__(Sec) - elif (symengine.is_a_ASin(deref(o))): + elif (symengine.is_a[symengine.ASin](deref(o))): r = Function.__new__(ASin) - elif (symengine.is_a_ACos(deref(o))): + elif (symengine.is_a[symengine.ACos](deref(o))): r = Function.__new__(ACos) - elif (symengine.is_a_ATan(deref(o))): + elif (symengine.is_a[symengine.ATan](deref(o))): r = Function.__new__(ATan) - elif (symengine.is_a_ACot(deref(o))): + elif (symengine.is_a[symengine.ACot](deref(o))): r = Function.__new__(ACot) - elif (symengine.is_a_ACsc(deref(o))): + elif (symengine.is_a[symengine.ACsc](deref(o))): r = Function.__new__(ACsc) - elif (symengine.is_a_ASec(deref(o))): + elif (symengine.is_a[symengine.ASec](deref(o))): r = Function.__new__(ASec) - elif (symengine.is_a_Sinh(deref(o))): + elif (symengine.is_a[symengine.Sinh](deref(o))): r = Function.__new__(Sinh) - elif (symengine.is_a_Cosh(deref(o))): + elif (symengine.is_a[symengine.Cosh](deref(o))): r = Function.__new__(Cosh) - elif (symengine.is_a_Tanh(deref(o))): + elif (symengine.is_a[symengine.Tanh](deref(o))): r = Function.__new__(Tanh) - elif (symengine.is_a_Coth(deref(o))): + elif (symengine.is_a[symengine.Coth](deref(o))): r = Function.__new__(Coth) - elif (symengine.is_a_Csch(deref(o))): + elif (symengine.is_a[symengine.Csch](deref(o))): r = Function.__new__(Csch) - elif (symengine.is_a_Sech(deref(o))): + elif (symengine.is_a[symengine.Sech](deref(o))): r = Function.__new__(Sech) - elif (symengine.is_a_ASinh(deref(o))): + elif (symengine.is_a[symengine.ASinh](deref(o))): r = Function.__new__(ASinh) - elif (symengine.is_a_ACosh(deref(o))): + elif (symengine.is_a[symengine.ACosh](deref(o))): r = Function.__new__(ACosh) - elif (symengine.is_a_ATanh(deref(o))): + elif (symengine.is_a[symengine.ATanh](deref(o))): r = Function.__new__(ATanh) - elif (symengine.is_a_ACoth(deref(o))): + elif (symengine.is_a[symengine.ACoth](deref(o))): r = Function.__new__(ACoth) - elif (symengine.is_a_ACsch(deref(o))): + elif (symengine.is_a[symengine.ACsch](deref(o))): r = Function.__new__(ACsch) - elif (symengine.is_a_ASech(deref(o))): + elif (symengine.is_a[symengine.ASech](deref(o))): r = Function.__new__(ASech) - elif (symengine.is_a_ATan2(deref(o))): + elif (symengine.is_a[symengine.ATan2](deref(o))): r = Function.__new__(ATan2) - elif (symengine.is_a_LambertW(deref(o))): + elif (symengine.is_a[symengine.LambertW](deref(o))): r = Function.__new__(LambertW) - elif (symengine.is_a_Zeta(deref(o))): + elif (symengine.is_a[symengine.Zeta](deref(o))): r = Function.__new__(zeta) - elif (symengine.is_a_DirichletEta(deref(o))): + elif (symengine.is_a[symengine.Dirichlet_eta](deref(o))): r = Function.__new__(dirichlet_eta) - elif (symengine.is_a_KroneckerDelta(deref(o))): + elif (symengine.is_a[symengine.KroneckerDelta](deref(o))): r = Function.__new__(KroneckerDelta) - elif (symengine.is_a_LeviCivita(deref(o))): + elif (symengine.is_a[symengine.LeviCivita](deref(o))): r = Function.__new__(LeviCivita) - elif (symengine.is_a_Erf(deref(o))): + elif (symengine.is_a[symengine.Erf](deref(o))): r = Function.__new__(erf) - elif (symengine.is_a_Erfc(deref(o))): + elif (symengine.is_a[symengine.Erfc](deref(o))): r = Function.__new__(erfc) - elif (symengine.is_a_LowerGamma(deref(o))): + elif (symengine.is_a[symengine.LowerGamma](deref(o))): r = Function.__new__(lowergamma) - elif (symengine.is_a_UpperGamma(deref(o))): + elif (symengine.is_a[symengine.UpperGamma](deref(o))): r = Function.__new__(uppergamma) - elif (symengine.is_a_LogGamma(deref(o))): + elif (symengine.is_a[symengine.LogGamma](deref(o))): r = Function.__new__(loggamma) - elif (symengine.is_a_Beta(deref(o))): + elif (symengine.is_a[symengine.Beta](deref(o))): r = Function.__new__(beta) - elif (symengine.is_a_PolyGamma(deref(o))): + elif (symengine.is_a[symengine.PolyGamma](deref(o))): r = Function.__new__(polygamma) - elif (symengine.is_a_Sign(deref(o))): + elif (symengine.is_a[symengine.Sign](deref(o))): r = Function.__new__(sign) - elif (symengine.is_a_Floor(deref(o))): + elif (symengine.is_a[symengine.Floor](deref(o))): r = Function.__new__(floor) - elif (symengine.is_a_Ceiling(deref(o))): + elif (symengine.is_a[symengine.Ceiling](deref(o))): r = Function.__new__(ceiling) - elif (symengine.is_a_Conjugate(deref(o))): + elif (symengine.is_a[symengine.Conjugate](deref(o))): r = Function.__new__(conjugate) - elif (symengine.is_a_PyNumber(deref(o))): + elif (symengine.is_a[symengine.PyNumber](deref(o))): r = PyNumber.__new__(PyNumber) - elif (symengine.is_a_Piecewise(deref(o))): + elif (symengine.is_a[symengine.Piecewise](deref(o))): r = Function.__new__(Piecewise) - elif (symengine.is_a_Contains(deref(o))): + elif (symengine.is_a[symengine.Contains](deref(o))): r = Boolean.__new__(Contains) - elif (symengine.is_a_Interval(deref(o))): + elif (symengine.is_a[symengine.Interval](deref(o))): r = Set.__new__(Interval) - elif (symengine.is_a_EmptySet(deref(o))): + elif (symengine.is_a[symengine.EmptySet](deref(o))): r = Set.__new__(EmptySet) - elif (symengine.is_a_Reals(deref(o))): + elif (symengine.is_a[symengine.Reals](deref(o))): r = Set.__new__(Reals) - elif (symengine.is_a_Integers(deref(o))): + elif (symengine.is_a[symengine.Integers](deref(o))): r = Set.__new__(Integers) - elif (symengine.is_a_Rationals(deref(o))): + elif (symengine.is_a[symengine.Rationals](deref(o))): r = Set.__new__(Rationals) - elif (symengine.is_a_UniversalSet(deref(o))): + elif (symengine.is_a[symengine.UniversalSet](deref(o))): r = Set.__new__(UniversalSet) - elif (symengine.is_a_FiniteSet(deref(o))): + elif (symengine.is_a[symengine.FiniteSet](deref(o))): r = Set.__new__(FiniteSet) - elif (symengine.is_a_Union(deref(o))): + elif (symengine.is_a[symengine.Union](deref(o))): r = Set.__new__(Union) - elif (symengine.is_a_Complement(deref(o))): + elif (symengine.is_a[symengine.Complement](deref(o))): r = Set.__new__(Complement) - elif (symengine.is_a_ConditionSet(deref(o))): + elif (symengine.is_a[symengine.ConditionSet](deref(o))): r = Set.__new__(ConditionSet) - elif (symengine.is_a_ImageSet(deref(o))): + elif (symengine.is_a[symengine.ImageSet](deref(o))): r = Set.__new__(ImageSet) - elif (symengine.is_a_And(deref(o))): + elif (symengine.is_a[symengine.And](deref(o))): r = Boolean.__new__(And) - elif (symengine.is_a_Not(deref(o))): + elif (symengine.is_a[symengine.Not](deref(o))): r = Boolean.__new__(Not) - elif (symengine.is_a_Or(deref(o))): + elif (symengine.is_a[symengine.Or](deref(o))): r = Boolean.__new__(Or) - elif (symengine.is_a_Xor(deref(o))): + elif (symengine.is_a[symengine.Xor](deref(o))): r = Boolean.__new__(Xor) - elif (symengine.is_a_UnevaluatedExpr(deref(o))): + elif (symengine.is_a[symengine.UnevaluatedExpr](deref(o))): r = Function.__new__(UnevaluatedExpr) else: raise Exception("Unsupported SymEngine class.") From d7c6e4f4abc07e38bb0aaa8bf170b10cda703989 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 12 Jun 2023 16:35:55 -0500 Subject: [PATCH 235/314] use move template --- symengine/lib/symengine.pxd | 7 ------- symengine/lib/symengine_wrapper.in.pyx | 9 +++++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 2b9cfc3b3..ee96731ba 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -827,13 +827,6 @@ cdef extern from "" namespace "SymEngine": cdef RCP[const Boolean] contains(rcp_const_basic &expr, RCP[const Set] &set) nogil -cdef extern from "" namespace "std": - cdef integer_class std_move_mpz "std::move" (integer_class) nogil - cdef mpfr_class std_move_mpfr "std::move" (mpfr_class) nogil - cdef mpc_class std_move_mpc "std::move" (mpc_class) nogil - cdef map_basic_basic std_move_map_basic_basic "std::move" (map_basic_basic) nogil - cdef PiecewiseVec std_move_PiecewiseVec "std::move" (PiecewiseVec) nogil - cdef extern from "" namespace "SymEngine": cdef cppclass EvalfDomain: pass diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 325033e43..0ac4cb0ac 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -5,6 +5,7 @@ from symengine cimport (RCP, pair, map_basic_basic, umap_int_basic, rcp_const_basic, std_pair_short_rcp_const_basic, rcp_const_seriescoeffinterface, CRCPBasic, tribool, is_indeterminate, is_true, is_false) from libcpp cimport bool as cppbool +from libcpp.utility cimport move from libcpp.string cimport string from libcpp.vector cimport vector from cpython cimport PyObject, Py_XINCREF, Py_XDECREF, \ @@ -2035,7 +2036,7 @@ class RealMPFR(Float): cdef string i_ = str(i).encode("utf-8") cdef symengine.mpfr_class m m = symengine.mpfr_class(i_, prec, base) - return c2py(symengine.real_mpfr(symengine.std_move_mpfr(m))) + return c2py(symengine.real_mpfr(move[symengine.mpfr](m))) def get_prec(Basic self): return Integer(deref(symengine.rcp_static_cast_RealMPFR(self.thisptr)).get_prec()) @@ -2064,7 +2065,7 @@ cdef class ComplexMPC(ComplexBase): return cdef string i_ = ("(" + str(i) + " " + str(j) + ")").encode("utf-8") cdef symengine.mpc_class m = symengine.mpc_class(i_, prec, base) - self.thisptr = symengine.complex_mpc(symengine.std_move_mpc(m)) + self.thisptr = symengine.complex_mpc(move[symengine.mpc](m)) def _sympy_(self): import sympy @@ -2330,7 +2331,7 @@ class Mul(AssocOp): d = collections.defaultdict(int) d[c2py(symengine.mul_from_dict(\ (one), - symengine.std_move_map_basic_basic(dict)))] =\ + move[symengine.map_basic_basic](dict)))] =\ c2py(deref(X).get_coef()) return d @@ -5457,7 +5458,7 @@ def piecewise(*v): p.first = e.thisptr p.second = symengine.rcp_static_cast_Boolean(b.thisptr) vec.push_back(p) - return c2py(symengine.piecewise(symengine.std_move_PiecewiseVec(vec))) + return c2py(symengine.piecewise(move[symengine.PiecewiseVec](vec))) def interval(start, end, left_open=False, right_open=False): From 2798227928c572d7a72e080c4672f7faf01cae84 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 16:03:00 -0500 Subject: [PATCH 236/314] remmina --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 30da13f3a..cabc616b8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -132,5 +132,5 @@ test_script: # Enable this to be able to login to the build worker. You can use the # `remmina` program in Ubuntu, use the login information that the line below # prints into the log. -# #on_finish: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +on_finish: +- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 4816650f697cb9bf6c752f39cfb56d9e0d1087ad Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 16:40:25 -0500 Subject: [PATCH 237/314] Fix compilation --- symengine/lib/symengine_wrapper.in.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 0ac4cb0ac..c368355f2 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -2036,7 +2036,7 @@ class RealMPFR(Float): cdef string i_ = str(i).encode("utf-8") cdef symengine.mpfr_class m m = symengine.mpfr_class(i_, prec, base) - return c2py(symengine.real_mpfr(move[symengine.mpfr](m))) + return c2py(symengine.real_mpfr(move[symengine.mpfr_class](m))) def get_prec(Basic self): return Integer(deref(symengine.rcp_static_cast_RealMPFR(self.thisptr)).get_prec()) @@ -2065,7 +2065,7 @@ cdef class ComplexMPC(ComplexBase): return cdef string i_ = ("(" + str(i) + " " + str(j) + ")").encode("utf-8") cdef symengine.mpc_class m = symengine.mpc_class(i_, prec, base) - self.thisptr = symengine.complex_mpc(move[symengine.mpc](m)) + self.thisptr = symengine.complex_mpc(move[symengine.mpc_class](m)) def _sympy_(self): import sympy From 17b7c89949da37a38cd4aa0b4d891b5c5b56bf03 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 17:38:19 -0500 Subject: [PATCH 238/314] Fix output --- symengine/lib/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index d37d94dca..34e38a463 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -11,7 +11,7 @@ add_custom_command( ${PROJECT_SOURCE_DIR}/cmake/preprocess.py COMMAND ${PYTHON_BIN} ${PROJECT_SOURCE_DIR}/cmake/preprocess.py ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd - ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.pxd + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pxd HAVE_SYMENGINE_MPFR=${HAVE_SYMENGINE_MPFR} HAVE_SYMENGINE_MPC=${HAVE_SYMENGINE_MPC} HAVE_SYMENGINE_PIRANHA=${HAVE_SYMENGINE_PIRANHA} @@ -23,11 +23,12 @@ add_custom_command( add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pyx DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pyx - ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd + ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pxd + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pxd ${PROJECT_SOURCE_DIR}/cmake/preprocess.py COMMAND ${PYTHON_BIN} ${PROJECT_SOURCE_DIR}/cmake/preprocess.py ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.in.pyx - ${CMAKE_CURRENT_SOURCE_DIR}/symengine_wrapper.pyx + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pyx HAVE_SYMENGINE_MPFR=${HAVE_SYMENGINE_MPFR} HAVE_SYMENGINE_MPC=${HAVE_SYMENGINE_MPC} HAVE_SYMENGINE_PIRANHA=${HAVE_SYMENGINE_PIRANHA} From 41d9d11cc4ab35f9ee485ebcf3951d39196aabc9 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 17:38:30 -0500 Subject: [PATCH 239/314] Revert "remmina" This reverts commit a5974ea630b267f7bf8f97b2ce5f007c9eb096fc. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cabc616b8..30da13f3a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -132,5 +132,5 @@ test_script: # Enable this to be able to login to the build worker. You can use the # `remmina` program in Ubuntu, use the login information that the line below # prints into the log. -on_finish: -- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +# #on_finish: +#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 2315247f6acc8fbc41d6c2adfebb8b77c5f0aa4b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 17:39:23 -0500 Subject: [PATCH 240/314] remove symengine/lib/config.pxi.in --- symengine/lib/config.pxi.in | 7 ------- symengine/lib/symengine_wrapper.in.pyx | 1 - 2 files changed, 8 deletions(-) delete mode 100644 symengine/lib/config.pxi.in diff --git a/symengine/lib/config.pxi.in b/symengine/lib/config.pxi.in deleted file mode 100644 index 5ae5675f2..000000000 --- a/symengine/lib/config.pxi.in +++ /dev/null @@ -1,7 +0,0 @@ -DEF HAVE_SYMENGINE_MPFR = ${HAVE_SYMENGINE_MPFR} -DEF HAVE_SYMENGINE_MPC = ${HAVE_SYMENGINE_MPC} -DEF HAVE_SYMENGINE_PIRANHA = ${HAVE_SYMENGINE_PIRANHA} -DEF HAVE_SYMENGINE_FLINT = ${HAVE_SYMENGINE_FLINT} -DEF HAVE_SYMENGINE_LLVM = ${HAVE_SYMENGINE_LLVM} -DEF HAVE_SYMENGINE_LLVM_LONG_DOUBLE = ${HAVE_SYMENGINE_LLVM_LONG_DOUBLE} -DEF ENDIF = 1 diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index c368355f2..e10d14768 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -31,7 +31,6 @@ try: except ImportError: have_numpy = False -# include "config.pxi" class SympifyError(Exception): pass From c3d89d406aae8c2dbe577d403efbcd3a0fa3eaa7 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 17:55:25 -0500 Subject: [PATCH 241/314] fix install --- symengine/lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/CMakeLists.txt b/symengine/lib/CMakeLists.txt index 34e38a463..7683d4aa8 100644 --- a/symengine/lib/CMakeLists.txt +++ b/symengine/lib/CMakeLists.txt @@ -60,7 +60,7 @@ install(TARGETS symengine_wrapper ) install(FILES symengine.pxd - symengine_wrapper.pxd + ${CMAKE_CURRENT_BINARY_DIR}/symengine_wrapper.pxd pywrapper.h DESTINATION ${PY_PATH} ) From 33ab529b783f56228a4373165a5c48e7cc9a7e98 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 15 Jun 2023 19:47:05 -0500 Subject: [PATCH 242/314] better names for CYTHON_ADD_MODULE_PYX args --- cmake/FindCython.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 073e561d1..beac6c568 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -63,13 +63,13 @@ if(NOT CYTHON_INCLUDE_DIRECTORIES) endif(NOT CYTHON_INCLUDE_DIRECTORIES) # Cythonizes the .pyx files into .cpp file (but doesn't compile it) -macro(CYTHON_ADD_MODULE_PYX name filename) +macro(CYTHON_ADD_MODULE_PYX cpp_name pyx_name) # Allow the user to specify dependencies as optional arguments set(DEPENDS ${DEPENDS} ${ARGN}) add_custom_command( - OUTPUT ${name} + OUTPUT ${cpp_name} COMMAND ${CYTHON_BIN} - ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${name} ${filename} - DEPENDS ${DEPENDS} ${filename} - COMMENT "Cythonizing ${filename}") + ARGS ${CYTHON_FLAGS} -I ${CYTHON_INCLUDE_DIRECTORIES} -o ${cpp_name} ${pyx_name} + DEPENDS ${DEPENDS} ${pyx_name} + COMMENT "Cythonizing ${pyx_name}") endmacro(CYTHON_ADD_MODULE_PYX) From a22115c91779e8fe356d4923e0f7da915942cd37 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 1 Oct 2023 18:28:40 +0200 Subject: [PATCH 243/314] ci: Add Python 3.11 to the testing * #427 * #425 --- .github/workflows/ci.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4916921cc..324d6ad2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,13 @@ jobs: fail-fast: false matrix: include: + - BUILD_TYPE: Debug + WITH_BFD: yes + PYTHON_VERSION: '3.12' + TEST_SYMPY: yes + OS: ubuntu-20.04 + CC: gcc + - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: '3.11' @@ -138,7 +145,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build and test symengine shell: bash From 701366408a8fa4f220fe77516d0eb39bdf4049fc Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 2 Oct 2023 17:32:36 -0500 Subject: [PATCH 244/314] Require python>=3.8 and bump version to 0.11 --- setup.py | 11 ++++++----- symengine/__init__.py | 4 ++-- symengine_version.txt | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 88f2d1c7b..1c5e92077 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,8 @@ import platform # Make sure the system has the right Python version. -if sys.version_info[:2] < (3, 7): - print("SymEngine requires Python 3.7 or newer. " +if sys.version_info[:2] < (3, 8): + print("SymEngine requires Python 3.8 or newer. " "Python %d.%d detected" % sys.version_info[:2]) sys.exit(-1) @@ -222,7 +222,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.10.0", + version="0.11.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, @@ -230,7 +230,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", - python_requires='>=3.7,<4', + python_requires='>=3.8,<4', zip_safe=False, packages=['symengine', 'symengine.lib', 'symengine.tests'], cmdclass = cmdclass, @@ -241,9 +241,10 @@ def finalize_options(self): 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Scientific/Engineering :: Physics', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ] ) diff --git a/symengine/__init__.py b/symengine/__init__.py index fa72ded4f..b6002a281 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -1,7 +1,7 @@ import os import sys -if sys.version_info >= (3, 8, 0) and sys.platform == 'win32' \ +if sys.platform == 'win32' \ and 'SYMENGINE_PY_ADD_PATH_TO_SEARCH_DIRS' in os.environ: for directory in os.environ['PATH'].split(';'): if os.path.isdir(directory): @@ -63,7 +63,7 @@ def __getattr__(name): raise AttributeError(f"module 'symengine' has no attribute '{name}'") -__version__ = "0.10.0" +__version__ = "0.11.0" # To not expose internals diff --git a/symengine_version.txt b/symengine_version.txt index c91125db5..4f7638fd9 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.10.1 +v0.11.1 From 2a3f762bf1c9e5e5e92efbbb1a824c8f3e29e915 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 2 Oct 2023 18:17:17 -0500 Subject: [PATCH 245/314] update appveyor --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 30da13f3a..cb17323e9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,14 +24,14 @@ environment: CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 37-x64 + PYTHON_VERSION: 39-x64 WITH_NUMPY: no - BUILD_TYPE: "Release" COMPILER: MinGW-w64 - PYTHON_VERSION: 37-x64 + PYTHON_VERSION: 39-x64 - BUILD_TYPE: "Debug" COMPILER: MinGW-w64 - PYTHON_VERSION: 37-x64 + PYTHON_VERSION: 39-x64 WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 From 2bdf33ff9c8b546ce883dcb944a771ad72f9494b Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 2 Oct 2023 18:50:24 -0500 Subject: [PATCH 246/314] Fix GHA yaml --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 324d6ad2c..6993dd9e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,13 +37,13 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' BUILD_SHARED_LIBS: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' WITH_MPFR: yes INTEGER_CLASS: gmpxx WITH_NUMPY: no @@ -91,7 +91,7 @@ jobs: CC: clang - BUILD_TYPE: Release - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' WITH_NUMPY: yes OS: ubuntu-20.04 CC: clang @@ -108,7 +108,7 @@ jobs: EXTRA_APT_PACKAGES: 'llvm-14' - BUILD_TYPE: Debug - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' WITH_SCIPY: yes WITH_LLVM: 5.0 OS: macos-latest @@ -121,7 +121,7 @@ jobs: CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' WITH_NUMPY: no OS: macos-latest CC: gcc @@ -183,6 +183,7 @@ jobs: WITH_MPC: ${{ matrix.WITH_MPC }} MAKEFLAGS: ${{ matrix.MAKEFLAGS }} BUILD_SHARED_LIBS: ${{ matrix.BUILD_SHARED_LIBS }} + PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} - name: Deploy Documentation if: ${{ (github.ref == 'refs/heads/main' && github.repository == 'Symengine/symengine.py') || (github.ref == 'refs/heads/master' && github.repository == 'Symengine/symengine.py')}} From 7e7b9df9d11b326fc450c7faf7097905c39967fe Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Oct 2023 04:01:56 -0500 Subject: [PATCH 247/314] Fix appveyor tests --- appveyor.yml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cb17323e9..69467fd4d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,6 @@ version: '{build}' -# Uncomment this to enable the fast build environment if your account does not -# support it automatically: -#os: Visual Studio 2015 RC +image: Visual Studio 2019 environment: global: @@ -16,7 +14,6 @@ environment: CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 WITH_MPFR: yes WITH_MPC: yes - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" @@ -45,7 +42,6 @@ environment: PLATFORM: "x64" PYTHON_VERSION: 310-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 WITH_MPFR: yes WITH_MPC: yes WITH_LLVM: yes @@ -103,15 +99,16 @@ install: - if [%COMPILER%]==[MinGW] set "CMAKE_GENERATOR=MinGW Makefiles" - if [%COMPILER%]==[MinGW-w64] set "CMAKE_GENERATOR=MinGW Makefiles" -- if [%COMPILER%]==[MSVC15] cmake -DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library .. -- if [%COMPILER%]==[MinGW] cmake -DCMAKE_PREFIX_PATH=C:\MinGW -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. -- if [%COMPILER%]==[MinGW-w64] cmake -DCMAKE_PREFIX_PATH=C:\mingw64 -DCMAKE_BUILD_TYPE=%BUILD_TYPE% .. +- if [%COMPILER%]==[MSVC15] set "CMAKE_ARGS=-DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\\Library" +- if [%COMPILER%]==[MinGW] set "CMAKE_ARGS=-DCMAKE_PREFIX_PATH=C:\MinGW -DCMAKE_BUILD_TYPE=%BUILD_TYPE%" +- if [%COMPILER%]==[MinGW-w64] set "CMAKE_ARGS=-DCMAKE_PREFIX_PATH=C:\mingw64 -DCMAKE_BUILD_TYPE=%BUILD_TYPE%" -- if [%WITH_MPFR%]==[yes] cmake -DWITH_MPFR=yes .. -- if [%WITH_MPC%]==[yes] cmake -DWITH_MPC=yes .. -- if [%WITH_LLVM%]==[yes] cmake -DWITH_LLVM=yes -DMSVC_USE_MT=no .. +- if [%WITH_MPFR%]==[yes] set "CMAKE_ARGS=%CMAKE_ARGS% -DWITH_MPFR=yes" +- if [%WITH_MPC%]==[yes] set "CMAKE_ARGS=%CMAKE_ARGS% -DWITH_MPC=yes" +- if [%WITH_LLVM%]==[yes] set "CMAKE_ARGS=%CMAKE_ARGS% -DWITH_LLVM=yes -DMSVC_USE_MT=no" -- cmake -DBUILD_SHARED_LIBS=yes -DBUILD_TESTS=no -DBUILD_BENCHMARKS=no -DCMAKE_INSTALL_PREFIX=C:\symengine .. +- echo "CMAKE_ARGS: %CMAKE_ARGS%" +- cmake %CMAKE_ARGS% -DBUILD_SHARED_LIBS=yes -DBUILD_TESTS=no -DBUILD_BENCHMARKS=no -DCMAKE_INSTALL_PREFIX=C:\symengine .. - cmake --build . --config %BUILD_TYPE% --target install - cd ../../ From 557c231a9c8bcc13ef0aae0ee34195f09b693d59 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Oct 2023 04:02:53 -0500 Subject: [PATCH 248/314] Fix syntax --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 69467fd4d..3c5b227b9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: '{build}' -image: Visual Studio 2019 +image: "Visual Studio 2019" environment: global: From 26aeb30336f3538ed0ee7be8dd0177efb03561e0 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 7 Oct 2023 04:04:04 -0500 Subject: [PATCH 249/314] Try to fix yaml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3c5b227b9..40fd5ab36 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -107,7 +107,7 @@ install: - if [%WITH_MPC%]==[yes] set "CMAKE_ARGS=%CMAKE_ARGS% -DWITH_MPC=yes" - if [%WITH_LLVM%]==[yes] set "CMAKE_ARGS=%CMAKE_ARGS% -DWITH_LLVM=yes -DMSVC_USE_MT=no" -- echo "CMAKE_ARGS: %CMAKE_ARGS%" +- echo "CMAKE_ARGS=%CMAKE_ARGS%" - cmake %CMAKE_ARGS% -DBUILD_SHARED_LIBS=yes -DBUILD_TESTS=no -DBUILD_BENCHMARKS=no -DCMAKE_INSTALL_PREFIX=C:\symengine .. - cmake --build . --config %BUILD_TYPE% --target install From 696676efb221948960e68e23f359d91edb4510a6 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Oct 2023 21:01:23 -0500 Subject: [PATCH 250/314] Update for new requirements --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 40fd5ab36..0966b24a4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "Win32" - PYTHON_VERSION: 37 + PYTHON_VERSION: 39 CONDA_INSTALL_LOCN: C:\\Miniconda36 WITH_MPFR: yes WITH_MPC: yes @@ -61,7 +61,7 @@ install: - if [%COMPILER%]==[MSVC15] echo %PATH% - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 -- if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=3.9 +- if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=4.0 - if [%COMPILER%]==[MinGW] set "PATH=C:\MinGW\bin;%PATH%" - if [%COMPILER%]==[MinGW] mingw-get update From ea09366f72de6397e9c66db10f5dd0373202b7c8 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Oct 2023 21:17:05 -0500 Subject: [PATCH 251/314] Install cython with wheels --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0966b24a4..bde013d24 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,8 +83,7 @@ install: - set "PATH=C:\Python%PYTHON_VERSION%;C:\Python%PYTHON_VERSION%\Scripts;%PATH%" - echo %PATH% -- pip install nose pytest -- pip install --install-option="--no-cython-compile" cython +- pip install nose pytest cython - if NOT [%WITH_NUMPY%]==[no] pip install numpy - if NOT [%WITH_SYMPY%]==[no] pip install sympy From 946e6612194cd0d2f7883e080061afe994c6d6ec Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 31 Oct 2023 07:41:11 -0500 Subject: [PATCH 252/314] Disable MinGW-w64 builds for now This was using MSVC built python with a non-UCRT based MinGW-w64 and it was a hack anyway. To get it properly working we probably need a MinGW-w64 based python or a UCRT based MinGW-w64. --- appveyor.yml | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index bde013d24..05e6b6ebb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,17 +19,29 @@ environment: PLATFORM: "x64" PYTHON_VERSION: 38-x64 CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 - - BUILD_TYPE: "Debug" - COMPILER: MinGW-w64 - PYTHON_VERSION: 39-x64 - WITH_NUMPY: no - BUILD_TYPE: "Release" - COMPILER: MinGW-w64 - PYTHON_VERSION: 39-x64 - - BUILD_TYPE: "Debug" - COMPILER: MinGW-w64 + COMPILER: MSVC15 + PLATFORM: "x64" PYTHON_VERSION: 39-x64 WITH_SYMPY: no + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "x64" + PYTHON_VERSION: 311-x64 + WITH_NUMPY: no + CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + #- BUILD_TYPE: "Debug" + # COMPILER: MinGW-w64 + # PYTHON_VERSION: 39-x64 + # WITH_NUMPY: no + #- BUILD_TYPE: "Release" + # COMPILER: MinGW-w64 + # PYTHON_VERSION: 39-x64 + #- BUILD_TYPE: "Debug" + # COMPILER: MinGW-w64 + # PYTHON_VERSION: 39-x64 + # WITH_SYMPY: no - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "Win32" From 1d65600ec6197b3969e1399b807711e3328c17e3 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 5 Nov 2023 09:35:08 +0545 Subject: [PATCH 253/314] README.md: Set minimum Python >= 3.8 https://github.com/symengine/symengine.py/blob/810ef475f34388bb63ae366bf6b238762b5c2d62/setup.py#L8 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6fc3742f..847af7d6f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ optionally, you may choose to install an early [developer preview](https://githu Install prerequisites. CMake >= 2.8.12 - Python3 >= 3.7 + Python3 >= 3.8 Cython >= 0.29.24 SymEngine >= 0.7.0 From fd81a6c907ef3ac0cef9d5fef0016b8ff57ac0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 17 Nov 2023 21:20:53 +0100 Subject: [PATCH 254/314] add DenseMatrixBase.__abs__ --- symengine/lib/symengine_wrapper.in.pyx | 3 +++ symengine/tests/test_matrices.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index e10d14768..8974b7d99 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -3529,6 +3529,9 @@ cdef class DenseMatrixBase(MatrixBase): def __neg__(self): return self.mul_scalar(-1) + def __abs__(self): + return self.applyfunc(abs) + def __getitem__(self, item): if isinstance(item, slice): if (self.ncols() == 0 or self.nrows() == 0): diff --git a/symengine/tests/test_matrices.py b/symengine/tests/test_matrices.py index de9975299..9733e10b1 100644 --- a/symengine/tests/test_matrices.py +++ b/symengine/tests/test_matrices.py @@ -286,11 +286,13 @@ def test_mul_scalar(): assert a * A == DenseMatrix(2, 2, [a, 2*a, 3*a, 4*a]) -def test_neg(): +def test_neg_abs(): A = DenseMatrix(2, 3, [1, 2, 3, 4, 5, 6]) B = DenseMatrix(2, 3, [-1, -2, -3, -4, -5, -6]) assert -A == B + assert A == abs(B) + def test_sub(): A = DenseMatrix(2, 2, [1, 2, 3, 4]) From 42ee1435fd7a91c91aabbd7aedaff8c3eafd1853 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 20 Jan 2024 13:59:15 -0600 Subject: [PATCH 255/314] Implement unary addition --- symengine/lib/symengine_wrapper.in.pyx | 3 +++ symengine/tests/test_arit.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 8974b7d99..71b4734b4 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -951,6 +951,9 @@ cdef class Basic(object): def __neg__(Basic self not None): return c2py(symengine.neg(self.thisptr)) + def __pos__(self): + return self + def __abs__(Basic self not None): return c2py(symengine.abs(self.thisptr)) diff --git a/symengine/tests/test_arit.py b/symengine/tests/test_arit.py index e6ff192b7..931b8adb5 100644 --- a/symengine/tests/test_arit.py +++ b/symengine/tests/test_arit.py @@ -95,6 +95,12 @@ def test_arit8(): assert (2*y**(-2*x**2)) * (3*y**(2*x**2)) == 6 +def test_unary(): + x = Symbol("x") + assert -x == 0 - x + assert +x == x + + def test_expand1(): x = Symbol("x") y = Symbol("y") From a7136d7890d8fbd439719bccfbc6c7b4ede70e9d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 22 Jan 2024 21:38:36 -0600 Subject: [PATCH 256/314] Raise error on wrong number of arguments to Function --- symengine/lib/symengine_wrapper.in.pyx | 11 +++++++++-- symengine/tests/test_functions.py | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 8974b7d99..4fdc0f9c2 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -2412,8 +2412,15 @@ class Pow(Expr): class Function(Expr): def __new__(cls, *args, **kwargs): - if cls == Function and len(args) == 1: - return UndefFunction(args[0]) + if cls == Function: + nargs = len(args) + if nargs == 0: + raise TypeError("Required at least one argument to Function") + elif nargs == 1: + return UndefFunction(args[0]) + elif nargs > 1: + raise TypeError(f"Unexpected extra arguments {args[1:]}.") + return super(Function, cls).__new__(cls) @property diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index 3a19b122c..c5241ad4d 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -103,6 +103,15 @@ def test_derivative(): assert i == fxy.diff(y, 1, x) +def test_function(): + x = Symbol("x") + assert Function("f")(x) == function_symbol("f", x) + + raises(TypeError, lambda: Function("f", "x")) + raises(TypeError, lambda: Function("f", x)) + raises(TypeError, lambda: Function()) + + def test_abs(): x = Symbol("x") e = abs(x) From a165060bd2fb2d3e64770fa68ad6968689f06f38 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 22 Jan 2024 21:43:00 -0600 Subject: [PATCH 257/314] add name property to FunctionSymbol --- symengine/lib/symengine_wrapper.in.pyx | 4 ++++ symengine/tests/test_functions.py | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 4fdc0f9c2..06b85266b 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -2841,6 +2841,10 @@ class FunctionSymbol(Function): name = deref(X).get_name().decode("utf-8") return str(name) + @property + def name(Basic self): + return self.get_name() + def _sympy_(self): import sympy name = self.get_name() diff --git a/symengine/tests/test_functions.py b/symengine/tests/test_functions.py index c5241ad4d..207add989 100644 --- a/symengine/tests/test_functions.py +++ b/symengine/tests/test_functions.py @@ -105,12 +105,15 @@ def test_derivative(): def test_function(): x = Symbol("x") - assert Function("f")(x) == function_symbol("f", x) + fx = Function("f")(x) + assert fx == function_symbol("f", x) raises(TypeError, lambda: Function("f", "x")) raises(TypeError, lambda: Function("f", x)) raises(TypeError, lambda: Function()) + assert fx.name == "f" + def test_abs(): x = Symbol("x") From e72006d5f7425cd50c54b22766e0ed4bcd2dca85 Mon Sep 17 00:00:00 2001 From: Moraxyc Date: Tue, 21 May 2024 14:33:35 +0800 Subject: [PATCH 258/314] build(cmake): avoid the usage of distutils distutils has been removed since python 3.12 --- cmake/FindPython.cmake | 6 +++--- cmake/get_suffix.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 52539cb79..f3381327e 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -1,7 +1,7 @@ set(PYTHON_BIN python CACHE STRING "Python executable name") execute_process( - COMMAND ${PYTHON_BIN} -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())" + COMMAND ${PYTHON_BIN} -c "from sysconfig import get_paths; print(get_paths()['include'])" OUTPUT_VARIABLE PYTHON_SYS_PATH ) string(STRIP ${PYTHON_SYS_PATH} PYTHON_SYS_PATH) @@ -16,7 +16,7 @@ set(PYTHON_INSTALL_HEADER_PATH ${PYTHON_INCLUDE_PATH}/symengine CACHE BOOL "Python install headers path") execute_process( - COMMAND ${PYTHON_BIN} -c "from distutils.sysconfig import get_config_var; print(get_config_var('LIBDIR'))" + COMMAND ${PYTHON_BIN} -c "from sysconfig import get_config_var; print(get_config_var('LIBDIR'))" OUTPUT_VARIABLE PYTHON_LIB_PATH ) string(STRIP ${PYTHON_LIB_PATH} PYTHON_LIB_PATH) @@ -50,7 +50,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") endif() execute_process( - COMMAND ${PYTHON_BIN} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())" + COMMAND ${PYTHON_BIN} -c "from sysconfig import get_paths; print(get_paths()['purelib'])" OUTPUT_VARIABLE PYTHON_INSTALL_PATH_tmp ) string(STRIP ${PYTHON_INSTALL_PATH_tmp} PYTHON_INSTALL_PATH_tmp) diff --git a/cmake/get_suffix.py b/cmake/get_suffix.py index 8fc5b1050..42470fce5 100644 --- a/cmake/get_suffix.py +++ b/cmake/get_suffix.py @@ -1,4 +1,4 @@ -from distutils.sysconfig import get_config_var +from sysconfig import get_config_var extsuffix = get_config_var('EXT_SUFFIX') if extsuffix is None: print("") From f6426fc4019a1edc2d8e61d4bb91ad72f14250ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Mon, 27 May 2024 21:55:22 +0200 Subject: [PATCH 259/314] Fix cython syntax, add tests --- symengine/lib/symengine_wrapper.in.pyx | 8 ++++++-- symengine/tests/test_logic.py | 5 ++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index e10d14768..c29c89787 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -1627,7 +1627,9 @@ class Equality(Relational): def is_Equality(self): return True - func = __class__ + @property + def func(self): + return self.__class__ Eq = Equality @@ -1648,7 +1650,9 @@ class Unequality(Relational): s = self.args_as_sage() return sage.ne(*s) - func = __class__ + @property + def func(self): + return self.__class__ Ne = Unequality diff --git a/symengine/tests/test_logic.py b/symengine/tests/test_logic.py index 7c01f8e9b..3d0c33911 100644 --- a/symengine/tests/test_logic.py +++ b/symengine/tests/test_logic.py @@ -27,6 +27,10 @@ def test_relationals(): assert Ge(1, 1) == true assert Eq(I, 2) == false assert Ne(I, 2) == true + eq = Eq(x, y) + assert eq.func(*eq.args) == eq + ne = Ne(x, y) + assert ne.func(*ne.args) == ne def test_rich_cmp(): @@ -118,4 +122,3 @@ def test_Contains(): assert Contains(x, Interval(1, 1)) != false assert Contains(oo, Interval(-oo, oo)) == false assert Contains(-oo, Interval(-oo, oo)) == false - From b131af835fbb1e4b7df38615d199b6e535c26b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 28 May 2024 16:41:21 +0200 Subject: [PATCH 260/314] Bump one CI config to ubuntu-24.04 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6993dd9e9..33c2dceb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: WITH_BFD: yes PYTHON_VERSION: '3.12' TEST_SYMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-24.04 CC: gcc - BUILD_TYPE: Debug From 02bd6d4a37ef62a9bd8588e100b040459f70b40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 28 May 2024 16:49:43 +0200 Subject: [PATCH 261/314] try to work around hardcoded versions in symengine's install_travis.sh --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33c2dceb6..4a44aa8ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: PYTHON_VERSION: '3.12' TEST_SYMPY: yes OS: ubuntu-24.04 - CC: gcc + CC: 'ccache gcc' # symengine's bin/install_travis.sh needs refactoring... - BUILD_TYPE: Debug WITH_BFD: yes From fdff48def4d936eb9f7935b3bfef35096aadd83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 28 May 2024 16:54:42 +0200 Subject: [PATCH 262/314] try another workaround --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a44aa8ab..9cddcb2bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: PYTHON_VERSION: '3.12' TEST_SYMPY: yes OS: ubuntu-24.04 - CC: 'ccache gcc' # symengine's bin/install_travis.sh needs refactoring... + CC: 'gcc -v' # symengine's bin/install_travis.sh needs refactoring... - BUILD_TYPE: Debug WITH_BFD: yes From 8a4f3b895050c6164ba5ee1ee19d7fa13238d1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Tue, 28 May 2024 16:58:18 +0200 Subject: [PATCH 263/314] also set CXX --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9cddcb2bc..b41561014 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: TEST_SYMPY: yes OS: ubuntu-24.04 CC: 'gcc -v' # symengine's bin/install_travis.sh needs refactoring... + CXX: 'g++ -v' - BUILD_TYPE: Debug WITH_BFD: yes From de69b995e9116356823960253de046fee294f43a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 10:19:53 +0200 Subject: [PATCH 264/314] test against symengine/symengine#2026 --- .github/workflows/ci.yml | 3 +-- bin/test_symengine_unix.sh | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b41561014..33c2dceb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,7 @@ jobs: PYTHON_VERSION: '3.12' TEST_SYMPY: yes OS: ubuntu-24.04 - CC: 'gcc -v' # symengine's bin/install_travis.sh needs refactoring... - CXX: 'g++ -v' + CC: gcc - BUILD_TYPE: Debug WITH_BFD: yes diff --git a/bin/test_symengine_unix.sh b/bin/test_symengine_unix.sh index 976f305d1..63e3f6ca6 100644 --- a/bin/test_symengine_unix.sh +++ b/bin/test_symengine_unix.sh @@ -2,10 +2,10 @@ export PYTHON_SOURCE_DIR=`pwd` export TEST_CPP="no" export MAKEFLAGS="-j2" -git clone https://github.com/symengine/symengine symengine-cpp +git clone -b update-CI https://github.com/bjodah/symengine symengine-cpp cd symengine-cpp export SOURCE_DIR=`pwd` -git checkout `cat ../symengine_version.txt` +#git checkout `cat ../symengine_version.txt` cd .. # Setup travis for C++ library From b4933abc696fcd7d68dc999db66888b264cad26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 10:50:21 +0200 Subject: [PATCH 265/314] use gcc-13 & llvm-18 under ubuntu-24.04 --- .github/workflows/ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33c2dceb6..55c844f7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: WITH_BFD: yes PYTHON_VERSION: '3.12' TEST_SYMPY: yes - OS: ubuntu-24.04 + OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Debug @@ -97,15 +97,16 @@ jobs: CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: '3.10' + PYTHON_VERSION: '3.12' WITH_SYMPY: yes - WITH_LLVM: 14 + WITH_LLVM: 18 WITH_SCIPY: yes INTEGER_CLASS: 'boostmp' PYTEST_ADDOPTS: '-k "not integer_nthroot"' - OS: ubuntu-22.04 - EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main' - EXTRA_APT_PACKAGES: 'llvm-14' + OS: ubuntu-24.04 + CC: gcc # ubuntu nobel uses gcc-13 + #EXTRA_APT_REPOSITORY: 'deb http://apt.llvm.org/jammy/ llvm-toolchain-nobel-18 main' + EXTRA_APT_PACKAGES: 'llvm-18' - BUILD_TYPE: Debug PYTHON_VERSION: '3.8' From 43f282a8111970ed06ee813f75bf591edd257338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 11:16:29 +0200 Subject: [PATCH 266/314] long is not a built-in --- symengine/lib/symengine_wrapper.in.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 76b8288d9..61cb4d6b3 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -1214,7 +1214,7 @@ cdef class Basic(object): return int(float(self)) def __long__(self): - return long(float(self)) + return int(float(self)) def __complex__(self): f = self.n(real=False) From 7472cce6f326ad53ca25ccc541198497cc2edb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 11:16:29 +0200 Subject: [PATCH 267/314] long is not a built-in --- symengine/lib/symengine_wrapper.in.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index c29c89787..34c11e9f8 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -1211,7 +1211,7 @@ cdef class Basic(object): return int(float(self)) def __long__(self): - return long(float(self)) + return int(float(self)) def __complex__(self): f = self.n(real=False) From dd3dc6efc228c9193088e3b284fa88faf920b393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 11:41:58 +0200 Subject: [PATCH 268/314] vector lambda_double -> unique_ptr lambda_visitor --- symengine/lib/symengine_wrapper.in.pxd | 11 +++-- symengine/lib/symengine_wrapper.in.pyx | 66 +++++++++++++------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/symengine/lib/symengine_wrapper.in.pxd b/symengine/lib/symengine_wrapper.in.pxd index 3712e17ce..03dbf1f01 100644 --- a/symengine/lib/symengine_wrapper.in.pxd +++ b/symengine/lib/symengine_wrapper.in.pxd @@ -2,6 +2,7 @@ cimport symengine from symengine cimport RCP, map_basic_basic, rcp_const_basic +from libcpp.memory cimport unique_ptr from libcpp.vector cimport vector from libcpp.string cimport string from libcpp cimport bool as cppbool @@ -44,7 +45,7 @@ cdef class _Lambdify(object): cpdef unsafe_eval(sef, inp, out, unsigned nbroadcast=*) cdef class LambdaDouble(_Lambdify): - cdef vector[symengine.LambdaRealDoubleVisitor] lambda_double + cdef unique_ptr[symengine.LambdaRealDoubleVisitor] lambda_visitor cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse) cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=*, int out_offset=*) cpdef as_scipy_low_level_callable(self) @@ -54,7 +55,7 @@ cdef class LambdaDouble(_Lambdify): int inp_offset=*, int out_offset=*) cdef class LambdaComplexDouble(_Lambdify): - cdef vector[symengine.LambdaComplexDoubleVisitor] lambda_double + cdef unique_ptr[symengine.LambdaComplexDoubleVisitor] lambda_visitor cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse) cpdef unsafe_complex(self, double complex[::1] inp, double complex[::1] out, int inp_offset=*, int out_offset=*) @@ -63,7 +64,7 @@ IF HAVE_SYMENGINE_LLVM: cdef int opt_level cdef class LLVMDouble(_LLVMLambdify): - cdef vector[symengine.LLVMDoubleVisitor] lambda_double + cdef unique_ptr[symengine.LLVMDoubleVisitor] lambda_visitor cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse) cdef _load(self, const string &s) cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=*, int out_offset=*) @@ -71,14 +72,14 @@ IF HAVE_SYMENGINE_LLVM: cpdef as_ctypes(self) cdef class LLVMFloat(_LLVMLambdify): - cdef vector[symengine.LLVMFloatVisitor] lambda_double + cdef unique_ptr[symengine.LLVMFloatVisitor] lambda_visitor cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse) cdef _load(self, const string &s) cpdef unsafe_real(self, float[::1] inp, float[::1] out, int inp_offset=*, int out_offset=*) IF HAVE_SYMENGINE_LLVM_LONG_DOUBLE: cdef class LLVMLongDouble(_LLVMLambdify): - cdef vector[symengine.LLVMLongDoubleVisitor] lambda_double + cdef unique_ptr[symengine.LLVMLongDoubleVisitor] lambda_visitor cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse) cdef _load(self, const string &s) cpdef unsafe_real(self, long double[::1] inp, long double[::1] out, int inp_offset=*, int out_offset=*) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 34c11e9f8..44688fbe0 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -5156,11 +5156,11 @@ cdef class LambdaDouble(_Lambdify): pass cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): - self.lambda_double.resize(1) - self.lambda_double[0].init(args_, outs_, cse) + self.lambda_visitor.reset(new symengine.LambdaRealDoubleVisitor()) + deref(self.lambda_visitor).init(args_, outs_, cse) cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=0, int out_offset=0): - self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) + deref(self.lambda_visitor).call(&out[out_offset], &inp[inp_offset]) cpdef unsafe_eval(self, inp, out, unsigned nbroadcast=1): cdef double[::1] c_inp, c_out @@ -5168,7 +5168,7 @@ cdef class LambdaDouble(_Lambdify): c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + deref(self.lambda_visitor).call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) cpdef as_scipy_low_level_callable(self): from ctypes import c_double, c_void_p, c_int, cast, POINTER, CFUNCTYPE @@ -5176,7 +5176,7 @@ cdef class LambdaDouble(_Lambdify): raise RuntimeError("SciPy LowLevelCallable supports only functions with 1 output") addr1 = cast(&_scipy_callback_lambda_real, CFUNCTYPE(c_double, c_int, POINTER(c_double), c_void_p)) - addr2 = cast(&self.lambda_double[0], c_void_p) + addr2 = cast(self.lambda_visitor.get(), c_void_p) return create_low_level_callable(self, addr1, addr2) cpdef as_ctypes(self): @@ -5191,7 +5191,7 @@ cdef class LambdaDouble(_Lambdify): from ctypes import c_double, c_void_p, c_int, cast, POINTER, CFUNCTYPE addr1 = cast(&_ctypes_callback_lambda_real, CFUNCTYPE(c_void_p, POINTER(c_double), POINTER(c_double), c_void_p)) - addr2 = cast(&self.lambda_double[0], c_void_p) + addr2 = cast(self.lambda_visitor.get(), c_void_p) return addr1, addr2 @@ -5201,11 +5201,11 @@ cdef class LambdaComplexDouble(_Lambdify): pass cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): - self.lambda_double.resize(1) - self.lambda_double[0].init(args_, outs_, cse) + self.lambda_visitor.reset(new symengine.LambdaComplexDoubleVisitor()) + deref(self.lambda_visitor).init(args_, outs_, cse) cpdef unsafe_complex(self, double complex[::1] inp, double complex[::1] out, int inp_offset=0, int out_offset=0): - self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) + deref(self.lambda_visitor).call(&out[out_offset], &inp[inp_offset]) cpdef unsafe_eval(self, inp, out, unsigned nbroadcast=1): cdef double complex[::1] c_inp, c_out @@ -5213,7 +5213,7 @@ cdef class LambdaComplexDouble(_Lambdify): c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + deref(self.lambda_visitor).call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) IF HAVE_SYMENGINE_LLVM: @@ -5222,23 +5222,23 @@ IF HAVE_SYMENGINE_LLVM: self.opt_level = opt_level cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): - self.lambda_double.resize(1) - self.lambda_double[0].init(args_, outs_, cse, self.opt_level) + self.lambda_visitor.reset(new symengine.LLVMDoubleVisitor()) + deref(self.lambda_visitor).init(args_, outs_, cse, self.opt_level) cdef _load(self, const string &s): - self.lambda_double.resize(1) - self.lambda_double[0].loads(s) + self.lambda_visitor.reset(new symengine.LLVMDoubleVisitor()) + deref(self.lambda_visitor).loads(s) def __reduce__(self): """ Interface for pickle. Note that the resulting object is platform dependent. """ - cdef bytes s = self.lambda_double[0].dumps() + cdef bytes s = deref(self.lambda_visitor).dumps() return llvm_loading_func, (self.args_size, self.tot_out_size, self.out_shapes, self.real, \ self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, s) cpdef unsafe_real(self, double[::1] inp, double[::1] out, int inp_offset=0, int out_offset=0): - self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) + deref(self.lambda_visitor).call(&out[out_offset], &inp[inp_offset]) cpdef unsafe_eval(self, inp, out, unsigned nbroadcast=1): cdef double[::1] c_inp, c_out @@ -5246,7 +5246,7 @@ IF HAVE_SYMENGINE_LLVM: c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + deref(self.lambda_visitor).call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) cpdef as_scipy_low_level_callable(self): from ctypes import c_double, c_void_p, c_int, cast, POINTER, CFUNCTYPE @@ -5256,7 +5256,7 @@ IF HAVE_SYMENGINE_LLVM: raise RuntimeError("SciPy LowLevelCallable supports only functions with 1 output") addr1 = cast(&_scipy_callback_llvm_real, CFUNCTYPE(c_double, c_int, POINTER(c_double), c_void_p)) - addr2 = cast(&self.lambda_double[0], c_void_p) + addr2 = cast(self.lambda_visitor.get(), c_void_p) return create_low_level_callable(self, addr1, addr2) cpdef as_ctypes(self): @@ -5273,7 +5273,7 @@ IF HAVE_SYMENGINE_LLVM: raise RuntimeError("Lambda function has to be real") addr1 = cast(&_ctypes_callback_llvm_real, CFUNCTYPE(c_void_p, POINTER(c_double), POINTER(c_double), c_void_p)) - addr2 = cast(&self.lambda_double[0], c_void_p) + addr2 = cast(self.lambda_visitor.get(), c_void_p) return addr1, addr2 cdef class LLVMFloat(_LLVMLambdify): @@ -5281,23 +5281,23 @@ IF HAVE_SYMENGINE_LLVM: self.opt_level = opt_level cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): - self.lambda_double.resize(1) - self.lambda_double[0].init(args_, outs_, cse, self.opt_level) + self.lambda_visitor.reset(new symengine.LLVMFloatVisitor()) + deref(self.lambda_visitor).init(args_, outs_, cse, self.opt_level) cdef _load(self, const string &s): - self.lambda_double.resize(1) - self.lambda_double[0].loads(s) + self.lambda_visitor.reset(new symengine.LLVMFloatVisitor()) + deref(self.lambda_visitor).loads(s) def __reduce__(self): """ Interface for pickle. Note that the resulting object is platform dependent. """ - cdef bytes s = self.lambda_double[0].dumps() + cdef bytes s = deref(self.lambda_visitor).dumps() return llvm_float_loading_func, (self.args_size, self.tot_out_size, self.out_shapes, self.real, \ self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, s) cpdef unsafe_real(self, float[::1] inp, float[::1] out, int inp_offset=0, int out_offset=0): - self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) + deref(self.lambda_visitor).call(&out[out_offset], &inp[inp_offset]) cpdef unsafe_eval(self, inp, out, unsigned nbroadcast=1): cdef float[::1] c_inp, c_out @@ -5305,7 +5305,7 @@ IF HAVE_SYMENGINE_LLVM: c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + deref(self.lambda_visitor).call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) IF HAVE_SYMENGINE_LLVM_LONG_DOUBLE: cdef class LLVMLongDouble(_LLVMLambdify): @@ -5313,23 +5313,23 @@ IF HAVE_SYMENGINE_LLVM: self.opt_level = opt_level cdef _init(self, symengine.vec_basic& args_, symengine.vec_basic& outs_, cppbool cse): - self.lambda_double.resize(1) - self.lambda_double[0].init(args_, outs_, cse, self.opt_level) + self.lambda_visitor.reset(new symengine.LLVMLongDoubleVisitor()) + deref(self.lambda_visitor).init(args_, outs_, cse, self.opt_level) cdef _load(self, const string &s): - self.lambda_double.resize(1) - self.lambda_double[0].loads(s) + self.lambda_visitor.reset(new symengine.LLVMLongDoubleVisitor()) + deref(self.lambda_visitor).loads(s) def __reduce__(self): """ Interface for pickle. Note that the resulting object is platform dependent. """ - cdef bytes s = self.lambda_double[0].dumps() + cdef bytes s = deref(self.lambda_visitor).dumps() return llvm_long_double_loading_func, (self.args_size, self.tot_out_size, self.out_shapes, self.real, \ self.n_exprs, self.order, self.accum_out_sizes, self.numpy_dtype, s) cpdef unsafe_real(self, long double[::1] inp, long double[::1] out, int inp_offset=0, int out_offset=0): - self.lambda_double[0].call(&out[out_offset], &inp[inp_offset]) + deref(self.lambda_visitor).call(&out[out_offset], &inp[inp_offset]) cpdef unsafe_eval(self, inp, out, unsigned nbroadcast=1): cdef long double[::1] c_inp, c_out @@ -5337,7 +5337,7 @@ IF HAVE_SYMENGINE_LLVM: c_inp = np.ascontiguousarray(inp.ravel(order=self.order), dtype=self.numpy_dtype) c_out = out for idx in range(nbroadcast): - self.lambda_double[0].call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) + deref(self.lambda_visitor).call(&c_out[idx*self.tot_out_size], &c_inp[idx*self.args_size]) def llvm_loading_func(*args): return LLVMDouble(args, _load=True) From 4204b2dca364c47d9b32be99bd7e58430d39397e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 15:34:33 +0200 Subject: [PATCH 269/314] Try to add work-around for sympy/sympy#26645 --- symengine/lib/symengine_wrapper.in.pyx | 18 ++++++++++++++++++ symengine/tests/test_sympy_conv.py | 1 + 2 files changed, 19 insertions(+) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 44688fbe0..8fa62c83b 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -31,6 +31,13 @@ try: except ImportError: have_numpy = False +try: + import flint as _flint + have_flint_py = True +except ImportError: + _flint = None + have_flint_py = False + class SympifyError(Exception): pass @@ -499,6 +506,17 @@ def sympy2symengine(a, raise_error=False): elif isinstance(a, sympy.ConditionSet): return conditionset(*(a.args)) + if have_flint_py: + if isinstance(a, _flint.types.nmod.nmod): + # Work around for sympy/sympy#26645 + class _modular_integer(sympy.polys.domains.modularinteger.ModularInteger): + mod = int(a.modulus()) + dom = sympy.polys.domains.ZZ + sym = True + + b = _modular_integer(int(a)) + return PyNumber(b, sympy_module) + if raise_error: raise SympifyError(("sympy2symengine: Cannot convert '%r' (of type %s)" " to a symengine type.") % (a, type(a))) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index 5d173dc4f..fbba81795 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -778,6 +778,7 @@ def test_pynumber(): assert isinstance(b, PyNumber) assert b == a # Check equality via SymEngine assert a == b # Check equality via SymPy + assert (b-a).simplify() == 0 assert str(a) == str(b) a = 1 - a From 14cd07d8c81f3c2c220e9fc894927465ca0177a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 15:37:21 +0200 Subject: [PATCH 270/314] bump symengine version to v0.12.0 --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 4f7638fd9..87a1cf595 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.11.1 +v0.12.0 From 1618a867fa40c7f82dc9ccbdc2e711d97365c598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 16:33:35 +0200 Subject: [PATCH 271/314] Add python-flint to one CI config --- .github/workflows/ci.yml | 3 ++- bin/install_travis.sh | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6993dd9e9..8b9877b1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,11 +132,12 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.11' OS: ubuntu-20.04 WITH_MPC: yes WITH_MPFR: yes WITH_FLINT: yes + WITH_FLINT_PY: yes WITH_SCIPY: yes WITH_DOCS: yes INTEGER_CLASS: flint diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 581354a06..8176202dc 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -16,6 +16,10 @@ if [[ "${WITH_DOCS}" == "yes" ]]; then export conda_pkgs="${conda_pkgs} sphinx recommonmark"; fi +if [[ "${WITH_FLINT_PY}" == "yes" ]]; then + export conda_pkgs="${conda_pkgs} python-flint"; # python-flint affects sympy, see e.g. sympy/sympy#26645 +fi + if [[ "${WITH_SAGE}" == "yes" ]]; then # This is split to avoid the 10 minute limit conda install -q sagelib=8.1 From c6f95e3a3fe6ca3a1398830fc2e792f7e88794e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 31 May 2024 16:44:17 +0200 Subject: [PATCH 272/314] Revert adaptions to flint.types.nmod.nmod Following the explanation in https://github.com/sympy/sympy/issues/26645#issuecomment-2142388813 --- symengine/lib/symengine_wrapper.in.pyx | 18 ------------------ symengine/tests/test_sympy_conv.py | 1 - 2 files changed, 19 deletions(-) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 8fa62c83b..44688fbe0 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -31,13 +31,6 @@ try: except ImportError: have_numpy = False -try: - import flint as _flint - have_flint_py = True -except ImportError: - _flint = None - have_flint_py = False - class SympifyError(Exception): pass @@ -506,17 +499,6 @@ def sympy2symengine(a, raise_error=False): elif isinstance(a, sympy.ConditionSet): return conditionset(*(a.args)) - if have_flint_py: - if isinstance(a, _flint.types.nmod.nmod): - # Work around for sympy/sympy#26645 - class _modular_integer(sympy.polys.domains.modularinteger.ModularInteger): - mod = int(a.modulus()) - dom = sympy.polys.domains.ZZ - sym = True - - b = _modular_integer(int(a)) - return PyNumber(b, sympy_module) - if raise_error: raise SympifyError(("sympy2symengine: Cannot convert '%r' (of type %s)" " to a symengine type.") % (a, type(a))) diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py index fbba81795..5d173dc4f 100644 --- a/symengine/tests/test_sympy_conv.py +++ b/symengine/tests/test_sympy_conv.py @@ -778,7 +778,6 @@ def test_pynumber(): assert isinstance(b, PyNumber) assert b == a # Check equality via SymEngine assert a == b # Check equality via SymPy - assert (b-a).simplify() == 0 assert str(a) == str(b) a = 1 - a From 621141b2fc0182a045e9d6a22db778065839626e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 8 Jul 2024 21:10:20 -0500 Subject: [PATCH 273/314] update CI --- .github/workflows/ci.yml | 8 ++++---- appveyor.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b9877b1b..2763750cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,24 +111,24 @@ jobs: PYTHON_VERSION: '3.8' WITH_SCIPY: yes WITH_LLVM: 5.0 - OS: macos-latest + OS: macos-13 CC: clang - BUILD_TYPE: Release PYTHON_VERSION: '3.9' WITH_NUMPY: no - OS: macos-latest + OS: macos-13 CC: clang - BUILD_TYPE: Debug PYTHON_VERSION: '3.8' WITH_NUMPY: no - OS: macos-latest + OS: macos-13 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: '3.8' - OS: macos-latest + OS: macos-13 CC: gcc - BUILD_TYPE: Release diff --git a/appveyor.yml b/appveyor.yml index 05e6b6ebb..24947d3b1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -63,7 +63,7 @@ install: - git clone https://github.com/sympy/symengine symengine-cpp - if [%COMPILER%]==[MSVC15] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat -- if [%COMPILER%]==[MSVC15] conda install --yes --quiet conda python=3.6 +- if [%COMPILER%]==[MSVC15] conda install --yes --quiet conda - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 From a23b620dd3d671f4a19944153cffb2506815aaa3 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 8 Jul 2024 21:23:05 -0500 Subject: [PATCH 274/314] updat eappveyor --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 24947d3b1..91abed7b0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -63,7 +63,6 @@ install: - git clone https://github.com/sympy/symengine symengine-cpp - if [%COMPILER%]==[MSVC15] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat -- if [%COMPILER%]==[MSVC15] conda install --yes --quiet conda - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 From 25ee71fc89d79d015fac09271804a031ddbdaa51 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 8 Jul 2024 21:37:11 -0500 Subject: [PATCH 275/314] update appveyor 2 --- appveyor.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 91abed7b0..f82bda2af 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,26 +11,26 @@ environment: COMPILER: MSVC15 PLATFORM: "x64" PYTHON_VERSION: 310-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 WITH_MPFR: yes WITH_MPC: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" PYTHON_VERSION: 38-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" PYTHON_VERSION: 39-x64 WITH_SYMPY: no - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" PYTHON_VERSION: 311-x64 WITH_NUMPY: no - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 #- BUILD_TYPE: "Debug" # COMPILER: MinGW-w64 # PYTHON_VERSION: 39-x64 @@ -46,14 +46,14 @@ environment: COMPILER: MSVC15 PLATFORM: "Win32" PYTHON_VERSION: 39 - CONDA_INSTALL_LOCN: C:\\Miniconda36 + CONDA_INSTALL_LOCN: C:\\Miniconda38 WITH_MPFR: yes WITH_MPC: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" PYTHON_VERSION: 310-x64 - CONDA_INSTALL_LOCN: C:\\Miniconda36-x64 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 WITH_MPFR: yes WITH_MPC: yes WITH_LLVM: yes From 4e85a86849e4c68048033f589c0abb8efb99c46c Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 8 Jul 2024 21:45:00 -0500 Subject: [PATCH 276/314] refactor appveyor --- appveyor.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f82bda2af..514d9107b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -65,14 +65,15 @@ install: - if [%COMPILER%]==[MSVC15] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat - if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge - if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug -- if [%COMPILER%]==[MSVC15] conda install --yes mpir=3.0.0 vc=14 +- if [%COMPILER%]==[MSVC15] set "CONDA_DEPS=mpir=3.0.0 vc=14" +- if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% mpfr=3.1.5" +- if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% mpc=1.0.3" +- if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% llvmdev=4.0" +- if [%COMPILER%]==[MSVC15] conda install --yes %CONDA_DEPS% - if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% - if [%COMPILER%]==[MSVC15] echo %PATH% - if [%COMPILER%]==[MSVC15] set "PATH=%PATH%;%CONDA_PREFIX%\\Library\\bin;%CONDA_PREFIX%" - if [%COMPILER%]==[MSVC15] echo %PATH% -- if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] conda install --yes mpfr=3.1.5 -- if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] conda install --yes mpc=1.0.3 -- if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] conda install --yes llvmdev=4.0 - if [%COMPILER%]==[MinGW] set "PATH=C:\MinGW\bin;%PATH%" - if [%COMPILER%]==[MinGW] mingw-get update From 3eaf92179d5a9c74ac4ff60ee009ece2a79ff103 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 8 Jul 2024 22:58:03 -0500 Subject: [PATCH 277/314] Fix 32 bit appveyor --- appveyor.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 514d9107b..f21df0aef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,6 +7,13 @@ environment: PLATFORMTOOLSET: "v140" matrix: + - BUILD_TYPE: "Release" + COMPILER: MSVC15 + PLATFORM: "Win32" + PYTHON_VERSION: 39 + CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 + WITH_MPFR: yes + WITH_MPC: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" @@ -42,13 +49,6 @@ environment: # COMPILER: MinGW-w64 # PYTHON_VERSION: 39-x64 # WITH_SYMPY: no - - BUILD_TYPE: "Release" - COMPILER: MSVC15 - PLATFORM: "Win32" - PYTHON_VERSION: 39 - CONDA_INSTALL_LOCN: C:\\Miniconda38 - WITH_MPFR: yes - WITH_MPC: yes - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" @@ -61,15 +61,17 @@ environment: install: - set PYTHON_SOURCE_DIR=%CD% - git clone https://github.com/sympy/symengine symengine-cpp +- if [%PLATFORM%]==[Win32] set "CONDA_SUBDIR=win-32" - if [%COMPILER%]==[MSVC15] call %CONDA_INSTALL_LOCN%\Scripts\activate.bat -- if [%COMPILER%]==[MSVC15] conda config --add channels conda-forge -- if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] conda config --add channels symengine/label/debug - if [%COMPILER%]==[MSVC15] set "CONDA_DEPS=mpir=3.0.0 vc=14" - if [%COMPILER%]==[MSVC15] if [%WITH_MPFR%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% mpfr=3.1.5" - if [%COMPILER%]==[MSVC15] if [%WITH_MPC%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% mpc=1.0.3" - if [%COMPILER%]==[MSVC15] if [%WITH_LLVM%]==[yes] set "CONDA_DEPS=%CONDA_DEPS% llvmdev=4.0" -- if [%COMPILER%]==[MSVC15] conda install --yes %CONDA_DEPS% +- if [%COMPILER%]==[MSVC15] set "CONDA_DEPS=%CONDA_DEPS% -c conda-forge" +- if [%COMPILER%]==[MSVC15] if [%BUILD_TYPE%]==[Debug] set "CONDA_DEPS=%CONDA_DEPS% -c symengine/label/debug" +- if [%COMPILER%]==[MSVC15] conda create -n deps --yes %CONDA_DEPS% +- if [%COMPILER%]==[MSVC15] call conda activate deps - if [%COMPILER%]==[MSVC15] echo %CONDA_PREFIX% - if [%COMPILER%]==[MSVC15] echo %PATH% - if [%COMPILER%]==[MSVC15] set "PATH=%PATH%;%CONDA_PREFIX%\\Library\\bin;%CONDA_PREFIX%" From 8f6f7a371e8cf915d4f6f779bff16b8a73415090 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 25 Jul 2024 10:30:10 -0500 Subject: [PATCH 278/314] Mark subs as throwing exceptions --- symengine/lib/symengine.pxd | 6 +++--- symengine/tests/test_subs.py | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index ee96731ba..3e2b5d08a 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -168,9 +168,9 @@ cdef extern from "" namespace "SymEngine": void cse(vec_pair &replacements, vec_basic &reduced_exprs, const vec_basic &exprs) except+ nogil cdef extern from "" namespace "SymEngine": - rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) nogil - rcp_const_basic ssubs (rcp_const_basic &x, const map_basic_basic &x) nogil - rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) nogil + rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) except+ nogil + rcp_const_basic ssubs (rcp_const_basic &x, const map_basic_basic &x) except+ nogil + rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) except+ nogil cdef extern from "" namespace "SymEngine": rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) except+ nogil diff --git a/symengine/tests/test_subs.py b/symengine/tests/test_subs.py index 4d8c6f0a4..b346659bf 100644 --- a/symengine/tests/test_subs.py +++ b/symengine/tests/test_subs.py @@ -1,7 +1,7 @@ import unittest from symengine.test_utilities import raises -from symengine import Symbol, sin, cos, sqrt, Add, function_symbol, have_numpy +from symengine import Symbol, sin, cos, sqrt, Add, function_symbol, have_numpy, log def test_basic(): @@ -24,6 +24,12 @@ def test_sin(): assert e.subs(x, 0) == 1 +def test_subs_exception(): + x = Symbol("x") + expr = sin(log(x)) + raises(RuntimeError, lambda: expr.subs({x: 0})) + + def test_args(): x = Symbol("x") e = cos(x) From f09067861cbd99538508932e57ac29191a80eaa1 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 25 Aug 2024 18:44:49 -0500 Subject: [PATCH 279/314] Bump version --- setup.py | 2 +- symengine/__init__.py | 2 +- symengine_version.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 1c5e92077..f105b328f 100644 --- a/setup.py +++ b/setup.py @@ -222,7 +222,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.11.0", + version="0.13.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index b6002a281..97e9afd0f 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -63,7 +63,7 @@ def __getattr__(name): raise AttributeError(f"module 'symengine' has no attribute '{name}'") -__version__ = "0.11.0" +__version__ = "0.13.0" # To not expose internals diff --git a/symengine_version.txt b/symengine_version.txt index 87a1cf595..b78dbf252 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.12.0 +ed1e3e4fd8260097fa25aa1282e1d3a4ac4527f3 From d60e88e3e2a7eea03f0d09bfcc1c28710664ec75 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 28 Sep 2024 10:47:02 -0500 Subject: [PATCH 280/314] Add Moraxyc to authors --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b0719fd56..427f83ad9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,3 +35,4 @@ Garming Sam Pieter Eendebak Ayush Kumar Christian Clauss +Moraxyc From 282d13486b8784b60927c17aba0f608a59da137a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 28 Sep 2024 10:47:11 -0500 Subject: [PATCH 281/314] Bump symengine version --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index b78dbf252..6345c2168 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -ed1e3e4fd8260097fa25aa1282e1d3a4ac4527f3 +v0.13.0 From 1e47d959c4edd9c15e1f893a570e4b0082a39501 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 29 Sep 2024 16:25:26 -0500 Subject: [PATCH 282/314] cython 3.1 fixes --- cmake/cython_test.pyx | 3 --- symengine/lib/symengine_wrapper.in.pyx | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cmake/cython_test.pyx b/cmake/cython_test.pyx index 22cdb17c6..cb803c60d 100644 --- a/cmake/cython_test.pyx +++ b/cmake/cython_test.pyx @@ -1,6 +1,3 @@ -# Test that numpy works in Cython: -from numpy cimport ndarray - # Test that libcpp module is present: from libcpp.vector cimport vector from libcpp.string cimport string diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 8bb9f9cb8..26c31ad87 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -5135,24 +5135,24 @@ cdef class _Lambdify(object): return result -cdef double _scipy_callback_lambda_real(int n, double *x, void *user_data) nogil: +cdef double _scipy_callback_lambda_real(int n, double *x, void *user_data) noexcept nogil: cdef symengine.LambdaRealDoubleVisitor* lamb = user_data cdef double result deref(lamb).call(&result, x) return result -cdef void _ctypes_callback_lambda_real(double *output, const double *input, void *user_data) nogil: +cdef void _ctypes_callback_lambda_real(double *output, const double *input, void *user_data) noexcept nogil: cdef symengine.LambdaRealDoubleVisitor* lamb = user_data deref(lamb).call(output, input) IF HAVE_SYMENGINE_LLVM: - cdef double _scipy_callback_llvm_real(int n, double *x, void *user_data) nogil: + cdef double _scipy_callback_llvm_real(int n, double *x, void *user_data) noexcept nogil: cdef symengine.LLVMDoubleVisitor* lamb = user_data cdef double result deref(lamb).call(&result, x) return result - cdef void _ctypes_callback_llvm_real(double *output, const double *input, void *user_data) nogil: + cdef void _ctypes_callback_llvm_real(double *output, const double *input, void *user_data) noexcept nogil: cdef symengine.LLVMDoubleVisitor* lamb = user_data deref(lamb).call(output, input) From 845168d3683f28781b32577abf4f38ed93f0bc79 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Sep 2024 11:38:54 -0500 Subject: [PATCH 283/314] Another cython 3.1 fix --- cmake/cython_test.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/cython_test.pyx b/cmake/cython_test.pyx index cb803c60d..47f98476d 100644 --- a/cmake/cython_test.pyx +++ b/cmake/cython_test.pyx @@ -75,8 +75,8 @@ cdef extern from "" namespace "SymEngine": string get_name() nogil cdef extern from "" namespace "SymEngine": - cdef RCP[Basic] add(RCP[Basic] &a, RCP[Basic] &b) nogil except+ - cdef RCP[Basic] sub(RCP[Basic] &a, RCP[Basic] &b) nogil except+ + cdef RCP[Basic] add(RCP[Basic] &a, RCP[Basic] &b) except+ nogil + cdef RCP[Basic] sub(RCP[Basic] &a, RCP[Basic] &b) except+ nogil cdef cppclass Add(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) From 170e7ded46b60ee43ec1e6ee997fd95205cad2f4 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 30 Sep 2024 11:39:06 -0500 Subject: [PATCH 284/314] freethreading support --- cmake/FindPython.cmake | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index f3381327e..2f54f5096 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -22,26 +22,36 @@ execute_process( string(STRIP ${PYTHON_LIB_PATH} PYTHON_LIB_PATH) execute_process( - COMMAND ${PYTHON_BIN} -c "import sys; print(sys.prefix)" - OUTPUT_VARIABLE PYTHON_PREFIX_PATH - ) + COMMAND ${PYTHON_BIN} -c "import sys; print(sys.prefix)" + OUTPUT_VARIABLE PYTHON_PREFIX_PATH +) string(STRIP ${PYTHON_PREFIX_PATH} PYTHON_PREFIX_PATH) execute_process( - COMMAND ${PYTHON_BIN} -c "import sys; print('%s.%s' % sys.version_info[:2])" + COMMAND ${PYTHON_BIN} -c "import sys; print('%s.%s' % sys.version_info[:2])" OUTPUT_VARIABLE PYTHON_VERSION - ) +) string(STRIP ${PYTHON_VERSION} PYTHON_VERSION) message(STATUS "Python version: ${PYTHON_VERSION}") string(REPLACE "." "" PYTHON_VERSION_WITHOUT_DOTS ${PYTHON_VERSION}) +execute_process( + COMMAND ${PYTHON_BIN} -c "import sysconfig;print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))" + OUTPUT_VARIABLE PY_GIL_DISABLED +) +string(STRIP ${PY_GIL_DISABLED} PY_GIL_DISABLED) + +if ("${PY_GIL_DISABLED}" STREQUAL "True") + set (PY_THREAD "t") +endif() + if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") FIND_LIBRARY(PYTHON_LIBRARY NAMES - python${PYTHON_VERSION} + python${PYTHON_VERSION}${PY_THREAD} python${PYTHON_VERSION}m - python${PYTHON_VERSION_WITHOUT_DOTS} + python${PYTHON_VERSION_WITHOUT_DOTS}${PY_THREAD} PATHS ${PYTHON_LIB_PATH} ${PYTHON_PREFIX_PATH}/lib ${PYTHON_PREFIX_PATH}/libs PATH_SUFFIXES ${CMAKE_LIBRARY_ARCHITECTURE} NO_DEFAULT_PATH @@ -51,8 +61,8 @@ endif() execute_process( COMMAND ${PYTHON_BIN} -c "from sysconfig import get_paths; print(get_paths()['purelib'])" - OUTPUT_VARIABLE PYTHON_INSTALL_PATH_tmp - ) + OUTPUT_VARIABLE PYTHON_INSTALL_PATH_tmp +) string(STRIP ${PYTHON_INSTALL_PATH_tmp} PYTHON_INSTALL_PATH_tmp) set(PYTHON_INSTALL_PATH ${PYTHON_INSTALL_PATH_tmp} CACHE BOOL "Python install path") @@ -129,5 +139,9 @@ macro(ADD_PYTHON_LIBRARY name) IF(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") target_link_libraries(${name} ${PYTHON_LIBRARY}) set_target_properties(${name} PROPERTIES SUFFIX ".pyd") + IF("${PY_GIL_DISABLED}" STREQUAL "True") + target_compile_definitions(${name} PRIVATE Py_GIL_DISABLED=1) + ENDIF() ENDIF() + endmacro(ADD_PYTHON_LIBRARY) From 8157e6a483b72a6278606ebf5c53f2fae414e734 Mon Sep 17 00:00:00 2001 From: Aaron Miller <78561124+aaron-skydio@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:18:50 -0800 Subject: [PATCH 285/314] Fix build with spaces Building symenginepy as part of the SymForce build, I get an error currently if I try to build under a source directory with a space in the path: ``` [100%] Linking CXX shared library symengine_wrapper.cpython-38-x86_64-linux-gnu.so c++: error: test/build/symenginepy-prefix/src/symenginepy-build/build/lib.linux-x86_64-cpython-38/symengine/lib/version_script_symengine_wrapper.txt: No such file or directory make[5]: *** [symengine/lib/CMakeFiles/symengine_wrapper.dir/build.make:121: symengine/lib/symengine_wrapper.cpython-38-x86_64-linux-gnu.so] Error 1 make[4]: *** [CMakeFiles/Makefile2:132: symengine/lib/CMakeFiles/symengine_wrapper.dir/all] Error 2 make[3]: *** [Makefile:136: all] Error 2 error: error building project make[2]: *** [CMakeFiles/symenginepy.dir/build.make:86: symenginepy-prefix/src/symenginepy-stamp/symenginepy-build] Error 1 ``` This change seems to fix that. I'm not 100% sure in what scenarios this applies to a standalone build of symengine? But I figured I'd open a PR and propose this change Coming from here on the SymForce repo: https://github.com/symforce-org/symforce/pull/414 --- cmake/FindPython.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index 2f54f5096..df8bfdc15 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -130,7 +130,7 @@ macro(ADD_PYTHON_LIBRARY name) configure_file(${CMAKE_SOURCE_DIR}/cmake/version_script.txt ${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt @ONLY) set_property(TARGET ${name} APPEND_STRING PROPERTY - LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt") + LINK_FLAGS " \"-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/version_script_${name}.txt\"") ELSE() add_library(${name} SHARED ${ARGN}) ENDIF() From 0bc912b865cc4ce643011c92d93c9ffb7670c67a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sat, 21 Dec 2024 14:46:10 +0530 Subject: [PATCH 286/314] Fix CI --- bin/install_travis.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 8176202dc..572bb0d2b 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -2,7 +2,7 @@ # symengine's bin/install_travis.sh will install miniconda -export conda_pkgs="python=${PYTHON_VERSION} pip 'cython>=0.29.24' pytest gmp mpfr" +export conda_pkgs="python=${PYTHON_VERSION} pip pytest gmp mpfr" if [[ "${WITH_NUMPY}" != "no" ]]; then export conda_pkgs="${conda_pkgs} numpy"; @@ -27,7 +27,7 @@ if [[ "${WITH_SAGE}" == "yes" ]]; then export conda_pkgs="${conda_pkgs} sage=8.1"; fi -conda install -q ${conda_pkgs} +conda install -q ${conda_pkgs} "cython>=0.29.24" if [[ "${WITH_SYMPY}" != "no" ]]; then pip install sympy; From 21485318d0ba4ece84df8fb9b2cc646fd2fea06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Mon, 13 Jan 2025 15:16:48 +0100 Subject: [PATCH 287/314] normlize cython syntax: cython/cython#5430 --- cmake/cython_test.pyx | 4 +- symengine/lib/symengine.pxd | 304 ++++++++++++++++++------------------ 2 files changed, 154 insertions(+), 154 deletions(-) diff --git a/cmake/cython_test.pyx b/cmake/cython_test.pyx index 47f98476d..e97be0b43 100644 --- a/cmake/cython_test.pyx +++ b/cmake/cython_test.pyx @@ -75,8 +75,8 @@ cdef extern from "" namespace "SymEngine": string get_name() nogil cdef extern from "" namespace "SymEngine": - cdef RCP[Basic] add(RCP[Basic] &a, RCP[Basic] &b) except+ nogil - cdef RCP[Basic] sub(RCP[Basic] &a, RCP[Basic] &b) except+ nogil + cdef RCP[Basic] add(RCP[Basic] &a, RCP[Basic] &b) nogil except + + cdef RCP[Basic] sub(RCP[Basic] &a, RCP[Basic] &b) nogil except + cdef cppclass Add(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index 3e2b5d08a..65b3456aa 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -51,11 +51,11 @@ cdef extern from "" namespace "SymEngine": cdef cppclass RCP[T]: T& operator*() nogil # Not yet supported in Cython: -# RCP[T]& operator=(RCP[T] &r_ptr) except+ nogil - void reset() except+ nogil +# RCP[T]& operator=(RCP[T] &r_ptr) nogil except + + void reset() nogil except + cdef cppclass Ptr[T]: - T& operator*() except+ nogil + T& operator*() nogil except + void print_stack_on_segfault() nogil @@ -65,7 +65,7 @@ cdef extern from "" namespace "SymEngine": ctypedef RCP[const_Basic] rcp_const_basic "SymEngine::RCP" #cdef cppclass rcp_const_basic "SymEngine::RCP": # Basic& operator*() nogil - # void reset() except+ nogil + # void reset() nogil except + # pass # Cython has broken support for the following: # ctypedef map[rcp_const_basic, rcp_const_basic] map_basic_basic @@ -112,8 +112,8 @@ cdef extern from "" namespace "SymEngine": ctypedef multiset[rcp_const_basic] multiset_basic "SymEngine::multiset_basic" cdef cppclass Basic: - string __str__() except+ nogil - unsigned int hash() except+ nogil + string __str__() nogil except + + unsigned int hash() nogil except + vec_basic get_args() nogil int __cmp__(const Basic &o) nogil @@ -124,11 +124,11 @@ cdef extern from "" namespace "SymEngine": ctypedef unordered_map[rcp_const_basic, rcp_const_number].iterator umap_basic_num_iterator "SymEngine::umap_basic_num::iterator" ctypedef vector[pair[rcp_const_basic, rcp_const_basic]] vec_pair "SymEngine::vec_pair" - bool eq(const Basic &a, const Basic &b) except+ nogil - bool neq(const Basic &a, const Basic &b) except+ nogil + bool eq(const Basic &a, const Basic &b) nogil except + + bool neq(const Basic &a, const Basic &b) nogil except + RCP[const Symbol] rcp_static_cast_Symbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil - RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) except+ nogil + RCP[const PySymbol] rcp_static_cast_PySymbol "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil except + RCP[const Integer] rcp_static_cast_Integer "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Rational] rcp_static_cast_Rational "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil RCP[const Complex] rcp_static_cast_Complex "SymEngine::rcp_static_cast"(rcp_const_basic &b) nogil @@ -162,18 +162,18 @@ cdef extern from "" namespace "SymEngine": bool is_a[T] (const Basic &b) nogil bool is_a_sub[T] (const Basic &b) nogil - rcp_const_basic expand(rcp_const_basic &o, bool deep) except+ nogil + rcp_const_basic expand(rcp_const_basic &o, bool deep) nogil except + void as_numer_denom(rcp_const_basic &x, const Ptr[RCP[Basic]] &numer, const Ptr[RCP[Basic]] &denom) nogil void as_real_imag(rcp_const_basic &x, const Ptr[RCP[Basic]] &real, const Ptr[RCP[Basic]] &imag) nogil - void cse(vec_pair &replacements, vec_basic &reduced_exprs, const vec_basic &exprs) except+ nogil + void cse(vec_pair &replacements, vec_basic &reduced_exprs, const vec_basic &exprs) nogil except + cdef extern from "" namespace "SymEngine": - rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) except+ nogil - rcp_const_basic ssubs (rcp_const_basic &x, const map_basic_basic &x) except+ nogil - rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) except+ nogil + rcp_const_basic msubs (rcp_const_basic &x, const map_basic_basic &x) nogil except + + rcp_const_basic ssubs (rcp_const_basic &x, const map_basic_basic &x) nogil except + + rcp_const_basic xreplace (rcp_const_basic &x, const map_basic_basic &x) nogil except + cdef extern from "" namespace "SymEngine": - rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) except+ nogil + rcp_const_basic diff "SymEngine::sdiff"(rcp_const_basic &arg, rcp_const_basic &x) nogil except + cdef extern from "" namespace "SymEngine": cdef cppclass Symbol(Basic): @@ -215,8 +215,8 @@ cdef extern from "pywrapper.h" namespace "SymEngine": PySymbol(string name, PyObject* pyobj, bool use_pickle) except + PyObject* get_py_object() except + - string wrapper_dumps(const Basic &x) except+ nogil - rcp_const_basic wrapper_loads(const string &s) except+ nogil + string wrapper_dumps(const Basic &x) nogil except + + rcp_const_basic wrapper_loads(const string &s) nogil except + cdef extern from "" namespace "SymEngine": cdef cppclass Integer(Number): @@ -286,9 +286,9 @@ cdef extern from "" namespace "SymEngine": pass cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic add(rcp_const_basic &a, rcp_const_basic &b) except+ nogil - cdef rcp_const_basic sub(rcp_const_basic &a, rcp_const_basic &b) except+ nogil - cdef rcp_const_basic add(const vec_basic &a) except+ nogil + cdef rcp_const_basic add(rcp_const_basic &a, rcp_const_basic &b) nogil except + + cdef rcp_const_basic sub(rcp_const_basic &a, rcp_const_basic &b) nogil except + + cdef rcp_const_basic add(const vec_basic &a) nogil except + cdef cppclass Add(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) @@ -296,10 +296,10 @@ cdef extern from "" namespace "SymEngine": const umap_basic_num &get_dict() cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic mul(rcp_const_basic &a, rcp_const_basic &b) except+ nogil - cdef rcp_const_basic div(rcp_const_basic &a, rcp_const_basic &b) except+ nogil - cdef rcp_const_basic neg(rcp_const_basic &a) except+ nogil - cdef rcp_const_basic mul(const vec_basic &a) except+ nogil + cdef rcp_const_basic mul(rcp_const_basic &a, rcp_const_basic &b) nogil except + + cdef rcp_const_basic div(rcp_const_basic &a, rcp_const_basic &b) nogil except + + cdef rcp_const_basic neg(rcp_const_basic &a) nogil except + + cdef rcp_const_basic mul(const vec_basic &a) nogil except + cdef cppclass Mul(Basic): void as_two_terms(const Ptr[RCP[Basic]] &a, const Ptr[RCP[Basic]] &b) @@ -308,9 +308,9 @@ cdef extern from "" namespace "SymEngine": cdef RCP[const Mul] mul_from_dict "SymEngine::Mul::from_dict"(RCP[const Number] coef, map_basic_basic &d) nogil cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic pow(rcp_const_basic &a, rcp_const_basic &b) except+ nogil - cdef rcp_const_basic sqrt(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic exp(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic pow(rcp_const_basic &a, rcp_const_basic &b) nogil except + + cdef rcp_const_basic sqrt(rcp_const_basic &x) nogil except + + cdef rcp_const_basic exp(rcp_const_basic &x) nogil except + cdef cppclass Pow(Basic): rcp_const_basic get_base() nogil @@ -344,58 +344,58 @@ cdef extern from "" namespace "SymEngine": RCP[const PyFunctionClass] pyfunc_class, const PyObject* pyobject) nogil cdef extern from "" namespace "SymEngine": - cdef rcp_const_basic sin(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic cos(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic tan(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic cot(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic csc(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic sec(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic asin(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acos(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic atan(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acot(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acsc(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic asec(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic sinh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic cosh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic tanh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic coth(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic csch(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic sech(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic asinh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acosh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic atanh(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acoth(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic acsch(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic asech(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic function_symbol(string name, const vec_basic &arg) except+ nogil - cdef rcp_const_basic abs(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic max(const vec_basic &arg) except+ nogil - cdef rcp_const_basic min(const vec_basic &arg) except+ nogil - cdef rcp_const_basic gamma(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic atan2(rcp_const_basic &num, rcp_const_basic &den) except+ nogil - cdef rcp_const_basic lambertw(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic zeta(rcp_const_basic &s) except+ nogil - cdef rcp_const_basic zeta(rcp_const_basic &s, rcp_const_basic &a) except+ nogil - cdef rcp_const_basic dirichlet_eta(rcp_const_basic &s) except+ nogil - cdef rcp_const_basic kronecker_delta(rcp_const_basic &i, rcp_const_basic &j) except+ nogil - cdef rcp_const_basic levi_civita(const vec_basic &arg) except+ nogil - cdef rcp_const_basic erf(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic erfc(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic lowergamma(rcp_const_basic &s, rcp_const_basic &x) except+ nogil - cdef rcp_const_basic uppergamma(rcp_const_basic &s, rcp_const_basic &x) except+ nogil - cdef rcp_const_basic loggamma(rcp_const_basic &arg) except+ nogil - cdef rcp_const_basic beta(rcp_const_basic &x, rcp_const_basic &y) except+ nogil - cdef rcp_const_basic polygamma(rcp_const_basic &n, rcp_const_basic &x) except+ nogil - cdef rcp_const_basic digamma(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic trigamma(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic sign(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic floor(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic ceiling(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic conjugate(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic log(rcp_const_basic &x) except+ nogil - cdef rcp_const_basic log(rcp_const_basic &x, rcp_const_basic &y) except+ nogil - cdef rcp_const_basic unevaluated_expr(rcp_const_basic &x) except+ nogil + cdef rcp_const_basic sin(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic cos(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic tan(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic cot(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic csc(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic sec(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic asin(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acos(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic atan(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acot(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acsc(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic asec(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic sinh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic cosh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic tanh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic coth(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic csch(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic sech(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic asinh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acosh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic atanh(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acoth(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic acsch(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic asech(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic function_symbol(string name, const vec_basic &arg) nogil except + + cdef rcp_const_basic abs(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic max(const vec_basic &arg) nogil except + + cdef rcp_const_basic min(const vec_basic &arg) nogil except + + cdef rcp_const_basic gamma(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic atan2(rcp_const_basic &num, rcp_const_basic &den) nogil except + + cdef rcp_const_basic lambertw(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic zeta(rcp_const_basic &s) nogil except + + cdef rcp_const_basic zeta(rcp_const_basic &s, rcp_const_basic &a) nogil except + + cdef rcp_const_basic dirichlet_eta(rcp_const_basic &s) nogil except + + cdef rcp_const_basic kronecker_delta(rcp_const_basic &i, rcp_const_basic &j) nogil except + + cdef rcp_const_basic levi_civita(const vec_basic &arg) nogil except + + cdef rcp_const_basic erf(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic erfc(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic lowergamma(rcp_const_basic &s, rcp_const_basic &x) nogil except + + cdef rcp_const_basic uppergamma(rcp_const_basic &s, rcp_const_basic &x) nogil except + + cdef rcp_const_basic loggamma(rcp_const_basic &arg) nogil except + + cdef rcp_const_basic beta(rcp_const_basic &x, rcp_const_basic &y) nogil except + + cdef rcp_const_basic polygamma(rcp_const_basic &n, rcp_const_basic &x) nogil except + + cdef rcp_const_basic digamma(rcp_const_basic &x) nogil except + + cdef rcp_const_basic trigamma(rcp_const_basic &x) nogil except + + cdef rcp_const_basic sign(rcp_const_basic &x) nogil except + + cdef rcp_const_basic floor(rcp_const_basic &x) nogil except + + cdef rcp_const_basic ceiling(rcp_const_basic &x) nogil except + + cdef rcp_const_basic conjugate(rcp_const_basic &x) nogil except + + cdef rcp_const_basic log(rcp_const_basic &x) nogil except + + cdef rcp_const_basic log(rcp_const_basic &x, rcp_const_basic &y) nogil except + + cdef rcp_const_basic unevaluated_expr(rcp_const_basic &x) nogil except + cdef cppclass Function(Basic): pass @@ -632,7 +632,7 @@ cdef extern from "" namespace "SymEngine": const unsigned ncols() nogil rcp_const_basic get(unsigned i, unsigned j) nogil rcp_const_basic set(unsigned i, unsigned j, rcp_const_basic e) nogil - string __str__() except+ nogil + string __str__() nogil except + bool eq(const MatrixBase &) nogil rcp_const_basic det() nogil void inv(MatrixBase &) @@ -681,20 +681,20 @@ cdef extern from "" namespace "SymEngine": DenseMatrix* static_cast_DenseMatrix "static_cast"(const MatrixBase *a) void inverse_FFLU "SymEngine::inverse_fraction_free_LU"(const DenseMatrix &A, - DenseMatrix &B) except+ nogil - void pivoted_LU_solve (const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) except+ nogil + DenseMatrix &B) nogil except + + void pivoted_LU_solve (const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) nogil except + void inverse_GJ "SymEngine::inverse_gauss_jordan"(const DenseMatrix &A, - DenseMatrix &B) except+ nogil + DenseMatrix &B) nogil except + void FFLU_solve "SymEngine::fraction_free_LU_solve"(const DenseMatrix &A, - const DenseMatrix &b, DenseMatrix &x) except+ nogil + const DenseMatrix &b, DenseMatrix &x) nogil except + void FFGJ_solve "SymEngine::fraction_free_gauss_jordan_solve"(const DenseMatrix &A, - const DenseMatrix &b, DenseMatrix &x) except+ nogil + const DenseMatrix &b, DenseMatrix &x) nogil except + void LDL_solve "SymEngine::LDL_solve"(const DenseMatrix &A, const DenseMatrix &b, - DenseMatrix &x) except+ nogil + DenseMatrix &x) nogil except + void jacobian "SymEngine::sjacobian"(const DenseMatrix &A, - const DenseMatrix &x, DenseMatrix &result) except+ nogil + const DenseMatrix &x, DenseMatrix &result) nogil except + void diff "SymEngine::sdiff"(const DenseMatrix &A, - rcp_const_basic &x, DenseMatrix &result) except+ nogil + rcp_const_basic &x, DenseMatrix &result) nogil except + void eye (DenseMatrix &A, int k) nogil void diag(DenseMatrix &A, vec_basic &v, int k) nogil void ones(DenseMatrix &A) nogil @@ -707,7 +707,7 @@ cdef extern from "" namespace "SymEngine": void cross(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &C) nogil cdef extern from "": - void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[pair[int, int]] &P) except+ nogil + void pivoted_LU (const DenseMatrix &A, DenseMatrix &L, DenseMatrix &U, vector[pair[int, int]] &P) nogil except + cdef extern from "" namespace "SymEngine": int probab_prime_p(const Integer &a, int reps) @@ -716,10 +716,10 @@ cdef extern from "" namespace "SymEngine": RCP[const Integer] lcm(const Integer &a, const Integer &b) nogil void gcd_ext(const Ptr[RCP[Integer]] &g, const Ptr[RCP[Integer]] &s, const Ptr[RCP[Integer]] &t, const Integer &a, const Integer &b) nogil - RCP[const Integer] mod "SymEngine::mod_f"(const Integer &n, const Integer &d) except+ nogil - RCP[const Integer] quotient "SymEngine::quotient_f"(const Integer &n, const Integer &d) except+ nogil + RCP[const Integer] mod "SymEngine::mod_f"(const Integer &n, const Integer &d) nogil except + + RCP[const Integer] quotient "SymEngine::quotient_f"(const Integer &n, const Integer &d) nogil except + void quotient_mod "SymEngine::quotient_mod_f"(const Ptr[RCP[Integer]] &q, const Ptr[RCP[Integer]] &mod, - const Integer &n, const Integer &d) except+ nogil + const Integer &n, const Integer &d) nogil except + int mod_inverse(const Ptr[RCP[Integer]] &b, const Integer &a, const Integer &m) nogil bool crt(const Ptr[RCP[Integer]] &R, const vec_integer &rem, @@ -739,9 +739,9 @@ cdef extern from "" namespace "SymEngine": unsigned B, unsigned retries) nogil int factor_pollard_rho_method(const Ptr[RCP[Integer]] &f, const Integer &n, unsigned retries) nogil - void prime_factors(vec_integer &primes, const Integer &n) except+ nogil - void prime_factor_multiplicities(map_integer_uint &primes, const Integer &n) except+ nogil - RCP[const Number] bernoulli(unsigned long n) except+ nogil + void prime_factors(vec_integer &primes, const Integer &n) nogil except + + void prime_factor_multiplicities(map_integer_uint &primes, const Integer &n) nogil except + + RCP[const Number] bernoulli(unsigned long n) nogil except + bool primitive_root(const Ptr[RCP[Integer]] &g, const Integer &n) nogil void primitive_root_list(vec_integer &roots, const Integer &n) nogil RCP[const Integer] totient(RCP[const Integer] n) nogil @@ -769,15 +769,15 @@ cdef extern from "" namespace "SymEngine": unsigned next_prime() nogil cdef extern from "" namespace "SymEngine": - bool has_symbol(const Basic &b, const Basic &x) except+ nogil - rcp_const_basic coeff(const Basic &b, const Basic &x, const Basic &n) except+ nogil - set_basic free_symbols(const Basic &b) except+ nogil - set_basic free_symbols(const MatrixBase &b) except+ nogil + bool has_symbol(const Basic &b, const Basic &x) nogil except + + rcp_const_basic coeff(const Basic &b, const Basic &x, const Basic &n) nogil except + + set_basic free_symbols(const Basic &b) nogil except + + set_basic free_symbols(const MatrixBase &b) nogil except + unsigned count_ops(const vec_basic &a) nogil cdef extern from "" namespace "SymEngine": cdef cppclass Boolean(Basic): - RCP[const Boolean] logical_not() except+ nogil + RCP[const Boolean] logical_not() nogil except + cdef cppclass BooleanAtom(Boolean): bool get_val() nogil cdef cppclass Relational(Boolean): @@ -805,25 +805,25 @@ cdef extern from "" namespace "SymEngine": rcp_const_basic boolTrue rcp_const_basic boolFalse - cdef RCP[const Boolean] Eq(rcp_const_basic &lhs) except+ nogil - cdef RCP[const Boolean] Eq(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil - cdef RCP[const Boolean] Ne(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil - cdef RCP[const Boolean] Ge(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil - cdef RCP[const Boolean] Gt(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil - cdef RCP[const Boolean] Le(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil - cdef RCP[const Boolean] Lt(rcp_const_basic &lhs, rcp_const_basic &rhs) except+ nogil + cdef RCP[const Boolean] Eq(rcp_const_basic &lhs) nogil except + + cdef RCP[const Boolean] Eq(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + + cdef RCP[const Boolean] Ne(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + + cdef RCP[const Boolean] Ge(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + + cdef RCP[const Boolean] Gt(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + + cdef RCP[const Boolean] Le(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + + cdef RCP[const Boolean] Lt(rcp_const_basic &lhs, rcp_const_basic &rhs) nogil except + ctypedef Boolean const_Boolean "const SymEngine::Boolean" ctypedef vector[pair[rcp_const_basic, RCP[const_Boolean]]] PiecewiseVec; ctypedef vector[RCP[Boolean]] vec_boolean "SymEngine::vec_boolean" ctypedef set[RCP[Boolean]] set_boolean "SymEngine::set_boolean" - cdef RCP[const Boolean] logical_and(set_boolean &s) except+ nogil - cdef RCP[const Boolean] logical_nand(set_boolean &s) except+ nogil - cdef RCP[const Boolean] logical_or(set_boolean &s) except+ nogil - cdef RCP[const Boolean] logical_not(RCP[const Boolean] &s) except+ nogil - cdef RCP[const Boolean] logical_nor(set_boolean &s) except+ nogil - cdef RCP[const Boolean] logical_xor(vec_boolean &s) except+ nogil - cdef RCP[const Boolean] logical_xnor(vec_boolean &s) except+ nogil - cdef rcp_const_basic piecewise(PiecewiseVec vec) except+ nogil + cdef RCP[const Boolean] logical_and(set_boolean &s) nogil except + + cdef RCP[const Boolean] logical_nand(set_boolean &s) nogil except + + cdef RCP[const Boolean] logical_or(set_boolean &s) nogil except + + cdef RCP[const Boolean] logical_not(RCP[const Boolean] &s) nogil except + + cdef RCP[const Boolean] logical_nor(set_boolean &s) nogil except + + cdef RCP[const Boolean] logical_xor(vec_boolean &s) nogil except + + cdef RCP[const Boolean] logical_xnor(vec_boolean &s) nogil except + + cdef rcp_const_basic piecewise(PiecewiseVec vec) nogil except + cdef RCP[const Boolean] contains(rcp_const_basic &expr, RCP[const Set] &set) nogil @@ -833,26 +833,26 @@ cdef extern from "" namespace "SymEngine": cdef EvalfDomain EvalfComplex "SymEngine::EvalfDomain::Complex" cdef EvalfDomain EvalfReal "SymEngine::EvalfDomain::Real" cdef EvalfDomain EvalfSymbolic "SymEngine::EvalfDomain::Symbolic" - rcp_const_basic evalf(const Basic &b, unsigned long bits, EvalfDomain domain) except+ nogil + rcp_const_basic evalf(const Basic &b, unsigned long bits, EvalfDomain domain) nogil except + cdef extern from "" namespace "SymEngine": - double eval_double(const Basic &b) except+ nogil - double complex eval_complex_double(const Basic &b) except+ nogil + double eval_double(const Basic &b) nogil except + + double complex eval_complex_double(const Basic &b) nogil except + cdef extern from "" namespace "SymEngine": cdef cppclass LambdaRealDoubleVisitor: LambdaRealDoubleVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse) except+ nogil + void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except + void call(double *r, const double *x) nogil cdef cppclass LambdaComplexDoubleVisitor: LambdaComplexDoubleVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse) except+ nogil + void init(const vec_basic &x, const vec_basic &b, bool cse) nogil except + void call(double complex *r, const double complex *x) nogil cdef extern from "" namespace "SymEngine": cdef cppclass LLVMVisitor: LLVMVisitor() nogil - void init(const vec_basic &x, const vec_basic &b, bool cse, int opt_level) except+ nogil + void init(const vec_basic &x, const vec_basic &b, bool cse, int opt_level) nogil except + const string& dumps() nogil void loads(const string&) nogil @@ -868,27 +868,27 @@ cdef extern from "" namespace "SymEngine": cdef extern from "" namespace "SymEngine": cdef cppclass SeriesCoeffInterface: - rcp_const_basic as_basic() except+ nogil - umap_int_basic as_dict() except+ nogil - rcp_const_basic get_coeff(int) except+ nogil + rcp_const_basic as_basic() nogil except + + umap_int_basic as_dict() nogil except + + rcp_const_basic get_coeff(int) nogil except + ctypedef RCP[const SeriesCoeffInterface] rcp_const_seriescoeffinterface "SymEngine::RCP" - rcp_const_seriescoeffinterface series "SymEngine::series"(rcp_const_basic &ex, RCP[const Symbol] &var, unsigned int prec) except+ nogil + rcp_const_seriescoeffinterface series "SymEngine::series"(rcp_const_basic &ex, RCP[const Symbol] &var, unsigned int prec) nogil except + cdef extern from "" namespace "SymEngine": - void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil + void eval_mpfr(mpfr_t result, const Basic &b, mpfr_rnd_t rnd) nogil except + cdef extern from "" namespace "SymEngine": - void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) except+ nogil + void eval_mpc(mpc_t result, const Basic &b, mpfr_rnd_t rnd) nogil except + cdef extern from "" namespace "SymEngine": - rcp_const_basic parse(const string &n) except+ nogil + rcp_const_basic parse(const string &n) nogil except + cdef extern from "" namespace "SymEngine": cdef cppclass Set(Basic): - RCP[const Set] set_intersection(RCP[const Set] &o) except+ nogil - RCP[const Set] set_union(RCP[const Set] &o) except+ nogil - RCP[const Set] set_complement(RCP[const Set] &o) except+ nogil - RCP[const Boolean] contains(rcp_const_basic &a) except+ nogil + RCP[const Set] set_intersection(RCP[const Set] &o) nogil except + + RCP[const Set] set_union(RCP[const Set] &o) nogil except + + RCP[const Set] set_complement(RCP[const Set] &o) nogil except + + RCP[const Boolean] contains(rcp_const_basic &a) nogil except + cdef cppclass Interval(Set): pass cdef cppclass EmptySet(Set): @@ -912,24 +912,24 @@ cdef extern from "" namespace "SymEngine": cdef cppclass ImageSet(Set): pass ctypedef set[RCP[Set]] set_set "SymEngine::set_set" - cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) except+ nogil - cdef RCP[const EmptySet] emptyset() except+ nogil - cdef RCP[const Reals] reals() except+ nogil - cdef RCP[const Rationals] rationals() except+ nogil - cdef RCP[const Integers] integers() except+ nogil - cdef RCP[const UniversalSet] universalset() except+ nogil - cdef RCP[const Set] finiteset(set_basic &container) except+ nogil - cdef RCP[const Set] set_union(set_set &a) except+ nogil - cdef RCP[const Set] set_intersection(set_set &a) except+ nogil - cdef RCP[const Set] set_complement_helper(RCP[const Set] &container, RCP[const Set] &universe) except+ nogil - cdef RCP[const Set] set_complement(RCP[const Set] &universe, RCP[const Set] &container) except+ nogil - cdef RCP[const Set] conditionset(rcp_const_basic &sym, RCP[const Boolean] &condition) except+ nogil - cdef RCP[const Set] imageset(rcp_const_basic &sym, rcp_const_basic &expr, RCP[const Set] &base) except+ nogil + cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except + + cdef RCP[const EmptySet] emptyset() nogil except + + cdef RCP[const Reals] reals() nogil except + + cdef RCP[const Rationals] rationals() nogil except + + cdef RCP[const Integers] integers() nogil except + + cdef RCP[const UniversalSet] universalset() nogil except + + cdef RCP[const Set] finiteset(set_basic &container) nogil except + + cdef RCP[const Set] set_union(set_set &a) nogil except + + cdef RCP[const Set] set_intersection(set_set &a) nogil except + + cdef RCP[const Set] set_complement_helper(RCP[const Set] &container, RCP[const Set] &universe) nogil except + + cdef RCP[const Set] set_complement(RCP[const Set] &universe, RCP[const Set] &container) nogil except + + cdef RCP[const Set] conditionset(rcp_const_basic &sym, RCP[const Boolean] &condition) nogil except + + cdef RCP[const Set] imageset(rcp_const_basic &sym, rcp_const_basic &expr, RCP[const Set] &base) nogil except + cdef extern from "" namespace "SymEngine": - cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym) except+ nogil - cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym, RCP[const Set] &domain) except+ nogil - cdef vec_basic linsolve(const vec_basic &eqs, const vec_sym &syms) except+ nogil + cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym) nogil except + + cdef RCP[const Set] solve(rcp_const_basic &f, RCP[const Symbol] &sym, RCP[const Set] &domain) nogil except + + cdef vec_basic linsolve(const vec_basic &eqs, const vec_sym &syms) nogil except + cdef extern from "symengine/tribool.h" namespace "SymEngine": cdef cppclass tribool: @@ -945,10 +945,10 @@ cdef extern from "symengine/tribool.h" namespace "SymEngine::tribool": cdef tribool tritrue cdef extern from "" namespace "SymEngine": - string ccode(const Basic &x) except+ nogil - string latex(const Basic &x) except+ nogil - string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) except+ nogil - string unicode(const Basic &x) except+ nogil + string ccode(const Basic &x) nogil except + + string latex(const Basic &x) nogil except + + string latex(const DenseMatrix &x, unsigned max_rows, unsigned max_cols) nogil except + + string unicode(const Basic &x) nogil except + ## Defined in 'symengine/cwrapper.cpp' cdef struct CRCPBasic: From cb92ff6a9190ada12daaff78ca31cb97bad2b618 Mon Sep 17 00:00:00 2001 From: firatbezir Date: Mon, 10 Feb 2025 22:01:51 +0300 Subject: [PATCH 288/314] Update README with verification instructions --- README.md | 108 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 847af7d6f..d9141c7c1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ + # SymEngine Python Wrappers -Python wrappers to the C++ library [SymEngine](https://github.com/symengine/symengine), +Python wrappers to the C++ library [SymEngine](https://github.com/symengine/symengine), a fast C++ symbolic manipulation library. -[![Build Status](https://travis-ci.org/symengine/symengine.py.svg)](https://travis-ci.org/symengine/symengine.py) [![Build status](https://ci.appveyor.com/api/projects/status/sl189l9ck3gd8qvk/branch/master?svg=true)](https://ci.appveyor.com/project/symengine/symengine-py/branch/master) +[![Build Status](https://travis-ci.org/symengine/symengine.py.svg)](https://travis-ci.org/symengine/symengine.py) +[![Build status](https://ci.appveyor.com/api/projects/status/sl189l9ck3gd8qvk/branch/master?svg=true)](https://ci.appveyor.com/project/symengine/symengine-py/branch/master) ## Installation @@ -11,71 +13,91 @@ a fast C++ symbolic manipulation library. See License section for information about wheels - pip install symengine --user +```bash +pip install symengine --user +``` ### Conda package manager - conda install python-symengine -c symengine -c conda-forge +```bash +conda install python-symengine -c symengine -c conda-forge +``` -optionally, you may choose to install an early [developer preview](https://github.com/symengine/python-symengine-feedstock): +Optionally, you may choose to install an early [developer preview](https://github.com/symengine/python-symengine-feedstock): - conda install python-symengine -c symengine/label/dev -c conda-forge +```bash +conda install python-symengine -c symengine/label/dev -c conda-forge +``` ### Build from source Install prerequisites. - CMake >= 2.8.12 - Python3 >= 3.8 - Cython >= 0.29.24 - SymEngine >= 0.7.0 +```bash +CMake >= 2.8.12 +Python3 >= 3.8 +Cython >= 0.29.24 +SymEngine >= 0.7.0 +``` -For SymEngine, only a specific commit/tag (see symengine_version.txt) is supported. -Latest git master branch may not work as there may be breaking changes in SymEngine. +For **SymEngine**, only a specific commit/tag (see `symengine_version.txt`) is supported. +The latest git master branch may not work as there may be breaking changes in **SymEngine**. Python wrappers can be installed by, - python setup.py install +```bash +python setup.py install +``` + +Additional options to `setup.py` are: + +```bash +python setup.py install build_ext + --symengine-dir=/path/to/symengine/install/dir # Path to SymEngine install directory or build directory + --compiler=mingw32|msvc|cygwin # Select the compiler for Windows + --generator=cmake-generator # CMake Generator + --build-type=Release|Debug # Set build-type for multi-configuration generators like MSVC + --define="var1=value1;var2=value2" # Give options to CMake + --inplace # Build the extension in source tree +``` + +Standard options to `setup.py` like `--user`, `--prefix` can be used to configure install location. +NumPy is used if found by default, if you wish to make your choice of NumPy use explicit: then add e.g. `WITH_NUMPY=False` to `--define`. + +### Notes on Dependencies -Additional options to setup.py are +If you intend to evaluate floating-point expressions (using **lambdify**), you should consider linking against **LLVM**. Many users might also benefit from linking against **FLINT**, as it is now LGPL-licensed. - python setup.py install build_ext - --symengine-dir=/path/to/symengine/install/dir # Path to SymEngine install directory or build directory - --compiler=mingw32|msvc|cygwin # Select the compiler for Windows - --generator=cmake-generator # CMake Generator - --build-type=Release|Debug # Set build-type for multi-configuration generators like MSVC - --define="var1=value1;var2=value2" # Give options to CMake - --inplace # Build the extension in source tree +In general, **sudo** is only required if you are installing to the default prefix (`/usr/local`). We recommend specifying a custom prefix (`--prefix=$HOME/.local`) to avoid requiring administrative privileges, which most users can do without using **sudo**. -Standard options to setup.py like `--user`, `--prefix` can be used to -configure install location. NumPy is used if found by default, if you wish -to make your choice of NumPy use explicit: then add -e.g. ``WITH_NUMPY=False`` to ``--define``. +If you're uncomfortable specifying the prefix manually, we suggest using **Conda** or installing the pre-built wheels via **pip** instead of building from source. -Use SymEngine from Python as follows: +## Verification - >>> from symengine import var - >>> var("x y z") - (x, y, z) - >>> e = (x+y+z)**2 - >>> e.expand() - 2*x*y + 2*x*z + 2*y*z + x**2 + y**2 + z**2 +You can verify the installation of **SymEngine** by using the provided code snippet in this README. This snippet ensures that the installation works as expected and that basic functionality is available. -You can read Python tests in `symengine/tests` to see what features are -implemented. +```python +from symengine import var +x, y, z = var('x y z') +e = (x + y + z)**2 +expanded_e = e.expand() +print(expanded_e) +``` +This will output: +```python +x**2 + y**2 + z**2 + 2*x*y + 2*x*z + 2*y*z +``` +Note: The verification code provided above checks the functionality of SymEngine. For additional verification specific to SymEngine, please refer to the [official SymEngine Python bindings repository](https://github.com/symengine/symengine.py) for further tests and examples. ## License -symengine.py is MIT licensed and uses several LGPL, BSD-3 and MIT licensed libraries +symengine.py is MIT licensed and uses several LGPL, BSD-3, and MIT licensed libraries. -Licenses for the dependencies of pip wheels are as follows, +Licenses for the dependencies of pip wheels are as follows: -pip wheels on Unix use GMP (LGPL-3.0-or-later), MPFR (LGPL-3.0-or-later), -MPC (LGPL-3.0-or-later), LLVM (Apache-2.0), zlib (Zlib), libxml2 (MIT), -zstd (BSD-3-Clause) and symengine (MIT AND BSD-3-Clause). -pip wheels on Windows use MPIR (LGPL-3.0-or-later) instead of GMP above and -pthreads-win32 (LGPL-3.0-or-later) additionally. -NumPy (BSD-3-Clause) and SymPy (BSD-3-Clause) are optional dependencies. -Sources for these binary dependencies can be found on https://github.com/symengine/symengine-wheels/releases +- pip wheels on Unix use **GMP** (LGPL-3.0-or-later), **MPFR** (LGPL-3.0-or-later), **MPC** (LGPL-3.0-or-later), **LLVM** (Apache-2.0), **zlib** (Zlib), **libxml2** (MIT), **zstd** (BSD-3-Clause), and **symengine** (MIT AND BSD-3-Clause). +- pip wheels on Windows use **MPIR** (LGPL-3.0-or-later) instead of **GMP** above and **pthreads-win32** (LGPL-3.0-or-later) additionally. +- **NumPy** (BSD-3-Clause) and **SymPy** (BSD-3-Clause) are optional dependencies. +- Sources for these binary dependencies can be found on [symengine-wheels](https://github.com/symengine/symengine-wheels/releases). From 984cb44b9b85c55b6e375b548b5665fd9183dece Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 18:30:19 -0600 Subject: [PATCH 289/314] Remove symengine conda channel from isntructions --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index d9141c7c1..6e6e624fc 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,7 @@ pip install symengine --user ### Conda package manager ```bash -conda install python-symengine -c symengine -c conda-forge -``` - -Optionally, you may choose to install an early [developer preview](https://github.com/symengine/python-symengine-feedstock): - -```bash -conda install python-symengine -c symengine/label/dev -c conda-forge +conda install python-symengine -c conda-forge ``` ### Build from source From 63a7a0f6d3bde94b1fb21cd87874935478ee4875 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 18:35:57 -0600 Subject: [PATCH 290/314] Update README.md --- README.md | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6e6e624fc..2a89249ea 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SymEngine Python Wrappers -Python wrappers to the C++ library [SymEngine](https://github.com/symengine/symengine), +Python wrappers to the C++ library [SymEngine](https://github.com/symengine/symengine), a fast C++ symbolic manipulation library. [![Build Status](https://travis-ci.org/symengine/symengine.py.svg)](https://travis-ci.org/symengine/symengine.py) @@ -34,8 +34,9 @@ Cython >= 0.29.24 SymEngine >= 0.7.0 ``` -For **SymEngine**, only a specific commit/tag (see `symengine_version.txt`) is supported. -The latest git master branch may not work as there may be breaking changes in **SymEngine**. +For **SymEngine**, only a specific commit/tag (see `symengine_version.txt`) is +supported. The latest git master branch may not work as there may be breaking +changes in **SymEngine**. Python wrappers can be installed by, @@ -55,20 +56,31 @@ python setup.py install build_ext --inplace # Build the extension in source tree ``` -Standard options to `setup.py` like `--user`, `--prefix` can be used to configure install location. -NumPy is used if found by default, if you wish to make your choice of NumPy use explicit: then add e.g. `WITH_NUMPY=False` to `--define`. +Standard options to `setup.py` like `--user`, `--prefix` can be used to +configure install location. NumPy is used if found by default, if you wish +to make your choice of NumPy use explicit: then add +e.g. `WITH_NUMPY=False` to `--define`. ### Notes on Dependencies -If you intend to evaluate floating-point expressions (using **lambdify**), you should consider linking against **LLVM**. Many users might also benefit from linking against **FLINT**, as it is now LGPL-licensed. +If you intend to evaluate floating-point expressions (using **lambdify**), +you should consider linking against **LLVM**. Many users might also benefit +from linking against **FLINT**, as it is now LGPL-licensed. -In general, **sudo** is only required if you are installing to the default prefix (`/usr/local`). We recommend specifying a custom prefix (`--prefix=$HOME/.local`) to avoid requiring administrative privileges, which most users can do without using **sudo**. +In general, **sudo** is only required if you are installing to the default +prefix (`/usr/local`). We recommend specifying a custom prefix +(`--prefix=$HOME/.local`) to avoid requiring administrative privileges, +which most users can do without using **sudo**. -If you're uncomfortable specifying the prefix manually, we suggest using **Conda** or installing the pre-built wheels via **pip** instead of building from source. +If you're uncomfortable specifying the prefix manually, we suggest using +**Conda** or installing the pre-built wheels via **pip** instead of building +from source. ## Verification -You can verify the installation of **SymEngine** by using the provided code snippet in this README. This snippet ensures that the installation works as expected and that basic functionality is available. +You can verify the installation of **SymEngine** by using the provided code +snippet in this README. This snippet ensures that the installation works as +expected and that basic functionality is available. ```python from symengine import var @@ -82,16 +94,26 @@ This will output: x**2 + y**2 + z**2 + 2*x*y + 2*x*z + 2*y*z ``` -Note: The verification code provided above checks the functionality of SymEngine. For additional verification specific to SymEngine, please refer to the [official SymEngine Python bindings repository](https://github.com/symengine/symengine.py) for further tests and examples. +Note: The verification code provided above checks the functionality of +SymEngine. For additional verification specific to SymEngine, please refer to +the [official SymEngine Python bindings repository](https://github.com/symengine/symengine.py) +for further tests and examples. ## License -symengine.py is MIT licensed and uses several LGPL, BSD-3, and MIT licensed libraries. +symengine.py is MIT licensed and uses several LGPL, BSD-3, and MIT licensed +libraries. Licenses for the dependencies of pip wheels are as follows: -- pip wheels on Unix use **GMP** (LGPL-3.0-or-later), **MPFR** (LGPL-3.0-or-later), **MPC** (LGPL-3.0-or-later), **LLVM** (Apache-2.0), **zlib** (Zlib), **libxml2** (MIT), **zstd** (BSD-3-Clause), and **symengine** (MIT AND BSD-3-Clause). -- pip wheels on Windows use **MPIR** (LGPL-3.0-or-later) instead of **GMP** above and **pthreads-win32** (LGPL-3.0-or-later) additionally. -- **NumPy** (BSD-3-Clause) and **SymPy** (BSD-3-Clause) are optional dependencies. -- Sources for these binary dependencies can be found on [symengine-wheels](https://github.com/symengine/symengine-wheels/releases). +- pip wheels on Unix use **GMP** (LGPL-3.0-or-later), + **MPFR** (LGPL-3.0-or-later), **MPC** (LGPL-3.0-or-later), + **LLVM** (Apache-2.0), **zlib** (Zlib), **libxml2** (MIT), + **zstd** (BSD-3-Clause), and **symengine** (MIT AND BSD-3-Clause). +- pip wheels on Windows use **MPIR** (LGPL-3.0-or-later) instead of **GMP** + above and **pthreads-win32** (LGPL-3.0-or-later) additionally. +- **NumPy** (BSD-3-Clause) and **SymPy** (BSD-3-Clause) are optional + dependencies. +- Sources for these binary dependencies can be found on + [symengine-wheels](https://github.com/symengine/symengine-wheels/releases). From a3a9ce81796a2b4defdc2b7f074d440c58158e39 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 18:38:47 -0600 Subject: [PATCH 291/314] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2a89249ea..e13eb7272 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # SymEngine Python Wrappers Python wrappers to the C++ library [SymEngine](https://github.com/symengine/symengine), From 7c48a0d75dcdd543486587584ecaa0643fa9d6d4 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 19:56:16 -0600 Subject: [PATCH 292/314] Update version --- CMakeLists.txt | 2 +- symengine_version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 418b6704c..3c83e7cfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(CMAKE_PREFIX_PATH ${SymEngine_DIR} ${CMAKE_PREFIX_PATH}) include(GNUInstallDirs) -find_package(SymEngine 0.8.1 REQUIRED CONFIG +find_package(SymEngine 0.14.0 REQUIRED CONFIG PATH_SUFFIXES lib/cmake/symengine cmake/symengine CMake/) message("SymEngine_DIR : " ${SymEngine_DIR}) message("SymEngine Version : " ${SymEngine_VERSION}) diff --git a/symengine_version.txt b/symengine_version.txt index 6345c2168..6718d65f7 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.13.0 +fac9314c78f2809570494017efc6603befeb4eda From 0a3e0af889785cb7ec489da2a96dd98b9a2aa138 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 20:06:48 -0600 Subject: [PATCH 293/314] Use RCPBasicAware{Output,Input}Archive --- symengine/lib/pywrapper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp index 4f45a0b7d..5ab5e5866 100644 --- a/symengine/lib/pywrapper.cpp +++ b/symengine/lib/pywrapper.cpp @@ -292,7 +292,7 @@ PyObject* pickle_loads(const std::string &pickle_str) { return obj; } -RCP load_basic(cereal::PortableBinaryInputArchive &ar, RCP &) +RCP load_basic(RCPBasicAwareInputArchive &ar, RCP &) { bool is_pysymbol; bool store_pickle; @@ -324,7 +324,7 @@ std::string pickle_dumps(const PyObject * obj) { return std::string(buffer, size); } -void save_basic(cereal::PortableBinaryOutputArchive &ar, const Symbol &b) +void save_basic(RCPBasicAwareOutputArchive &ar, const Symbol &b) { bool is_pysymbol = is_a_sub(b); ar(is_pysymbol); @@ -344,7 +344,7 @@ std::string wrapper_dumps(const Basic &x) std::ostringstream oss; unsigned short major = SYMENGINE_MAJOR_VERSION; unsigned short minor = SYMENGINE_MINOR_VERSION; - cereal::PortableBinaryOutputArchive{oss}(major, minor, + RCPBasicAwareOutputArchive{oss}(major, minor, x.rcp_from_this()); return oss.str(); } @@ -354,7 +354,7 @@ RCP wrapper_loads(const std::string &serialized) unsigned short major, minor; RCP obj; std::istringstream iss(serialized); - cereal::PortableBinaryInputArchive iarchive{iss}; + RCPBasicAwareInputArchive iarchive{iss}; iarchive(major, minor); if (major != SYMENGINE_MAJOR_VERSION or minor != SYMENGINE_MINOR_VERSION) { throw SerializationError(StreamFmt() From 320c984c1a196c03dd8c9442935db9f610022737 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Sun, 16 Feb 2025 20:18:34 -0600 Subject: [PATCH 294/314] update version to 0.14.0 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index f105b328f..035471db0 100644 --- a/setup.py +++ b/setup.py @@ -222,7 +222,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.13.0", + version="0.14.0", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 97e9afd0f..4ca4dd7cb 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -63,7 +63,7 @@ def __getattr__(name): raise AttributeError(f"module 'symengine' has no attribute '{name}'") -__version__ = "0.13.0" +__version__ = "0.14.0" # To not expose internals From 248e6dc1747c8e69633fde3072527a61abe9049d Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 17 Feb 2025 08:04:59 -0600 Subject: [PATCH 295/314] update symengine c++ to 0.14.0 --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 6718d65f7..4a29f93bb 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -fac9314c78f2809570494017efc6603befeb4eda +v0.14.0 From df4081db4a0167862e959cf3190e4dd54a269165 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 17 Feb 2025 12:15:17 -0600 Subject: [PATCH 296/314] Add Aaron and Firat to README. Welcome to SymEngine!! --- .mailmap | 1 + AUTHORS | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.mailmap b/.mailmap index 71840613b..5a35cee3f 100644 --- a/.mailmap +++ b/.mailmap @@ -21,3 +21,4 @@ Abhinav Agarwal Nilay Pochhi Björn Dahlgren Richard Otis richardotis +Firat Bezir diff --git a/AUTHORS b/AUTHORS index 427f83ad9..19d0bd089 100644 --- a/AUTHORS +++ b/AUTHORS @@ -36,3 +36,5 @@ Pieter Eendebak Ayush Kumar Christian Clauss Moraxyc +Aaron Miller <78561124+aaron-skydio@users.noreply.github.com> +Firat Bezir From e108841338568d5bc8f2034aa70722d9b221c982 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Mon, 17 Feb 2025 15:33:22 -0600 Subject: [PATCH 297/314] Drop python 3.8 --- .github/workflows/ci.yml | 18 +++++++++--------- appveyor.yml | 2 +- setup.py | 8 ++++---- symengine/lib/symengine_wrapper.in.pyx | 6 ------ 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2763750cb..ec7dc82a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,13 +37,13 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' BUILD_SHARED_LIBS: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_MPFR: yes INTEGER_CLASS: gmpxx WITH_NUMPY: no @@ -51,14 +51,14 @@ jobs: CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_MPC: yes OS: ubuntu-20.04 CC: gcc - BUILD_TYPE: Release WITH_MPFR: yes - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' OS: ubuntu-20.04 CC: gcc @@ -84,14 +84,14 @@ jobs: # CC: gcc - BUILD_TYPE: Debug - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_BFD: yes BUILD_SHARED_LIBS: yes OS: ubuntu-20.04 CC: clang - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_NUMPY: yes OS: ubuntu-20.04 CC: clang @@ -108,7 +108,7 @@ jobs: EXTRA_APT_PACKAGES: 'llvm-14' - BUILD_TYPE: Debug - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_SCIPY: yes WITH_LLVM: 5.0 OS: macos-13 @@ -121,13 +121,13 @@ jobs: CC: clang - BUILD_TYPE: Debug - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' WITH_NUMPY: no OS: macos-13 CC: gcc - BUILD_TYPE: Release - PYTHON_VERSION: '3.8' + PYTHON_VERSION: '3.13' OS: macos-13 CC: gcc diff --git a/appveyor.yml b/appveyor.yml index f21df0aef..1f02ccd7f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,7 @@ environment: - BUILD_TYPE: "Release" COMPILER: MSVC15 PLATFORM: "x64" - PYTHON_VERSION: 38-x64 + PYTHON_VERSION: 312-x64 CONDA_INSTALL_LOCN: C:\\Miniconda38-x64 - BUILD_TYPE: "Release" COMPILER: MSVC15 diff --git a/setup.py b/setup.py index 035471db0..f76c5a0d8 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,8 @@ import platform # Make sure the system has the right Python version. -if sys.version_info[:2] < (3, 8): - print("SymEngine requires Python 3.8 or newer. " +if sys.version_info[:2] < (3, 9): + print("SymEngine requires Python 3.9 or newer. " "Python %d.%d detected" % sys.version_info[:2]) sys.exit(-1) @@ -230,7 +230,7 @@ def finalize_options(self): author_email="symengine@googlegroups.com", license="MIT", url="https://github.com/symengine/symengine.py", - python_requires='>=3.8,<4', + python_requires='>=3.9,<4', zip_safe=False, packages=['symengine', 'symengine.lib', 'symengine.tests'], cmdclass = cmdclass, @@ -241,10 +241,10 @@ def finalize_options(self): 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Scientific/Engineering :: Physics', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ] ) diff --git a/symengine/lib/symengine_wrapper.in.pyx b/symengine/lib/symengine_wrapper.in.pyx index 26c31ad87..6fe0ffa5e 100644 --- a/symengine/lib/symengine_wrapper.in.pyx +++ b/symengine/lib/symengine_wrapper.in.pyx @@ -1213,9 +1213,6 @@ cdef class Basic(object): def __int__(self): return int(float(self)) - def __long__(self): - return int(float(self)) - def __complex__(self): f = self.n(real=False) if not isinstance(f, (ComplexDouble, RealDouble)): @@ -1523,9 +1520,6 @@ cdef class BooleanTrue(BooleanAtom): def _sage_(self): return True - def __nonzero__(self): - return True - def __bool__(self): return True From 08f04ec1341b49e4562fc87fb9cc2140e7702dcb Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 18 Feb 2025 07:20:04 -0600 Subject: [PATCH 298/314] install setuptools --- bin/install_travis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 572bb0d2b..0460c58a9 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -2,7 +2,7 @@ # symengine's bin/install_travis.sh will install miniconda -export conda_pkgs="python=${PYTHON_VERSION} pip pytest gmp mpfr" +export conda_pkgs="python=${PYTHON_VERSION} pip pytest setuptools gmp mpfr" if [[ "${WITH_NUMPY}" != "no" ]]; then export conda_pkgs="${conda_pkgs} numpy"; From 0fcebccafdbb35cc82ab1fcdbddd964dfdc65c6a Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 18 Feb 2025 08:09:39 -0600 Subject: [PATCH 299/314] install setuptools on win --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1f02ccd7f..ce1c487ce 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -97,7 +97,7 @@ install: - set "PATH=C:\Python%PYTHON_VERSION%;C:\Python%PYTHON_VERSION%\Scripts;%PATH%" - echo %PATH% -- pip install nose pytest cython +- pip install nose pytest cython setuptools - if NOT [%WITH_NUMPY%]==[no] pip install numpy - if NOT [%WITH_SYMPY%]==[no] pip install sympy From ec3a60522c84ed2b2942dab67ca77a03d6cbbb73 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 18 Feb 2025 11:24:18 -0600 Subject: [PATCH 300/314] add setuptools to setup_requires --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f76c5a0d8..c082f3ea9 100644 --- a/setup.py +++ b/setup.py @@ -224,7 +224,7 @@ def finalize_options(self): setup(name="symengine", version="0.14.0", description="Python library providing wrappers to SymEngine", - setup_requires=['cython>=0.29.24'], + setup_requires=['cython>=0.29.24', 'setuptools'], long_description=long_description, author="SymEngine development team", author_email="symengine@googlegroups.com", From 5f924464cbf300748c3b9e4aebf32d78d54d1b5b Mon Sep 17 00:00:00 2001 From: Adrian Ostrowski <81568391+aostrowski-hbn@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:25:46 -0700 Subject: [PATCH 301/314] Fix Fedora/RedHat installation location Those OSes have separate platlib and purelib directories. Symengine was installed partially into both from version 0.10.0 onwards. This change marks some of it's packages as ext_modules, which makes setuptools treat the wheel as platform specific and install if fully into platlib (lib64) instead of purelib (lib). This should solve #474. --- cmake/FindPython.cmake | 2 +- setup.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake index df8bfdc15..c1f6c4396 100644 --- a/cmake/FindPython.cmake +++ b/cmake/FindPython.cmake @@ -60,7 +60,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") endif() execute_process( - COMMAND ${PYTHON_BIN} -c "from sysconfig import get_paths; print(get_paths()['purelib'])" + COMMAND ${PYTHON_BIN} -c "from sysconfig import get_paths; print(get_paths()['platlib'])" OUTPUT_VARIABLE PYTHON_INSTALL_PATH_tmp ) string(STRIP ${PYTHON_INSTALL_PATH_tmp} PYTHON_INSTALL_PATH_tmp) diff --git a/setup.py b/setup.py index c082f3ea9..fcd97ec9d 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ if use_setuptools: try: - from setuptools import setup + from setuptools import Extension, setup from setuptools.command.install import install as _install from setuptools.command.build_ext import build_ext as _build_ext except ImportError: @@ -36,7 +36,7 @@ from distutils.command.build import build as _build if not use_setuptools: - from distutils.core import setup + from distutils.core import Extension, setup from distutils.command.install import install as _install from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build import build as _build @@ -232,7 +232,8 @@ def finalize_options(self): url="https://github.com/symengine/symengine.py", python_requires='>=3.9,<4', zip_safe=False, - packages=['symengine', 'symengine.lib', 'symengine.tests'], + ext_modules=[Extension(name='symengine.lib', sources=[])], + packages=['symengine', 'symengine.tests'], cmdclass = cmdclass, classifiers=[ 'License :: OSI Approved :: MIT License', From 6da52ebc8687f6477d54963524c8c841ce37f582 Mon Sep 17 00:00:00 2001 From: Adrian Ostrowski Date: Tue, 1 Apr 2025 16:34:43 +0200 Subject: [PATCH 302/314] Fix CMake 4.0.0 build break --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fcd97ec9d..5adb759f2 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,8 @@ from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), - ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] + ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes"), + ("CMAKE_POLICY_VERSION_MINIMUM", "3.5")] cmake_generator = [None] cmake_build_type = ["Release"] From 03918d1183d65a2cde1fb8809f2467ebed633257 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 1 Apr 2025 10:34:11 -0500 Subject: [PATCH 303/314] install py files from cmake --- setup.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/setup.py b/setup.py index 5adb759f2..28d05bcee 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ if use_setuptools: try: - from setuptools import Extension, setup + from setuptools import setup from setuptools.command.install import install as _install from setuptools.command.build_ext import build_ext as _build_ext except ImportError: @@ -36,14 +36,13 @@ from distutils.command.build import build as _build if not use_setuptools: - from distutils.core import Extension, setup + from distutils.core import setup from distutils.command.install import install as _install from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build import build as _build cmake_opts = [("PYTHON_BIN", sys.executable), - ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes"), - ("CMAKE_POLICY_VERSION_MINIMUM", "3.5")] + ("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "yes")] cmake_generator = [None] cmake_build_type = ["Release"] @@ -118,7 +117,7 @@ def cmake_build(self): cmake_cmd = ["cmake", source_dir, "-DCMAKE_BUILD_TYPE=" + cmake_build_type[0], - "-DSYMENGINE_INSTALL_PY_FILES=OFF", + "-DSYMENGINE_INSTALL_PY_FILES=ON", ] cmake_cmd.extend(process_opts(cmake_opts)) if not path.exists(path.join(build_dir, "CMakeCache.txt")): @@ -233,8 +232,7 @@ def finalize_options(self): url="https://github.com/symengine/symengine.py", python_requires='>=3.9,<4', zip_safe=False, - ext_modules=[Extension(name='symengine.lib', sources=[])], - packages=['symengine', 'symengine.tests'], + packages=[], cmdclass = cmdclass, classifiers=[ 'License :: OSI Approved :: MIT License', From fe654772f35b6bd2d285d26e6136ab3dd081a903 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 1 Apr 2025 10:39:47 -0500 Subject: [PATCH 304/314] fix cmake_minimum_required --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c83e7cfb..e83c95b18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 2.8.12...4.0.0) if (POLICY CMP0057) cmake_policy(SET CMP0057 NEW) # needed for llvm >= 16 From b93259288c8e36ff22d43c17d35e3a42e442ce0e Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Tue, 1 Apr 2025 22:12:45 -0500 Subject: [PATCH 305/314] fix installing --- symengine/CMakeLists.txt | 19 +++++++++++++------ symengine/tests/CMakeLists.txt | 19 ++++++++++++------- symengine_version.txt | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/symengine/CMakeLists.txt b/symengine/CMakeLists.txt index 907e6f648..bedec397d 100644 --- a/symengine/CMakeLists.txt +++ b/symengine/CMakeLists.txt @@ -1,10 +1,17 @@ add_subdirectory(lib) if (SYMENGINE_INSTALL_PY_FILES) - add_subdirectory(tests) - - set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine) - install(FILES __init__.py utilities.py sympy_compat.py functions.py printing.py - DESTINATION ${PY_PATH} - ) + add_subdirectory(tests) + set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine) + install( + FILES + __init__.py + functions.py + printing.py + sympy_compat.py + test_utilities.py + utilities.py + DESTINATION + ${PY_PATH} +) endif () diff --git a/symengine/tests/CMakeLists.txt b/symengine/tests/CMakeLists.txt index ebd4dfaa2..4f19093b7 100644 --- a/symengine/tests/CMakeLists.txt +++ b/symengine/tests/CMakeLists.txt @@ -1,13 +1,19 @@ set(PY_PATH ${PYTHON_INSTALL_PATH}/symengine/tests) -install(FILES __init__.py +install( + FILES + __init__.py test_arit.py + test_cse.py test_dict_basic.py test_eval.py test_expr.py test_functions.py - test_number.py + test_lambdify.py + test_logic.py test_matrices.py test_ntheory.py + test_number.py + test_pickling.py test_printing.py test_sage.py test_series_expansion.py @@ -16,10 +22,9 @@ install(FILES __init__.py test_subs.py test_symbol.py test_sympify.py + test_sympy_compat.py test_sympy_conv.py test_var.py - test_lambdify.py - test_sympy_compat.py - test_logic.py - DESTINATION ${PY_PATH} - ) + DESTINATION + ${PY_PATH} +) diff --git a/symengine_version.txt b/symengine_version.txt index 4a29f93bb..549ada382 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -v0.14.0 +153b7e98f310bccaae586dab6b49284ccd5f4174 From a924eeffc62a094a58f976b5213bf3d1d83fb099 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 3 Apr 2025 11:35:59 -0500 Subject: [PATCH 306/314] bump to 0.14.1 --- setup.py | 2 +- symengine/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 28d05bcee..23d948ef6 100644 --- a/setup.py +++ b/setup.py @@ -222,7 +222,7 @@ def finalize_options(self): ''' setup(name="symengine", - version="0.14.0", + version="0.14.1", description="Python library providing wrappers to SymEngine", setup_requires=['cython>=0.29.24', 'setuptools'], long_description=long_description, diff --git a/symengine/__init__.py b/symengine/__init__.py index 4ca4dd7cb..e9545baf6 100644 --- a/symengine/__init__.py +++ b/symengine/__init__.py @@ -63,7 +63,7 @@ def __getattr__(name): raise AttributeError(f"module 'symengine' has no attribute '{name}'") -__version__ = "0.14.0" +__version__ = "0.14.1" # To not expose internals From 6b35fd056a976d002d71c45ae233ab095563f056 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 3 Apr 2025 11:37:15 -0500 Subject: [PATCH 307/314] Add Adrian to AUTHORS. Welcome to SymEngine!! --- .mailmap | 1 + AUTHORS | 1 + 2 files changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index 5a35cee3f..11654a9b0 100644 --- a/.mailmap +++ b/.mailmap @@ -22,3 +22,4 @@ Nilay Pochhi Björn Dahlgren Richard Otis richardotis Firat Bezir +Adrian Ostrowski <81568391+aostrowski-hbn@users.noreply.github.com> diff --git a/AUTHORS b/AUTHORS index 19d0bd089..484d38bee 100644 --- a/AUTHORS +++ b/AUTHORS @@ -38,3 +38,4 @@ Christian Clauss Moraxyc Aaron Miller <78561124+aaron-skydio@users.noreply.github.com> Firat Bezir +Adrian Ostrowski From 4a8b629da7b5d14901f129de6eee4379d17cf654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 11 Jul 2025 17:52:59 +0200 Subject: [PATCH 308/314] bump ubuntu-20.04 -> 22.04 --- .github/workflows/ci.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13e3399b8..d8a8f0854 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,34 +12,34 @@ jobs: WITH_BFD: yes PYTHON_VERSION: '3.12' TEST_SYMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: '3.11' TEST_SYMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: '3.10' TEST_SYMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Debug WITH_BFD: yes PYTHON_VERSION: '3.9' TEST_SYMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: '3.13' BUILD_SHARED_LIBS: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release @@ -47,25 +47,25 @@ jobs: WITH_MPFR: yes INTEGER_CLASS: gmpxx WITH_NUMPY: no - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: '3.13' WITH_MPC: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release WITH_MPFR: yes PYTHON_VERSION: '3.13' - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release PYTHON_VERSION: '3.9' WITH_MPC: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc - BUILD_TYPE: Release @@ -73,27 +73,27 @@ jobs: WITH_MPC: yes INTEGER_CLASS: flint WITH_FLINT: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: gcc #- BUILD_TYPE: Debug # PYTHON_VERSION: '3.9' # WITH_BFD: yes # WITH_PIRANHA: yes - # OS: ubuntu-20.04 + # OS: ubuntu-22.04 # CC: gcc - BUILD_TYPE: Debug PYTHON_VERSION: '3.13' WITH_BFD: yes BUILD_SHARED_LIBS: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: clang - BUILD_TYPE: Release PYTHON_VERSION: '3.13' WITH_NUMPY: yes - OS: ubuntu-20.04 + OS: ubuntu-22.04 CC: clang - BUILD_TYPE: Debug @@ -134,7 +134,7 @@ jobs: - BUILD_TYPE: Release PYTHON_VERSION: '3.11' - OS: ubuntu-20.04 + OS: ubuntu-22.04 WITH_MPC: yes WITH_MPFR: yes WITH_FLINT: yes From a42760575fa06aa608222372456fe68dbda28126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Fri, 11 Jul 2025 20:36:23 +0200 Subject: [PATCH 309/314] revert temporary changes in ci script --- bin/test_symengine_unix.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test_symengine_unix.sh b/bin/test_symengine_unix.sh index 63e3f6ca6..976f305d1 100644 --- a/bin/test_symengine_unix.sh +++ b/bin/test_symengine_unix.sh @@ -2,10 +2,10 @@ export PYTHON_SOURCE_DIR=`pwd` export TEST_CPP="no" export MAKEFLAGS="-j2" -git clone -b update-CI https://github.com/bjodah/symengine symengine-cpp +git clone https://github.com/symengine/symengine symengine-cpp cd symengine-cpp export SOURCE_DIR=`pwd` -#git checkout `cat ../symengine_version.txt` +git checkout `cat ../symengine_version.txt` cd .. # Setup travis for C++ library From 0cf427709abe1ce45a1998ff804e2cb1c5312445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ingvar=20Dahlgren?= Date: Sat, 12 Jul 2025 11:19:56 +0200 Subject: [PATCH 310/314] attempt updating CI scripts to match upstream --- .github/workflows/ci.yml | 10 ++++++++++ bin/test_symengine_unix.sh | 2 +- symengine_version.txt | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8a8f0854..d09546174 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -146,6 +146,16 @@ jobs: CC: gcc steps: + + - uses: conda-incubator/setup-miniconda@v3 + if: matrix.MSYS_ENV == '' + with: + activate-environment: symengine + channel-priority: strict + architecture: x86_64 + channels: conda-forge + conda-remove-defaults: "true" + - name: Checkout code uses: actions/checkout@v4 diff --git a/bin/test_symengine_unix.sh b/bin/test_symengine_unix.sh index 976f305d1..0c62b7d14 100644 --- a/bin/test_symengine_unix.sh +++ b/bin/test_symengine_unix.sh @@ -10,7 +10,7 @@ cd .. # Setup travis for C++ library cd $SOURCE_DIR -source bin/test_symengine_unix.sh +source bin/test_symengine.sh # Setup travis for Python wrappers cd $PYTHON_SOURCE_DIR diff --git a/symengine_version.txt b/symengine_version.txt index 549ada382..52a9266b2 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -153b7e98f310bccaae586dab6b49284ccd5f4174 +17871adbd8366d18fc8f372f23f07e508571de46 From 6b920b63966d784e3c0eba9932adb35379d0e665 Mon Sep 17 00:00:00 2001 From: Liam Keegan Date: Mon, 14 Jul 2025 13:50:22 +0200 Subject: [PATCH 311/314] add -el {0} to bash command (required by setup-miniconda) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d09546174..77578d0d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -160,7 +160,7 @@ jobs: uses: actions/checkout@v4 - name: Build and test symengine - shell: bash + shell: bash -el {0} run: | source bin/test_symengine_unix.sh env: From 40a91073c35f85cff54a5632a12b3c6675349dba Mon Sep 17 00:00:00 2001 From: Liam Keegan Date: Mon, 14 Jul 2025 13:59:31 +0200 Subject: [PATCH 312/314] remove activate - conda env should already be active --- bin/install_travis.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/install_travis.sh b/bin/install_travis.sh index 0460c58a9..f63a47479 100644 --- a/bin/install_travis.sh +++ b/bin/install_travis.sh @@ -33,5 +33,4 @@ if [[ "${WITH_SYMPY}" != "no" ]]; then pip install sympy; fi -conda clean --all -source activate $our_install_dir; +conda clean --all \ No newline at end of file From 94e136126075daa4263d676d68bd0d400f99c09c Mon Sep 17 00:00:00 2001 From: Liam Keegan Date: Mon, 14 Jul 2025 14:05:58 +0200 Subject: [PATCH 313/314] use WITH_LATEST_GCC on ubuntu-24.04 job to avoid symengine CI script trying to use gcc-9 --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77578d0d3..c176f13e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,6 +101,7 @@ jobs: WITH_SYMPY: yes WITH_LLVM: 18 WITH_SCIPY: yes + WITH_LATEST_GCC: yes INTEGER_CLASS: 'boostmp' PYTEST_ADDOPTS: '-k "not integer_nthroot"' OS: ubuntu-24.04 From 50682e97e748c135d0143ce02a830b080fff2730 Mon Sep 17 00:00:00 2001 From: Bjorn Date: Mon, 14 Jul 2025 14:41:00 +0200 Subject: [PATCH 314/314] Update symengine_version.txt --- symengine_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symengine_version.txt b/symengine_version.txt index 52a9266b2..e49372bea 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -17871adbd8366d18fc8f372f23f07e508571de46 +c9510fb4b5c30b84adb993573a51f2a9a38a4cfe