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 ringpolynomial
– an element ofring
with a unit leading coefficientnames
– (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]#
Bases:
DefaultConvertMap_unique
A coercion map from a
PolynomialQuotientRing
to aPolynomialQuotientRing
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 * >>> # needs sage.rings.padics >>> 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]#
Bases:
PolynomialQuotientRing_generic
,IntegralDomain
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 sage: loads(S.dumps()) == S True sage: loads(xbar.dumps()) == xbar 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 >>> loads(S.dumps()) == S True >>> loads(xbar.dumps()) == xbar 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 theNumberField
sending the generators to one another, and the inverse isomorphism.OUTPUT:
field
homomorphism from
self
to fieldhomomorphism 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]#
Bases:
PolynomialQuotientRing_domain
,Field
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 sage: loads(S.dumps()) == S True sage: loads(xbar.dumps()) == xbar 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 >>> loads(S.dumps()) == S True >>> loads(xbar.dumps()) == xbar True
- 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]#
Bases:
QuotientRing_generic
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 sage: loads(xbar.dumps()) == xbar True
>>> from sage.all import * >>> loads(S.dumps()) == S True >>> loads(xbar.dumps()) == xbar 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]#
alias of
PolynomialQuotientRingElement
- 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)
, wheregen
is a tuple of generators of an ideal \(I\) andorder
is the order of \(I\) in the \(S\)-class group.INPUT:
S
– a set of primes of the coefficient ringproof
– 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)
, wheregen
is a tuple of elements generating a fractional ideal \(I\) andorder
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: K.<a> = QuadraticField(-5) 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.<a> = QuadraticField(-5) 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: K.<a> = QuadraticField(-5) 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 fieldproof
– 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)
, wheregen
is a unit of orderorder
.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: K.<a> = QuadraticField(-3) 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'>
- 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 ofcardinality
.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)
, wheregen
is a tuple of generators of an ideal \(I\) andorder
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)
, wheregen
is a tuple of elements generating a fractional ideal andorder
is the order of \(I\) in the class group.EXAMPLES:
sage: # needs sage.rings.number_field sage: K.<a> = QuadraticField(-3) 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: K.<a> = QuadraticField(-5) 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.<a> = QuadraticField(-5) 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: K.<a> = QuadraticField(-5) 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 theis_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 * >>> # needs sage.rings.padics >>> 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 ofcardinality
.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 therandom_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 integerproof
– 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: K.<a> = QuadraticField(-5) 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 integerproof
– 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: K.<a> = QuadraticField(-5) 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)
, wheregen
is a unit of orderorder
.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: K.<a> = QuadraticField(-3) 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'>