# Quotients of Univariate Polynomial Rings#

EXAMPLES:

sage: R.<x> = QQ[]
sage: S = R.quotient(x**3 - 3*x + 1, 'alpha')
sage: S.gen()**2 in S
True
sage: x in S
True
sage: S.gen() in R
False
sage: 1 in S
True

>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(3) - Integer(3)*x + Integer(1), 'alpha')
>>> S.gen()**Integer(2) in S
True
>>> x in S
True
>>> S.gen() in R
False
>>> Integer(1) in S
True

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRingFactory[source]#

Bases: UniqueFactory

Create a quotient of a polynomial ring.

INPUT:

• ring – a univariate polynomial ring

• polynomial – an element of ring with a unit leading coefficient

• names – (optional) name for the variable

OUTPUT: Creates the quotient ring $$R/I$$, where $$R$$ is the ring and $$I$$ is the principal ideal generated by polynomial.

EXAMPLES:

We create the quotient ring $$\ZZ[x]/(x^3+7)$$, and demonstrate many basic functions with it:

sage: Z = IntegerRing()
sage: R = PolynomialRing(Z, 'x'); x = R.gen()
sage: S = R.quotient(x^3 + 7, 'a'); a = S.gen()
sage: S
Univariate Quotient Polynomial Ring in a
over Integer Ring with modulus x^3 + 7
sage: a^3
-7
sage: S.is_field()
False
sage: a in S
True
sage: x in S
True
sage: a in R
False
sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Integer Ring
sage: S.modulus()
x^3 + 7
sage: S.degree()
3

>>> from sage.all import *
>>> Z = IntegerRing()
>>> R = PolynomialRing(Z, 'x'); x = R.gen()
>>> S = R.quotient(x**Integer(3) + Integer(7), 'a'); a = S.gen()
>>> S
Univariate Quotient Polynomial Ring in a
over Integer Ring with modulus x^3 + 7
>>> a**Integer(3)
-7
>>> S.is_field()
False
>>> a in S
True
>>> x in S
True
>>> a in R
False
>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Integer Ring
>>> S.modulus()
x^3 + 7
>>> S.degree()
3


We create the “iterated” polynomial ring quotient

$R = (\GF{2}[y]/(y^{2}+y+1))[x]/(x^3 - 5).$
sage: # needs sage.libs.ntl
sage: A.<y> = PolynomialRing(GF(2)); A
Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X)
sage: B = A.quotient(y^2 + y + 1, 'y2'); B
Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2
with modulus y^2 + y + 1
sage: C = PolynomialRing(B, 'x'); x = C.gen(); C
Univariate Polynomial Ring in x
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
sage: R = C.quotient(x^3 - 5); R
Univariate Quotient Polynomial Ring in xbar
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
with modulus x^3 + 1

>>> from sage.all import *
>>> # needs sage.libs.ntl
>>> A = PolynomialRing(GF(Integer(2)), names=('y',)); (y,) = A._first_ngens(1); A
Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X)
>>> B = A.quotient(y**Integer(2) + y + Integer(1), 'y2'); B
Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2
with modulus y^2 + y + 1
>>> C = PolynomialRing(B, 'x'); x = C.gen(); C
Univariate Polynomial Ring in x
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
>>> R = C.quotient(x**Integer(3) - Integer(5)); R
Univariate Quotient Polynomial Ring in xbar
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
with modulus x^3 + 1


Next we create a number field, but viewed as a quotient of a polynomial ring over $$\QQ$$:

sage: R = PolynomialRing(RationalField(), 'x'); x = R.gen()
sage: S = R.quotient(x^3 + 2*x - 5, 'a'); S
Univariate Quotient Polynomial Ring in a over Rational Field
with modulus x^3 + 2*x - 5
sage: S.is_field()
True
sage: S.degree()
3

>>> from sage.all import *
>>> R = PolynomialRing(RationalField(), 'x'); x = R.gen()
>>> S = R.quotient(x**Integer(3) + Integer(2)*x - Integer(5), 'a'); S
Univariate Quotient Polynomial Ring in a over Rational Field
with modulus x^3 + 2*x - 5
>>> S.is_field()
True
>>> S.degree()
3


There are conversion functions for easily going back and forth between quotients of polynomial rings over $$\QQ$$ and number fields:

sage: K = S.number_field(); K                                                   # needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + 2*x - 5
sage: K.polynomial_quotient_ring()                                              # needs sage.rings.number_field
Univariate Quotient Polynomial Ring in a
over Rational Field with modulus x^3 + 2*x - 5

>>> from sage.all import *
>>> K = S.number_field(); K                                                   # needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + 2*x - 5
>>> K.polynomial_quotient_ring()                                              # needs sage.rings.number_field
Univariate Quotient Polynomial Ring in a
over Rational Field with modulus x^3 + 2*x - 5


The leading coefficient must be a unit (but need not be 1).

sage: R = PolynomialRing(Integers(9), 'x'); x = R.gen()
sage: S = R.quotient(2*x^4 + 2*x^3 + x + 2, 'a')
sage: S = R.quotient(3*x^4 + 2*x^3 + x + 2, 'a')
Traceback (most recent call last):
...
TypeError: polynomial must have unit leading coefficient

>>> from sage.all import *
>>> R = PolynomialRing(Integers(Integer(9)), 'x'); x = R.gen()
>>> S = R.quotient(Integer(2)*x**Integer(4) + Integer(2)*x**Integer(3) + x + Integer(2), 'a')
>>> S = R.quotient(Integer(3)*x**Integer(4) + Integer(2)*x**Integer(3) + x + Integer(2), 'a')
Traceback (most recent call last):
...
TypeError: polynomial must have unit leading coefficient


Another example:

sage: R.<x> = PolynomialRing(IntegerRing())
sage: f = x^2 + 1
sage: R.quotient(f)
Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1

>>> from sage.all import *
>>> R = PolynomialRing(IntegerRing(), names=('x',)); (x,) = R._first_ngens(1)
>>> f = x**Integer(2) + Integer(1)
>>> R.quotient(f)
Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1


This shows that the issue at Issue #5482 is solved:

sage: R.<x> = PolynomialRing(QQ)
sage: f = x^2 - 1
sage: R.quotient_by_principal_ideal(f)
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> f = x**Integer(2) - Integer(1)
>>> R.quotient_by_principal_ideal(f)
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1

create_key(ring, polynomial, names=None)[source]#

Return a unique description of the quotient ring specified by the arguments.

EXAMPLES:

