# Why does $\frac{2}{3} t - \frac{2}{3} y$ factors only when the variables are polynomial ring over the rational numbers?

The expression $\frac{2}{3} t - \frac{2}{3} y$ can be factored as $\left(\frac{2}{3}\right) \cdot (y - t)$.

If I try to use sage in this way to do the factorization:

var('y t')
E = -2/3*y + 2/3 * t
E.factor()


The result is still E.

On the other hand, if do it like this:

R.<y,t> = PolynomialRing(QQ)
E = -2/3*t +2/3*y
E.factor()


The result is as expected.

Why does the call to factor() works as expected when the variable $y$ and $t$ are defined to be a polynomial ring in QQ and not work then they are symbolic expressions.

edit retag close merge delete

1

Asking for some more words in

sage: var('y t');
sage: E = -2/3*y + 2/3 * t
sage: E.factor?


we get (also)

   If you are factoring a polynomial with rational coefficients (and
dontfactor is empty) the factorization is done using Singular

sage: var('x,y')
(x, y)
sage: (x^99 + y^99).factor()


From a practical view, my need is to factor "true factors", not units over $\mathbb Q[t,y]$. (Working over $\mathbb Q$ 2/3 is a unit. Why factor it?) If i would have to chose between a quick existing factorization - when i need it - and a rewritten version of it...

This does not answer the question, it changes the view so that the issue is less important

Sort by » oldest newest most voted

[tl:dr] The Symbolic Ring is not able to represent expressions such as (2/3) * (t - y) and directly uses associativity to "simplify" such an expression.[/tl;dr]

Another answer to your question, which is complementary to the other one. Since your expression is a polynomial with rational coefficients, the factorization is done using Singular. The code for this can be seen using E.factor?? and the part of interest is

f = self.polynomial(QQ)
w = repr(f.factor())
return symbolic_expression_from_string(w)


where self is the expression you want to factor (here self is E, that is 2/3 * t - 2/3 * y. At the first line, f gets the expression as a polynomial over QQ, and at the second line this polynomial f is factored, and w gets the string representation of the polynomial. If you try this by hand you get:

sage: f = (2/3*t - 2/3*y).polynomial(QQ)
sage: f.factor()
(2/3) * (t - y)
sage: repr(_) # underscore represents the last result
'(2/3) * (t - y)'


So you get the string representation of what you want. Now the third line converts the string back to a symbolic expression, and you can verify that you obtain the same result as with E.factor(), which is not what you want:

sage: from sage.calculus.calculus import symbolic_expression_from_string
sage: symbolic_expression_from_string('(2/3) * (t - y)')
2/3*t - 2/3*y


OK, so now what is the difficulty? The problem is that symbolic expressions automatically make some "simplifications" to the expressions you enter. Compare:

sage: (y - t) * (y + 2)
-(t - y)*(y + 2)
sage: (y - t) * (3 + 2)
-5*t + 5*y


As you can see, the integer sums are directly "reduced", associativity is used as soon as one operand of a multiplication is an integer (or a rational number, etc.). The current implementation of symbolic expressions is thus unable to represent the factorization you want. I am not able to dig in the code for symbolic expressions, so I cannot explain why some simplifications are performed and other are not. Yet, note that one aim of the Symbolic Ring is to present the results as the user would probably like to see them. Of course, this is ill-defined and results in problems like the one you are experiencing. As a rule of thumb, you should try to avoid the Symbolic Ring as much as possible, and work with more specialized rings as often as you can.

more

The short (albeit not very interesting) answer is that E as a symbolic expression (first case), has a very different factor method than E as a polynomial (second case).

For example, consider:

sage: var('y t'); E = -2/3*y + 2/3 * t; type(E)
(y, t)
<type 'sage.symbolic.expression.Expression'>


Type one question mark to get the help (docstring), or two question marks to see what happens "under the hood" (read the code just after the docstring):

sage: E.factor()
2/3*t - 2/3*y
sage: E.factor??
Source:
def factor(self, dontfactor=[]):
"""
Factor the expression, containing any number of variables or functions, into
factors irreducible over the integers.
...
from sage.calculus.calculus import symbolic_expression_from_maxima_string, symbolic_expression_from_string
....


So factor here dispatches a suitable function from the Maxima interface.

Now, let's cast that symbolic expression into a polynomial

sage: P = E.polynomial(QQ); type(P)
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>
sage: P.factor()
(2/3) * (t - y)
sage: P.factor??
Source:
def factor(self, proof=True):
"""
Return the factorization of this polynomial.
...
cdef ring *_ring = self._parent_ring
....
cdef MPolynomialRing_libsingular parent = self._parent
....
.... return Factorization(list(U) + FF, unit=U.unit())


so if i get it right, in this case Sage makes use of the Factorization function of the CAS for polynomial computations Singular.

more