Skip to content

Commit 03671e2

Browse files
authored
Merge pull request symengine#440 from isuruf/as_powers_dict
Add as_powers_dict
2 parents 5674fb7 + 0c1111c commit 03671e2

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

symengine/lib/symengine_wrapper.pyx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,11 @@ cdef class Basic(object):
11691169
raise TypeError("Can't convert expression to float")
11701170
return complex(f)
11711171

1172+
def as_powers_dict(self):
1173+
d = collections.defaultdict(int)
1174+
d[self] = 1
1175+
return d
1176+
11721177

11731178
def series(ex, x=None, x0=0, n=6, as_deg_coef_pair=False):
11741179
# TODO: check for x0 an infinity, see sympy/core/expr.py
@@ -1345,6 +1350,11 @@ cdef class ImaginaryUnit(Complex):
13451350
def __cinit__(Basic self):
13461351
self.thisptr = symengine.I
13471352

1353+
def as_powers_dict(self):
1354+
d = collections.defaultdict(int)
1355+
d[minus_one] = half
1356+
return d
1357+
13481358
I = ImaginaryUnit()
13491359

13501360

@@ -2078,6 +2088,13 @@ cdef class NegativeInfinity(Number):
20782088
import sage.all as sage
20792089
return -sage.oo
20802090

2091+
def as_powers_dict(self):
2092+
d = collections.defaultdict(int)
2093+
d[minus_one] = 1
2094+
d[oo] = 1
2095+
return d
2096+
2097+
20812098
minus_oo = NegativeInfinity()
20822099

20832100

@@ -2276,6 +2293,28 @@ class Mul(AssocOp):
22762293
c2py(<rcp_const_basic>deref(X).get_coef())
22772294
return d
22782295

2296+
def as_powers_dict(Basic self):
2297+
cdef RCP[const symengine.Mul] X = symengine.rcp_static_cast_Mul(self.thisptr)
2298+
cdef map_basic_basic m = deref(X).get_dict()
2299+
coef = c2py(<rcp_const_basic>(deref(X).get_coef()))
2300+
if coef == 1:
2301+
d = collections.defaultdict(int)
2302+
else:
2303+
d = coef.as_powers_dict()
2304+
2305+
it = m.begin()
2306+
it_end = m.end()
2307+
while it != it_end:
2308+
base = c2py(<rcp_const_basic>(deref(it).first))
2309+
exp = c2py(<rcp_const_basic>(deref(it).second))
2310+
if base.is_Rational and base.p < base.q and base.p > 0:
2311+
d[1/base] -= exp
2312+
else:
2313+
d[base] += exp
2314+
inc(it)
2315+
2316+
return d
2317+
22792318

22802319
class Pow(Expr):
22812320

@@ -2319,6 +2358,15 @@ class Pow(Expr):
23192358
def func(self):
23202359
return self.__class__
23212360

2361+
def as_powers_dict(Basic self):
2362+
d = collections.defaultdict(int)
2363+
base, exp = self.as_base_exp()
2364+
if base.is_Rational and base.p < base.q and base.p > 0:
2365+
d[1/base] = -exp
2366+
else:
2367+
d[base] = exp
2368+
return d
2369+
23222370

23232371
class Function(Expr):
23242372

symengine/tests/test_expr.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from symengine import Symbol, Integer
1+
from symengine import Symbol, Integer, oo
22
from symengine.test_utilities import raises
33

44

@@ -12,3 +12,17 @@ def test_as_coefficients_dict():
1212
[0, 0, 3, 0]
1313
assert (3.0*x*y).as_coefficients_dict()[3.0*x*y] == 0
1414
assert (3.0*x*y).as_coefficients_dict()[x*y] == 3.0
15+
16+
17+
def test_as_powers_dict():
18+
x = Symbol('x')
19+
y = Symbol('y')
20+
21+
assert (2*x**y).as_powers_dict() == {2: 1, x: y}
22+
assert (2*x**2*y**3).as_powers_dict() == {2: 1, x: 2, y: 3}
23+
assert (-oo).as_powers_dict() == {Integer(-1): 1, oo: 1}
24+
assert (x**y).as_powers_dict() == {x: y}
25+
assert ((1/Integer(2))**y).as_powers_dict() == {Integer(2): -y}
26+
assert (x*(1/Integer(2))**y).as_powers_dict() == {x: Integer(1), Integer(2): -y}
27+
assert (2**y).as_powers_dict() == {2: y}
28+
assert (2**-y).as_powers_dict() == {2: -y}

0 commit comments

Comments
 (0)