sage: R.<x> = QQ[]
sage: PolynomialQuotientRing.create_key(R, x + 1)
(Univariate Polynomial Ring in x over Rational Field, x + 1, ('xbar',))

>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> PolynomialQuotientRing.create_key(R, x + Integer(1))
(Univariate Polynomial Ring in x over Rational Field, x + 1, ('xbar',))

create_object(version, key)[source]#

Return the quotient ring specified by key.

EXAMPLES:

sage: R.<x> = QQ[]
sage: PolynomialQuotientRing.create_object((8, 0, 0),
....:                                      (R, x^2 - 1, ('xbar')))
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1

>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> PolynomialQuotientRing.create_object((Integer(8), Integer(0), Integer(0)),
...                                      (R, x**Integer(2) - Integer(1), ('xbar')))
Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 1

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_coercion[source]#

A coercion map from a PolynomialQuotientRing to a PolynomialQuotientRing that restricts to the coercion map on the underlying ring of constants.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: S.<x> = QQ[]
sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f
Coercion map:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ring
with modulus x^2 + 1
To:   Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> S = QQ['x']; (x,) = S._first_ngens(1)
>>> f = S.quo(x**Integer(2) + Integer(1)).coerce_map_from(R.quo(x**Integer(2) + Integer(1))); f
Coercion map:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ring
with modulus x^2 + 1
To:   Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1

is_injective()[source]#

Return whether this coercion is injective.

EXAMPLES:

If the modulus of the domain and the codomain is the same and the leading coefficient is a unit in the domain, then the map is injective if the underlying map on the constants is:

sage: R.<x> = ZZ[]
sage: S.<x> = QQ[]
sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1))
sage: f.is_injective()
True

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> S = QQ['x']; (x,) = S._first_ngens(1)
>>> f = S.quo(x**Integer(2) + Integer(1)).coerce_map_from(R.quo(x**Integer(2) + Integer(1)))
>>> f.is_injective()
True

is_surjective()[source]#

Return whether this coercion is surjective.

EXAMPLES:

If the underlying map on constants is surjective, then this coercion is surjective since the modulus of the codomain divides the modulus of the domain:

sage: R.<x> = ZZ[]
sage: f = R.quo(x).coerce_map_from(R.quo(x^2))
sage: f.is_surjective()
True

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> f = R.quo(x).coerce_map_from(R.quo(x**Integer(2)))
>>> f.is_surjective()
True


If the modulus of the domain and the codomain is the same, then the map is surjective iff the underlying map on the constants is:

sage: # needs sage.rings.padics
sage: A.<a> = ZqCA(9)
sage: R.<x> = A[]
sage: S.<x> = A.fraction_field()[]
sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2))
sage: f.is_surjective()
False

>>> from sage.all import *
>>> A = ZqCA(Integer(9), names=('a',)); (a,) = A._first_ngens(1)
>>> R = A['x']; (x,) = R._first_ngens(1)
>>> S = A.fraction_field()['x']; (x,) = S._first_ngens(1)
>>> f = S.quo(x**Integer(2) + Integer(2)).coerce_map_from(R.quo(x**Integer(2) + Integer(2)))
>>> f.is_surjective()
False

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_domain(ring, polynomial, name=None, category=None)[source]#

EXAMPLES:

sage: R.<x> = PolynomialRing(ZZ)
sage: S.<xbar> = R.quotient(x^2 + 1)
sage: S
Univariate Quotient Polynomial Ring in xbar
over Integer Ring with modulus x^2 + 1
True
True

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) + Integer(1), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S
Univariate Quotient Polynomial Ring in xbar
over Integer Ring with modulus x^2 + 1
True
True

field_extension(names)[source]#

Take a polynomial quotient ring, and return a tuple with three elements: the NumberField defined by the same polynomial quotient ring, a homomorphism from its parent to the NumberField sending the generators to one another, and the inverse isomorphism.

OUTPUT:

• field

• homomorphism from self to field

• homomorphism from field to self

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = PolynomialRing(Rationals())
sage: S.<alpha> = R.quotient(x^3 - 2)
sage: F.<b>, f, g = S.field_extension()
sage: F
Number Field in b with defining polynomial x^3 - 2
sage: a = F.gen()
sage: f(alpha)
b
sage: g(a)
alpha

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = PolynomialRing(Rationals(), names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(3) - Integer(2), names=('alpha',)); (alpha,) = S._first_ngens(1)
>>> F, f, g  = S.field_extension(names=('b',)); (b,) = F._first_ngens(1)
>>> F
Number Field in b with defining polynomial x^3 - 2
>>> a = F.gen()
>>> f(alpha)
b
>>> g(a)
alpha


Note that the parent ring must be an integral domain:

sage: R.<x> = GF(25, 'f25')['x']                                            # needs sage.rings.finite_rings
sage: S.<a> = R.quo(x^3 - 2)                                                # needs sage.rings.finite_rings
sage: F, g, h = S.field_extension('b')                                      # needs sage.rings.finite_rings
Traceback (most recent call last):
...
AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension'...

>>> from sage.all import *
>>> R = GF(Integer(25), 'f25')['x']; (x,) = R._first_ngens(1)# needs sage.rings.finite_rings
>>> S = R.quo(x**Integer(3) - Integer(2), names=('a',)); (a,) = S._first_ngens(1)# needs sage.rings.finite_rings
>>> F, g, h = S.field_extension('b')                                      # needs sage.rings.finite_rings
Traceback (most recent call last):
...
AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension'...


Over a finite field, the corresponding field extension is not a number field:

sage: # needs sage.modules sage.rings.finite_rings
sage: R.<x> = GF(25, 'a')['x']
sage: S.<a> = R.quo(x^3 + 2*x + 1)
sage: F, g, h = S.field_extension('b')
sage: h(F.0^2 + 3)
a^2 + 3
sage: g(x^2 + 2)
b^2 + 2

>>> from sage.all import *
>>> # needs sage.modules sage.rings.finite_rings
>>> R = GF(Integer(25), 'a')['x']; (x,) = R._first_ngens(1)
>>> S = R.quo(x**Integer(3) + Integer(2)*x + Integer(1), names=('a',)); (a,) = S._first_ngens(1)
>>> F, g, h = S.field_extension('b')
>>> h(F.gen(0)**Integer(2) + Integer(3))
a^2 + 3
>>> g(x**Integer(2) + Integer(2))
b^2 + 2


We do an example involving a relative number field:

