When an expression is a ratio with powers that I expect sympy (v1.12) to be able to cancel, I sometimes get results I don't understand. Here's an example. Notice that all of the symbols except d
and n
are real. (d
is sometimes complex, and n
is a positive integer.)
from sympy import *
a, b, c, x, y = symbols('a b c x y', real=True)
n = symbols('n', integer=True, positive=True)
I get what I expect for reals:
d = (a * x**n + b * x**(n-1) + c) / x**n
print(d.equals(a + b/x + c/x**n))
prints True
.
This complex case gives what I expect:
d = (a * (x + I*y)**n + c)/(x + I*y)**n
print(d.equals(a + c/(x + I*y)**n))
prints True
.
Same here:
d = (b * (x + I*y)**(n-1) + c)/(x + I*y)**n
print(d.equals(b/(x + I*y) + c/(x + I*y)**n))
prints True
.
But not this case:
d = (a * (x + I*y)**n + b * (x + I*y)**(n-1) + c)/(x + I*y)**n
print(d.equals(a + b/(x + I*y) + c/(x + I*y)**n))
prints None
.
The correct (?) answer seems obvious; I'm checking d
against what I get when I cancel the x+I*y
factors by hand. The None
answer means sympy claims the answer is unknown, without further assumptions about the variables. What could make the result unknown, when the previous cases are not unknown?
The None answer means sympy claims the answer is unknown, without further assumptions about the variables.
According to my experience, it also returns None when SymPy is unable to verify the equality, for whatever reason.
d = (a * (x + I*y)**n + b * (x + I*y)**(n-1) + c)/(x + I*y)**n
test = a + b/(x + I*y) + c/(x + I*y)**n
display(d, test)
This is a case where you might need to put in extra effort to verify it, by rewriting LHS - RHS
(left-hand side, right-hand side) and verifying it is equal to 0.
d - test
Now we expand it:
(d - test).expand()
Note that the powers have not been simplified. Finally, we simplify it:
(d - test).expand().simplify()
# out: 0
What could make the result unknown, when the previous cases are not unknown?
My guess is that equals
is not using powsimp
in its code, or something similar in order to simplify powers.