Powers and complex numbers

105 views
Skip to first unread message

Paul Royik

unread,
Nov 4, 2015, 4:30:21 AM11/4/15
to sympy
I have the following expresssion:

f=x**(Rational(2,3))

How can I get 1, when substituting (-1) instead of complex number?
For now, I got complex number when run f.subs(x,-1).evalf()

Aaron Meurer

unread,
Nov 4, 2015, 11:29:29 AM11/4/15
to sy...@googlegroups.com
You need to use real_root, like

In [3]: real_root(-1, 3)
Out[3]: -1

In [4]: real_root(-1, 3)**2
Out[4]: 1

SymPy, like most math libraries, uses complex roots (i.e., principal
roots) because they have nicer mathematical properties.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/662a2085-1030-42d5-bbde-feb524fd246c%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Paul Royik

unread,
Nov 4, 2015, 2:19:37 PM11/4/15
to sympy
So, there is no way to do it using subs and/or some manipulations?

real_root(-1, 3) is of no help, because I can have arbitrary expression.

Aaron Meurer

unread,
Nov 4, 2015, 2:25:17 PM11/4/15
to sy...@googlegroups.com
You can generally do this sort of thing using replace().
Unfortunately, the pattern matcher doesn't recognize rational numbers
as a/b, so you have to do a more manual check. This should work:

e.replace(lambda i: i.is_Pow and i.base == x and i.exp.is_Rational,
lambda i: real_root(-1,
i.exp.as_numer_denom()[1])**i.exp.as_numer_denom()[0])

(replace -1 with whatever value you want to replace). A "cleaner"
solution would be to create a custom Pow subclass that evaluates like
you want, and replace instances of Pow with your class before doing a
substitution.

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/c88261c0-3449-4d7a-abf8-8d28ebdca59d%40googlegroups.com.

Paul Royik

unread,
Nov 4, 2015, 6:43:33 PM11/4/15
to sympy
Thank you.

Paul Royik

unread,
Nov 6, 2015, 2:42:20 PM11/6/15
to sympy
I decided to use "cleaner" solution: create a custom Pow subclass that evaluates. What method should I override?

Aaron Meurer

unread,
Nov 6, 2015, 2:51:39 PM11/6/15
to sy...@googlegroups.com

Paul Royik

unread,
Nov 6, 2015, 3:32:12 PM11/6/15
to sympy
Thank you.
How to override behaviour, so that above expression, i.e.(-1)**(2/3).is_real outputs True?

Aaron Meurer

unread,
Nov 9, 2015, 12:17:29 PM11/9/15
to sy...@googlegroups.com
I guess you'll want to check if the base is_Number and is_negative and
do the custom logic, otherwise run the superclass eval. Something like
(untested):

@classmethod
def eval(cls, base, exp):
if base.is_Number and base.is_negative:
# Custom logic here
else:
return super().eval(base, exp)

Aaron Meurer
> https://groups.google.com/d/msgid/sympy/2a8b8984-c262-4b64-8c05-80deb5d74700%40googlegroups.com.

Paul Royik

unread,
Nov 10, 2015, 4:33:03 PM11/10/15
to sympy
Thank you very much.
Reply all
Reply to author
Forward
0 new messages