sage: # needs sage.rings.number_field
sage: R.<x> = QQ['x']
sage: K.<a> = NumberField(x^3 - 2)
sage: S.<X> = K['X']
sage: Q.<b> = S.quo(X^3 + 2*X + 1)
sage: Q.field_extension('b')
(Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field, ...
Defn: b |--> b, Relative number field morphism:
From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field
To:   Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^3 - 2 with modulus X^3 + 2*X + 1
Defn: b |--> b
a |--> a)

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> S = K['X']; (X,) = S._first_ngens(1)
>>> Q = S.quo(X**Integer(3) + Integer(2)*X + Integer(1), names=('b',)); (b,) = Q._first_ngens(1)
>>> Q.field_extension('b')
(Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field, ...
Defn: b |--> b, Relative number field morphism:
From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field
To:   Univariate Quotient Polynomial Ring in b over Number Field in a with defining polynomial x^3 - 2 with modulus X^3 + 2*X + 1
Defn: b |--> b
a |--> a)


We slightly change the example above so it works.

sage: # needs sage.rings.number_field
sage: R.<x> = QQ['x']
sage: K.<a> = NumberField(x^3 - 2)
sage: S.<X> = K['X']
sage: f = (X+a)^3 + 2*(X+a) + 1
sage: f
X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3
sage: Q.<z> = S.quo(f)
sage: F.<w>, g, h = Q.field_extension()
sage: c = g(z)
sage: f(c)
0
sage: h(g(z))
z
sage: g(h(w))
w

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> S = K['X']; (X,) = S._first_ngens(1)
>>> f = (X+a)**Integer(3) + Integer(2)*(X+a) + Integer(1)
>>> f
X^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3
>>> Q = S.quo(f, names=('z',)); (z,) = Q._first_ngens(1)
>>> F, g, h  = Q.field_extension(names=('w',)); (w,) = F._first_ngens(1)
>>> c = g(z)
>>> f(c)
0
>>> h(g(z))
z
>>> g(h(w))
w


AUTHORS:

• Craig Citro (2006-08-07)

• William Stein (2006-08-06)

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field(ring, polynomial, name=None, category=None)[source]#

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = PolynomialRing(QQ)
sage: S.<xbar> = R.quotient(x^2 + 1)
sage: S
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1
True
True

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) + Integer(1), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1
True
True

base_field()[source]#

Alias for base_ring(), when we’re defined over a field.

complex_embeddings(prec=53)[source]#

Return all homomorphisms of this ring into the approximate complex field with precision prec.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = QQ[]
sage: f = x^5 + x + 17
sage: k = R.quotient(f)
sage: v = k.complex_embeddings(100)
sage: [phi(k.0^2) for phi in v]
[2.9757207403766761469671194565,
-2.4088994371613850098316292196 + 1.9025410530350528612407363802*I,
-2.4088994371613850098316292196 - 1.9025410530350528612407363802*I,
0.92103906697304693634806949137 - 3.0755331188457794473265418086*I,
0.92103906697304693634806949137 + 3.0755331188457794473265418086*I]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> f = x**Integer(5) + x + Integer(17)
>>> k = R.quotient(f)
>>> v = k.complex_embeddings(Integer(100))
>>> [phi(k.gen(0)**Integer(2)) for phi in v]
[2.9757207403766761469671194565,
-2.4088994371613850098316292196 + 1.9025410530350528612407363802*I,
-2.4088994371613850098316292196 - 1.9025410530350528612407363802*I,
0.92103906697304693634806949137 - 3.0755331188457794473265418086*I,
0.92103906697304693634806949137 + 3.0755331188457794473265418086*I]

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic(ring, polynomial, name=None, category=None)[source]#

Quotient of a univariate polynomial ring by an ideal.

EXAMPLES:

sage: R.<x> = PolynomialRing(Integers(8)); R
Univariate Polynomial Ring in x over Ring of integers modulo 8
sage: S.<xbar> = R.quotient(x^2 + 1); S
Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8
with modulus x^2 + 1

>>> from sage.all import *
>>> R = PolynomialRing(Integers(Integer(8)), names=('x',)); (x,) = R._first_ngens(1); R
Univariate Polynomial Ring in x over Ring of integers modulo 8
>>> S = R.quotient(x**Integer(2) + Integer(1), names=('xbar',)); (xbar,) = S._first_ngens(1); S
Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8
with modulus x^2 + 1


We demonstrate object persistence.

sage: loads(S.dumps()) == S
True
True

>>> from sage.all import *
True
True


We create some sample homomorphisms;

sage: R.<x> = PolynomialRing(ZZ)
sage: S = R.quo(x^2 - 4)
sage: f = S.hom([2])
sage: f
Ring morphism:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ring
with modulus x^2 - 4
To:   Integer Ring
Defn: xbar |--> 2
sage: f(x)
2
sage: f(x^2 - 4)
0
sage: f(x^2)
4

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quo(x**Integer(2) - Integer(4))
>>> f = S.hom([Integer(2)])
>>> f
Ring morphism:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ring
with modulus x^2 - 4
To:   Integer Ring
Defn: xbar |--> 2
>>> f(x)
2
>>> f(x**Integer(2) - Integer(4))
0
>>> f(x**Integer(2))
4

Element[source]#
S_class_group(S, proof=True)[source]#

If self is an étale algebra $$D$$ over a number field $$K$$ (i.e. a quotient of $$K[x]$$ by a squarefree polynomial) and $$S$$ is a finite set of places of $$K$$, return a list of generators of the $$S$$-class group of $$D$$.

NOTE:

Since the ideal function behaves differently over number fields than over polynomial quotient rings (the quotient does not even know its ring of integers), we return a set of pairs (gen, order), where gen is a tuple of generators of an ideal $$I$$ and order is the order of $$I$$ in the $$S$$-class group.

INPUT:

• S – a set of primes of the coefficient ring

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of generators of the $$S$$-class group, in the form (gen, order), where gen is a tuple of elements generating a fractional ideal $$I$$ and order is the order of $$I$$ in the $$S$$-class group.

EXAMPLES:

