Something.expand() is 0 but factor() is not zero

53 views
Skip to first unread message

a.simpl...@gmail.com

unread,
Apr 3, 2022, 1:14:59 AM4/3/22
to sage-devel
The following code

> var("z y z")
> f = (x-y)^2*(y-z)*(z-x) + (y-z)^2*(z-x)*(x-y) + (z-x)^2*(x-y)*(y-z)
> f.expand()


outputs 0.
But
> f.factor()
simply prints the original formula (x-y)^2...

Maybe something is wrong?

Adarsh Kishore

unread,
Apr 3, 2022, 5:23:47 AM4/3/22
to sage-devel
Which version of Sage are you using? And on which platform?

Adarsh Kishore

unread,
Apr 3, 2022, 5:27:35 AM4/3/22
to sage-devel
By the way, f.expand() is not wrong. The expression is identically equal to 0 for all values of x, y and z.
https://www.mathpapa.com/algebra-calculator.html?q=(x-y)%5E2*(y-z)*(z-x)%2B(y-z)%5E2*(z-x)*(x-y)%2B(z-x)%5E2*(x-y)*(y-z)

Screenshot from 2022-04-03 14-55-22.png

As for `f.factor()`, the given expression cannot be factorized further. So the answer is correct. 

Adarsh Kishore

unread,
Apr 3, 2022, 5:29:17 AM4/3/22
to sage-devel
I checked this on my SageMath v9.6.beta5 on Ubuntu 20.04 LTS, and it checks out

Screenshot from 2022-04-03 14-58-46.png

Emmanuel Charpentier

unread,
Apr 3, 2022, 12:08:03 PM4/3/22
to sage-devel
sage: var("x, y, z")
(x, y, z)
sage: Ex = (x-y)^2*(y-z)*(z-x) + (y-z)^2*(z-x)*(x-y) + (z-x)^2*(x-y)*(y-z)
sage: Ex
-(x - y)^2*(x - z)*(y - z) + (x - y)*(x - z)^2*(y - z) - (x - y)*(x - z)*(y - z)^2
sage: Ex.expand()
0
sage: Ex.factor()
-(x - y)^2*(x - z)*(y - z) + (x - y)*(x - z)^2*(y - z) - (x - y)*(x - z)*(y - z)^2
sage: Ex.simplify()
-(x - y)^2*(x - z)*(y - z) + (x - y)*(x - z)^2*(y - z) - (x - y)*(x - z)*(y - z)^2
sage: Ex.simplify_full()
0
sage: Ex._sympy_().expand()._sage_()
0
sage: Ex._sympy_().factor()._sage_()
0
sage: Ex._giac_().factor()._sage_()
0
sage: Ex._fricas_().factor()._sage_()
0
sage: mathematica.Factor(Ex).sage()
0

So what ?

Sage’s factor doesn’t factorize this expression ? Big fail ! Film at 11…

As illustrated, Sage has lots of ways to factorize this expression. BTW, expand a symbolic expression is often a clever way to (start to) finding a “nice” expression of this quantity.

To understand why factorizing this expression is not trivial, meditate :

sage: Ex.operator()
<function add_vararg at 0x7ff7aaf70700>
sage: [u.expand() for u in Ex.operands()]
[-x^3*y + 2*x^2*y^2 - x*y^3 + x^3*z - x^2*y*z - x*y^2*z + y^3*z - x^2*z^2 + 2*x*y*z^2 - y^2*z^2,
 x^3*y - x^2*y^2 - x^3*z - x^2*y*z + 2*x*y^2*z + 2*x^2*z^2 - x*y*z^2 - y^2*z^2 - x*z^3 + y*z^3,
 -x^2*y^2 + x*y^3 + 2*x^2*y*z - x*y^2*z - y^3*z - x^2*z^2 - x*y*z^2 + 2*y^2*z^2 + x*z^3 - y*z^3]
sage: [u.expand().cancel() for u in Ex._sympy_().args]
[x**3*y - x**3*z - x**2*y**2 - x**2*y*z + 2*x**2*z**2 + 2*x*y**2*z - x*y*z**2 - x*z**3 - y**2*z**2 + y*z**3,
 -x**3*y + x**3*z + 2*x**2*y**2 - x**2*y*z - x**2*z**2 - x*y**3 - x*y**2*z + 2*x*y*z**2 + y**3*z - y**2*z**2,
 -x**2*y**2 + 2*x**2*y*z - x**2*z**2 + x*y**3 - x*y**2*z - x*y*z**2 + x*z**3 - y**3*z + 2*y**2*z**2 - y*z**3]
sage: Ex._sympy_().cancel()
0


HTH,

a.simpl...@gmail.com

unread,
Apr 3, 2022, 5:02:39 PM4/3/22
to sage-devel
I meant to say that f.expand() gives the correct answer.
To see why, factor out the common factors (x-y)(y-z)(z-x).
Once you did so, the rest is ( (x-y) + (y-z) + (z-x) )
and so I expect f.factor() returns 0.

The statement "the given expression cannot be factorized further"
seems weird to me.

dmo...@deductivepress.ca

unread,
Apr 3, 2022, 5:49:29 PM4/3/22
to sage-devel
I think this is indeed a bug, so thanks for reporting it.  My impression from a quick look at the code is that sagemath expands the expression into a polynomial (a linear combination of monomials) before trying to factor it. If the expansion has only a single term (a constant times a monomial), then nothing needs to be done, since this expansion is already factored. Sagemath erroneously thinks nothing needed to be done from the beginning, and returns the original expression, instead of the expanded expression.

Here is a simpler example:

sage: ((x + 1)^2 - 2*x - 1).factor() # bad (should be x^2)
(x + 1)^2 - 2*x - 1
sage: ((x + 2)^2 - 2*x - 3).factor() # good
(x + 1)^2

I opened trac ticket #33640 for further discussion.
Reply all
Reply to author
Forward
0 new messages