Skip to content

Commit 6b07491

Browse files
authored
Merge pull request #329 from rikardn/update_matrix
Update matrix
2 parents 62a0d89 + a68f7fc commit 6b07491

File tree

9 files changed

+367
-14
lines changed

9 files changed

+367
-14
lines changed

symengine/__init__.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import symengine.lib.symengine_wrapper as wrapper
2+
13
from .lib.symengine_wrapper import (
24
have_mpfr, have_mpc, have_flint, have_piranha, have_llvm, have_llvm_long_double,
35
I, E, pi, oo, zoo, nan, Symbol, Dummy, S, sympify, SympifyError,
@@ -12,7 +14,7 @@
1214
LessThan, StrictGreaterThan, StrictLessThan, Eq, Ne, Ge, Le,
1315
Gt, Lt, And, Or, Not, Nand, Nor, Xor, Xnor, perfect_power, integer_nthroot,
1416
isprime, sqrt_mod, Expr, cse, count_ops, ccode, Piecewise, Contains, Interval, FiniteSet,
15-
EmptySet, linsolve,
17+
linsolve,
1618
FunctionSymbol as AppliedUndef,
1719
golden_ratio as GoldenRatio,
1820
catalan as Catalan,
@@ -22,6 +24,13 @@
2224
from .functions import *
2325
from .printing import init_printing
2426

27+
28+
EmptySet = wrapper.S.EmptySet
29+
UniversalSet = wrapper.S.UniversalSet
30+
Reals = wrapper.S.Reals
31+
Integers = wrapper.S.Integers
32+
33+
2534
if have_mpfr:
2635
from .lib.symengine_wrapper import RealMPFR
2736

@@ -38,6 +47,12 @@ def lambdify(args, exprs, **kwargs):
3847
__version__ = "0.6.1"
3948

4049

50+
# To not expose internals
51+
del lib.symengine_wrapper
52+
del lib
53+
del wrapper
54+
55+
4156
def test():
4257
import pytest
4358
import os

symengine/lib/symengine.pxd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ cdef extern from "<symengine/basic.h>" namespace "SymEngine":
301301
bool is_a_Conjugate "SymEngine::is_a<SymEngine::Conjugate>"(const Basic &b) nogil
302302
bool is_a_Interval "SymEngine::is_a<SymEngine::Interval>"(const Basic &b) nogil
303303
bool is_a_EmptySet "SymEngine::is_a<SymEngine::EmptySet>"(const Basic &b) nogil
304+
bool is_a_Reals "SymEngine::is_a<SymEngine::Reals>"(const Basic &b) nogil
305+
bool is_a_Integers "SymEngine::is_a<SymEngine::Integers>"(const Basic &b) nogil
304306
bool is_a_UniversalSet "SymEngine::is_a<SymEngine::UniversalSet>"(const Basic &b) nogil
305307
bool is_a_FiniteSet "SymEngine::is_a<SymEngine::FiniteSet>"(const Basic &b) nogil
306308
bool is_a_Union "SymEngine::is_a<SymEngine::Union>"(const Basic &b) nogil
@@ -345,6 +347,12 @@ cdef extern from "<symengine/number.h>" namespace "SymEngine":
345347
pass
346348
cdef cppclass NumberWrapper(Basic):
347349
pass
350+
cdef int is_zero(const Basic &x) nogil
351+
cdef int is_positive(const Basic &x) nogil
352+
cdef int is_negative(const Basic &x) nogil
353+
cdef int is_nonnegative(const Basic &x) nogil
354+
cdef int is_nonpositive(const Basic &x) nogil
355+
cdef int is_real(const Basic &x) nogil
348356

349357
cdef extern from "pywrapper.h" namespace "SymEngine":
350358
cdef cppclass PyNumber(NumberWrapper):
@@ -779,8 +787,12 @@ cdef extern from "<symengine/matrix.h>" namespace "SymEngine":
779787
bool eq(const MatrixBase &) nogil
780788
rcp_const_basic det() nogil
781789
void inv(MatrixBase &)
790+
bool is_square() nogil
782791
void add_matrix(const MatrixBase &other, MatrixBase &result) nogil
783792
void mul_matrix(const MatrixBase &other, MatrixBase &result) nogil
793+
void elementwise_mul_matrix(const MatrixBase &other, MatrixBase &result) nogil
794+
void conjugate(MatrixBase &result) nogil
795+
void conjugate_transpose(MatrixBase &result) nogil
784796
void add_scalar(rcp_const_basic k, MatrixBase &result) nogil
785797
void mul_scalar(rcp_const_basic k, MatrixBase &result) nogil
786798
void transpose(MatrixBase &result) nogil
@@ -807,6 +819,14 @@ cdef extern from "<symengine/matrix.h>" namespace "SymEngine":
807819
void col_insert(const DenseMatrix &B, unsigned pos) nogil
808820
void row_del(unsigned k) nogil
809821
void col_del(unsigned k) nogil
822+
rcp_const_basic trace() nogil
823+
int is_zero() nogil
824+
int is_real() nogil
825+
int is_diagonal() nogil
826+
int is_symmetric() nogil
827+
int is_hermitian() nogil
828+
int is_weakly_diagonally_dominant() nogil
829+
int is_strictly_diagonally_dominant() nogil
810830

811831
bool is_a_DenseMatrix "SymEngine::is_a<SymEngine::DenseMatrix>"(const MatrixBase &b) nogil
812832
DenseMatrix* static_cast_DenseMatrix "static_cast<SymEngine::DenseMatrix*>"(const MatrixBase *a)
@@ -1032,6 +1052,10 @@ cdef extern from "<symengine/sets.h>" namespace "SymEngine":
10321052
pass
10331053
cdef cppclass EmptySet(Set):
10341054
pass
1055+
cdef cppclass Reals(Set):
1056+
pass
1057+
cdef cppclass Integers(Set):
1058+
pass
10351059
cdef cppclass UniversalSet(Set):
10361060
pass
10371061
cdef cppclass FiniteSet(Set):
@@ -1047,6 +1071,8 @@ cdef extern from "<symengine/sets.h>" namespace "SymEngine":
10471071
ctypedef set[RCP[Set], RCPBasicKeyLess] set_set "SymEngine::set_set"
10481072
cdef rcp_const_basic interval(RCP[const Number] &start, RCP[const Number] &end, bool l, bool r) nogil except +
10491073
cdef RCP[const EmptySet] emptyset() nogil except +
1074+
cdef RCP[const Reals] reals() nogil except +
1075+
cdef RCP[const Integers] integers() nogil except +
10501076
cdef RCP[const UniversalSet] universalset() nogil except +
10511077
cdef RCP[const Set] finiteset(set_basic &container) nogil except +
10521078
cdef RCP[const Set] set_union(set_set &a) nogil except +

symengine/lib/symengine_wrapper.pyx

Lines changed: 187 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ cdef object c2py(rcp_const_basic o):
235235
r = Set.__new__(Interval)
236236
elif (symengine.is_a_EmptySet(deref(o))):
237237
r = Set.__new__(EmptySet)
238+
elif (symengine.is_a_Reals(deref(o))):
239+
r = Set.__new__(Reals)
240+
elif (symengine.is_a_Integers(deref(o))):
241+
r = Set.__new__(Integers)
238242
elif (symengine.is_a_UniversalSet(deref(o))):
239243
r = Set.__new__(UniversalSet)
240244
elif (symengine.is_a_FiniteSet(deref(o))):
@@ -443,12 +447,16 @@ def sympy2symengine(a, raise_error=False):
443447
return function_symbol(name, *(a.args))
444448
elif isinstance(a, (sympy.Piecewise)):
445449
return piecewise(*(a.args))
450+
elif a is sympy.S.Reals:
451+
return S.Reals
452+
elif a is sympy.S.Integers:
453+
return S.Integers
446454
elif isinstance(a, sympy.Interval):
447455
return interval(*(a.args))
448456
elif a is sympy.S.EmptySet:
449-
return emptyset()
457+
return S.EmptySet
450458
elif a is sympy.S.UniversalSet:
451-
return universalset()
459+
return S.UniversalSet
452460
elif isinstance(a, sympy.FiniteSet):
453461
return finiteset(*(a.args))
454462
elif isinstance(a, sympy.Contains):
@@ -649,6 +657,22 @@ class Singleton(object):
649657
def false(self):
650658
return false
651659

660+
@property
661+
def EmptySet(self):
662+
return empty_set_singleton
663+
664+
@property
665+
def UniversalSet(self):
666+
return universal_set_singleton
667+
668+
@property
669+
def Integers(self):
670+
return integers_singleton
671+
672+
@property
673+
def Reals(self):
674+
return reals_singleton
675+
652676
S = Singleton()
653677

654678

@@ -1044,6 +1068,30 @@ cdef class Basic(object):
10441068
def is_Matrix(self):
10451069
return False
10461070

1071+
@property
1072+
def is_zero(self):
1073+
return is_zero(self)
1074+
1075+
@property
1076+
def is_positive(self):
1077+
return is_positive(self)
1078+
1079+
@property
1080+
def is_negative(self):
1081+
return is_negative(self)
1082+
1083+
@property
1084+
def is_nonpositive(self):
1085+
return is_nonpositive(self)
1086+
1087+
@property
1088+
def is_nonnegative(self):
1089+
return is_nonnegative(self)
1090+
1091+
@property
1092+
def is_real(self):
1093+
return is_real(self)
1094+
10471095
def copy(self):
10481096
return self
10491097

@@ -1575,10 +1623,6 @@ cdef class Number(Expr):
15751623
def is_negative(Basic self):
15761624
return deref(symengine.rcp_static_cast_Number(self.thisptr)).is_negative()
15771625

1578-
@property
1579-
def is_zero(Basic self):
1580-
return deref(symengine.rcp_static_cast_Number(self.thisptr)).is_zero()
1581-
15821626
@property
15831627
def is_nonzero(self):
15841628
return not (self.is_complex or self.is_zero)
@@ -2962,6 +3006,34 @@ class EmptySet(Set):
29623006
return self.__class__
29633007

29643008

3009+
class Reals(Set):
3010+
3011+
def __new__(self):
3012+
return reals()
3013+
3014+
def _sympy_(self):
3015+
import sympy
3016+
return sympy.S.Reals
3017+
3018+
@property
3019+
def func(self):
3020+
return self.__class__
3021+
3022+
3023+
class Integers(Set):
3024+
3025+
def __new__(self):
3026+
return integers()
3027+
3028+
def _sympy_(self):
3029+
import sympy
3030+
return sympy.S.Integers
3031+
3032+
@property
3033+
def func(self):
3034+
return self.__class__
3035+
3036+
29653037
class UniversalSet(Set):
29663038

29673039
def __new__(self):
@@ -3381,7 +3453,7 @@ cdef class DenseMatrixBase(MatrixBase):
33813453

33823454
@property
33833455
def is_square(self):
3384-
return self.rows == self.cols
3456+
return deref(self.thisptr).is_square()
33853457

33863458
def nrows(self):
33873459
return deref(self.thisptr).nrows()
@@ -3487,6 +3559,12 @@ cdef class DenseMatrixBase(MatrixBase):
34873559
deref(self.thisptr).mul_matrix(deref(A_.thisptr), deref(result.thisptr))
34883560
return result
34893561

3562+
def multiply_elementwise(self, A):
3563+
cdef MatrixBase A_ = sympify(A)
3564+
cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols())
3565+
deref(self.thisptr).elementwise_mul_matrix(deref(A_.thisptr), deref(result.thisptr))
3566+
return result
3567+
34903568
def add_scalar(self, k):
34913569
cdef Basic k_ = sympify(k)
34923570
cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols())
@@ -3504,6 +3582,51 @@ cdef class DenseMatrixBase(MatrixBase):
35043582
deref(self.thisptr).transpose(deref(result.thisptr))
35053583
return result
35063584