A trivial algebra over $$\QQ(\sqrt{-5})$$ has the same class group as its base:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x)
sage: S.S_class_group([])
[((2, -a + 1), 2)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient(x, names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.S_class_group([])
[((2, -a + 1), 2)]


When we include the prime $$(2, -a+1)$$, the $$S$$-class group becomes trivial:

sage: S.S_class_group([K.ideal(2, -a+1)])                                   # needs sage.rings.number_field
[]

>>> from sage.all import *
>>> S.S_class_group([K.ideal(Integer(2), -a+Integer(1))])                                   # needs sage.rings.number_field
[]


Here is an example where the base and the extension both contribute to the class group:

sage: # needs sage.rings.number_field
sage: K.class_group()
Class group of order 2 with structure C2 of Number Field in a
with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x^2 + 23)
sage: S.S_class_group([])
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]
sage: S.S_class_group([K.ideal(3, a-1)])
[]
sage: S.S_class_group([K.ideal(2, a+1)])
[]
sage: S.S_class_group([K.ideal(a)])
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_group()
Class group of order 2 with structure C2 of Number Field in a
with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) + Integer(23), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.S_class_group([])
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]
>>> S.S_class_group([K.ideal(Integer(3), a-Integer(1))])
[]
>>> S.S_class_group([K.ideal(Integer(2), a+Integer(1))])
[]
>>> S.S_class_group([K.ideal(a)])
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]


