Ring \(\ZZ/n\ZZ\) of integers modulo \(n\)#
EXAMPLES:
sage: R = Integers(97)
sage: a = R(5)
sage: a**100000000000000000000000000000000000000000000000000000000000000
61
>>> from sage.all import *
>>> R = Integers(Integer(97))
>>> a = R(Integer(5))
>>> a**Integer(100000000000000000000000000000000000000000000000000000000000000)
61
This example illustrates the relation between \(\ZZ/p\ZZ\) and \(\GF{p}\). In particular, there is a canonical map to \(\GF{p}\), but not in the other direction.
sage: r = Integers(7)
sage: s = GF(7)
sage: r.has_coerce_map_from(s)
False
sage: s.has_coerce_map_from(r)
True
sage: s(1) + r(1)
2
sage: parent(s(1) + r(1))
Finite Field of size 7
sage: parent(r(1) + s(1))
Finite Field of size 7
>>> from sage.all import *
>>> r = Integers(Integer(7))
>>> s = GF(Integer(7))
>>> r.has_coerce_map_from(s)
False
>>> s.has_coerce_map_from(r)
True
>>> s(Integer(1)) + r(Integer(1))
2
>>> parent(s(Integer(1)) + r(Integer(1)))
Finite Field of size 7
>>> parent(r(Integer(1)) + s(Integer(1)))
Finite Field of size 7
We list the elements of \(\ZZ/3\ZZ\):
sage: R = Integers(3)
sage: list(R)
[0, 1, 2]
>>> from sage.all import *
>>> R = Integers(Integer(3))
>>> list(R)
[0, 1, 2]
AUTHORS:
William Stein (initial code)
David Joyner (2005-12-22): most examples
Robert Bradshaw (2006-08-24): convert to SageX (Cython)
William Stein (2007-04-29): square_roots_of_one
Simon King (2011-04-21): allow to prescribe a category
Simon King (2013-09): Only allow to prescribe the category of fields
- class sage.rings.finite_rings.integer_mod_ring.IntegerModFactory[source]#
Bases:
UniqueFactory
Return the quotient ring \(\ZZ / n\ZZ\).
INPUT:
order
– integer (default: 0); positive or negativeis_field
– bool (default:False
); assert that the order is prime and hence the quotient ring belongs to the category of fieldscategory
(optional) – the category that the quotient ring belongs to.
Note
The optional argument
is_field
is not part of the cache key. Hence, this factory will create precisely one instance of \(\ZZ / n\ZZ\). However, ifis_field
is true, then a previously created instance of the quotient ring will be updated to be in the category of fields.Use with care! Erroneously putting \(\ZZ / n\ZZ\) into the category of fields may have consequences that can compromise a whole Sage session, so that a restart will be needed.
EXAMPLES:
sage: IntegerModRing(15) Ring of integers modulo 15 sage: IntegerModRing(7) Ring of integers modulo 7 sage: IntegerModRing(-100) Ring of integers modulo 100
>>> from sage.all import * >>> IntegerModRing(Integer(15)) Ring of integers modulo 15 >>> IntegerModRing(Integer(7)) Ring of integers modulo 7 >>> IntegerModRing(-Integer(100)) Ring of integers modulo 100
Note that you can also use
Integers
, which is a synonym forIntegerModRing
.sage: Integers(18) Ring of integers modulo 18 sage: Integers() is Integers(0) is ZZ True
>>> from sage.all import * >>> Integers(Integer(18)) Ring of integers modulo 18 >>> Integers() is Integers(Integer(0)) is ZZ True
Note
Testing whether a quotient ring \(\ZZ / n\ZZ\) is a field can of course be very costly. By default, it is not tested whether \(n\) is prime or not, in contrast to
GF()
. If the user is sure that the modulus is prime and wants to avoid a primality test, (s)he can providecategory=Fields()
when constructing the quotient ring, and then the result will behave like a field. If the category is not provided during initialisation, and it is found out later that the ring is in fact a field, then the category will be changed at runtime, having the same effect as providingFields()
during initialisation.EXAMPLES:
sage: R = IntegerModRing(5) sage: R.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets sage: R in Fields() True sage: R.category() Join of Category of finite enumerated fields and Category of subquotients of monoids and Category of quotients of semigroups sage: S = IntegerModRing(5, is_field=True) sage: S is R True
>>> from sage.all import * >>> R = IntegerModRing(Integer(5)) >>> R.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets >>> R in Fields() True >>> R.category() Join of Category of finite enumerated fields and Category of subquotients of monoids and Category of quotients of semigroups >>> S = IntegerModRing(Integer(5), is_field=True) >>> S is R True
Warning
If the optional argument
is_field
was used by mistake, there is currently no way to revert its impact, even thoughIntegerModRing_generic.is_field()
with the optional argumentproof=True
would return the correct answer. So, prescribeis_field=True
only if you know what your are doing!EXAMPLES:
sage: R = IntegerModRing(33, is_field=True) sage: R in Fields() True sage: R.is_field() True
>>> from sage.all import * >>> R = IntegerModRing(Integer(33), is_field=True) >>> R in Fields() True >>> R.is_field() True
If the optional argument \(proof=True\) is provided, primality is tested and the mistaken category assignment is reported:
sage: R.is_field(proof=True) Traceback (most recent call last): ... ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED! The order 33 is not prime, but this ring has been put into the category of fields. This may already have consequences in other parts of Sage. Either it was a mistake of the user, or a probabilistic primality test has failed. In the latter case, please inform the developers.
>>> from sage.all import * >>> R.is_field(proof=True) Traceback (most recent call last): ... ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED! The order 33 is not prime, but this ring has been put into the category of fields. This may already have consequences in other parts of Sage. Either it was a mistake of the user, or a probabilistic primality test has failed. In the latter case, please inform the developers.
However, the mistaken assignment is not automatically corrected:
sage: R in Fields() True
>>> from sage.all import * >>> R in Fields() True
To avoid side-effects of this test on other tests, we clear the cache of the ring factory:
sage: IntegerModRing._cache.clear()
>>> from sage.all import * >>> IntegerModRing._cache.clear()
- create_key_and_extra_args(order=0, is_field=False, category=None)[source]#
An integer mod ring is specified uniquely by its order.
EXAMPLES:
sage: Zmod.create_key_and_extra_args(7) (7, {}) sage: Zmod.create_key_and_extra_args(7, True) (7, {'category': Category of fields})
>>> from sage.all import * >>> Zmod.create_key_and_extra_args(Integer(7)) (7, {}) >>> Zmod.create_key_and_extra_args(Integer(7), True) (7, {'category': Category of fields})
- class sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic(order, cache=None, category=None)[source]#
Bases:
QuotientRing_generic
,IntegerModRing
The ring of integers modulo \(N\).
INPUT:
order
– an integercategory
– a subcategory ofCommutativeRings()
(the default)
OUTPUT:
The ring of integers modulo \(N\).
EXAMPLES:
First we compute with integers modulo \(29\).
sage: FF = IntegerModRing(29) sage: FF Ring of integers modulo 29 sage: FF.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets sage: FF.is_field() True sage: FF.characteristic() 29 sage: FF.order() 29 sage: # needs sage.groups sage: gens = FF.unit_gens() sage: a = gens[0] sage: a 2 sage: a.is_square() False sage: def pow(i): return a**i sage: [pow(i) for i in range(16)] [1, 2, 4, 8, 16, 3, 6, 12, 24, 19, 9, 18, 7, 14, 28, 27] sage: TestSuite(FF).run()
>>> from sage.all import * >>> FF = IntegerModRing(Integer(29)) >>> FF Ring of integers modulo 29 >>> FF.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets >>> FF.is_field() True >>> FF.characteristic() 29 >>> FF.order() 29 >>> # needs sage.groups >>> gens = FF.unit_gens() >>> a = gens[Integer(0)] >>> a 2 >>> a.is_square() False >>> def pow(i): return a**i >>> [pow(i) for i in range(Integer(16))] [1, 2, 4, 8, 16, 3, 6, 12, 24, 19, 9, 18, 7, 14, 28, 27] >>> TestSuite(FF).run()
We have seen above that an integer mod ring is, by default, not initialised as an object in the category of fields. However, one can force it to be. Moreover, testing containment in the category of fields my re-initialise the category of the integer mod ring:
sage: F19 = IntegerModRing(19, is_field=True) sage: F19.category().is_subcategory(Fields()) True sage: F23 = IntegerModRing(23) sage: F23.category().is_subcategory(Fields()) False sage: F23 in Fields() True sage: F23.category().is_subcategory(Fields()) True sage: TestSuite(F19).run() sage: TestSuite(F23).run()
>>> from sage.all import * >>> F19 = IntegerModRing(Integer(19), is_field=True) >>> F19.category().is_subcategory(Fields()) True >>> F23 = IntegerModRing(Integer(23)) >>> F23.category().is_subcategory(Fields()) False >>> F23 in Fields() True >>> F23.category().is_subcategory(Fields()) True >>> TestSuite(F19).run() >>> TestSuite(F23).run()
By Issue #15229, there is a unique instance of the integral quotient ring of a given order. Using the
IntegerModRing()
factory twice, and usingis_field=True
the second time, will update the category of the unique instance:sage: F31a = IntegerModRing(31) sage: F31a.category().is_subcategory(Fields()) False sage: F31b = IntegerModRing(31, is_field=True) sage: F31a is F31b True sage: F31a.category().is_subcategory(Fields()) True
>>> from sage.all import * >>> F31a = IntegerModRing(Integer(31)) >>> F31a.category().is_subcategory(Fields()) False >>> F31b = IntegerModRing(Integer(31), is_field=True) >>> F31a is F31b True >>> F31a.category().is_subcategory(Fields()) True
Next we compute with the integers modulo \(16\).
sage: Z16 = IntegerModRing(16) sage: Z16.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets sage: Z16.is_field() False sage: Z16.order() 16 sage: Z16.characteristic() 16 sage: # needs sage.groups sage: gens = Z16.unit_gens() sage: gens (15, 5) sage: a = gens[0] sage: b = gens[1] sage: def powa(i): return a**i sage: def powb(i): return b**i sage: gp_exp = FF.unit_group_exponent() sage: gp_exp 28 sage: [powa(i) for i in range(15)] [1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1] sage: [powb(i) for i in range(15)] [1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9] sage: a.multiplicative_order() 2 sage: b.multiplicative_order() 4 sage: TestSuite(Z16).run()
>>> from sage.all import * >>> Z16 = IntegerModRing(Integer(16)) >>> Z16.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets >>> Z16.is_field() False >>> Z16.order() 16 >>> Z16.characteristic() 16 >>> # needs sage.groups >>> gens = Z16.unit_gens() >>> gens (15, 5) >>> a = gens[Integer(0)] >>> b = gens[Integer(1)] >>> def powa(i): return a**i >>> def powb(i): return b**i >>> gp_exp = FF.unit_group_exponent() >>> gp_exp 28 >>> [powa(i) for i in range(Integer(15))] [1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1] >>> [powb(i) for i in range(Integer(15))] [1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9] >>> a.multiplicative_order() 2 >>> b.multiplicative_order() 4 >>> TestSuite(Z16).run()
Saving and loading:
sage: R = Integers(100000) sage: TestSuite(R).run() # long time (17s on sage.math, 2011)
>>> from sage.all import * >>> R = Integers(Integer(100000)) >>> TestSuite(R).run() # long time (17s on sage.math, 2011)
Testing ideals and quotients:
sage: Z10 = Integers(10) sage: I = Z10.principal_ideal(0) sage: Z10.quotient(I) == Z10 True sage: I = Z10.principal_ideal(2) sage: Z10.quotient(I) == Z10 False sage: I.is_prime() True
>>> from sage.all import * >>> Z10 = Integers(Integer(10)) >>> I = Z10.principal_ideal(Integer(0)) >>> Z10.quotient(I) == Z10 True >>> I = Z10.principal_ideal(Integer(2)) >>> Z10.quotient(I) == Z10 False >>> I.is_prime() True
sage: R = IntegerModRing(97) sage: a = R(5) sage: a**(10^62) 61
>>> from sage.all import * >>> R = IntegerModRing(Integer(97)) >>> a = R(Integer(5)) >>> a**(Integer(10)**Integer(62)) 61
- cardinality()[source]#
Return the cardinality of this ring.
EXAMPLES:
sage: Zmod(87).cardinality() 87
>>> from sage.all import * >>> Zmod(Integer(87)).cardinality() 87
- characteristic()[source]#
EXAMPLES:
sage: R = IntegerModRing(18) sage: FF = IntegerModRing(17) sage: FF.characteristic() 17 sage: R.characteristic() 18
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> FF = IntegerModRing(Integer(17)) >>> FF.characteristic() 17 >>> R.characteristic() 18
- degree()[source]#
Return 1.
EXAMPLES:
sage: R = Integers(12345678900) sage: R.degree() 1
>>> from sage.all import * >>> R = Integers(Integer(12345678900)) >>> R.degree() 1
- extension(poly, name=None, names=None, **kwds)[source]#
Return an algebraic extension of
self
. Seesage.rings.ring.CommutativeRing.extension()
for more information.EXAMPLES:
sage: R.<t> = QQ[] sage: Integers(8).extension(t^2 - 3) Univariate Quotient Polynomial Ring in t over Ring of integers modulo 8 with modulus t^2 + 5
>>> from sage.all import * >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> Integers(Integer(8)).extension(t**Integer(2) - Integer(3)) Univariate Quotient Polynomial Ring in t over Ring of integers modulo 8 with modulus t^2 + 5
- factored_order()[source]#
EXAMPLES:
sage: R = IntegerModRing(18) sage: FF = IntegerModRing(17) sage: R.factored_order() 2 * 3^2 sage: FF.factored_order() 17
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> FF = IntegerModRing(Integer(17)) >>> R.factored_order() 2 * 3^2 >>> FF.factored_order() 17
- factored_unit_order()[source]#
Return a list of
Factorization
objects, each the factorization of the order of the units in a \(\ZZ / p^n \ZZ\) component of this group (using the Chinese Remainder Theorem).EXAMPLES:
sage: R = Integers(8*9*25*17*29) sage: R.factored_unit_order() [2^2, 2 * 3, 2^2 * 5, 2^4, 2^2 * 7]
>>> from sage.all import * >>> R = Integers(Integer(8)*Integer(9)*Integer(25)*Integer(17)*Integer(29)) >>> R.factored_unit_order() [2^2, 2 * 3, 2^2 * 5, 2^4, 2^2 * 7]
- field()[source]#
If this ring is a field, return the corresponding field as a finite field, which may have extra functionality and structure. Otherwise, raise a
ValueError
.EXAMPLES:
sage: R = Integers(7); R Ring of integers modulo 7 sage: R.field() Finite Field of size 7 sage: R = Integers(9) sage: R.field() Traceback (most recent call last): ... ValueError: self must be a field
>>> from sage.all import * >>> R = Integers(Integer(7)); R Ring of integers modulo 7 >>> R.field() Finite Field of size 7 >>> R = Integers(Integer(9)) >>> R.field() Traceback (most recent call last): ... ValueError: self must be a field
- is_field(proof=None)[source]#
Return
True
precisely if the order is prime.INPUT:
proof
(optional bool or None, default None): IfFalse
, then test whether the category of the quotient is a subcategory ofFields()
, or do a probabilistic primality test. IfNone
, then test the category and then do a primality test according to the global arithmetic proof settings. If True, do a deterministic primality test.
If it is found (perhaps probabilistically) that the ring is a field, then the category of the ring is refined to include the category of fields. This may change the Python class of the ring!
EXAMPLES:
sage: R = IntegerModRing(18) sage: R.is_field() False sage: FF = IntegerModRing(17) sage: FF.is_field() True
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> R.is_field() False >>> FF = IntegerModRing(Integer(17)) >>> FF.is_field() True
By Issue #15229, the category of the ring is refined, if it is found that the ring is in fact a field:
sage: R = IntegerModRing(127) sage: R.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets sage: R.is_field() True sage: R.category() Join of Category of finite enumerated fields and Category of subquotients of monoids and Category of quotients of semigroups
>>> from sage.all import * >>> R = IntegerModRing(Integer(127)) >>> R.category() Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets >>> R.is_field() True >>> R.category() Join of Category of finite enumerated fields and Category of subquotients of monoids and Category of quotients of semigroups
It is possible to mistakenly put \(\ZZ/n\ZZ\) into the category of fields. In this case,
is_field()
will return True without performing a primality check. However, if the optional argument \(proof=True\) is provided, primality is tested and the mistake is uncovered in a warning message:sage: R = IntegerModRing(21, is_field=True) sage: R.is_field() True sage: R.is_field(proof=True) Traceback (most recent call last): ... ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED! The order 21 is not prime, but this ring has been put into the category of fields. This may already have consequences in other parts of Sage. Either it was a mistake of the user, or a probabilistic primality test has failed. In the latter case, please inform the developers.
>>> from sage.all import * >>> R = IntegerModRing(Integer(21), is_field=True) >>> R.is_field() True >>> R.is_field(proof=True) Traceback (most recent call last): ... ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED! The order 21 is not prime, but this ring has been put into the category of fields. This may already have consequences in other parts of Sage. Either it was a mistake of the user, or a probabilistic primality test has failed. In the latter case, please inform the developers.
To avoid side-effects of this test on other tests, we clear the cache of the ring factory:
sage: IntegerModRing._cache.clear()
>>> from sage.all import * >>> IntegerModRing._cache.clear()
- is_integral_domain(proof=None)[source]#
Return
True
if and only if the order ofself
is prime.EXAMPLES:
sage: Integers(389).is_integral_domain() True sage: Integers(389^2).is_integral_domain() # needs sage.libs.pari False
>>> from sage.all import * >>> Integers(Integer(389)).is_integral_domain() True >>> Integers(Integer(389)**Integer(2)).is_integral_domain() # needs sage.libs.pari False
- is_noetherian()[source]#
Check if
self
is a Noetherian ring.EXAMPLES:
sage: Integers(8).is_noetherian() True
>>> from sage.all import * >>> Integers(Integer(8)).is_noetherian() True
- is_prime_field()[source]#
Return
True
if the order is prime.EXAMPLES:
sage: Zmod(7).is_prime_field() True sage: Zmod(8).is_prime_field() False
>>> from sage.all import * >>> Zmod(Integer(7)).is_prime_field() True >>> Zmod(Integer(8)).is_prime_field() False
- is_unique_factorization_domain(proof=None)[source]#
Return
True
if and only if the order ofself
is prime.EXAMPLES:
sage: Integers(389).is_unique_factorization_domain() True sage: Integers(389^2).is_unique_factorization_domain() # needs sage.libs.pari False
>>> from sage.all import * >>> Integers(Integer(389)).is_unique_factorization_domain() True >>> Integers(Integer(389)**Integer(2)).is_unique_factorization_domain() # needs sage.libs.pari False
- krull_dimension()[source]#
Return the Krull dimension of
self
.EXAMPLES:
sage: Integers(18).krull_dimension() 0
>>> from sage.all import * >>> Integers(Integer(18)).krull_dimension() 0
- list_of_elements_of_multiplicative_group()[source]#
Return a list of all invertible elements, as python ints.
EXAMPLES:
sage: R = Zmod(12) sage: L = R.list_of_elements_of_multiplicative_group(); L [1, 5, 7, 11] sage: type(L[0]) <... 'int'> sage: Zmod(1).list_of_elements_of_multiplicative_group() [0]
>>> from sage.all import * >>> R = Zmod(Integer(12)) >>> L = R.list_of_elements_of_multiplicative_group(); L [1, 5, 7, 11] >>> type(L[Integer(0)]) <... 'int'> >>> Zmod(Integer(1)).list_of_elements_of_multiplicative_group() [0]
- modulus()[source]#
Return the polynomial \(x - 1\) over this ring.
Note
This function exists for consistency with the finite-field modulus function.
EXAMPLES:
sage: R = IntegerModRing(18) sage: R.modulus() x + 17 sage: R = IntegerModRing(17) sage: R.modulus() x + 16
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> R.modulus() x + 17 >>> R = IntegerModRing(Integer(17)) >>> R.modulus() x + 16
- multiplicative_generator()[source]#
Return a generator for the multiplicative group of this ring, assuming the multiplicative group is cyclic.
Use the unit_gens function to obtain generators even in the non-cyclic case.
EXAMPLES:
sage: # needs sage.groups sage.libs.pari sage: R = Integers(7); R Ring of integers modulo 7 sage: R.multiplicative_generator() 3 sage: R = Integers(9) sage: R.multiplicative_generator() 2 sage: Integers(8).multiplicative_generator() Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic sage: Integers(4).multiplicative_generator() 3 sage: Integers(25*3).multiplicative_generator() Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic sage: Integers(25*3).unit_gens() (26, 52) sage: Integers(162).unit_gens() (83,)
>>> from sage.all import * >>> # needs sage.groups sage.libs.pari >>> R = Integers(Integer(7)); R Ring of integers modulo 7 >>> R.multiplicative_generator() 3 >>> R = Integers(Integer(9)) >>> R.multiplicative_generator() 2 >>> Integers(Integer(8)).multiplicative_generator() Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic >>> Integers(Integer(4)).multiplicative_generator() 3 >>> Integers(Integer(25)*Integer(3)).multiplicative_generator() Traceback (most recent call last): ... ValueError: multiplicative group of this ring is not cyclic >>> Integers(Integer(25)*Integer(3)).unit_gens() (26, 52) >>> Integers(Integer(162)).unit_gens() (83,)
- multiplicative_group_is_cyclic()[source]#
Return
True
if the multiplicative group of this field is cyclic. This is the case exactly when the order is less than 8, a power of an odd prime, or twice a power of an odd prime.EXAMPLES:
sage: R = Integers(7); R Ring of integers modulo 7 sage: R.multiplicative_group_is_cyclic() True sage: R = Integers(9) sage: R.multiplicative_group_is_cyclic() # needs sage.libs.pari True sage: Integers(8).multiplicative_group_is_cyclic() False sage: Integers(4).multiplicative_group_is_cyclic() True sage: Integers(25*3).multiplicative_group_is_cyclic() # needs sage.libs.pari False
>>> from sage.all import * >>> R = Integers(Integer(7)); R Ring of integers modulo 7 >>> R.multiplicative_group_is_cyclic() True >>> R = Integers(Integer(9)) >>> R.multiplicative_group_is_cyclic() # needs sage.libs.pari True >>> Integers(Integer(8)).multiplicative_group_is_cyclic() False >>> Integers(Integer(4)).multiplicative_group_is_cyclic() True >>> Integers(Integer(25)*Integer(3)).multiplicative_group_is_cyclic() # needs sage.libs.pari False
We test that Issue #5250 is fixed:
sage: Integers(162).multiplicative_group_is_cyclic() # needs sage.libs.pari True
>>> from sage.all import * >>> Integers(Integer(162)).multiplicative_group_is_cyclic() # needs sage.libs.pari True
- multiplicative_subgroups()[source]#
Return generators for each subgroup of \((\ZZ/N\ZZ)^*\).
EXAMPLES:
sage: # optional - gap_package_polycyclic, needs sage.groups sage: Integers(5).multiplicative_subgroups() ((2,), (4,), ()) sage: Integers(15).multiplicative_subgroups() ((11, 7), (11, 4), (2,), (11,), (14,), (7,), (4,), ()) sage: Integers(2).multiplicative_subgroups() ((),) sage: len(Integers(341).multiplicative_subgroups()) 80
>>> from sage.all import * >>> # optional - gap_package_polycyclic, needs sage.groups >>> Integers(Integer(5)).multiplicative_subgroups() ((2,), (4,), ()) >>> Integers(Integer(15)).multiplicative_subgroups() ((11, 7), (11, 4), (2,), (11,), (14,), (7,), (4,), ()) >>> Integers(Integer(2)).multiplicative_subgroups() ((),) >>> len(Integers(Integer(341)).multiplicative_subgroups()) 80
- order()[source]#
Return the order of this ring.
EXAMPLES:
sage: Zmod(87).order() 87
>>> from sage.all import * >>> Zmod(Integer(87)).order() 87
- quadratic_nonresidue()[source]#
Return a quadratic non-residue in
self
.EXAMPLES:
sage: R = Integers(17) sage: R.quadratic_nonresidue() # needs sage.libs.pari 3 sage: R(3).is_square() False
>>> from sage.all import * >>> R = Integers(Integer(17)) >>> R.quadratic_nonresidue() # needs sage.libs.pari 3 >>> R(Integer(3)).is_square() False
- random_element(bound=None)[source]#
Return a random element of this ring.
INPUT:
bound
, a positive integer orNone
(the default). Is given, return the coercion of an integer in the interval[-bound, bound]
into this ring.
EXAMPLES:
sage: R = IntegerModRing(18) sage: R.random_element().parent() is R True sage: found = [False]*18 sage: while not all(found): ....: found[R.random_element()] = True
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> R.random_element().parent() is R True >>> found = [False]*Integer(18) >>> while not all(found): ... found[R.random_element()] = True
We test
bound
-option:sage: R.random_element(2) in [R(16), R(17), R(0), R(1), R(2)] True
>>> from sage.all import * >>> R.random_element(Integer(2)) in [R(Integer(16)), R(Integer(17)), R(Integer(0)), R(Integer(1)), R(Integer(2))] True
- square_roots_of_one()[source]#
Return all square roots of 1 in self, i.e., all solutions to \(x^2 - 1 = 0\).
OUTPUT:
The square roots of 1 in
self
as a tuple.EXAMPLES:
sage: R = Integers(2^10) sage: [x for x in R if x^2 == 1] [1, 511, 513, 1023] sage: R.square_roots_of_one() (1, 511, 513, 1023)
>>> from sage.all import * >>> R = Integers(Integer(2)**Integer(10)) >>> [x for x in R if x**Integer(2) == Integer(1)] [1, 511, 513, 1023] >>> R.square_roots_of_one() (1, 511, 513, 1023)
sage: # needs sage.libs.pari sage: v = Integers(9*5).square_roots_of_one(); v (1, 19, 26, 44) sage: [x^2 for x in v] [1, 1, 1, 1] sage: v = Integers(9*5*8).square_roots_of_one(); v (1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, 271, 289, 341, 359) sage: [x^2 for x in v] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> from sage.all import * >>> # needs sage.libs.pari >>> v = Integers(Integer(9)*Integer(5)).square_roots_of_one(); v (1, 19, 26, 44) >>> [x**Integer(2) for x in v] [1, 1, 1, 1] >>> v = Integers(Integer(9)*Integer(5)*Integer(8)).square_roots_of_one(); v (1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, 271, 289, 341, 359) >>> [x**Integer(2) for x in v] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
- unit_gens(**kwds)[source]#
Returns generators for the unit group \((\ZZ/N\ZZ)^*\).
We compute the list of generators using a deterministic algorithm, so the generators list will always be the same. For each odd prime divisor of \(N\) there will be exactly one corresponding generator; if \(N\) is even there will be 0, 1 or 2 generators according to whether 2 divides \(N\) to order 1, 2 or \(\geq 3\).
OUTPUT:
A tuple containing the units of
self
.EXAMPLES:
sage: R = IntegerModRing(18) sage: R.unit_gens() # needs sage.groups (11,) sage: R = IntegerModRing(17) sage: R.unit_gens() # needs sage.groups (3,) sage: IntegerModRing(next_prime(10^30)).unit_gens() # needs sage.groups (5,)
>>> from sage.all import * >>> R = IntegerModRing(Integer(18)) >>> R.unit_gens() # needs sage.groups (11,) >>> R = IntegerModRing(Integer(17)) >>> R.unit_gens() # needs sage.groups (3,) >>> IntegerModRing(next_prime(Integer(10)**Integer(30))).unit_gens() # needs sage.groups (5,)
The choice of generators is affected by the optional keyword
algorithm
; this can be'sage'
(default) or'pari'
. Seeunit_group()
for details.sage: A = Zmod(55) sage: A.unit_gens(algorithm='sage') # needs sage.groups (12, 46) sage: A.unit_gens(algorithm='pari') # needs sage.groups sage.libs.pari (2, 21)
>>> from sage.all import * >>> A = Zmod(Integer(55)) >>> A.unit_gens(algorithm='sage') # needs sage.groups (12, 46) >>> A.unit_gens(algorithm='pari') # needs sage.groups sage.libs.pari (2, 21)
- unit_group(algorithm='sage')[source]#
Return the unit group of
self
.INPUT:
self
– the ring \(\ZZ/n\ZZ\) for a positive integer \(n\)algorithm
– either'sage'
(default) or'pari'
OUTPUT:
The unit group of
self
. This is a finite Abelian group equipped with a distinguished set of generators, which is computed using a deterministic algorithm depending on thealgorithm
parameter.If
algorithm == 'sage'
, the generators correspond to the prime factors \(p \mid n\) (one generator for each odd \(p\); the number of generators for \(p = 2\) is 0, 1 or 2 depending on the order to which 2 divides \(n\)).If
algorithm == 'pari'
, the generators are chosen such that their orders form a decreasing sequence with respect to divisibility.
EXAMPLES:
The output of the algorithms
'sage'
and'pari'
can differ in various ways. In the following example, the same cyclic factors are computed, but in a different order:sage: # needs sage.groups sage: A = Zmod(15) sage: G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C4 sage: G.gens_values() (11, 7) sage: H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 sage: H.gens_values() # needs sage.libs.pari (7, 11)
>>> from sage.all import * >>> # needs sage.groups >>> A = Zmod(Integer(15)) >>> G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C4 >>> G.gens_values() (11, 7) >>> H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 >>> H.gens_values() # needs sage.libs.pari (7, 11)
Here are two examples where the cyclic factors are isomorphic, but are ordered differently and have different generators:
sage: # needs sage.groups sage: A = Zmod(40) sage: G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C2 x C4 sage: G.gens_values() (31, 21, 17) sage: H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 x C2 sage: H.gens_values() # needs sage.libs.pari (17, 31, 21) sage: # needs sage.groups sage: A = Zmod(192) sage: G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C16 x C2 sage: G.gens_values() (127, 133, 65) sage: H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C16 x C2 x C2 sage: H.gens_values() # needs sage.libs.pari (133, 127, 65)
>>> from sage.all import * >>> # needs sage.groups >>> A = Zmod(Integer(40)) >>> G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C2 x C4 >>> G.gens_values() (31, 21, 17) >>> H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C4 x C2 x C2 >>> H.gens_values() # needs sage.libs.pari (17, 31, 21) >>> # needs sage.groups >>> A = Zmod(Integer(192)) >>> G = A.unit_group(); G Multiplicative Abelian group isomorphic to C2 x C16 x C2 >>> G.gens_values() (127, 133, 65) >>> H = A.unit_group(algorithm='pari'); H # needs sage.libs.pari Multiplicative Abelian group isomorphic to C16 x C2 x C2 >>> H.gens_values() # needs sage.libs.pari (133, 127, 65)
In the following examples, the cyclic factors are not even isomorphic:
sage: A = Zmod(319) sage: A.unit_group() # needs sage.groups Multiplicative Abelian group isomorphic to C10 x C28 sage: A.unit_group(algorithm='pari') # needs sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C140 x C2 sage: A = Zmod(30.factorial()) sage: A.unit_group() # needs sage.groups Multiplicative Abelian group isomorphic to C2 x C16777216 x C3188646 x C62500 x C2058 x C110 x C156 x C16 x C18 x C22 x C28 sage: A.unit_group(algorithm='pari') # needs sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C20499647385305088000000 x C55440 x C12 x C12 x C4 x C2 x C2 x C2 x C2 x C2 x C2
>>> from sage.all import * >>> A = Zmod(Integer(319)) >>> A.unit_group() # needs sage.groups Multiplicative Abelian group isomorphic to C10 x C28 >>> A.unit_group(algorithm='pari') # needs sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C140 x C2 >>> A = Zmod(Integer(30).factorial()) >>> A.unit_group() # needs sage.groups Multiplicative Abelian group isomorphic to C2 x C16777216 x C3188646 x C62500 x C2058 x C110 x C156 x C16 x C18 x C22 x C28 >>> A.unit_group(algorithm='pari') # needs sage.groups sage.libs.pari Multiplicative Abelian group isomorphic to C20499647385305088000000 x C55440 x C12 x C12 x C4 x C2 x C2 x C2 x C2 x C2 x C2
- unit_group_exponent()[source]#
EXAMPLES:
sage: R = IntegerModRing(17) sage: R.unit_group_exponent() # needs sage.groups 16 sage: R = IntegerModRing(18) sage: R.unit_group_exponent() # needs sage.groups 6
>>> from sage.all import * >>> R = IntegerModRing(Integer(17)) >>> R.unit_group_exponent() # needs sage.groups 16 >>> R = IntegerModRing(Integer(18)) >>> R.unit_group_exponent() # needs sage.groups 6
- sage.rings.finite_rings.integer_mod_ring.crt(v)[source]#
INPUT:
v
– (list) a lift of elements ofrings.IntegerMod(n)
, for various coprime modulin
EXAMPLES:
sage: from sage.rings.finite_rings.integer_mod_ring import crt sage: crt([mod(3, 8), mod(1,19), mod(7, 15)]) 1027
>>> from sage.all import * >>> from sage.rings.finite_rings.integer_mod_ring import crt >>> crt([mod(Integer(3), Integer(8)), mod(Integer(1),Integer(19)), mod(Integer(7), Integer(15))]) 1027