Sage Reference
Here’s some information about how to get Sage to do some of the types of calculations we’re learning about.
Fields
Basic fields:
QQ
(orRationalField()
) for the field of rationals.RR
(orRealField()
) for the field of reals.CC
(orComplexField()
) for the field of complex numbers.GF(13)
for the finite field of 13 elements.
Harder fields:
QQbar
for the field of algebraic numbers.GF(9,'a')
for the finite field of 9 elements \(\mathbb{F}_3(a)\) where \(a\) is an element of degree 2 over \(\mathbb{F}_3\). To be able to use the namea
, type something likek.<a> = GF(9,'a')
in analogy with the polynomial stuff below.
Single variable polynomials
You can get Sage to compute GCDs, as follows.
<x> = PolynomialRing(QQ)
R.
= x^5 + x^3
f = x^2
g
gcd(f,g)
The gcd
function only takes two arguments at a time. If
you have a list, use a loop:
def gcd_list(F, init=0):
= init
g for f in F:
= gcd(g,f)
g return g
<x> = PolynomialRing(QQ)
R.^3,x^2*(x+1), x^2]) gcd_list([x
You can get Sage to compute roots, as follows.
<x> = PolynomialRing(QQ)
R.
= x^2 - 1
f f.roots()
Note that the roots
function is sensitive to the base
field. For example, (x^2+1).roots()
returns different
results if your base field is CC
instead of
QQ
.
Similarly, you can also get Sage to factor polynomials.
<x> = PolynomialRing(QQ)
R.= x^2 + 2*x + 1
f f.factor()
Multivariable polynomials: Partial derivatives
Sage can compute partial derivatives of multivariable polynomials
using the gradient
function.
<x,y> = PolynomialRing(QQ)
R.= (x^2+y^2-4)*(x^2+y^2-1) + (x-3/2)^2 + (y-3/2)^2
f f.gradient()
The output is a list of the partial derivatives of \(f\), as follows:
4*x^3 + 4*x*y^2 - 8*x - 3, 4*x^2*y + 4*y^3 - 8*y - 3] [
Multivariable polynomials: GCDs, factoring, and reductions
Sage can also compute gcds of multivariable polynomials and factorizations, using the same syntax as for single variable polynomials described above.
You can put this together with the gradient
function to
compute the reduction \(f_{\mathrm{red}}\) of a polynomial \(f\) as well, as defined in definition
4.2.10.
def gcd_list(F, init=0):
= init
g for f in F:
= gcd(g,f)
g return g
def reduction(f):
return (f/gcd_list(f.gradient(), init=f)).numerator()
<x,y> = PolynomialRing(QQ)
R.= (x+y^2)^3*(x-y)
f reduction(f).factor()
The output of this is
-1) * (-x + y) * (x + y^2) (
which is the same as what’s given in the textbook on pgae 186 right after definition 4.2.10.
Multivariable polynomials: Monomial Orders
<x,y> = PolynomialRing(QQ, order='degrevlex') R.
Note that order='degrevlex'
tells Sage you want to use
grevlex order. This is default, so you can also omit this argument.
<x,y> = PolynomialRing(QQ)
R.= x^7*y^2 + x^3*y^2 - y + 1
f
# Leading term
f.lt() # Leading monomial
f.lm() # Leading coefficient
f.lc()
# Total degree of f = 9
f.degree() # Multidegree of f = (7,2) f.degrees()
If you want to change the order…
- For lex order, use
order='lex'
- For grlex order, use
order='deglex'
- For the product orders of 2.4.9 or 3.1.6(b), use things like
order='lex(2),deglex(3)'
. - For the weight order of 2.4.11, use things like
order=TermOrder('wdegrevlex',(1,2))
.- You can replace
wdegrevlex
withwdeglex
. - The elimination orders of 2.4.11(d), 3.1.6(a), etc, are special cases of these weight orders.
- You can replace
Multivariable polynomials: Division (Generic)
There are some problems with Sage’s built-in polynomial division functions when you’re not dividing by a Gröbner basis. Here’s some code that does this division correctly.
The function quo_rem_list(f,G)
divides a polynomial
f
by a list of polynomials G
. The output is a
pair (Q,r)
where Q
is the list of quotients
and r
is the remainder.
def quo_rem_list(f, G):
= [0 for i in range(len(G))]
Q = 0
r
while f != 0:
= False
divisionoccured for i, g in enumerate(G):
if g.lt().divides(f.lt()):
= (f.lt() / g.lt()).numerator()
q += q
Q[i] -= q*g
f = True
divisionoccured break
if not divisionoccured:
+= f.lt()
r -= f.lt()
f return Q, r
<x,y> = PolynomialRing(QQ, order='lex')
R.= x^7*y^2 + x^3*y^2 - y + 1
f = [-y^3+x, x*y^2-x]
G quo_rem_list(f,G)
Note that when you divide two polynomials, Sage treats the output as
an element of the fraction field of the ring of polynomials – even when
the quotient is just a polynomial! The .numerator()
is one
way I’ve found of “casting” from elements of the fraction field back to
polynomials. Maybe there’s a better way.
Multivariable Polynomials: S-polynomials
Here’s a function S
that takes as input a polynomial
ring R
and two polynomials f
and
g
in R
, and spits out the S-polynomial of
f
and g
.
def S(R,f,g):
= R.monomial_lcm(f.lm(), g.lm())
lcm return (((lcm/f.lt()) * f) - ((lcm/g.lt()) * g)).numerator()
Here’s a sample usage:
<x,y,z> = PolynomialRing(QQ, order='lex')
R.-x^2,z-x^3) S(R,y
Multivariable Polynomials: Ideals, Reduction, and Gröbner bases
Recall (from section 2.6, exercise 1) that given an ideal \(I \subseteq k[x_1, \dotsc, x_n]\) and a polynomial \(f \in k[x_1, \dotsc, x_n]\), there is a unique way to write \(f = g + r\) where \(g \in I\) and no term of \(r\) is divisible by any element of \(\mathrm{LT}(I)\). If \(G\) is a Gröbner basis for \(I\), then this \(r\) is also denoted \(\bar{f}^G\) in the textbook.
Sage can calculate this \(r\) using
the reduce
function, as follows:
<x,y,z> = PolynomialRing(QQ, order='deglex')
R.= Ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)
I = x^7*y^2 + x^3*y^2 - y + 1
f reduce(I) f.
In the background, Sage computes a Gröbner basis for I
to do this reduction. You can also get Sage to display a reduced Gröbner
basis for an ideal.
<x,y,z> = PolynomialRing(QQ, order='deglex')
R.= Ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)
I I.groebner_basis()
Multivariable Polynomials: Radicals
Sage can compute radicals of arbitrary ideals in polynomial rings. The output of the following is a Gröbner basis for \(\sqrt{I}\) where \(I = \langle x^2+y^2-1,y-1 \rangle\).
<x,y> = PolynomialRing(QQ, order='deglex')
R.= Ideal(x^2+y^2-1,y-1)
I I.radical().groebner_basis()