Now we take an example over a nontrivial base with two factors, each contributing to the class group:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 31))
sage: S.S_class_group([])           # not tested
[((1/4*xbar^2 + 31/4,
(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4,
(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),
((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,
-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),
2)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) + Integer(31)), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.S_class_group([])           # not tested
[((1/4*xbar^2 + 31/4,
(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4,
(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),
((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,
-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),
2)]


By using the ideal $$(a)$$, we cut the part of the class group coming from $$x^2 + 31$$ from 12 to 2, i.e. we lose a generator of order 6 (this was fixed in Issue #14489):

sage: S.S_class_group([K.ideal(a)])  # representation varies        # not tested, needs sage.rings.number_field
[((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
2)]

>>> from sage.all import *
>>> S.S_class_group([K.ideal(a)])  # representation varies        # not tested, needs sage.rings.number_field
[((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
2)]


Note that all the returned values live where we expect them to:

sage: # needs sage.rings.number_field
sage: CG = S.S_class_group([])
sage: type(CG[0][0][1])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic_with_category.element_class'>
sage: type(CG[0][1])
<class 'sage.rings.integer.Integer'>

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> CG = S.S_class_group([])
>>> type(CG[Integer(0)][Integer(0)][Integer(1)])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic_with_category.element_class'>
>>> type(CG[Integer(0)][Integer(1)])
<class 'sage.rings.integer.Integer'>

S_units(S, proof=True)[source]#

If self is an étale algebra $$D$$ over a number field $$K$$ (i.e. a quotient of $$K[x]$$ by a squarefree polynomial) and $$S$$ is a finite set of places of $$K$$, return a list of generators of the group of $$S$$-units of $$D$$.

INPUT:

• S – a set of primes of the base field

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of generators of the $$S$$-unit group, in the form (gen, order), where gen is a unit of order order.

EXAMPLES:

sage: K.<a> = QuadraticField(-3)                                            # needs sage.rings.number_field
sage: K.unit_group()                                                        # needs sage.rings.number_field
Unit group with structure C6 of Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = QQ['x'].quotient(x^2 + 3)
sage: u, o = K.S_units([])[0]; o
6
sage: 2*u - 1 in {a, -a}
True
sage: u^6
1
sage: u^3
-1
sage: 2*u^2 + 1 in {a, -a}
True

>>> from sage.all import *
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field
>>> K.unit_group()                                                        # needs sage.rings.number_field
Unit group with structure C6 of Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I

>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = QQ['x'].quotient(x**Integer(2) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> u, o = K.S_units([])[Integer(0)]; o
6
>>> Integer(2)*u - Integer(1) in {a, -a}
True
>>> u**Integer(6)
1
>>> u**Integer(3)
-1
>>> Integer(2)*u**Integer(2) + Integer(1) in {a, -a}
True

sage: # needs sage.rings.number_field
sage: y = polygen(K)
sage: L.<b> = K['y'].quotient(y^3 + 5); L
Univariate Quotient Polynomial Ring in b over Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
with modulus y^3 + 5
sage: [u for u, o in L.S_units([]) if o is Infinity]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)])
....:  if o is Infinity]
[(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a,
(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity]
[(1/2*a - 1/2)*b^2 + (a + 1)*b + 3,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2,
(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> y = polygen(K)
>>> L = K['y'].quotient(y**Integer(3) + Integer(5), names=('b',)); (b,) = L._first_ngens(1); L
Univariate Quotient Polynomial Ring in b over Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
with modulus y^3 + 5
>>> [u for u, o in L.S_units([]) if o is Infinity]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
>>> [u for u, o in L.S_units([K.ideal(Integer(1)/Integer(2)*a - Integer(3)/Integer(2))])
...  if o is Infinity]
[(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a,
(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
>>> [u for u, o in L.S_units([K.ideal(Integer(2))]) if o is Infinity]
[(1/2*a - 1/2)*b^2 + (a + 1)*b + 3,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2,
(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]


Note that all the returned values live where we expect them to:

sage: # needs sage.rings.number_field
sage: U = L.S_units([])
sage: type(U[0][0])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field_with_category.element_class'>
sage: type(U[0][1])
<class 'sage.rings.integer.Integer'>
sage: type(U[1][1])
<class 'sage.rings.infinity.PlusInfinity'>

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> U = L.S_units([])
>>> type(U[Integer(0)][Integer(0)])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field_with_category.element_class'>
>>> type(U[Integer(0)][Integer(1)])
<class 'sage.rings.integer.Integer'>
>>> type(U[Integer(1)][Integer(1)])
<class 'sage.rings.infinity.PlusInfinity'>

ambient()[source]#
base_ring()[source]#

Return the base ring of the polynomial ring, of which this ring is a quotient.

EXAMPLES:

The base ring of $$\ZZ[z]/(z^3 + z^2 + z + 1)$$ is $$\ZZ$$.

sage: R.<z> = PolynomialRing(ZZ)
sage: S.<beta> = R.quo(z^3 + z^2 + z + 1)
sage: S.base_ring()
Integer Ring

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('z',)); (z,) = R._first_ngens(1)
>>> S = R.quo(z**Integer(3) + z**Integer(2) + z + Integer(1), names=('beta',)); (beta,) = S._first_ngens(1)
>>> S.base_ring()
Integer Ring


Next we make a polynomial quotient ring over $$S$$ and ask for its base ring.

sage: T.<t> = PolynomialRing(S)
sage: W = T.quotient(t^99 + 99)
sage: W.base_ring()
Univariate Quotient Polynomial Ring in beta
over Integer Ring with modulus z^3 + z^2 + z + 1

>>> from sage.all import *
>>> T = PolynomialRing(S, names=('t',)); (t,) = T._first_ngens(1)
>>> W = T.quotient(t**Integer(99) + Integer(99))
>>> W.base_ring()
Univariate Quotient Polynomial Ring in beta
over Integer Ring with modulus z^3 + z^2 + z + 1

cardinality()[source]#

Return the number of elements of this quotient ring.

order is an alias of cardinality.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: R.quo(1).cardinality()
1
sage: R.quo(x^3 - 2).cardinality()
+Infinity

sage: R.quo(1).order()
1
sage: R.quo(x^3 - 2).order()
+Infinity

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> R.quo(Integer(1)).cardinality()
1
>>> R.quo(x**Integer(3) - Integer(2)).cardinality()
+Infinity

>>> R.quo(Integer(1)).order()
1
>>> R.quo(x**Integer(3) - Integer(2)).order()
+Infinity

sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(9, 'a')[]
sage: R.quo(2*x^3 + x + 1).cardinality()
729
sage: GF(9, 'a').extension(2*x^3 + x + 1).cardinality()
729
sage: R.quo(2).cardinality()
1

>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> R = GF(Integer(9), 'a')['x']; (x,) = R._first_ngens(1)
>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()
729
>>> GF(Integer(9), 'a').extension(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()
729
>>> R.quo(Integer(2)).cardinality()
1

characteristic()[source]#

Return the characteristic of this quotient ring.

This is always the same as the characteristic of the base ring.

EXAMPLES:

sage: R.<z> = PolynomialRing(ZZ)
sage: S.<a> = R.quo(z - 19)
sage: S.characteristic()
0
sage: R.<x> = PolynomialRing(GF(9, 'a'))                                    # needs sage.rings.finite_rings
sage: S = R.quotient(x^3 + 1)                                               # needs sage.rings.finite_rings
sage: S.characteristic()                                                    # needs sage.rings.finite_rings
3

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('z',)); (z,) = R._first_ngens(1)
>>> S = R.quo(z - Integer(19), names=('a',)); (a,) = S._first_ngens(1)
>>> S.characteristic()
0
>>> R = PolynomialRing(GF(Integer(9), 'a'), names=('x',)); (x,) = R._first_ngens(1)# needs sage.rings.finite_rings
>>> S = R.quotient(x**Integer(3) + Integer(1))                                               # needs sage.rings.finite_rings
>>> S.characteristic()                                                    # needs sage.rings.finite_rings
3

class_group(proof=True)[source]#

If self is a quotient ring of a polynomial ring over a number field $$K$$, by a polynomial of nonzero discriminant, return a list of generators of the class group.

NOTE:

Since the ideal function behaves differently over number fields than over polynomial quotient rings (the quotient does not even know its ring of integers), we return a set of pairs (gen, order), where gen is a tuple of generators of an ideal $$I$$ and order is the order of $$I$$ in the class group.

INPUT:

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of pairs (gen, order), where gen is a tuple of elements generating a fractional ideal and order is the order of $$I$$ in the class group.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: K.class_group()
Class group of order 1 of Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
sage: x = polygen(QQ, 'x')
sage: K.<a> = QQ['x'].quotient(x^2 + 3)
sage: K.class_group()
[]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_group()
Class group of order 1 of Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
>>> x = polygen(QQ, 'x')
>>> K = QQ['x'].quotient(x**Integer(2) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_group()
[]


A trivial algebra over $$\QQ(\sqrt{-5})$$ has the same class group as its base:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x)
sage: S.class_group()
[((2, -a + 1), 2)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient(x, names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.class_group()
[((2, -a + 1), 2)]


The same algebra constructed in a different way:

sage: x = polygen(ZZ, 'x')
sage: K.<a> = QQ['x'].quotient(x^2 + 5)
sage: K.class_group(())                                                     # needs sage.rings.number_field
[((2, a + 1), 2)]

>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = QQ['x'].quotient(x**Integer(2) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_group(())                                                     # needs sage.rings.number_field
[((2, a + 1), 2)]


Here is an example where the base and the extension both contribute to the class group:

sage: # needs sage.rings.number_field
sage: K.class_group()
Class group of order 2 with structure C2 of Number Field in a
with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x^2 + 23)
sage: S.class_group()
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_group()
Class group of order 2 with structure C2 of Number Field in a
with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) + Integer(23), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.class_group()
[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]


Here is an example of a product of number fields, both of which contribute to the class group:

sage: # needs sage.rings.number_field
sage: R.<x> = QQ[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 47))
sage: S.class_group()
[((1/12*xbar^2 + 47/12,
1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48),
3),
((-1/12*xbar^2 - 23/12,
-1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48),
5)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) + Integer(47)), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.class_group()
[((1/12*xbar^2 + 47/12,
1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48),
3),
((-1/12*xbar^2 - 23/12,
-1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48),
5)]


Now we take an example over a nontrivial base with two factors, each contributing to the class group:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 31))
sage: S.class_group()               # not tested
[((1/4*xbar^2 + 31/4,
(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4,
(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),
((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,
-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),
2)]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) + Integer(31)), names=('xbar',)); (xbar,) = S._first_ngens(1)
>>> S.class_group()               # not tested
[((1/4*xbar^2 + 31/4,
(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,
-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),
((-1/4*xbar^2 - 23/4,
(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,
-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),
((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,
-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),
2)]


Note that all the returned values live where we expect them to:

sage: # needs sage.rings.number_field
sage: CG = S.class_group()
sage: type(CG[0][0][1])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic_with_category.element_class'>
sage: type(CG[0][1])
<class 'sage.rings.integer.Integer'>

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> CG = S.class_group()
>>> type(CG[Integer(0)][Integer(0)][Integer(1)])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic_with_category.element_class'>
>>> type(CG[Integer(0)][Integer(1)])
<class 'sage.rings.integer.Integer'>

construction()[source]#

Functorial construction of self

EXAMPLES:

sage: P.<t> = ZZ[]
sage: Q = P.quo(5 + t^2)
sage: F, R = Q.construction()
sage: F(R) == Q
True
sage: P.<t> = GF(3)[]
sage: Q = P.quo([2 + t^2])
sage: F, R = Q.construction()
sage: F(R) == Q
True

>>> from sage.all import *
>>> P = ZZ['t']; (t,) = P._first_ngens(1)
>>> Q = P.quo(Integer(5) + t**Integer(2))
>>> F, R = Q.construction()
>>> F(R) == Q
True
>>> P = GF(Integer(3))['t']; (t,) = P._first_ngens(1)
>>> Q = P.quo([Integer(2) + t**Integer(2)])
>>> F, R = Q.construction()
>>> F(R) == Q
True


AUTHOR:

– Simon King (2010-05)

cover_ring()[source]#

Return the polynomial ring of which this ring is the quotient.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)
sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) - Integer(2))
>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

degree()[source]#

Return the degree of this quotient ring. The degree is the degree of the polynomial that we quotiented out by.

EXAMPLES:

sage: R.<x> = PolynomialRing(GF(3))
sage: S = R.quotient(x^2005 + 1)
sage: S.degree()
2005

>>> from sage.all import *
>>> R = PolynomialRing(GF(Integer(3)), names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2005) + Integer(1))
>>> S.degree()
2005

discriminant(v=None)[source]#

Return the discriminant of this ring over the base ring. This is by definition the discriminant of the polynomial that we quotiented out by.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^3 + x^2 + x + 1)
sage: S.discriminant()
-16
sage: S = R.quotient((x + 1) * (x + 1))
sage: S.discriminant()
0

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(3) + x**Integer(2) + x + Integer(1))
>>> S.discriminant()
-16
>>> S = R.quotient((x + Integer(1)) * (x + Integer(1)))
>>> S.discriminant()
0


The discriminant of the quotient polynomial ring need not equal the discriminant of the corresponding number field, since the discriminant of a number field is by definition the discriminant of the ring of integers of the number field:

sage: S = R.quotient(x^2 - 8)
sage: S.number_field().discriminant()                                       # needs sage.rings.number_field
8
sage: S.discriminant()
32

>>> from sage.all import *
>>> S = R.quotient(x**Integer(2) - Integer(8))
>>> S.number_field().discriminant()                                       # needs sage.rings.number_field
8
>>> S.discriminant()
32

gen(n=0)[source]#

Return the generator of this quotient ring. This is the equivalence class of the image of the generator of the polynomial ring.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 8, 'gamma')
sage: S.gen()
gamma

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) - Integer(8), 'gamma')
>>> S.gen()
gamma

is_field(proof=True)[source]#

Return whether or not this quotient ring is a field.

EXAMPLES:

sage: R.<z> = PolynomialRing(ZZ)
sage: S = R.quo(z^2 - 2)
sage: S.is_field()
False
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)
sage: S.is_field()
True

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('z',)); (z,) = R._first_ngens(1)
>>> S = R.quo(z**Integer(2) - Integer(2))
>>> S.is_field()
False
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) - Integer(2))
>>> S.is_field()
True


