From 352be013f0ae82313c537e69a781d978ec34a825 Mon Sep 17 00:00:00 2001 From: Shikhar Jaiswal Date: Sat, 1 Jul 2017 04:28:57 +0530 Subject: [PATCH] Wrapped Union, Complement, ConditionSet and ImageSet --- symengine/lib/symengine.pxd | 28 +++++- symengine/lib/symengine_wrapper.pyx | 136 +++++++++++++++++++++++++--- symengine_version.txt | 2 +- 3 files changed, 146 insertions(+), 20 deletions(-) diff --git a/symengine/lib/symengine.pxd b/symengine/lib/symengine.pxd index e4eda445e..aeae5bc42 100644 --- a/symengine/lib/symengine.pxd +++ b/symengine/lib/symengine.pxd @@ -41,6 +41,7 @@ cdef extern from "" namespace "std": bint operator!=(iterator) nogil iterator begin() nogil iterator end() nogil + iterator insert(T&) nogil cdef cppclass multiset[T, U]: cppclass iterator: @@ -205,7 +206,7 @@ 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 set[RCP[Basic], RCPBasicKeyLess] set_basic "SymEngine::set_basic" ctypedef multiset[RCP[const_Basic], RCPBasicKeyLess] multiset_basic "SymEngine::multiset_basic" cdef cppclass Basic: string __str__() nogil except + @@ -281,6 +282,10 @@ cdef extern from "" namespace "SymEngine": bool is_a_EmptySet "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_Piecewise "SymEngine::is_a"(const Basic &b) nogil bool is_a_Contains "SymEngine::is_a"(const Basic &b) nogil @@ -814,8 +819,8 @@ cdef extern from "" namespace "SymEngine": 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[const_Boolean]] vec_boolean "SymEngine::vec_boolean" - ctypedef set[RCP[const_Boolean], RCPBasicKeyLess] set_boolean "SymEngine::set_boolean" + 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+ @@ -892,7 +897,22 @@ cdef extern from "" namespace "SymEngine": pass cdef cppclass FiniteSet(Set): pass + cdef cppclass Union(Set): + pass + cdef cppclass Complement(Set): + pass + cdef cppclass ConditionSet(Set): + 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 UniversalSet] universalset() nogil except + - cdef RCP[const Set] finiteset(set_basic &container) nogil except + + cdef RCP[const Set] finiteset(const set_basic &container) nogil except + + cdef RCP[const Set] set_union(const set_set &a) nogil except + + cdef RCP[const Set] set_intersection(const 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 + diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx index 2d7151031..42fd7af56 100644 --- a/symengine/lib/symengine_wrapper.pyx +++ b/symengine/lib/symengine_wrapper.pyx @@ -160,6 +160,14 @@ cdef c2py(RCP[const symengine.Basic] o): r = UniversalSet.__new__(UniversalSet) elif (symengine.is_a_FiniteSet(deref(o))): r = FiniteSet.__new__(FiniteSet) + elif (symengine.is_a_Union(deref(o))): + r = Union.__new__(Union) + elif (symengine.is_a_Complement(deref(o))): + r = Complement.__new__(Complement) + elif (symengine.is_a_ConditionSet(deref(o))): + r = ConditionSet.__new__(ConditionSet) + elif (symengine.is_a_ImageSet(deref(o))): + r = ImageSet.__new__(ImageSet) elif (symengine.is_a_And(deref(o))): r = Boolean.__new__(And) elif (symengine.is_a_Not(deref(o))): @@ -326,6 +334,16 @@ def sympy2symengine(a, raise_error=False): return finiteset(*(a.args)) elif isinstance(a, sympy.Contains): return contains(*(a.args)) + elif isinstance(a, sympy.Union): + return set_union(*(a.args)) + elif isinstance(a, sympy.Intersection): + return set_intersection(*(a.args)) + elif isinstance(a, sympy.Complement): + return set_complement(*(a.args)) + elif isinstance(a, sympy.ConditionSet): + return conditionset(*(a.args)) + elif isinstance(a, sympy.ImageSet): + return imageset(*(a.args)) elif isinstance(a, sympy.Function): return PyFunction(a, a.args, a.func, sympy_module) elif isinstance(a, sympy.MatrixBase): @@ -2089,7 +2107,7 @@ class Subs(Basic): return self.__class__ -cdef class Piecewise(Basic): +class Piecewise(Basic): def __new__(self, *args): return piecewise(*args) @@ -2126,10 +2144,10 @@ cdef class Set(Basic): def contains(self, a): cdef Basic a_ = sympify(a) return c2py((deref(symengine.rcp_static_cast_Set(self.thisptr)) - .contains(a_))) + .contains(a_.thisptr))) -cdef class Interval(Set): +class Interval(Set): def __new__(self, *args): return interval(*args) @@ -2139,7 +2157,7 @@ cdef class Interval(Set): return sympy.Interval(*[arg._sympy_() for arg in self.args]) -cdef class EmptySet(Set): +class EmptySet(Set): def __new__(self): return emptyset() @@ -2149,7 +2167,7 @@ cdef class EmptySet(Set): return sympy.EmptySet() -cdef class UniversalSet(Set): +class UniversalSet(Set): def __new__(self): return universalset() @@ -2159,7 +2177,7 @@ cdef class UniversalSet(Set): return sympy.UniversalSet() -cdef class FiniteSet(Set): +class FiniteSet(Set): def __new__(self, *args): return finiteset(*args) @@ -2169,7 +2187,7 @@ cdef class FiniteSet(Set): return sympy.FiniteSet(*[arg._sympy_() for arg in self.args]) -cdef class Contains(Boolean): +class Contains(Boolean): def __new__(self, expr, sset): return contains(expr, sset) @@ -2179,6 +2197,46 @@ cdef class Contains(Boolean): return sympy.Contains(*[arg._sympy_() for arg in self.args]) +class Union(Set): + + def __new__(self, *args): + return set_union(*args) + + def _sympy_(self): + import sympy + return sympy.Union(*[arg._sympy_() for arg in self.args]) + + +class Complement(Set): + + def __new__(self, universe, container): + return set_complement(universe, container) + + def _sympy_(self): + import sympy + return sympy.Complement(*[arg._sympy_() for arg in self.args]) + + +class ConditionSet(Set): + + def __new__(self, sym, condition): + return conditionset(sym, condition) + + def _sympy_(self): + import sympy + return sympy.ConditionSet(*[arg._sympy_() for arg in self.args]) + + +class ImageSet(Set): + + def __new__(self, sym, expr, base): + return imageset(sym, expr, base) + + def _sympy_(self): + import sympy + return sympy.ImageSet(*[arg._sympy_() for arg in self.args]) + + cdef class MatrixBase: @property @@ -2982,7 +3040,7 @@ def logical_and(*args): cdef Boolean e_ for e in args: e_ = sympify(e) - s.insert(e_.thisptr) + s.insert(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_and(s))) def logical_or(*args): @@ -2990,7 +3048,7 @@ def logical_or(*args): cdef Boolean e_ for e in args: e_ = sympify(e) - s.insert(e_.thisptr) + s.insert(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_or(s))) def logical_nor(*args): @@ -2998,7 +3056,7 @@ def logical_nor(*args): cdef Boolean e_ for e in args: e_ = sympify(e) - s.insert(e_.thisptr) + s.insert(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_nor(s))) Nor = logical_nor @@ -3008,21 +3066,21 @@ def logical_nand(*args): cdef Boolean e_ for e in args: e_ = sympify(e) - s.insert(e_.thisptr) + s.insert(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_nand(s))) Nand = logical_nand def logical_not(x): cdef Boolean X = sympify(x) - return c2py((symengine.logical_not(X.thisptr))) + return c2py((symengine.logical_not(symengine.rcp_static_cast_Boolean(X.thisptr)))) def logical_xor(*args): cdef symengine.vec_boolean v cdef Boolean e_ for e in args: e_ = sympify(e) - v.push_back(e_.thisptr) + v.push_back(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_xor(v))) def logical_xnor(*args): @@ -3030,7 +3088,7 @@ def logical_xnor(*args): cdef Boolean e_ for e in args: e_ = sympify(e) - v.push_back(e_.thisptr) + v.push_back(symengine.rcp_static_cast_Boolean(e_.thisptr)) return c2py((symengine.logical_xnor(v))) Xnor = logical_xnor @@ -3856,7 +3914,7 @@ def universalset(): return c2py((symengine.universalset())) -def finiteset(*args) +def finiteset(*args): cdef symengine.set_basic s cdef Basic e_ for e in args: @@ -3872,5 +3930,53 @@ def contains(expr, sset): return c2py((symengine.contains(expr_.thisptr, s))) +def set_union(*args): + cdef symengine.set_set s + cdef Set e_ + for e in args: + e_ = sympify(e) + s.insert(symengine.rcp_static_cast_Set(e_.thisptr)) + return c2py((symengine.set_union(s))) + + +def set_intersection(*args): + cdef symengine.set_set s + cdef Set e_ + for e in args: + e_ = sympify(e) + s.insert(symengine.rcp_static_cast_Set(e_.thisptr)) + return c2py((symengine.set_intersection(s))) + + +def set_complement(universe, container): + cdef Set universe_ = sympify(universe) + cdef Set container_ = sympify(container) + cdef RCP[const symengine.Set] u = symengine.rcp_static_cast_Set(universe_.thisptr) + cdef RCP[const symengine.Set] c = symengine.rcp_static_cast_Set(container_.thisptr) + return c2py((symengine.set_complement(u, c))) + + +def set_complement_helper(container, universe): + cdef Set container_ = sympify(container) + cdef Set universe_ = sympify(universe) + cdef RCP[const symengine.Set] c = symengine.rcp_static_cast_Set(container_.thisptr) + cdef RCP[const symengine.Set] u = symengine.rcp_static_cast_Set(universe_.thisptr) + return c2py((symengine.set_complement_helper(c, u))) + + +def conditionset(sym, condition): + cdef Basic sym_ = sympify(sym) + cdef Boolean condition_ = sympify(condition) + cdef RCP[const symengine.Boolean] c = symengine.rcp_static_cast_Boolean(condition_.thisptr) + return c2py((symengine.conditionset(sym_.thisptr, c))) + + +def imageset(sym, expr, base): + cdef Basic sym_ = sympify(sym) + cdef Basic expr_ = sympify(expr) + cdef Set base_ = sympify(base) + cdef RCP[const symengine.Set] b = symengine.rcp_static_cast_Set(base_.thisptr) + return c2py((symengine.imageset(sym_.thisptr, expr_.thisptr, b))) + # Turn on nice stacktraces: symengine.print_stack_on_segfault() diff --git a/symengine_version.txt b/symengine_version.txt index e75eff917..38ebb5ff9 100644 --- a/symengine_version.txt +++ b/symengine_version.txt @@ -1 +1 @@ -d575a3a073607589e7307a143cfdecaef439e71c +3e87d58a9404535fbc2bb8d09357faf4ab8eb5a1