parent, [is_gen=False]) |
The following examples illustrate creation of elements of polynomial rings, and some basic arithmetic.
First we make a polynomial over the integers and do some arithmetic:
sage: x = PolynomialRing(IntegerRing()).gen() sage: f = x**5 + 2*x**2 + (-1); f x^5 + 2*x^2 - 1 sage: f**2 x^10 + 4*x^7 - 2*x^5 + 4*x^4 - 4*x^2 + 1
Next we do arithmetic in a sparse polynomial ring over the integers:
sage: R = PolynomialRing(IntegerRing(), "x"); x = R.gen(); R Univariate Polynomial Ring in x over Integer Ring sage: S = PolynomialRing(R, "Z"); Z = S.gen(); S Univariate Polynomial Ring in Z over Univariate Polynomial Ring in x over Integer Ring sage: f = Z**3 + (x**2-2*x+1)*Z - 3; f Z^3 + (x^2 - 2*x + 1)*Z + -3 sage: f*f Z^6 + (2*x^2 - 4*x + 2)*Z^4 + (-6)*Z^3 + (x^4 - 4*x^3 + 6*x^2 - 4*x + 1)*Z^2 + (-6*x^2 + 12*x - 6)*Z + 9 sage: f**3 == f*f*f True
To have the element print as 'y', give 'y' as the second argument to the PolynomialRing constructor.
sage: y = PolynomialRing(IntegerRing(), 'y').gen() sage: y**3 - 2*y y^3 - 2*y
base_ring,
copy,
degree,
denominator,
derivative,
dict,
factor,
integral,
inverse_of_unit,
is_gen,
is_irreducible,
is_monic,
is_unit,
is_zero,
lcm,
leading_coefficient,
list,
make_monic,
name,
polynomial,
resultant,
reverse,
roots,
truncate,
valuation,
xgcd
Further documentation:
) |
Return the base ring of the parent of self.
sage: x = PolynomialRing(ZZ).gen() sage: x.base_ring() Integer Ring sage: (2*x+3).base_ring() Integer Ring
) |
Return a copy of self.
We create the polynomial
, then set
, and change
the coefficient of
in
, which also changes the coefficient
of
in
. If we instead copy
, then changing the
coefficient of
of
does not change
.
sage: x = PolynomialRing(IntegerRing()).gen() sage: f = x+3 sage: g = f sage: g[1]=3 sage: f 3*x + 3 sage: g = f.copy() sage: g[1]=5 sage: f 3*x + 3 sage: g 5*x + 3
) |
Return the degree of this polynomial. The zero polynomial has degree -1.
sage: x = PolynomialRing(ZZ).gen() sage: f = x**93 + 2*x + 1 sage: f.degree() 93 sage: x = PolynomialRing(QQ, sparse=True).gen() sage: f = x**100000 sage: f.degree() 100000
) |
Return the least common multiple of the denominators of the entries of self, when this makes sense, i.e., when the coefficients have a denominator function.
WARNING: This is not the denominator of the rational function defined by self, which would always be 1 since self is a polynomial.
First we compute the denominator of a polynomial with integer coefficients, which is of course 1.
sage: x = PolynomialRing(IntegerRing()).gen() sage: f = x**3 + 17*x + 1 sage: f.denominator() 1
Next we compute the denominator of a polynomial with rational coefficients.
sage: Q = RationalField() sage: x = PolynomialRing(Q).gen() sage: f = Q('1/17')*x**19 - Q('2/3')*x + Q('1/3'); f 1/17*x^19 - 2/3*x + 1/3 sage: f.denominator() 51
Finally, we try to compute the denominator of a polynomial with coefficients in the real numbers, which is a ring whose elements do not have a denominator method.
sage: R = RealField() sage: x = PolynomialRing(R).gen() sage: f = x + R('0.3'); f 1.0000000000000000*x + 0.29999999999999999 sage: f.denominator() Traceback (most recent call last): ... AttributeError: '_mpfr.RealNumber' object has no attribute 'denominator'
) |
Return polynomials f1, ..., fn and exponents e1, ..., en such that the gcd fo the coefficients of the fi is 1, and prod fi**ei is equal to a scalar multiple of self.
INPUT: a polynomial OUTPUT: Factorization -- the factorization of self
sage: x = PolynomialRing(RationalField()).gen() sage: f = (x**3 - 1)**2 sage: f.factor() (x - 1)^2 * (x^2 + x + 1)^2
) |
Returns True if this polynomial is monic. The zero polynomial is by definition not monic.
other) |
Let f and g be two polynomials. Then this function returns the monic least common multiple of f and g.
) |
Return this polynomial divided by its leading coefficient.
) |
Return all roots of this polynomial.
sage: x = PolynomialRing(RationalField()).gen() sage: f = x**3 - 1 sage: f.roots() [(1, 1)] sage: f = (x**3 - 1)**2 sage: f.roots() [(1, 2)]
n) |
Replace this polynomial by
where the sum is
over
. The resulting polynomial is equivalent to self
modulo
.
) |
If
, with
nonzero,
then the valuation of
is
. The valuation of the zero
polynomial is
.
other) |
Extended gcd of self and polynomial other.
Instances of class Polynomial also have the following special methods:
__call__,
__cmp__,
__float__,
__floordiv__,
__getitem__,
__int__,
__invert__,
__long__,
__mod__,
__pow__,
__repr__,
__setitem__,
_add,
_factor_pari_helper,
_integer_,
_latex_,
_mul,
_mul_generic,
_mul_karatsuba,
_pari_
Further documentation:
a) |
Evaluate polynomial at x=a using Horner's rule
INPUT: a -- ring element a; need not be in the coefficient ring of the polynomial. OUTPUT: ring element, in the parent of a, if a is a ring element.
sage: x = PolynomialRing(QQ, 'x').gen() sage: f = x - 5 sage: f(3) -2 sage: f = (x-1)**5 sage: f(2) 1
AUTHOR: David Joyner, 2005-04-10.
right) |
Quotient of division of self by other. This is denoted //.
other) |
Remainder of division of self by other.
sage: x = PolynomialRing(IntegerRing()).gen() sage: x % (x+1) -1 sage: (x**3 + x - 1) % (x**2 - 1) 2*x - 1
right) |
sage: x = PolynomialRing(IntegerRing()).gen() sage: (x - 4)*(x**2 - 8*x + 16) x^3 - 12*x^2 + 48*x - 64
right) |
Returns the product of two polynomials using the Karatsuba divide and conquer multiplication algorithm. This is only used over a generic base ring. (Special libraries like NTL are used, e.g., for the integers and rationals, which are much faster.)
INPUT: self: Polynomial right: Polynomial (over same base ring as self) OUTPUT: Polynomial The product self*right.
ALGORITHM: The basic idea is to use that
where ac=a*c and bd=b*d, which requires three multiplications instead of the naive four. (In my examples, strangely just doing the above with four multiplications does tend to speed things up noticeably.) Given f and g of arbitrary degree bigger than one, let e be min(deg(f),deg(g))/2. Write
and use the identity
to recursively compute
TIMINGS: On a Pentium M 1.8Ghz laptop: f=R.random(1000,bound=100) g=R.random(1000,bound=100) time h=f._mul_karatsuba(g) Time: 0.42 seconds The naive multiplication algorithm takes 14.58 seconds. In contrast, MAGMA does this sort of product almost instantly, and can easily deal with degree 5000. Basically MAGMA is 100 times faster at polynomial multiplication.
Over Z using NTL, multiplying two polynomials constructed using R.random(10000,bound=100) takes 0.10 seconds. Using MAGMA V2.11-10 the same takes 0.14 seconds.
Over Q using PARI, multiplying two polynomials constructed using R.random(10000,bound=100) takes 1.23 seconds. Not good! TODO: use NTL polynomials over Z with a denominator instead of PARI.
NOTES: * Karatsuba multiplication of polynomials is also implemented in PARI in src/basemath/polarit3.c * The MAGMA documentation appears to give no information about how polynomial multiplication is implemented.
See About this document... for information on suggesting changes.