If proof is True, requires the is_irreducible method of the modulus to be implemented:

sage: # needs sage.rings.padics
sage: R1.<x> = Qp(2)[]
sage: F1 = R1.quotient_ring(x^2 + x + 1)
sage: R2.<x> = F1[]
sage: F2 = R2.quotient_ring(x^2 + x + 1)
sage: F2.is_field()
Traceback (most recent call last):
...
NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in
xbar over 2-adic Field with capped relative precision 20 with modulus
(1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring
sage: F2.is_field(proof = False)
False

>>> from sage.all import *
>>> R1 = Qp(Integer(2))['x']; (x,) = R1._first_ngens(1)
>>> F1 = R1.quotient_ring(x**Integer(2) + x + Integer(1))
>>> R2 = F1['x']; (x,) = R2._first_ngens(1)
>>> F2 = R2.quotient_ring(x**Integer(2) + x + Integer(1))
>>> F2.is_field()
Traceback (most recent call last):
...
NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in
xbar over 2-adic Field with capped relative precision 20 with modulus
(1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring
>>> F2.is_field(proof = False)
False

is_finite()[source]#

Return whether or not this quotient ring is finite.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: R.quo(1).is_finite()
True
sage: R.quo(x^3 - 2).is_finite()
False

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> R.quo(Integer(1)).is_finite()
True
>>> R.quo(x**Integer(3) - Integer(2)).is_finite()
False

sage: R.<x> = GF(9, 'a')[]                                                  # needs sage.rings.finite_rings
sage: R.quo(2*x^3 + x + 1).is_finite()                                      # needs sage.rings.finite_rings
True
sage: R.quo(2).is_finite()                                                  # needs sage.rings.finite_rings
True

>>> from sage.all import *
>>> R = GF(Integer(9), 'a')['x']; (x,) = R._first_ngens(1)# needs sage.rings.finite_rings
>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).is_finite()                                      # needs sage.rings.finite_rings
True
>>> R.quo(Integer(2)).is_finite()                                                  # needs sage.rings.finite_rings
True

sage: P.<v> = GF(2)[]
sage: P.quotient(v^2 - v).is_finite()
True

>>> from sage.all import *
>>> P = GF(Integer(2))['v']; (v,) = P._first_ngens(1)
>>> P.quotient(v**Integer(2) - v).is_finite()
True

is_integral_domain(proof=True)[source]#

Return whether or not this quotient ring is an integral domain.

EXAMPLES:

sage: R.<z> = PolynomialRing(ZZ)

sage: S = R.quotient(z^2 - z)
sage: S.is_integral_domain()
False
sage: T = R.quotient(z^2 + 1)
sage: T.is_integral_domain()
True
sage: U = R.quotient(-1)
sage: U.is_integral_domain()
False

sage: # needs sage.libs.singular
sage: R2.<y> = PolynomialRing(R)
sage: S2 = R2.quotient(z^2 - y^3)
sage: S2.is_integral_domain()
True
sage: S3 = R2.quotient(z^2 - 2*y*z + y^2)
sage: S3.is_integral_domain()
False

sage: R.<z> = PolynomialRing(ZZ.quotient(4))
sage: S = R.quotient(z - 1)
sage: S.is_integral_domain()
False

>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('z',)); (z,) = R._first_ngens(1)

>>> S = R.quotient(z**Integer(2) - z)
>>> S.is_integral_domain()
False
>>> T = R.quotient(z**Integer(2) + Integer(1))
>>> T.is_integral_domain()
True
>>> U = R.quotient(-Integer(1))
>>> U.is_integral_domain()
False

>>> # needs sage.libs.singular
>>> R2 = PolynomialRing(R, names=('y',)); (y,) = R2._first_ngens(1)
>>> S2 = R2.quotient(z**Integer(2) - y**Integer(3))
>>> S2.is_integral_domain()
True
>>> S3 = R2.quotient(z**Integer(2) - Integer(2)*y*z + y**Integer(2))
>>> S3.is_integral_domain()
False

>>> R = PolynomialRing(ZZ.quotient(Integer(4)), names=('z',)); (z,) = R._first_ngens(1)
>>> S = R.quotient(z - Integer(1))
>>> S.is_integral_domain()
False

krull_dimension()[source]#

