def __init__(self, order, cache=None, category=None): """ Create with the command ``IntegerModRing(order)``. TESTS:: sage: FF = IntegerModRing(29) sage: TestSuite(FF).run() sage: F19 = IntegerModRing(19, category = Fields()) sage: TestSuite(F19).run() sage: F23 = IntegerModRing(23) sage: F23 in Fields() True sage: TestSuite(F23).run() sage: Z16 = IntegerModRing(16) sage: TestSuite(Z16).run() sage: R = Integers(100000) sage: TestSuite(R).run() # long time (17s on sage.math, 2011) """ order = ZZ(order) if order <= 0: raise ZeroDivisionError("order must be positive") self.__order = order self._pyx_order = integer_mod.NativeIntStruct(order) if category is None: from sage.categories.commutative_rings import CommutativeRings from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.category import Category category = Category.join( [CommutativeRings(), FiniteEnumeratedSets()]) # category = default_category # If the category is given then we trust that is it right. # Give the generator a 'name' to make quotients work. The # name 'x' is used because it's also used for the ring of # integers: see the __init__ method for IntegerRing_class in # sage/rings/integer_ring.pyx. quotient_ring.QuotientRing_generic.__init__(self, ZZ, ZZ.ideal(order), names=('x', ), category=category) # Calling ParentWithGens is not needed, the job is done in # the quotient ring initialisation. #ParentWithGens.__init__(self, self, category = category) # We want that the ring is its own base ring. self._base = self if cache is None: cache = order < 500 if cache: self._precompute_table() self._zero_element = integer_mod.IntegerMod(self, 0) self._one_element = integer_mod.IntegerMod(self, 1)
def __init__(self, order, cache=None, category=None): """ Create with the command ``IntegerModRing(order)``. TESTS:: sage: FF = IntegerModRing(29) sage: TestSuite(FF).run() sage: F19 = IntegerModRing(19, is_field=True) sage: TestSuite(F19).run() sage: F23 = IntegerModRing(23) sage: F23 in Fields() True sage: TestSuite(F23).run() sage: Z16 = IntegerModRing(16) sage: TestSuite(Z16).run() sage: R = Integers(100000) sage: TestSuite(R).run() # long time (17s on sage.math, 2011) """ order = ZZ(order) if order <= 0: raise ZeroDivisionError("order must be positive") self.__order = order self._pyx_order = integer_mod.NativeIntStruct(order) global default_category if category is None: category = default_category else: # If the category is given, e.g., as Fields(), then we still # know that the result will also live in default_category. # Hence, we use the join of the default and the given category. category = category.join([category, default_category]) # Give the generator a 'name' to make quotients work. The # name 'x' is used because it's also used for the ring of # integers: see the __init__ method for IntegerRing_class in # sage/rings/integer_ring.pyx. quotient_ring.QuotientRing_generic.__init__(self, ZZ, ZZ.ideal(order), names=('x', ), category=category) # We want that the ring is its own base ring. self._base = self if cache is None: cache = order < 500 if cache: self._precompute_table() self._zero_element = integer_mod.IntegerMod(self, 0) self._one_element = integer_mod.IntegerMod(self, 1)
def __init__(self, order, cache=None, category=None): """ Create with the command IntegerModRing(order) INPUT: - ``order`` - an integer 1 - ``category`` - a subcategory of ``CommutativeRings()`` (the default) (currently only available for subclasses) OUTPUT: - ``IntegerModRing`` - 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 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: 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() 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, category = Fields()) 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() Next we compute with the integers modulo `16`. :: sage: Z16 = IntegerModRing(16) sage: Z16.category() Join of Category of 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: 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() Saving and loading:: sage: R = Integers(100000) sage: 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 """ order = ZZ(order) if order <= 0: raise ZeroDivisionError, "order must be positive" self.__order = order self._pyx_order = integer_mod.NativeIntStruct(order) self.__unit_group_exponent = None self.__factored_order = None self.__factored_unit_order = None if category is None: from sage.categories.commutative_rings import CommutativeRings from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.category import Category category = Category.join( [CommutativeRings(), FiniteEnumeratedSets()]) # category = default_category # If the category is given then we trust that is it right. # Give the generator a 'name' to make quotients work. The # name 'x' is used because it's also used for the ring of # integers: see the __init__ method for IntegerRing_class in # sage/rings/integer_ring.pyx. quotient_ring.QuotientRing_generic.__init__(self, ZZ, ZZ.ideal(order), names=('x', ), category=category) # Calling ParentWithGens is not needed, the job is done in # the quotient ring initialisation. #ParentWithGens.__init__(self, self, category = category) # We want that the ring is its own base ring. self._base = self if cache is None: cache = order < 500 if cache: self._precompute_table() self._zero_element = integer_mod.IntegerMod(self, 0) self._one_element = integer_mod.IntegerMod(self, 1)