Quotient Rings#
AUTHORS:
William Stein
Simon King (2011-04): Put it into the category framework, use the new coercion model.
Simon King (2011-04): Quotients of non-commutative rings by twosided ideals.
Todo
The following skipped tests should be removed once Issue #13999 is fixed:
sage: TestSuite(S).run(skip=['_test_nonzero_equal', '_test_elements', '_test_zero'])
>>> from sage.all import *
>>> TestSuite(S).run(skip=['_test_nonzero_equal', '_test_elements', '_test_zero'])
In Issue #11068, non-commutative quotient rings \(R/I\) were
implemented. The only requirement is that the two-sided ideal \(I\)
provides a reduce
method so that I.reduce(x)
is the normal
form of an element \(x\) with respect to \(I\) (i.e., we have
I.reduce(x) == I.reduce(y)
if \(x-y \in I\), and
x - I.reduce(x) in I
). Here is a toy example:
sage: from sage.rings.noncommutative_ideals import Ideal_nc
sage: from itertools import product
sage: class PowerIdeal(Ideal_nc):
....: def __init__(self, R, n):
....: self._power = n
....: self._power = n
....: Ideal_nc.__init__(self, R, [R.prod(m) for m in product(R.gens(), repeat=n)])
....: def reduce(self,x):
....: R = self.ring()
....: return add([c*R(m) for m,c in x if len(m)<self._power],R(0))
sage: F.<x,y,z> = FreeAlgebra(QQ, 3) # needs sage.combinat sage.modules
sage: I3 = PowerIdeal(F,3); I3 # needs sage.combinat sage.modules
Twosided Ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y,
x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2,
z*x^2, z*x*y, z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) of
Free Algebra on 3 generators (x, y, z) over Rational Field
>>> from sage.all import *
>>> from sage.rings.noncommutative_ideals import Ideal_nc
>>> from itertools import product
>>> class PowerIdeal(Ideal_nc):
... def __init__(self, R, n):
... self._power = n
... self._power = n
... Ideal_nc.__init__(self, R, [R.prod(m) for m in product(R.gens(), repeat=n)])
... def reduce(self,x):
... R = self.ring()
... return add([c*R(m) for m,c in x if len(m)<self._power],R(Integer(0)))
>>> F = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3)# needs sage.combinat sage.modules
>>> I3 = PowerIdeal(F,Integer(3)); I3 # needs sage.combinat sage.modules
Twosided Ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y,
x*z^2, y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2,
z*x^2, z*x*y, z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3) of
Free Algebra on 3 generators (x, y, z) over Rational Field
Free algebras have a custom quotient method that serves at creating finite dimensional quotients defined by multiplication matrices. We are bypassing it, so that we obtain the default quotient:
sage: # needs sage.combinat sage.modules
sage: Q3.<a,b,c> = F.quotient(I3)
sage: Q3
Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field by
the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y, x*z^2,
y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y,
z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3)
sage: (a+b+2)^4
16 + 32*a + 32*b + 24*a^2 + 24*a*b + 24*b*a + 24*b^2
sage: Q3.is_commutative()
False
>>> from sage.all import *
>>> # needs sage.combinat sage.modules
>>> Q3 = F.quotient(I3, names=('a', 'b', 'c',)); (a, b, c,) = Q3._first_ngens(3)
>>> Q3
Quotient of Free Algebra on 3 generators (x, y, z) over Rational Field by
the ideal (x^3, x^2*y, x^2*z, x*y*x, x*y^2, x*y*z, x*z*x, x*z*y, x*z^2,
y*x^2, y*x*y, y*x*z, y^2*x, y^3, y^2*z, y*z*x, y*z*y, y*z^2, z*x^2, z*x*y,
z*x*z, z*y*x, z*y^2, z*y*z, z^2*x, z^2*y, z^3)
>>> (a+b+Integer(2))**Integer(4)
16 + 32*a + 32*b + 24*a^2 + 24*a*b + 24*b*a + 24*b^2
>>> Q3.is_commutative()
False
Even though \(Q_3\) is not commutative, there is commutativity for products of degree three:
sage: a*(b*c)-(b*c)*a==F.zero() # needs sage.combinat sage.modules
True
>>> from sage.all import *
>>> a*(b*c)-(b*c)*a==F.zero() # needs sage.combinat sage.modules
True
If we quotient out all terms of degree two then of course the resulting quotient ring is commutative:
sage: # needs sage.combinat sage.modules
sage: I2 = PowerIdeal(F,2); I2
Twosided Ideal (x^2, x*y, x*z, y*x, y^2, y*z, z*x, z*y, z^2) of Free Algebra
on 3 generators (x, y, z) over Rational Field
sage: Q2.<a,b,c> = F.quotient(I2)
sage: Q2.is_commutative()
True
sage: (a+b+2)^4
16 + 32*a + 32*b
>>> from sage.all import *
>>> # needs sage.combinat sage.modules
>>> I2 = PowerIdeal(F,Integer(2)); I2
Twosided Ideal (x^2, x*y, x*z, y*x, y^2, y*z, z*x, z*y, z^2) of Free Algebra
on 3 generators (x, y, z) over Rational Field
>>> Q2 = F.quotient(I2, names=('a', 'b', 'c',)); (a, b, c,) = Q2._first_ngens(3)
>>> Q2.is_commutative()
True
>>> (a+b+Integer(2))**Integer(4)
16 + 32*a + 32*b
Since Issue #7797, there is an implementation of free algebras based on Singular’s implementation of the Letterplace Algebra. Our letterplace wrapper allows to provide the above toy example more easily:
sage: # needs sage.combinat sage.libs.singular sage.modules
sage: from itertools import product
sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
sage: Q3 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=3)]*F)
sage: Q3
Quotient of Free Associative Unital Algebra on 3 generators (x, y, z)
over Rational Field by the ideal (x*x*x, x*x*y, x*x*z, x*y*x, x*y*y, x*y*z,
x*z*x, x*z*y, x*z*z, y*x*x, y*x*y, y*x*z, y*y*x, y*y*y, y*y*z, y*z*x, y*z*y,
y*z*z, z*x*x, z*x*y, z*x*z, z*y*x, z*y*y, z*y*z, z*z*x, z*z*y, z*z*z)
sage: Q3.0*Q3.1 - Q3.1*Q3.0
xbar*ybar - ybar*xbar
sage: Q3.0*(Q3.1*Q3.2) - (Q3.1*Q3.2)*Q3.0
0
sage: Q2 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=2)]*F)
sage: Q2.is_commutative()
True
>>> from sage.all import *
>>> # needs sage.combinat sage.libs.singular sage.modules
>>> from itertools import product
>>> F = FreeAlgebra(QQ, implementation='letterplace', names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3)
>>> Q3 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=Integer(3))]*F)
>>> Q3
Quotient of Free Associative Unital Algebra on 3 generators (x, y, z)
over Rational Field by the ideal (x*x*x, x*x*y, x*x*z, x*y*x, x*y*y, x*y*z,
x*z*x, x*z*y, x*z*z, y*x*x, y*x*y, y*x*z, y*y*x, y*y*y, y*y*z, y*z*x, y*z*y,
y*z*z, z*x*x, z*x*y, z*x*z, z*y*x, z*y*y, z*y*z, z*z*x, z*z*y, z*z*z)
>>> Q3.gen(0)*Q3.gen(1) - Q3.gen(1)*Q3.gen(0)
xbar*ybar - ybar*xbar
>>> Q3.gen(0)*(Q3.gen(1)*Q3.gen(2)) - (Q3.gen(1)*Q3.gen(2))*Q3.gen(0)
0
>>> Q2 = F.quo(F*[F.prod(m) for m in product(F.gens(), repeat=Integer(2))]*F)
>>> Q2.is_commutative()
True
- sage.rings.quotient_ring.QuotientRing(R, I, names=None, **kwds)[source]#
Creates a quotient ring of the ring \(R\) by the twosided ideal \(I\).
Variables are labeled by
names
(if the quotient ring is a quotient of a polynomial ring). Ifnames
isn’t given, ‘bar’ will be appended to the variable names in \(R\).INPUT:
R
– a ring.I
– a twosided ideal of \(R\).names
– (optional) a list of strings to be used as names for the variables in the quotient ring \(R/I\).further named arguments that will be passed to the constructor of the quotient ring instance.
OUTPUT: \(R/I\) - the quotient ring \(R\) mod the ideal \(I\)
ASSUMPTION:
I
has a methodI.reduce(x)
returning the normal form of elements \(x\in R\). In other words, it is required thatI.reduce(x)==I.reduce(y)
\(\iff x-y \in I\), andx-I.reduce(x) in I
, for all \(x,y\in R\).EXAMPLES:
Some simple quotient rings with the integers:
sage: R = QuotientRing(ZZ, 7*ZZ); R Quotient of Integer Ring by the ideal (7) sage: R.gens() (1,) sage: 1*R(3); 6*R(3); 7*R(3) 3 4 0
>>> from sage.all import * >>> R = QuotientRing(ZZ, Integer(7)*ZZ); R Quotient of Integer Ring by the ideal (7) >>> R.gens() (1,) >>> Integer(1)*R(Integer(3)); Integer(6)*R(Integer(3)); Integer(7)*R(Integer(3)) 3 4 0
sage: S = QuotientRing(ZZ,ZZ.ideal(8)); S Quotient of Integer Ring by the ideal (8) sage: 2*S(4) 0
>>> from sage.all import * >>> S = QuotientRing(ZZ,ZZ.ideal(Integer(8))); S Quotient of Integer Ring by the ideal (8) >>> Integer(2)*S(Integer(4)) 0
With polynomial rings (note that the variable name of the quotient ring can be specified as shown below):
sage: # needs sage.libs.pari sage: P.<x> = QQ[] sage: R.<xx> = QuotientRing(P, P.ideal(x^2 + 1)) sage: R Univariate Quotient Polynomial Ring in xx over Rational Field with modulus x^2 + 1 sage: R.gens(); R.gen() (xx,) xx sage: for n in range(4): xx^n 1 xx -1 -xx
>>> from sage.all import * >>> # needs sage.libs.pari >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> R = QuotientRing(P, P.ideal(x**Integer(2) + Integer(1)), names=('xx',)); (xx,) = R._first_ngens(1) >>> R Univariate Quotient Polynomial Ring in xx over Rational Field with modulus x^2 + 1 >>> R.gens(); R.gen() (xx,) xx >>> for n in range(Integer(4)): xx**n 1 xx -1 -xx
sage: # needs sage.libs.pari sage: P.<x> = QQ[] sage: S = QuotientRing(P, P.ideal(x^2 - 2)) sage: S Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 2 sage: xbar = S.gen(); S.gen() xbar sage: for n in range(3): xbar^n 1 xbar 2
>>> from sage.all import * >>> # needs sage.libs.pari >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> S = QuotientRing(P, P.ideal(x**Integer(2) - Integer(2))) >>> S Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 - 2 >>> xbar = S.gen(); S.gen() xbar >>> for n in range(Integer(3)): xbar**n 1 xbar 2
Sage coerces objects into ideals when possible:
sage: P.<x> = QQ[] sage: R = QuotientRing(P, x^2 + 1); R # needs sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1
>>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> R = QuotientRing(P, x**Integer(2) + Integer(1)); R # needs sage.libs.pari Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1
By Noether’s homomorphism theorems, the quotient of a quotient ring of \(R\) is just the quotient of \(R\) by the sum of the ideals. In this example, we end up modding out the ideal \((x)\) from the ring \(\QQ[x,y]\):
sage: # needs sage.libs.pari sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S.<a,b> = QuotientRing(R, R.ideal(1 + y^2)) sage: T.<c,d> = QuotientRing(S, S.ideal(a)) sage: T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) sage: R.gens(); S.gens(); T.gens() (x, y) (a, b) (0, d) sage: for n in range(4): d^n 1 d -1 -d
>>> from sage.all import * >>> # needs sage.libs.pari sage.libs.singular >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = QuotientRing(R, R.ideal(Integer(1) + y**Integer(2)), names=('a', 'b',)); (a, b,) = S._first_ngens(2) >>> T = QuotientRing(S, S.ideal(a), names=('c', 'd',)); (c, d,) = T._first_ngens(2) >>> T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) >>> R.gens(); S.gens(); T.gens() (x, y) (a, b) (0, d) >>> for n in range(Integer(4)): d**n 1 d -1 -d
- class sage.rings.quotient_ring.QuotientRingIdeal_generic(ring, gens, coerce=True, **kwds)[source]#
Bases:
Ideal_generic
Specialized class for quotient-ring ideals.
EXAMPLES:
sage: Zmod(9).ideal([-6,9]) Ideal (3, 0) of Ring of integers modulo 9
>>> from sage.all import * >>> Zmod(Integer(9)).ideal([-Integer(6),Integer(9)]) Ideal (3, 0) of Ring of integers modulo 9
- class sage.rings.quotient_ring.QuotientRingIdeal_principal(ring, gens, coerce=True, **kwds)[source]#
Bases:
Ideal_principal
,QuotientRingIdeal_generic
Specialized class for principal quotient-ring ideals.
EXAMPLES:
sage: Zmod(9).ideal(-33) Principal ideal (3) of Ring of integers modulo 9
>>> from sage.all import * >>> Zmod(Integer(9)).ideal(-Integer(33)) Principal ideal (3) of Ring of integers modulo 9
- class sage.rings.quotient_ring.QuotientRing_generic(R, I, names, category=None)[source]#
Bases:
QuotientRing_nc
,CommutativeRing
Creates a quotient ring of a commutative ring \(R\) by the ideal \(I\).
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ) sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I); S Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1)
>>> from sage.all import * >>> R = PolynomialRing(ZZ, names=('x',)); (x,) = R._first_ngens(1) >>> I = R.ideal([Integer(4) + Integer(3)*x + x**Integer(2), Integer(1) + x**Integer(2)]) >>> S = R.quotient_ring(I); S Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1)
- class sage.rings.quotient_ring.QuotientRing_nc(R, I, names, category=None)[source]#
Bases:
Ring
,ParentWithGens
The quotient ring of \(R\) by a twosided ideal \(I\).
This class is for rings that do not inherit from
CommutativeRing
.EXAMPLES:
Here is a quotient of a free algebra by a twosided homogeneous ideal:
sage: # needs sage.combinat sage.libs.singular sage.modules sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2]*F sage: Q.<a,b,c> = F.quo(I); Q Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) sage: a*b -b*c sage: a^3 -b*c*a - b*c*b - b*c*c
>>> from sage.all import * >>> # needs sage.combinat sage.libs.singular sage.modules >>> F = FreeAlgebra(QQ, implementation='letterplace', names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3) >>> I = F * [x*y + y*z, x**Integer(2) + x*y - y*x - y**Integer(2)]*F >>> Q = F.quo(I, names=('a', 'b', 'c',)); (a, b, c,) = Q._first_ngens(3); Q Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (x*y + y*z, x*x + x*y - y*x - y*y) >>> a*b -b*c >>> a**Integer(3) -b*c*a - b*c*b - b*c*c
A quotient of a quotient is just the quotient of the original top ring by the sum of two ideals:
sage: # needs sage.combinat sage.libs.singular sage.modules sage: J = Q * [a^3 - b^3] * Q sage: R.<i,j,k> = Q.quo(J); R Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) sage: i^3 -j*k*i - j*k*j - j*k*k sage: j^3 -j*k*i - j*k*j - j*k*k
>>> from sage.all import * >>> # needs sage.combinat sage.libs.singular sage.modules >>> J = Q * [a**Integer(3) - b**Integer(3)] * Q >>> R = Q.quo(J, names=('i', 'j', 'k',)); (i, j, k,) = R._first_ngens(3); R Quotient of Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field by the ideal (-y*y*z - y*z*x - 2*y*z*z, x*y + y*z, x*x + x*y - y*x - y*y) >>> i**Integer(3) -j*k*i - j*k*j - j*k*k >>> j**Integer(3) -j*k*i - j*k*j - j*k*k
For rings that do inherit from
CommutativeRing
, we provide a subclassQuotientRing_generic
, for backwards compatibility.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ,'x') sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I); S Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1)
>>> from sage.all import * >>> R = PolynomialRing(ZZ,'x', names=('x',)); (x,) = R._first_ngens(1) >>> I = R.ideal([Integer(4) + Integer(3)*x + x**Integer(2), Integer(1) + x**Integer(2)]) >>> S = R.quotient_ring(I); S Quotient of Univariate Polynomial Ring in x over Integer Ring by the ideal (x^2 + 3*x + 4, x^2 + 1)
sage: R.<x,y> = PolynomialRing(QQ) sage: S.<a,b> = R.quo(x^2 + y^2) # needs sage.libs.singular sage: a^2 + b^2 == 0 # needs sage.libs.singular True sage: S(0) == a^2 + b^2 # needs sage.libs.singular True
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quo(x**Integer(2) + y**Integer(2), names=('a', 'b',)); (a, b,) = S._first_ngens(2)# needs sage.libs.singular >>> a**Integer(2) + b**Integer(2) == Integer(0) # needs sage.libs.singular True >>> S(Integer(0)) == a**Integer(2) + b**Integer(2) # needs sage.libs.singular True
Again, a quotient of a quotient is just the quotient of the original top ring by the sum of two ideals.
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S.<a,b> = R.quo(1 + y^2) sage: T.<c,d> = S.quo(a) sage: T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) sage: T.gens() (0, d)
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quo(Integer(1) + y**Integer(2), names=('a', 'b',)); (a, b,) = S._first_ngens(2) >>> T = S.quo(a, names=('c', 'd',)); (c, d,) = T._first_ngens(2) >>> T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) >>> T.gens() (0, d)
- Element[source]#
alias of
QuotientRingElement
- ambient()[source]#
Returns the cover ring of the quotient ring: that is, the original ring \(R\) from which we modded out an ideal, \(I\).
EXAMPLES:
sage: Q = QuotientRing(ZZ, 7 * ZZ) sage: Q.cover_ring() Integer Ring
>>> from sage.all import * >>> Q = QuotientRing(ZZ, Integer(7) * ZZ) >>> Q.cover_ring() Integer Ring
sage: P.<x> = QQ[] sage: Q = QuotientRing(P, x^2 + 1) # needs sage.libs.pari sage: Q.cover_ring() # needs sage.libs.pari Univariate Polynomial Ring in x over Rational Field
>>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> Q = QuotientRing(P, x**Integer(2) + Integer(1)) # needs sage.libs.pari >>> Q.cover_ring() # needs sage.libs.pari Univariate Polynomial Ring in x over Rational Field
- characteristic()[source]#
Return the characteristic of the quotient ring.
Todo
Not yet implemented!
EXAMPLES:
sage: Q = QuotientRing(ZZ,7*ZZ) sage: Q.characteristic() Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> Q = QuotientRing(ZZ,Integer(7)*ZZ) >>> Q.characteristic() Traceback (most recent call last): ... NotImplementedError
- construction()[source]#
Returns the functorial construction of
self
.EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ,'x') sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: R.quotient_ring(I).construction() (QuotientFunctor, Univariate Polynomial Ring in x over Integer Ring) sage: # needs sage.combinat sage.libs.singular sage.modules sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F sage: Q = F.quo(I) sage: Q.construction() (QuotientFunctor, Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field)
>>> from sage.all import * >>> R = PolynomialRing(ZZ,'x', names=('x',)); (x,) = R._first_ngens(1) >>> I = R.ideal([Integer(4) + Integer(3)*x + x**Integer(2), Integer(1) + x**Integer(2)]) >>> R.quotient_ring(I).construction() (QuotientFunctor, Univariate Polynomial Ring in x over Integer Ring) >>> # needs sage.combinat sage.libs.singular sage.modules >>> F = FreeAlgebra(QQ, implementation='letterplace', names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3) >>> I = F * [x*y + y*z, x**Integer(2) + x*y - y*x - y**Integer(2)] * F >>> Q = F.quo(I) >>> Q.construction() (QuotientFunctor, Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field)
- cover()[source]#
The covering ring homomorphism \(R \to R/I\), equipped with a section.
EXAMPLES:
sage: R = ZZ.quo(3 * ZZ) sage: pi = R.cover() sage: pi Ring morphism: From: Integer Ring To: Ring of integers modulo 3 Defn: Natural quotient map sage: pi(5) 2 sage: l = pi.lift()
>>> from sage.all import * >>> R = ZZ.quo(Integer(3) * ZZ) >>> pi = R.cover() >>> pi Ring morphism: From: Integer Ring To: Ring of integers modulo 3 Defn: Natural quotient map >>> pi(Integer(5)) 2 >>> l = pi.lift()
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ) sage: Q = R.quo((x^2, y^2)) sage: pi = Q.cover() sage: pi(x^3 + y) ybar sage: l = pi.lift(x + y^3) sage: l x sage: l = pi.lift(); l Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map sage: l(x + y^3) x
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> Q = R.quo((x**Integer(2), y**Integer(2))) >>> pi = Q.cover() >>> pi(x**Integer(3) + y) ybar >>> l = pi.lift(x + y**Integer(3)) >>> l x >>> l = pi.lift(); l Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2, y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map >>> l(x + y**Integer(3)) x
- cover_ring()[source]#
Returns the cover ring of the quotient ring: that is, the original ring \(R\) from which we modded out an ideal, \(I\).
EXAMPLES:
sage: Q = QuotientRing(ZZ, 7 * ZZ) sage: Q.cover_ring() Integer Ring
>>> from sage.all import * >>> Q = QuotientRing(ZZ, Integer(7) * ZZ) >>> Q.cover_ring() Integer Ring
sage: P.<x> = QQ[] sage: Q = QuotientRing(P, x^2 + 1) # needs sage.libs.pari sage: Q.cover_ring() # needs sage.libs.pari Univariate Polynomial Ring in x over Rational Field
>>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> Q = QuotientRing(P, x**Integer(2) + Integer(1)) # needs sage.libs.pari >>> Q.cover_ring() # needs sage.libs.pari Univariate Polynomial Ring in x over Rational Field
- defining_ideal()[source]#
Returns the ideal generating this quotient ring.
EXAMPLES:
In the integers:
sage: Q = QuotientRing(ZZ,7*ZZ) sage: Q.defining_ideal() Principal ideal (7) of Integer Ring
>>> from sage.all import * >>> Q = QuotientRing(ZZ,Integer(7)*ZZ) >>> Q.defining_ideal() Principal ideal (7) of Integer Ring
An example involving a quotient of a quotient. By Noether’s homomorphism theorems, this is actually a quotient by a sum of two ideals:
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S.<a,b> = QuotientRing(R, R.ideal(1 + y^2)) sage: T.<c,d> = QuotientRing(S, S.ideal(a)) sage: S.defining_ideal() Ideal (y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field sage: T.defining_ideal() Ideal (x, y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = QuotientRing(R, R.ideal(Integer(1) + y**Integer(2)), names=('a', 'b',)); (a, b,) = S._first_ngens(2) >>> T = QuotientRing(S, S.ideal(a), names=('c', 'd',)); (c, d,) = T._first_ngens(2) >>> S.defining_ideal() Ideal (y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field >>> T.defining_ideal() Ideal (x, y^2 + 1) of Multivariate Polynomial Ring in x, y over Rational Field
- gen(i=0)[source]#
Returns the \(i\)-th generator for this quotient ring.
EXAMPLES:
sage: R = QuotientRing(ZZ, 7*ZZ) sage: R.gen(0) 1
>>> from sage.all import * >>> R = QuotientRing(ZZ, Integer(7)*ZZ) >>> R.gen(Integer(0)) 1
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ,2) sage: S.<a,b> = QuotientRing(R, R.ideal(1 + y^2)) sage: T.<c,d> = QuotientRing(S, S.ideal(a)) sage: T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) sage: R.gen(0); R.gen(1) x y sage: S.gen(0); S.gen(1) a b sage: T.gen(0); T.gen(1) 0 d
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ,Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = QuotientRing(R, R.ideal(Integer(1) + y**Integer(2)), names=('a', 'b',)); (a, b,) = S._first_ngens(2) >>> T = QuotientRing(S, S.ideal(a), names=('c', 'd',)); (c, d,) = T._first_ngens(2) >>> T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) >>> R.gen(Integer(0)); R.gen(Integer(1)) x y >>> S.gen(Integer(0)); S.gen(Integer(1)) a b >>> T.gen(Integer(0)); T.gen(Integer(1)) 0 d
- ideal(*gens, **kwds)[source]#
Return the ideal of
self
with the given generators.EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ) sage: S = R.quotient_ring(x^2 + y^2) sage: S.ideal() # needs sage.libs.singular Ideal (0) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) sage: S.ideal(x + y + 1) # needs sage.libs.singular Ideal (xbar + ybar + 1) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2)
>>> from sage.all import * >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quotient_ring(x**Integer(2) + y**Integer(2)) >>> S.ideal() # needs sage.libs.singular Ideal (0) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) >>> S.ideal(x + y + Integer(1)) # needs sage.libs.singular Ideal (xbar + ybar + 1) of Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2)
- is_commutative()[source]#
Tell whether this quotient ring is commutative.
Note
This is certainly the case if the cover ring is commutative. Otherwise, if this ring has a finite number of generators, it is tested whether they commute. If the number of generators is infinite, a
NotImplementedError
is raised.AUTHOR:
Simon King (2011-03-23): See Issue #7797.
EXAMPLES:
Any quotient of a commutative ring is commutative:
sage: P.<a,b,c> = QQ[] sage: P.quo(P.random_element()).is_commutative() True
>>> from sage.all import * >>> P = QQ['a, b, c']; (a, b, c,) = P._first_ngens(3) >>> P.quo(P.random_element()).is_commutative() True
The non-commutative case is more interesting:
sage: # needs sage.combinat sage.libs.singular sage.modules sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F sage: Q = F.quo(I) sage: Q.is_commutative() False sage: Q.1*Q.2 == Q.2*Q.1 False
>>> from sage.all import * >>> # needs sage.combinat sage.libs.singular sage.modules >>> F = FreeAlgebra(QQ, implementation='letterplace', names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3) >>> I = F * [x*y + y*z, x**Integer(2) + x*y - y*x - y**Integer(2)] * F >>> Q = F.quo(I) >>> Q.is_commutative() False >>> Q.gen(1)*Q.gen(2) == Q.gen(2)*Q.gen(1) False
In the next example, the generators apparently commute:
sage: # needs sage.combinat sage.libs.singular sage.modules sage: J = F * [x*y - y*x, x*z - z*x, y*z - z*y, x^3 - y^3] * F sage: R = F.quo(J) sage: R.is_commutative() True
>>> from sage.all import * >>> # needs sage.combinat sage.libs.singular sage.modules >>> J = F * [x*y - y*x, x*z - z*x, y*z - z*y, x**Integer(3) - y**Integer(3)] * F >>> R = F.quo(J) >>> R.is_commutative() True
- is_field(proof=True)[source]#
Returns
True
if the quotient ring is a field. Checks to see if the defining ideal is maximal.
- is_integral_domain(proof=True)[source]#
With
proof
equal toTrue
(the default), this function may raise aNotImplementedError
.When
proof
isFalse
, ifTrue
is returned, then self is definitely an integral domain. If the function returnsFalse
, then eitherself
is not an integral domain or it was unable to determine whether or notself
is an integral domain.EXAMPLES:
sage: R.<x,y> = QQ[] sage: R.quo(x^2 - y).is_integral_domain() # needs sage.libs.singular True sage: R.quo(x^2 - y^2).is_integral_domain() # needs sage.libs.singular False sage: R.quo(x^2 - y^2).is_integral_domain(proof=False) # needs sage.libs.singular False sage: R.<a,b,c> = ZZ[] sage: Q = R.quotient_ring([a, b]) sage: Q.is_integral_domain() Traceback (most recent call last): ... NotImplementedError sage: Q.is_integral_domain(proof=False) False
>>> from sage.all import * >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> R.quo(x**Integer(2) - y).is_integral_domain() # needs sage.libs.singular True >>> R.quo(x**Integer(2) - y**Integer(2)).is_integral_domain() # needs sage.libs.singular False >>> R.quo(x**Integer(2) - y**Integer(2)).is_integral_domain(proof=False) # needs sage.libs.singular False >>> R = ZZ['a, b, c']; (a, b, c,) = R._first_ngens(3) >>> Q = R.quotient_ring([a, b]) >>> Q.is_integral_domain() Traceback (most recent call last): ... NotImplementedError >>> Q.is_integral_domain(proof=False) False
- is_noetherian()[source]#
Return
True
if this ring is Noetherian.EXAMPLES:
sage: R = QuotientRing(ZZ, 102 * ZZ) sage: R.is_noetherian() True sage: P.<x> = QQ[] sage: R = QuotientRing(P, x^2 + 1) # needs sage.libs.pari sage: R.is_noetherian() True
>>> from sage.all import * >>> R = QuotientRing(ZZ, Integer(102) * ZZ) >>> R.is_noetherian() True >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> R = QuotientRing(P, x**Integer(2) + Integer(1)) # needs sage.libs.pari >>> R.is_noetherian() True
If the cover ring of
self
is not Noetherian, we currently have no way of testing whetherself
is Noetherian, so we raise an error:sage: R.<x> = InfinitePolynomialRing(QQ) sage: R.is_noetherian() False sage: I = R.ideal([x[1]^2, x[2]]) sage: S = R.quotient(I) sage: S.is_noetherian() Traceback (most recent call last): ... NotImplementedError
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> R.is_noetherian() False >>> I = R.ideal([x[Integer(1)]**Integer(2), x[Integer(2)]]) >>> S = R.quotient(I) >>> S.is_noetherian() Traceback (most recent call last): ... NotImplementedError
- lift(x=None)[source]#
Return the lifting map to the cover, or the image of an element under the lifting map.
Note
The category framework imposes that
Q.lift(x)
returns the image of an element \(x\) under the lifting map. For backwards compatibility, we letQ.lift()
return the lifting map.EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) sage: S.lift() # needs sage.libs.singular Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map sage: S.lift(S.0) == x # needs sage.libs.singular True
>>> from sage.all import * >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quotient(x**Integer(2) + y**Integer(2)) >>> S.lift() # needs sage.libs.singular Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map >>> S.lift(S.gen(0)) == x # needs sage.libs.singular True
- lifting_map()[source]#
Return the lifting map to the cover.
EXAMPLES:
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) sage: pi = S.cover(); pi Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) Defn: Natural quotient map sage: L = S.lifting_map(); L Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map sage: L(S.0) x sage: L(S.1) y
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quotient(x**Integer(2) + y**Integer(2)) >>> pi = S.cover(); pi Ring morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) Defn: Natural quotient map >>> L = S.lifting_map(); L Set-theoretic ring morphism: From: Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x^2 + y^2) To: Multivariate Polynomial Ring in x, y over Rational Field Defn: Choice of lifting map >>> L(S.gen(0)) x >>> L(S.gen(1)) y
Note that some reduction may be applied so that the lift of a reduction need not equal the original element:
sage: z = pi(x^3 + 2*y^2); z # needs sage.libs.singular -xbar*ybar^2 + 2*ybar^2 sage: L(z) # needs sage.libs.singular -x*y^2 + 2*y^2 sage: L(z) == x^3 + 2*y^2 # needs sage.libs.singular False
>>> from sage.all import * >>> z = pi(x**Integer(3) + Integer(2)*y**Integer(2)); z # needs sage.libs.singular -xbar*ybar^2 + 2*ybar^2 >>> L(z) # needs sage.libs.singular -x*y^2 + 2*y^2 >>> L(z) == x**Integer(3) + Integer(2)*y**Integer(2) # needs sage.libs.singular False
Test that there also is a lift for rings that are no instances of
Ring
(see Issue #11068):sage: # needs sage.modules sage: MS = MatrixSpace(GF(5), 2, 2) sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS sage: Q = MS.quo(I) sage: Q.lift() Set-theoretic ring morphism: From: Quotient of Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 by the ideal ( [0 1] [0 0], [0 0] [1 1] ) To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 Defn: Choice of lifting map
>>> from sage.all import * >>> # needs sage.modules >>> MS = MatrixSpace(GF(Integer(5)), Integer(2), Integer(2)) >>> I = MS * [MS.gen(0)*MS.gen(1), MS.gen(2) + MS.gen(3)] * MS >>> Q = MS.quo(I) >>> Q.lift() Set-theoretic ring morphism: From: Quotient of Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 by the ideal ( [0 1] [0 0], <BLANKLINE> [0 0] [1 1] ) <BLANKLINE> To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 5 Defn: Choice of lifting map
- ngens()[source]#
Returns the number of generators for this quotient ring.
Todo
Note that
ngens
counts 0 as a generator. Does this make sense? That is, since 0 only generates itself and the fact that this is true for all rings, is there a way to “knock it off” of the generators list if a generator of some original ring is modded out?EXAMPLES:
sage: R = QuotientRing(ZZ, 7*ZZ) sage: R.gens(); R.ngens() (1,) 1
>>> from sage.all import * >>> R = QuotientRing(ZZ, Integer(7)*ZZ) >>> R.gens(); R.ngens() (1,) 1
sage: # needs sage.libs.singular sage: R.<x,y> = PolynomialRing(QQ,2) sage: S.<a,b> = QuotientRing(R, R.ideal(1 + y^2)) sage: T.<c,d> = QuotientRing(S, S.ideal(a)) sage: T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) sage: R.gens(); S.gens(); T.gens() (x, y) (a, b) (0, d) sage: R.ngens(); S.ngens(); T.ngens() 2 2 2
>>> from sage.all import * >>> # needs sage.libs.singular >>> R = PolynomialRing(QQ,Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = QuotientRing(R, R.ideal(Integer(1) + y**Integer(2)), names=('a', 'b',)); (a, b,) = S._first_ngens(2) >>> T = QuotientRing(S, S.ideal(a), names=('c', 'd',)); (c, d,) = T._first_ngens(2) >>> T Quotient of Multivariate Polynomial Ring in x, y over Rational Field by the ideal (x, y^2 + 1) >>> R.gens(); S.gens(); T.gens() (x, y) (a, b) (0, d) >>> R.ngens(); S.ngens(); T.ngens() 2 2 2
- random_element()[source]#
Return a random element of this quotient ring obtained by sampling a random element of the cover ring and reducing it modulo the defining ideal.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: S = R.quotient([x^3, y^2]) sage: S.random_element() # random -8/5*xbar^2 + 3/2*xbar*ybar + 2*xbar - 4/23
>>> from sage.all import * >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> S = R.quotient([x**Integer(3), y**Integer(2)]) >>> S.random_element() # random -8/5*xbar^2 + 3/2*xbar*ybar + 2*xbar - 4/23
- retract(x)[source]#
The image of an element of the cover ring under the quotient map.
INPUT:
x
– An element of the cover ring
OUTPUT:
The image of the given element in
self
.EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2) sage: S = R.quotient(x^2 + y^2) sage: S.retract((x+y)^2) # needs sage.libs.singular 2*xbar*ybar
>>> from sage.all import * >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> S = R.quotient(x**Integer(2) + y**Integer(2)) >>> S.retract((x+y)**Integer(2)) # needs sage.libs.singular 2*xbar*ybar
- term_order()[source]#
Return the term order of this ring.
EXAMPLES:
sage: P.<a,b,c> = PolynomialRing(QQ) sage: I = Ideal([a^2 - a, b^2 - b, c^2 - c]) sage: Q = P.quotient(I) sage: Q.term_order() Degree reverse lexicographic term order
>>> from sage.all import * >>> P = PolynomialRing(QQ, names=('a', 'b', 'c',)); (a, b, c,) = P._first_ngens(3) >>> I = Ideal([a**Integer(2) - a, b**Integer(2) - b, c**Integer(2) - c]) >>> Q = P.quotient(I) >>> Q.term_order() Degree reverse lexicographic term order
- sage.rings.quotient_ring.is_QuotientRing(x)[source]#
Tests whether or not
x
inherits fromQuotientRing_nc
.EXAMPLES:
sage: from sage.rings.quotient_ring import is_QuotientRing sage: R.<x> = PolynomialRing(ZZ,'x') sage: I = R.ideal([4 + 3*x + x^2, 1 + x^2]) sage: S = R.quotient_ring(I) sage: is_QuotientRing(S) True sage: is_QuotientRing(R) False
>>> from sage.all import * >>> from sage.rings.quotient_ring import is_QuotientRing >>> R = PolynomialRing(ZZ,'x', names=('x',)); (x,) = R._first_ngens(1) >>> I = R.ideal([Integer(4) + Integer(3)*x + x**Integer(2), Integer(1) + x**Integer(2)]) >>> S = R.quotient_ring(I) >>> is_QuotientRing(S) True >>> is_QuotientRing(R) False
sage: # needs sage.combinat sage.libs.singular sage.modules sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace') sage: I = F * [x*y + y*z, x^2 + x*y - y*x - y^2] * F sage: Q = F.quo(I) sage: is_QuotientRing(Q) True sage: is_QuotientRing(F) False
>>> from sage.all import * >>> # needs sage.combinat sage.libs.singular sage.modules >>> F = FreeAlgebra(QQ, implementation='letterplace', names=('x', 'y', 'z',)); (x, y, z,) = F._first_ngens(3) >>> I = F * [x*y + y*z, x**Integer(2) + x*y - y*x - y**Integer(2)] * F >>> Q = F.quo(I) >>> is_QuotientRing(Q) True >>> is_QuotientRing(F) False