Return the Krull dimension.

This is the Krull dimension of the base ring, unless the quotient is zero.

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: R = PolynomialRing(ZZ, 'x').quotient(x**6 - 1)
sage: R.krull_dimension()
1
sage: R = PolynomialRing(ZZ, 'x').quotient(1)
sage: R.krull_dimension()
-1

>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> R = PolynomialRing(ZZ, 'x').quotient(x**Integer(6) - Integer(1))
>>> R.krull_dimension()
1
>>> R = PolynomialRing(ZZ, 'x').quotient(Integer(1))
>>> R.krull_dimension()
-1

lift(x)[source]#

Return an element of the ambient ring mapping to the given argument.

EXAMPLES:

sage: P.<x> = QQ[]
sage: Q = P.quotient(x^2 + 2)
sage: Q.lift(Q.0^3)
-2*x
sage: Q(-2*x)
-2*xbar
sage: Q.0^3
-2*xbar

>>> from sage.all import *
>>> P = QQ['x']; (x,) = P._first_ngens(1)
>>> Q = P.quotient(x**Integer(2) + Integer(2))
>>> Q.lift(Q.gen(0)**Integer(3))
-2*x
>>> Q(-Integer(2)*x)
-2*xbar
>>> Q.gen(0)**Integer(3)
-2*xbar

modulus()[source]#

Return the polynomial modulus of this quotient ring.

EXAMPLES:

sage: R.<x> = PolynomialRing(GF(3))
sage: S = R.quotient(x^2 - 2)
sage: S.modulus()
x^2 + 1

>>> from sage.all import *
>>> R = PolynomialRing(GF(Integer(3)), names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) - Integer(2))
>>> S.modulus()
x^2 + 1

ngens()[source]#

Return the number of generators of this quotient ring over the base ring. This function always returns 1.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: S.<y> = PolynomialRing(R)
sage: T.<z> = S.quotient(y + x)
sage: T
Univariate Quotient Polynomial Ring in z over
Univariate Polynomial Ring in x over Rational Field with modulus y + x
sage: T.ngens()
1

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = PolynomialRing(R, names=('y',)); (y,) = S._first_ngens(1)
>>> T = S.quotient(y + x, names=('z',)); (z,) = T._first_ngens(1)
>>> T
Univariate Quotient Polynomial Ring in z over
Univariate Polynomial Ring in x over Rational Field with modulus y + x
>>> T.ngens()
1

number_field()[source]#

Return the number field isomorphic to this quotient polynomial ring, if possible.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = PolynomialRing(QQ)
sage: S.<alpha> = R.quotient(x^29 - 17*x - 1)
sage: K = S.number_field(); K
Number Field in alpha with defining polynomial x^29 - 17*x - 1
sage: alpha = K.gen()
sage: alpha^29
17*alpha + 1

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(29) - Integer(17)*x - Integer(1), names=('alpha',)); (alpha,) = S._first_ngens(1)
>>> K = S.number_field(); K
Number Field in alpha with defining polynomial x^29 - 17*x - 1
>>> alpha = K.gen()
>>> alpha**Integer(29)
17*alpha + 1

order()[source]#

Return the number of elements of this quotient ring.

order is an alias of cardinality.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: R.quo(1).cardinality()
1
sage: R.quo(x^3 - 2).cardinality()
+Infinity

sage: R.quo(1).order()
1
sage: R.quo(x^3 - 2).order()
+Infinity

>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> R.quo(Integer(1)).cardinality()
1
>>> R.quo(x**Integer(3) - Integer(2)).cardinality()
+Infinity

>>> R.quo(Integer(1)).order()
1
>>> R.quo(x**Integer(3) - Integer(2)).order()
+Infinity

sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(9, 'a')[]
sage: R.quo(2*x^3 + x + 1).cardinality()
729
sage: GF(9, 'a').extension(2*x^3 + x + 1).cardinality()
729
sage: R.quo(2).cardinality()
1

>>> from sage.all import *
>>> # needs sage.rings.finite_rings
>>> R = GF(Integer(9), 'a')['x']; (x,) = R._first_ngens(1)
>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()
729
>>> GF(Integer(9), 'a').extension(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()
729
>>> R.quo(Integer(2)).cardinality()
1

polynomial_ring()[source]#

Return the polynomial ring of which this ring is the quotient.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)
sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> S = R.quotient(x**Integer(2) - Integer(2))
>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

random_element(degree=None, *args, **kwds)[source]#

Return a random element of this quotient ring.

INPUT:

• degree – Optional argument: either an integer for fixing the degree, or a tuple of the minimum and maximum degree. By default the degree is n - 1 with n the degree of the polynomial ring. Note that the degree of the polynomial is fixed before the modulo calculation. So when $$degree$$ is bigger than the degree of the polynomial ring, the degree of the returned polynomial would be lower than $$degree$$.

• *args, **kwds – Arguments for randomization that are passed on to the random_element method of the polynomial ring, and from there to the base ring

OUTPUT:

Element of this quotient ring

EXAMPLES:

sage: # needs sage.modules sage.rings.finite_rings
sage: F1.<a> = GF(2^7)
sage: P1.<x> = F1[]
sage: F2 = F1.extension(x^2 + x + 1, 'u')
sage: F2.random_element().parent() is F2
True

>>> from sage.all import *
>>> # needs sage.modules sage.rings.finite_rings
>>> F1 = GF(Integer(2)**Integer(7), names=('a',)); (a,) = F1._first_ngens(1)
>>> P1 = F1['x']; (x,) = P1._first_ngens(1)
>>> F2 = F1.extension(x**Integer(2) + x + Integer(1), 'u')
>>> F2.random_element().parent() is F2
True

retract(x)[source]#

Return the coercion of x into this polynomial quotient ring.

The rings that coerce into the quotient ring canonically are:

• this ring

• any canonically isomorphic ring

• anything that coerces into the ring of which this is the quotient

selmer_generators(S, m, proof=True)[source]#

If self is an étale algebra $$D$$ over a number field $$K$$ (i.e. a quotient of $$K[x]$$ by a squarefree polynomial) and $$S$$ is a finite set of places of $$K$$, compute the Selmer group $$D(S,m)$$. This is the subgroup of $$D^*/(D^*)^m$$ consisting of elements $$a$$ such that $$D(\sqrt[m]{a})/D$$ is unramified at all primes of $$D$$ lying above a place outside of $$S$$.

INPUT:

• S – A set of primes of the coefficient ring (which is a number field).

