def _element_constructor_(self, x): r""" Coerce ``x`` into the finite field. INPUT: - ``x`` -- object OUTPUT: If possible, makes a finite field element from ``x``. EXAMPLES:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: k = FiniteField_ext_pari(3^4, 'a') sage: b = k(5) # indirect doctest sage: b.parent() Finite Field in a of size 3^4 sage: a = k.gen() sage: k(a + 2) a + 2 Univariate polynomials coerce into finite fields by evaluating the polynomial at the field's generator:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: R.<x> = QQ[] sage: k, a = FiniteField_ext_pari(5^2, 'a').objgen() sage: k(R(2/3)) 4 sage: k(x^2) a + 3 sage: R.<x> = GF(5)[] sage: k(x^3-2*x+1) 2*a + 4 sage: x = polygen(QQ) sage: k(x^25) a sage: Q, q = FiniteField_ext_pari(5^7, 'q').objgen() sage: L = GF(5) sage: LL.<xx> = L[] sage: Q(xx^2 + 2*xx + 4) q^2 + 2*q + 4 Multivariate polynomials only coerce if constant:: sage: R = k['x,y,z']; R Multivariate Polynomial Ring in x, y, z over Finite Field in a of size 5^2 sage: k(R(2)) 2 sage: R = QQ['x,y,z'] sage: k(R(1/5)) Traceback (most recent call last): ... TypeError: unable to coerce Gap elements can also be coerced into finite fields:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: F = FiniteField_ext_pari(8, 'a') sage: a = F.multiplicative_generator(); a a sage: b = gap(a^3); b Z(2^3)^3 sage: F(b) a + 1 sage: a^3 a + 1 sage: a = GF(13)(gap('0*Z(13)')); a 0 sage: a.parent() Finite Field of size 13 sage: F = GF(16, 'a', impl='pari_mod') sage: F(gap('Z(16)^3')) a^3 sage: F(gap('Z(16)^2')) a^2 You can also call a finite extension field with a string to produce an element of that field, like this:: sage: k = GF(2^8, 'a', impl='pari_mod') sage: k('a^200') a^4 + a^3 + a^2 This is especially useful for fast conversions from Singular etc. to ``FiniteField_ext_pariElements``. AUTHORS: - David Joyner (2005-11) - Martin Albrecht (2006-01-23) - Martin Albrecht (2006-03-06): added coercion from string """ if isinstance(x, element_ext_pari.FiniteField_ext_pariElement): if x.parent() is self: return x elif x.parent() == self: # canonically isomorphic finite fields return element_ext_pari.FiniteField_ext_pariElement(self, x) else: # This is where we *would* do coercion from one finite field to another... raise TypeError, "no coercion defined" elif sage.interfaces.gap.is_GapElement(x): from sage.interfaces.gap import gfq_gap_to_sage try: return gfq_gap_to_sage(x, self) except (ValueError, IndexError, TypeError): raise TypeError, "no coercion defined" if isinstance(x, (int, long, integer.Integer, rational.Rational, pari.pari_gen, list)): return element_ext_pari.FiniteField_ext_pariElement(self, x) elif isinstance(x, multi_polynomial_element.MPolynomial): if x.is_constant(): return self(x.constant_coefficient()) else: raise TypeError, "no coercion defined" elif isinstance(x, polynomial_element.Polynomial): if x.is_constant(): return self(x.constant_coefficient()) else: return x.change_ring(self)(self.gen()) elif isinstance(x, str): x = x.replace(self.variable_name(),'a') x = pari.pari(x) t = x.type() if t == 't_POL': if (x.variable() == 'a' \ and x.polcoeff(0).type()[2] == 'I'): #t_INT and t_INTMOD return self(x) if t[2] == 'I': #t_INT and t_INTMOD return self(x) raise TypeError, "string element does not match this finite field" try: if x.parent() == self.vector_space(): x = pari.pari('+'.join(['%s*a^%s'%(x[i], i) for i in range(self.degree())])) return element_ext_pari.FiniteField_ext_pariElement(self, x) except AttributeError: pass try: return element_ext_pari.FiniteField_ext_pariElement(self, integer.Integer(x)) except TypeError, msg: raise TypeError, "%s\nno coercion defined"%msg
def __init__(self, q, name, modulus=None): """ Create finite field of order `q` with variable printed as name. EXAMPLES:: sage: k = FiniteField(9, 'a', impl='pari_mod'); k Finite Field in a of size 3^2 """ from sage.misc.superseded import deprecation deprecation( 17297, 'The "pari_mod" finite field implementation is deprecated') if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from finite_field_constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError("q must be a prime power") # note: the following call takes care of the fact that # proof.arithmetic() is True or False. p, n = q.is_prime_power(get_data=True) if n > 1: base_ring = GF(p) elif n == 0: raise ArithmeticError("q must be a prime power") else: raise ValueError("The size of the finite field must not be prime.") FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = p self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = n self.__order = q self.__is_field = True if not sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): from sage.misc.superseded import deprecation deprecation( 16930, "constructing a FiniteField_ext_pari without giving a polynomial as modulus is deprecated, use the more general FiniteField constructor instead" ) if modulus is None or modulus == "default": from conway_polynomials import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus, str): if modulus == "conway": from conway_polynomials import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree( ) == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.base_ring() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self._modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement( self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def __init__(self, q, name, modulus=None): """ Create finite field of order `q` with variable printed as name. EXAMPLES:: sage: from sage.rings.finite_rings.finite_field_ext_pari import FiniteField_ext_pari sage: k = FiniteField_ext_pari(9, 'a'); k Finite Field in a of size 3^2 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from conway_polynomials import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus,str): if modulus == "conway": from conway_polynomials import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree() == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement(self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)
def __init__(self, q, name, modulus=None): """ Create finite field of order q with variable printed as name. INPUT: - ``q`` -- integer, size of the finite field, not prime - ``name`` -- variable used for printing element of the finite field. Also, two finite fields are considered equal if they have the same variable name, and not otherwise. - ``modulus`` -- you may provide a polynomial to use for reduction or a string: 'conway': force the use of a Conway polynomial, will raise a RuntimeError if none is found in the database; 'random': use a random irreducible polynomial. 'default': a Conway polynomial is used if found. Otherwise a random polynomial is used. OUTPUT: - FiniteField_ext_pari -- a finite field of order q with given variable name. EXAMPLES:: sage: FiniteField(65537) Finite Field of size 65537 sage: FiniteField(2^20, 'c') Finite Field in c of size 2^20 sage: FiniteField(3^11, "b") Finite Field in b of size 3^11 sage: FiniteField(3^11, "b").gen() b You can also create a finite field using GF, which is a synonym for FiniteField. :: sage: GF(19^5, 'a') Finite Field in a of size 19^5 """ if element_ext_pari.dynamic_FiniteField_ext_pariElement is None: element_ext_pari._late_import() from constructor import FiniteField as GF q = integer.Integer(q) if q < 2: raise ArithmeticError, "q must be a prime power" from sage.structure.proof.all import arithmetic proof = arithmetic() if proof: F = q.factor() else: from sage.rings.arith import is_pseudoprime_small_power F = is_pseudoprime_small_power(q, get_data=True) if len(F) != 1: raise ArithmeticError, "q must be a prime power" if F[0][1] > 1: base_ring = GF(F[0][0]) else: raise ValueError, "The size of the finite field must not be prime." #base_ring = self FiniteField_generic.__init__(self, base_ring, name, normalize=True) self._kwargs = {} self.__char = F[0][0] self.__pari_one = pari.pari(1).Mod(self.__char) self.__degree = integer.Integer(F[0][1]) self.__order = q self.__is_field = True if modulus is None or modulus == "default": from constructor import exists_conway_polynomial if exists_conway_polynomial(self.__char, self.__degree): modulus = "conway" else: modulus = "random" if isinstance(modulus, str): if modulus == "conway": from constructor import conway_polynomial modulus = conway_polynomial(self.__char, self.__degree) elif modulus == "random": # The following is fast/deterministic, but has serious problems since # it crashes on 64-bit machines, and I can't figure out why: # self.__pari_modulus = pari.pari.finitefield_init(self.__char, self.__degree, self.variable_name()) # So instead we iterate through random polys until we find an irreducible one. R = GF(self.__char)['x'] while True: modulus = R.random_element(self.__degree) modulus = modulus.monic() if modulus.degree( ) == self.__degree and modulus.is_irreducible(): break else: raise ValueError("Modulus parameter not understood") elif isinstance(modulus, (list, tuple)): modulus = GF(self.__char)['x'](modulus) elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus): if modulus.parent() is not base_ring: modulus = modulus.change_ring(base_ring) else: raise ValueError("Modulus parameter not understood") self.__modulus = modulus f = pari.pari(str(modulus)) self.__pari_modulus = f.subst(modulus.parent().variable_name(), 'a') * self.__pari_one self.__gen = element_ext_pari.FiniteField_ext_pariElement( self, pari.pari('a')) self._zero_element = self._element_constructor_(0) self._one_element = self._element_constructor_(1)