3585+
def conjugate(self):
3586+
cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols())
3587+
deref(self.thisptr).conjugate(deref(result.thisptr))
3588+
return result
3589+
3590+
def conjugate_transpose(self):
3591+
cdef DenseMatrixBase result = self.__class__(self.nrows(), self.ncols())
3592+
deref(self.thisptr).conjugate_transpose(deref(result.thisptr))
3593+
return result
3594+
3595+
@property
3596+
def H(self):
3597+
return self.conjugate_transpose()
3598+
3599+
def trace(self):
3600+
return c2py(deref(symengine.static_cast_DenseMatrix(self.thisptr)).trace())
3601+
3602+
@property
3603+
def is_zero_matrix(self):
3604+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_zero())
3605+
3606+
@property
3607+
def is_real_matrix(self):
3608+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_real())
3609+
3610+
@property
3611+
def is_diagonal(self):
3612+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_diagonal())
3613+
3614+
@property
3615+
def is_symmetric(self):
3616+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_symmetric())
3617+
3618+
@property
3619+
def is_hermitian(self):
3620+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_hermitian())
3621+
3622+
@property
3623+
def is_weakly_diagonally_dominant(self):
3624+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_weakly_diagonally_dominant())
3625+
3626+
@property
3627+
def is_strongly_diagonally_dominant(self):
3628+
return tribool(deref(symengine.static_cast_DenseMatrix(self.thisptr)).is_strictly_diagonally_dominant())
3629+
35073630
@property
35083631
def T(self):
35093632
return self.transpose()
@@ -5050,6 +5173,14 @@ def universalset():
50505173
return c2py(<rcp_const_basic>(symengine.universalset()))
50515174