• m – a positive integer

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of generators of $$D(S,m)$$.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: D.<T> = R.quotient(x)
sage: D.selmer_generators((), 2)
[-1, 2]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 2)
[2, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2)
[2, a + 1, -1]
sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4)
[2, a + 1, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 3)
[2]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3)
[2, a + 1]
sage: D.selmer_generators([K.ideal(2, -a + 1),
....:                      K.ideal(3, a + 1),
....:                      K.ideal(a)], 3)
[2, a + 1, -a]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> D = R.quotient(x, names=('T',)); (T,) = D._first_ngens(1)
>>> D.selmer_generators((), Integer(2))
[-1, 2]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(2))
[2, -1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))], Integer(2))
[2, a + 1, -1]
>>> D.selmer_generators((K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))), Integer(4))
[2, a + 1, -1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(3))
[2]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))], Integer(3))
[2, a + 1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)),
...                      K.ideal(Integer(3), a + Integer(1)),
...                      K.ideal(a)], Integer(3))
[2, a + 1, -a]

selmer_group(S, m, proof=True)[source]#

If self is an étale algebra $$D$$ over a number field $$K$$ (i.e. a quotient of $$K[x]$$ by a squarefree polynomial) and $$S$$ is a finite set of places of $$K$$, compute the Selmer group $$D(S,m)$$. This is the subgroup of $$D^*/(D^*)^m$$ consisting of elements $$a$$ such that $$D(\sqrt[m]{a})/D$$ is unramified at all primes of $$D$$ lying above a place outside of $$S$$.

INPUT:

• S – A set of primes of the coefficient ring (which is a number field).

• m – a positive integer

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of generators of $$D(S,m)$$.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: R.<x> = K[]
sage: D.<T> = R.quotient(x)
sage: D.selmer_generators((), 2)
[-1, 2]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 2)
[2, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2)
[2, a + 1, -1]
sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4)
[2, a + 1, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 3)
[2]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3)
[2, a + 1]
sage: D.selmer_generators([K.ideal(2, -a + 1),
....:                      K.ideal(3, a + 1),
....:                      K.ideal(a)], 3)
[2, a + 1, -a]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['x']; (x,) = R._first_ngens(1)
>>> D = R.quotient(x, names=('T',)); (T,) = D._first_ngens(1)
>>> D.selmer_generators((), Integer(2))
[-1, 2]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(2))
[2, -1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))], Integer(2))
[2, a + 1, -1]
>>> D.selmer_generators((K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))), Integer(4))
[2, a + 1, -1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(3))
[2]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.ideal(Integer(3), a + Integer(1))], Integer(3))
[2, a + 1]
>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)),
...                      K.ideal(Integer(3), a + Integer(1)),
...                      K.ideal(a)], Integer(3))
[2, a + 1, -a]

units(proof=True)[source]#

If this quotient ring is over a number field K, by a polynomial of nonzero discriminant, returns a list of generators of the units.

INPUT:

• proof – if False, assume the GRH in computing the class group

OUTPUT:

A list of generators of the unit group, in the form (gen, order), where gen is a unit of order order.

EXAMPLES:

sage: K.<a> = QuadraticField(-3)                                            # needs sage.rings.number_field
sage: K.unit_group()                                                        # needs sage.rings.number_field
Unit group with structure C6 of
Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = QQ['x'].quotient(x^2 + 3)
sage: u = K.units()[0][0]
sage: 2*u - 1 in {a, -a}
True
sage: u^6
1
sage: u^3
-1
sage: 2*u^2 + 1 in {a, -a}
True
sage: x = polygen(ZZ, 'x')
sage: K.<a> = QQ['x'].quotient(x^2 + 5)
sage: K.units(())
[(-1, 2)]

>>> from sage.all import *
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field
>>> K.unit_group()                                                        # needs sage.rings.number_field
Unit group with structure C6 of
Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I

>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = QQ['x'].quotient(x**Integer(2) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> u = K.units()[Integer(0)][Integer(0)]
>>> Integer(2)*u - Integer(1) in {a, -a}
True
>>> u**Integer(6)
1
>>> u**Integer(3)
-1
>>> Integer(2)*u**Integer(2) + Integer(1) in {a, -a}
True
>>> x = polygen(ZZ, 'x')
>>> K = QQ['x'].quotient(x**Integer(2) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.units(())
[(-1, 2)]

sage: # needs sage.rings.number_field
sage: y = polygen(K)
sage: L.<b> = K['y'].quotient(y^3 + 5); L
Univariate Quotient Polynomial Ring in b over Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
with modulus y^3 + 5
sage: [u for u, o in L.units() if o is Infinity]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: L.<b> = K.extension(y^3 + 5)
sage: L.unit_group()
Unit group with structure C6 x Z x Z of
Number Field in b with defining polynomial x^3 + 5 over its base field
sage: L.unit_group().gens()    # abstract generators
(u0, u1, u2)
sage: L.unit_group().gens_values()[1:]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> y = polygen(K)
>>> L = K['y'].quotient(y**Integer(3) + Integer(5), names=('b',)); (b,) = L._first_ngens(1); L
Univariate Quotient Polynomial Ring in b over Number Field in a
with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
with modulus y^3 + 5
>>> [u for u, o in L.units() if o is Infinity]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
>>> L = K.extension(y**Integer(3) + Integer(5), names=('b',)); (b,) = L._first_ngens(1)
>>> L.unit_group()
Unit group with structure C6 x Z x Z of
Number Field in b with defining polynomial x^3 + 5 over its base field
>>> L.unit_group().gens()    # abstract generators
(u0, u1, u2)
>>> L.unit_group().gens_values()[Integer(1):]
[(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]


Note that all the returned values live where we expect them to:

sage: # needs sage.rings.number_field
sage: L.<b> = K['y'].quotient(y^3 + 5)
sage: U = L.units()
sage: type(U[0][0])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field_with_category.element_class'>
sage: type(U[0][1])
<class 'sage.rings.integer.Integer'>
sage: type(U[1][1])
<class 'sage.rings.infinity.PlusInfinity'>

>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> L = K['y'].quotient(y**Integer(3) + Integer(5), names=('b',)); (b,) = L._first_ngens(1)
>>> U = L.units()
>>> type(U[Integer(0)][Integer(0)])
<class 'sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field_with_category.element_class'>
>>> type(U[Integer(0)][Integer(1)])
<class 'sage.rings.integer.Integer'>
>>> type(U[Integer(1)][Integer(1)])
<class 'sage.rings.infinity.PlusInfinity'>

sage.rings.polynomial.polynomial_quotient_ring.is_PolynomialQuotientRing(x)[source]#