50525175

5176+
def reals():
5177+
return c2py(<rcp_const_basic>(symengine.reals()))
5178+
5179+
5180+
def integers():
5181+
return c2py(<rcp_const_basic>(symengine.integers()))
5182+
5183+
50535184
def finiteset(*args):
50545185
cdef symengine.set_basic s
50555186
cdef Basic e_
@@ -5066,6 +5197,49 @@ def contains(expr, sset):
50665197
return c2py(<rcp_const_basic>(symengine.contains(expr_.thisptr, s)))
50675198

50685199

5200+
def tribool(value):
5201+
if value == -1:
5202+
return None
5203+
else:
5204+
return bool(value)
5205+
5206+
5207+
def is_zero(expr):
5208+
cdef Basic expr_ = sympify(expr)
5209+
cdef int tbool = symengine.is_zero(deref(expr_.thisptr))
5210+
return tribool(tbool)
5211+
5212+
5213+
def is_positive(expr):
5214+
cdef Basic expr_ = sympify(expr)
5215+
cdef int tbool = symengine.is_positive(deref(expr_.thisptr))
5216+
return tribool(tbool)
5217+
5218+
5219+
def is_negative(expr):
5220+
cdef Basic expr_ = sympify(expr)
5221+
cdef int tbool = symengine.is_negative(deref(expr_.thisptr))
5222+
return tribool(tbool)
5223+
5224+
5225+
def is_nonpositive(expr):
5226+
cdef Basic expr_ = sympify(expr)
5227+
cdef int tbool = symengine.is_nonpositive(deref(expr_.thisptr))
5228+
return tribool(tbool)
5229+
5230+
5231+
def is_nonnegative(expr):
5232+
cdef Basic expr_ = sympify(expr)
5233+
cdef int tbool = symengine.is_nonnegative(deref(expr_.thisptr))
5234+
return tribool(tbool)
5235+
5236+
5237+
def is_real(expr):
5238+
cdef Basic expr_ = sympify(expr)
5239+
cdef int tbool = symengine.is_real(deref(expr_.thisptr))
5240+
return tribool(tbool)
5241+
5242+
50695243
def set_union(*args):
50705244
cdef symengine.set_set s
50715245
cdef Set e_
@@ -5115,6 +5289,12 @@ def imageset(sym, expr, base):
51155289
return c2py(<rcp_const_basic>(symengine.imageset(sym_.thisptr, expr_.thisptr, b)))
51165290

51175291

5292+
universal_set_singleton = UniversalSet()
5293+
integers_singleton = Integers()
5294+
reals_singleton = Reals()
5295+
empty_set_singleton = EmptySet()
5296+
5297+
51185298
def solve(f, sym, domain=None):
51195299
cdef Basic f_ = sympify(f)
51205300
cdef Basic sym_ = sympify(sym)

0 commit comments

Comments
 (0)