Ticket #8335: trac_8335_sd51.patch

File trac_8335_sd51.patch, 35.6 KB (added by pbruin, 8 years ago)

to work on during Sage Days 51

  • sage/categories/pushout.py

    # HG changeset patch
    # User Peter Bruin <peter.bruin@math.uzh.ch>
    # Date 1374618061 -7200
    # Node ID 6b7dc03ff604c73152aeb22cdeb5eba17f8bbe45
    # Parent  c34bbb1813e6342c416fff2472043d9a8c2728b4
    Trac 8335: unified and rebased, to be worked on during Sage Days 51
    
    diff --git a/sage/categories/pushout.py b/sage/categories/pushout.py
    a b  
    22912291        ...
    22922292        TypeError: Could not find a mapping of the passed element to this ring.
    22932293    """
    2294     rank = 7
     2294    rank = 4.5
    22952295   
    22962296    def __init__(self, I, names=None, as_field=False):
    22972297        """
     
    23482348
    23492349        Note that the ``quo()`` method of a field used to return the
    23502350        integer zero. That strange behaviour was removed in trac
    2351         ticket #9138. It now returns a trivial quotient ring when
    2352         applied to a field::
     2351        ticket :trac:`9138`. It now returns a trivial quotient ring
     2352        when applied to a field::
    23532353
    23542354            sage: F = ZZ.quo([5]*ZZ).construction()[0]
    2355             sage: F(QQ) is Integers(1)
    2356             True
     2355            sage: F(QQ)
     2356            Ring of integers modulo 1
    23572357            sage: QQ.quo(5)
    23582358            Quotient of Rational Field by the ideal (1)
    2359 
    23602359        """
    23612360        I = self.I
    23622361        from sage.all import QQ
     
    24932492    """
    24942493    rank = 3
    24952494   
    2496     def __init__(self, polys, names, embeddings, cyclotomic=None):
     2495    def __init__(self, polys, names, embeddings, cyclotomic=None, conway=None, prefix=None):
    24972496        """
    24982497        INPUT:
    24992498
    2500         - ``polys``: a list of polynomials
     2499        - ``polys``: a list of polynomials (or of integers, for
     2500          finite fields and unramified local extensions)
    25012501        - ``names``: a list of strings of the same length as the
    25022502          list ``polys``
    25032503        - ``embeddings``: a list of approximate complex values,
     
    25072507        - ``cyclotomic``: optional integer. If it is provided,
    25082508          application of the functor to the rational field yields
    25092509          a cyclotomic field, rather than just a number field.
     2510        - ``conway``: optional integer. If it is provided,
     2511          application of the functor to finite fields yields
     2512          pseudo-Conway extensions of the given degree.
     2513        - ``prefix``: optional string.  If it is provided, it will
     2514          allow application of this functor to some finite fields to
     2515          function without providing a variable name
    25102516
    25112517        REMARK:
    25122518
     
    25712577        self.names = list(names)
    25722578        self.embeddings = list(embeddings)
    25732579        self.cyclotomic = int(cyclotomic) if cyclotomic is not None else None
     2580        from sage.rings.integer import Integer
     2581        self.conway = Integer(conway) if conway is not None else None
     2582        self.prefix = prefix
    25742583
    25752584    def _apply_functor(self, R):
    25762585        """
     
    25882597            Univariate Quotient Polynomial Ring in a over Real Field with 53 bits of precision with modulus a^3 + a^2 + 1.00000000000000
    25892598        """
    25902599        from sage.all import QQ, ZZ, CyclotomicField
     2600        from sage.rings.finite_rings.finite_field_base import is_FiniteField
    25912601        if self.cyclotomic:
    25922602            if R==QQ:
    25932603                return CyclotomicField(self.cyclotomic)
    25942604            if R==ZZ:
    25952605                return CyclotomicField(self.cyclotomic).maximal_order()
    2596         if len(self.polys) == 1:
    2597             return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0])
     2606        if len(self.polys) == 1 or self.conway is not None:
     2607            if is_FiniteField(R):
     2608                if self.conway is not None:
     2609                    return R.extension(self.conway, self.names[0], embedding=self.embeddings[0], prefix=self.prefix)
     2610                else:
     2611                    return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0], prefix=self.prefix)
     2612            else:
     2613                return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0])
    25982614        return R.extension(self.polys, self.names, embedding=self.embeddings)
    25992615
    26002616    def __cmp__(self, other):
     
    26332649          associated with the pushout of the codomains
    26342650          of the two embeddings is returned, provided that
    26352651          it is a number field.
     2652        - If these two extensions are defined by Conway polynomials over finite fields
     2653          (indicated by the fact that their ``conway`` fields are integers and not None),
     2654          merges them into a single extension of degree the lcm of the two degrees.
    26362655        - Otherwise, None is returned.
    2637          
     2656
    26382657        REMARK:
    26392658
    26402659        Algebraic extension with embeddings currently only
     
    26422661        why we use the admittedly strange rule above for
    26432662        merging.
    26442663
    2645         TESTS::
     2664        EXAMPLES:
     2665
     2666        The following demonstrate coercions for finite fields using Conway or
     2667        pseudo-Conway polynomials::
     2668
     2669            sage: k = GF(3^2); a = k.gen()
     2670            sage: l = GF(3^3); b = l.gen()
     2671            sage: a + b # indirect doctest
     2672            z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 1
     2673
     2674        Note that embeddings are compatible in lattices of such finite fields::
     2675
     2676            sage: m = GF(3^5); c = m.gen()
     2677            sage: (a+b)+c == a+(b+c) # indirect doctest
     2678            True
     2679            sage: from sage.categories.pushout import pushout
     2680            sage: n = pushout(k, l)
     2681            sage: o = pushout(l, m)
     2682            sage: q = pushout(n, o)
     2683            sage: q(o(b)) == q(n(b)) # indirect doctest
     2684            True
     2685
     2686        Coercion is also available for number fields::
    26462687
    26472688            sage: P.<x> = QQ[]
    26482689            sage: L.<b> = NumberField(x^8-x^4+1, embedding=CDF.0)
     
    26532694            sage: c1+c2; parent(c1+c2)    #indirect doctest
    26542695            -b^6 + b^4 - 1
    26552696            Number Field in b with defining polynomial x^8 - x^4 + 1
    2656             sage: from sage.categories.pushout import pushout
    26572697            sage: pushout(M1['x'],M2['x'])
    26582698            Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^8 - x^4 + 1
    26592699
     
    26732713            CoercionException: ('Ambiguous Base Extension', Number Field in a with defining polynomial x^3 - 2, Number Field in b with defining polynomial x^6 - 2)
    26742714
    26752715        """
    2676         if not isinstance(other,AlgebraicExtensionFunctor):
     2716        if isinstance(other, AlgebraicClosureFunctor):
     2717            return other
     2718        elif not isinstance(other,AlgebraicExtensionFunctor):
    26772719            return None
    26782720        if self == other:
    26792721            return self
     
    26932735#                return self
    26942736#            if  other.embeddings==[None]:
    26952737#                return other
    2696         # ... or we may use the given embeddings:
     2738        # ... or we may use the given embeddings
     2739        from sage.rings.integer import Integer
     2740        # finite fields use an Integer to encode the pseudo-Conway extension that allows pushouts
     2741        if isinstance(self.conway, Integer) and isinstance(other.conway, Integer) and self.prefix is not None and self.prefix == other.prefix:
     2742            if self.embeddings != [None] or other.embeddings != [None]:
     2743                raise NotImplementedError
     2744            polys = self.polys+other.polys
     2745            return AlgebraicExtensionFunctor(polys,[None]*len(polys),[None]*len(polys),conway=self.conway.lcm(other.conway),prefix=self.prefix)
    26972746        if self.embeddings!=[None] and other.embeddings!=[None]:
    26982747            from sage.all import QQ
    26992748            KS = self(QQ)
     
    27652814        """
    27662815        if len(self.polys)==1:
    27672816            return [self]
    2768         return [AlgebraicExtensionFunctor([self.polys[i]], [self.names[i]], [self.embeddings[i]]) for i in range(len(self.polys))]
     2817        return [AlgebraicExtensionFunctor([self.polys[i]], [self.names[i]], [self.embeddings[i]], conway=[self.polys[i].degree()] if self.conway is not None else None, prefix=self.prefix) for i in range(len(self.polys))]
    27692818
    27702819class AlgebraicClosureFunctor(ConstructionFunctor):
    27712820    """
     
    30903139    S_tower = construction_tower(S)
    30913140    Rs = [c[1] for c in R_tower]
    30923141    Ss = [c[1] for c in S_tower]
    3093    
     3142
    30943143    if R in Ss:
    30953144        return S
    30963145    elif S in Rs:
    30973146        return R
    30983147   
    3099     if R_tower[-1][1] in Ss:
     3148    if Rs[-1] in Ss:
    31003149        Rs, Ss = Ss, Rs
    31013150        R_tower, S_tower = S_tower, R_tower
    31023151   
  • sage/interfaces/singular.py

    diff --git a/sage/interfaces/singular.py b/sage/interfaces/singular.py
    a b  
    14351435            sage: singular.eval('minpoly = 1+z+z2+z3+z4')
    14361436            'minpoly = 1+z+z2+z3+z4;'
    14371437            sage: singular('r3').sage_global_ring()
    1438             Multivariate Polynomial Ring in a, b, c over Univariate Quotient Polynomial Ring in z over Finite Field of size 3 with modulus z^4 + z^3 + z^2 + z + 1
     1438            Multivariate Polynomial Ring in a, b, c over Finite Field in z of size 3^4
    14391439
    14401440        Real and complex fields in both Singular and Sage are defined with a precision.
    14411441        The precision in Singular is given in terms of digits, but in Sage it is given
     
    15221522                    singular.eval('short=%s'%is_short)
    15231523                else:
    15241524                    minpoly = ZZ[charstr[1]](minpoly)
    1525                 BR = br.extension(minpoly)
     1525                BR = br.extension(minpoly,name=charstr[1])
    15261526        else:
    15271527            BR = br
    15281528       
     
    15851585            'minpoly = 1+z+z2+z3+z4;'
    15861586            sage: p = singular('z^4*a^3+z^2*a*b*c')
    15871587            sage: p.sage_poly()
    1588             (2*z^3 + 2*z^2 + 2*z + 2)*a^3 + z^2*a*b*c
     1588            (-z^3 - z^2 - z - 1)*a^3 + (z^2)*a*b*c
    15891589            sage: singular('z^4')
    15901590            (-z3-z2-z-1)
    15911591
  • sage/rings/finite_rings/constructor.py

    diff --git a/sage/rings/finite_rings/constructor.py b/sage/rings/finite_rings/constructor.py
    a b  
    321321        sage: a
    322322        2
    323323
     324    The following demonstrate coercions for finite fields using Conway
     325    or pseudo-Conway polynomials::
     326
     327        sage: k = GF(5^2); a = k.gen()
     328        sage: l = GF(5^5); b = l.gen()
     329        sage: a + b
     330        3*z10^5 + z10^4 + z10^2 + 3*z10 + 1
     331
     332    Note that embeddings are compatible in lattices of such finite
     333    fields::
     334
     335        sage: m = GF(5^3); c = m.gen()
     336        sage: (a+b)+c == a+(b+c)
     337        True
     338        sage: (a*b)*c == a*(b*c)
     339        True
     340        sage: from sage.categories.pushout import pushout
     341        sage: n = pushout(k, l)
     342        sage: o = pushout(l, m)
     343        sage: q = pushout(n, o)
     344        sage: q(o(b)) == q(n(b))
     345        True
     346
     347    Another check that embeddings are defined properly::
     348
     349        sage: k = GF(3**10)
     350        sage: l = GF(3**20)
     351        sage: l(k.gen()**10) == l(k.gen())**10
     352        True
    324353    """
    325354    def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
    326355                                  impl=None, proof=None, **kwds):
    327356        """
    328357        EXAMPLES::
    329        
     358
    330359            sage: GF.create_key_and_extra_args(9, 'a')
    331360            ((9, ('a',), x^2 + 2*x + 2, None, '{}', 3, 2, True), {})
    332361            sage: GF.create_key_and_extra_args(9, 'a', foo='value')
  • sage/rings/finite_rings/element_base.pyx

    diff --git a/sage/rings/finite_rings/element_base.pyx b/sage/rings/finite_rings/element_base.pyx
    a b  
    3232cdef class FiniteRingElement(CommutativeRingElement):
    3333    def _nth_root_common(self, n, all, algorithm, cunningham):
    3434        """
    35         This function exists to reduce code duplication between finite field nth roots and integer_mod nth roots.
    36        
     35        This function exists to reduce code duplication between finite field
     36        nth roots and integer_mod nth roots.
     37
    3738        The inputs are described there.
    38        
     39
    3940        TESTS::
    40        
     41
    4142            sage: a = Zmod(17)(13)
    4243            sage: a._nth_root_common(4, True, "Johnston", False)
    4344            [3, 5, 14, 12]
     
    545546        - ``all`` - bool (default: ``False``); if ``True``, return all `n`\th
    546547          roots of ``self``, instead of just one.
    547548
    548         - ``algorithm`` - string (default: ``None``); 'Johnston' is the only 
     549        - ``algorithm`` - string (default: ``None``); 'Johnston' is the only
    549550          currently supported option.  For IntegerMod elements, the problem
    550551          is reduced to the prime modulus case using CRT and `p`-adic logs,
    551552          and then this algorithm used.
     
    553554        OUTPUT:
    554555
    555556        If self has an `n`\th root, returns one (if ``all`` is ``False``) or a
    556         list of all of them (if ``all`` is ``True``).  Otherwise, raises a
    557         ValueError (if ``extend`` is ``False``) or a ``NotImplementedError`` (if
    558         ``extend`` is ``True``).
     557        list of all of them (if ``all`` is ``True``).
     558        Otherwise, raises a ``ValueError`` (if ``extend`` is ``False``)
     559        or a ``NotImplementedError`` (if ``extend`` is ``True``).
    559560
    560561        .. warning::
    561        
    562            The 'extend' option is not implemented (yet).
     562
     563           The ``extend`` option is not implemented (yet).
    563564
    564565        EXAMPLES::
    565566
  • sage/rings/finite_rings/element_ntl_gf2e.pyx

    diff --git a/sage/rings/finite_rings/element_ntl_gf2e.pyx b/sage/rings/finite_rings/element_ntl_gf2e.pyx
    a b  
    10931093            sage: g = K.random_element()
    10941094            sage: g.minpoly()(g)
    10951095            0
     1096
     1097        We check that the NTL modulus is restored properly::
     1098
     1099            sage: k.<a> = GF(2^1000)
     1100            sage: b = a^(k.order()//(2^20-1))
     1101            sage: l.<c> = GF(2^20)
     1102            sage: b.minpoly()
     1103            x^20 + x^17 + x^16 + x^14 + x^13 + x^11 + x^8 + x^7 + x^3 + x + 1
    10961104        """
    10971105        (<Cache_ntl_gf2e>self._parent._cache).F.restore()
    10981106        cdef GF2X_c r = GF2X_IrredPolyMod(GF2E_rep(self.x), GF2E_modulus())
  • sage/rings/finite_rings/finite_field_base.pyx

    diff --git a/sage/rings/finite_rings/finite_field_base.pyx b/sage/rings/finite_rings/finite_field_base.pyx
    a b  
    321321            ...
    322322            TypeError: images do not define a valid homomorphism           
    323323        """
    324 
    325324        if (self.characteristic() != codomain.characteristic()):
    326325            raise ValueError, "no map from %s to %s"%(self, codomain)
    327326        if (len(im_gens) != 1):
     
    551550            [2^4 * 3]
    552551        """
    553552        if self.__factored_unit_order is None:
    554             if self.characteristic() in []: # want to be [2,3,5,7,11] once #7240 is finished.
    555                 from sage.rings.factorint import factor_cunningham
    556                 self.__factored_unit_order = [factor_cunningham(self.order()-1)]
    557             else:
    558                 self.__factored_unit_order = [(self.order()-1).factor()]
     553            self.__factored_unit_order = [(self.order()-1).factor()]
    559554        return self.__factored_unit_order
    560555
    561556    def cardinality(self):
     
    746741        """
    747742        return hash("GF") + hash(self.order())
    748743
     744    def construction(self):
     745        """
     746        Return the construction of this finite field, as a ``ConstructionFunctor``
     747        and the base field.
     748
     749        EXAMPLES::
     750
     751            sage: v = GF(3^3).construction(); v
     752            (AlgebraicExtensionFunctor, Finite Field of size 3)
     753            sage: v[0].polys[0]
     754            z3^3 + 2*z3 + 1
     755            sage: v = GF(2^1000,'a').construction(); v[0].polys[0]
     756            a^1000 + a^5 + a^4 + a^3 + 1
     757        """
     758        from sage.categories.pushout import AlgebraicExtensionFunctor
     759        if self.degree() == 1:
     760            # this is not of type FiniteField_prime_modn
     761            from sage.rings.integer import Integer
     762            return AlgebraicExtensionFunctor([self.polynomial()],[None],[None],conway=1), self.base_ring()
     763        elif hasattr(self, '_PCPT') and self._PCPT is not None:
     764            return AlgebraicExtensionFunctor([self.polynomial()],[self.variable_name()],[None],conway=self.degree(),prefix=self._prefix), self.base_ring()
     765        else:
     766            return AlgebraicExtensionFunctor([self.polynomial()],[self.variable_name()],[None]), self.base_ring()
     767
     768    def extension(self, modulus, name=None, names=None, embedding=None, conway=None, prefix='z'):
     769        """
     770        Return an extension of this finite field.
     771
     772        INPUT:
     773
     774        - ``modulus`` -- either a polynomial with coefficients in this field or
     775          an integer.
     776          If an Integer, returns the pseudo-Conway extension of this field of
     777          that degree.
     778
     779        - ``name`` -- the name of the generator in the new extension
     780
     781        - ``embedding`` -- currently not used; for compatibility with other
     782          ``AlgebraicExtensionFunctor`` calls.
     783
     784        - ``conway`` -- currently not used; None or an ``Integer`` used to indicate
     785          that the extension is pseudo-Conway of the given degree.
     786
     787        - ``prefix`` -- Passed on to the finite field constructor.
     788          See the documentation of ``GF`` in ``sage.rings.finite_rings.constructor``
     789
     790        OUTPUT:
     791
     792        An extension of the given modulus, or pseudo-Conway of the given degree
     793        if ``conway`` is an integer.
     794
     795        EXAMPLES::
     796
     797            sage: k = GF(2)
     798            sage: R.<x> = k[]
     799            sage: k.extension(x^1000 + x^5 + x^4 + x^3 + 1, 'a')
     800            Finite Field in a of size 2^1000
     801            sage: k = GF(3^4)
     802            sage: R.<x> = k[]
     803            sage: k.extension(3)
     804            Finite Field in z12 of size 3^12
     805
     806        Extensions of non-prime finite fields by polynomials are not yet
     807        supported: we fall back to generic code::
     808
     809            sage: k.extension(x^5 + x^2 + x - 1)
     810            Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2
     811        """
     812        from constructor import GF
     813        from sage.rings.polynomial.all import is_Polynomial
     814        from sage.rings.integer import Integer
     815        if name is None and names is not None:
     816            name = names
     817        if self.degree() == 1:
     818            if isinstance(modulus, Integer):
     819                return GF(self.characteristic()**modulus, modulus='conway', name=name, prefix=prefix)
     820            elif isinstance(modulus, (list, tuple)):
     821                return GF(self.characteristic()**(len(modulus) - 1), name=name, modulus=modulus, prefix=prefix)
     822            elif is_Polynomial(modulus):
     823                if modulus.change_ring(self).is_irreducible():
     824                    return GF(self.characteristic()**(modulus.degree()), name=name, modulus=modulus, prefix=prefix)
     825                else:
     826                    return Field.extension(self, modulus, name=name, embedding=embedding)
     827        elif isinstance(modulus, Integer):
     828            if hasattr(self, '_PCPT') and self._PCPT is not None:
     829                return GF(self.order()**modulus, name=name, prefix=prefix)
     830        return Field.extension(self, modulus, name=name, embedding=embedding)
     831
     832    def subfields(self, degree=0, name=None):
     833        """
     834        Return all proper subfields of ``self`` of the given ``degree``,
     835        or of all possible degrees if ``degree`` is `0`.
     836
     837        The subfields are returned as absolute fields together with
     838        an embedding into ``self``.
     839
     840        INPUT:
     841
     842        - ``degree`` -- (default: `0`) an integer
     843
     844        - ``name`` -- a string, a dictionary or ``None``:
     845
     846          - If ``degree`` is nonzero, ``name`` must be a string
     847            (or ``None``, if this is a pseudo-Conway extension),
     848            and will be the variable name of the returned field.
     849          - If ``degree`` is zero, the dictionary should have keys the divisors
     850            of the degree of this field, with the desired variable name for the
     851            field of that degree as an entry.
     852          - As a shortcut, you can provide a string and the degree of each
     853            subfield will be appended for the variable name of that subfield.
     854          - If ``None``, uses the prefix of this field.
     855
     856        OUTPUT:
     857
     858        A list of pairs ``(K, e)``, where ``K`` ranges over the subfields of
     859        this field and ``e`` gives an embedding of ``K`` into this field.
     860
     861        EXAMPLES::
     862
     863            sage: k.<a> = GF(2^21)
     864            sage: k.subfields()
     865            [(Finite Field of size 2,
     866              Conversion map:
     867                  From: Finite Field of size 2
     868                  To:   Finite Field in a of size 2^21),
     869             (Finite Field in z3 of size 2^3,
     870              Ring morphism:
     871                  From: Finite Field in z3 of size 2^3
     872                  To:   Finite Field in a of size 2^21
     873                  Defn: z3 |--> a^20 + a^19 + a^17 + a^15 + a^11 + a^9 + a^8 + a^6 + a^2),
     874             (Finite Field in z7 of size 2^7,
     875              Ring morphism:
     876                  From: Finite Field in z7 of size 2^7
     877                  To:   Finite Field in a of size 2^21
     878                  Defn: z7 |--> a^20 + a^19 + a^17 + a^15 + a^14 + a^6 + a^4 + a^3 + a)]
     879        """
     880        from sage.rings.integer import Integer
     881        from constructor import GF
     882        p = self.characteristic()
     883        if degree != 0:
     884            degree = Integer(degree)
     885            if degree.divides(self.degree()):
     886                if hasattr(self, '_PCPT') and self._PCPT is not None:
     887                    K = GF(p**degree, name=name, prefix=self._prefix)
     888                    return [K, self.coerce_map_from(K)]
     889                elif degree == 1:
     890                    K = GF(p)
     891                    return [K, self.coerce_map_from(K)]
     892                else:
     893                    deg_gen = self.multiplicative_generator()**((self.order() - 1)//(p**degree-1))
     894                    from homset import FiniteFieldHomset, FiniteFieldHomomorphism_im_gens
     895                    K = GF(p**degree, modulus=deg_gen.minimal_polynomial(), name=name, prefix=self._prefix)
     896                    return [K, FiniteFieldHomomorphism_im_gens(FiniteFieldHomset(K, self), deg_gen)]
     897            else:
     898                return []
     899        if hasattr(self, '_PCPT') and self._PCPT is not None:
     900            if name is None:
     901                name = self._prefix
     902        else:
     903            if isinstance(name, str):
     904                prefix = name
     905                name = {}
     906            else:
     907                if self._prefix is None:
     908                    prefix = self.variable_name()
     909                else:
     910                    prefix = self._prefix
     911                if name is None:
     912                    name = {}
     913                elif not isinstance(name, dict):
     914                    raise ValueError, "name must be None, a string or a dictionary indexed by divisors of the degree"
     915            for m in self.degree().divisors():
     916                name[m] = prefix + str(m)
     917        ans = []
     918        from homset import FiniteFieldHomset, FiniteFieldHomomorphism_im_gens
     919        for m in self.degree().divisors():
     920            if m == self.degree(): continue
     921            if hasattr(self, '_PCPT') and self._PCPT is not None:
     922                K = GF(p**m, prefix=name)
     923                ans.append((K, self.coerce_map_from(K)))
     924            elif m == 1:
     925                ans.append((GF(p), self.coerce_map_from(K)))
     926            else:
     927                deg_gen = self.multiplicative_generator()**((self.order() - 1)//(p**m-1))
     928                K = GF(p**m, modulus=deg_gen.minimal_polynomial(), name=name[m])
     929                print K
     930                ans.append((K, FiniteFieldHomomorphism_im_gens(FiniteFieldHomset(K, self), deg_gen)))
     931        return ans
     932
    749933    def algebraic_closure(self):
    750934        """
    751935        Return the algebraic closure of ``self`` (not implemented).
     
    755939           This is not yet implemented for finite fields.
    756940
    757941        EXAMPLES::
    758        
     942
    759943            sage: GF(5).algebraic_closure()
    760944            Traceback (most recent call last):
    761945            ...
     
    799983    r"""
    800984    Used to unpickle finite prime fields. Now superseded (hence no doctest),
    801985    but kept around for backward compatibility.
    802    
     986
    803987    EXAMPLE::
    804988
    805989        sage: # not tested
     
    8261010        False
    8271011    """
    8281012    return IS_INSTANCE(x, FiniteField)
    829 
  • sage/rings/finite_rings/finite_field_ext_pari.py

    diff --git a/sage/rings/finite_rings/finite_field_ext_pari.py b/sage/rings/finite_rings/finite_field_ext_pari.py
    a b  
    593593            ...
    594594            TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^3
    595595            sage: FiniteField_ext_pari(16,'a')._coerce_(FiniteField_ext_pari(4,'a').0)
    596             Traceback (most recent call last):
    597             ...
    598             TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^4
     596            a^2 + a
    599597            sage: k = FiniteField_ext_pari(8,'a')
    600598            sage: k._coerce_(FiniteField(7,'a')(2))
    601599            Traceback (most recent call last):
     
    603601            TypeError: no canonical coercion from Finite Field of size 7 to Finite Field in a of size 2^3
    604602        """
    605603        from sage.rings.integer_ring import ZZ
     604        from sage.rings.finite_rings.finite_field_base import is_FiniteField
    606605        from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic
    607606        if R is int or R is long or R is ZZ:
    608607            return True
    609         if isinstance(R, FiniteField_ext_pari):
     608        if is_FiniteField(R):
    610609            if R is self:
    611610                return True
     611            from sage.rings.residue_field import ResidueField_generic
     612            if isinstance(R, ResidueField_generic):
     613                return False
    612614            if R.characteristic() == self.characteristic():
     615                if isinstance(R, IntegerModRing_generic):
     616                    return True
    613617                if R.degree() == 1:
    614618                    return True
    615                 elif self.degree() % R.degree() == 0:
    616                     # TODO: This is where we *would* do coercion from one nontrivial finite field to another...
    617                     return False               
    618         from sage.rings.residue_field import ResidueField_generic
    619         if isinstance(R, IntegerModRing_generic) and R.characteristic() == self.characteristic() and not isinstance(R, ResidueField_generic):
    620             return True
     619                if self.degree() % R.degree() == 0:
     620                    if hasattr(self, '_PCPT') and hasattr(R, '_PCPT') and R._PCPT is not None:
     621                        from homset import FiniteFieldHomset, FiniteFieldHomomorphism_im_gens
     622                        return FiniteFieldHomomorphism_im_gens(FiniteFieldHomset(R, self), self.gen()**((self.order()-1)//(R.order()-1)))
    621623
    622624    def __len__(self):
    623625        """
  • sage/rings/finite_rings/finite_field_givaro.py

    diff --git a/sage/rings/finite_rings/finite_field_givaro.py b/sage/rings/finite_rings/finite_field_givaro.py
    a b  
    353353            sage: F9 = FiniteField_givaro(9)
    354354            sage: F81 = FiniteField_givaro(81)
    355355            sage: F81(F9.gen())
    356             Traceback (most recent call last):
    357             ...
    358             TypeError: unable to coerce from a finite field other than the prime subfield
     356            2*a^3 + 2*a^2 + 1
    359357        """
    360358        return self._cache.element_from_data(e)
    361359
     
    389387                    return True
    390388                if R.degree() == 1:
    391389                    return True
    392                 elif self.degree() % R.degree() == 0:
    393                     # This is where we *would* do coercion from one nontrivial finite field to another...
    394                     # We use this error message for backward compatibility until #8335 is finished
    395                     raise TypeError, "unable to coerce from a finite field other than the prime subfield"
     390                if self.degree() % R.degree() == 0:
     391                    if hasattr(self, '_PCPT') and hasattr(R, '_PCPT') and R._PCPT is not None:
     392                        from homset import FiniteFieldHomset, FiniteFieldHomomorphism_im_gens
     393                        return FiniteFieldHomomorphism_im_gens(FiniteFieldHomset(R, self), self.gen()**((self.order()-1)//(R.order()-1)))
    396394
    397395    def gen(self, n=0):
    398396        r"""
  • sage/rings/finite_rings/finite_field_ntl_gf2e.py

    diff --git a/sage/rings/finite_rings/finite_field_ntl_gf2e.py b/sage/rings/finite_rings/finite_field_ntl_gf2e.py
    a b  
    253253                return True
    254254            if isinstance(R, ResidueField_generic):
    255255                return False
    256             if isinstance(R, IntegerModRing_generic) and R.characteristic() % 2 == 0:
    257                 return True
    258256            if R.characteristic() == 2:
     257                if isinstance(R, IntegerModRing_generic):
     258                    return True
    259259                if R.degree() == 1:
    260260                    return True
    261261                elif self.degree() % R.degree() == 0:
    262                     # This is where we *would* do coercion from one nontrivial finite field to another...
    263                     raise NotImplementedError
     262                    if self._PCPT is not None and hasattr(R, '_PCPT') and R._PCPT is not None:
     263                        from homset import FiniteFieldHomset, FiniteFieldHomomorphism_im_gens
     264                        return FiniteFieldHomomorphism_im_gens(FiniteFieldHomset(R, self), self.gen()**((self.order()-1)//(R.order()-1)))
    264265
    265266    def gen(self, ignored=None):
    266267        r"""
  • sage/rings/finite_rings/finite_field_prime_modn.py

    diff --git a/sage/rings/finite_rings/finite_field_prime_modn.py b/sage/rings/finite_rings/finite_field_prime_modn.py
    a b  
    189189        if to_ZZ is not None:
    190190            return integer_mod.Integer_to_IntegerMod(self) * to_ZZ
    191191
     192    def construction(self):
     193        """
     194        Returns the construction of this finite field (for use by sage.categories.pushout)
     195
     196        EXAMPLES::
     197
     198            sage: GF(3).construction()
     199            (QuotientFunctor, Integer Ring)
     200        """
     201        return integer_mod_ring.IntegerModRing_generic.construction(self)
     202
    192203    def characteristic(self):
    193204        r"""
    194205        Return the characteristic of \code{self}.
  • sage/rings/finite_rings/homset.py

    diff --git a/sage/rings/finite_rings/homset.py b/sage/rings/finite_rings/homset.py
    a b  
    4444    """
    4545    Set of homomorphisms with domain a given finite field.
    4646    """
     47#     def __init__(self, R, S, category=None):
     48#         if category is None:
     49#             from sage.categories.finite_fields import FiniteFields
     50#             category = FiniteFields()
     51#         RingHomset_generic.__init__(self, R, S, category)
     52
    4753    def __call__(self, im_gens, check=True):
    4854        """
    4955        Construct the homomorphism defined by ``im_gens``.
  • sage/rings/finite_rings/integer_mod.pyx

    diff --git a/sage/rings/finite_rings/integer_mod.pyx b/sage/rings/finite_rings/integer_mod.pyx
    a b  
    21522152        IntegerMod_abstract.__init__(self, parent)
    21532153        if empty:
    21542154            return
     2155        if self.__modulus.int32 == 1:
     2156            self.ivalue = 0
     2157            return
    21552158        cdef long x
    21562159        if PY_TYPE_CHECK(value, int):
    21572160            x = value
  • sage/rings/finite_rings/integer_mod_ring.py

    diff --git a/sage/rings/finite_rings/integer_mod_ring.py b/sage/rings/finite_rings/integer_mod_ring.py
    a b  
    395395        """
    396396        return True
    397397
     398    def extension(self, poly, name=None, names=None, embedding=None):
     399        if self.modulus() == 1:
     400            return self
     401        else:
     402            from sage.rings.ring import CommutativeRing
     403            return CommutativeRing.extension(self, poly, name, names, embedding)
     404
    398405    @cached_method
    399406    def is_prime_field(self):
    400407        """
  • sage/rings/polynomial/polynomial_quotient_ring.py

    diff --git a/sage/rings/polynomial/polynomial_quotient_ring.py b/sage/rings/polynomial/polynomial_quotient_ring.py
    a b  
    5353    -  ``ring`` - a univariate polynomial ring in one
    5454       variable.
    5555   
    56     -  ``polynomial`` - element
     56    -  ``polynomial`` - element with unit leading coefficient
    5757   
    5858    -  ``names`` - (optional) name for the variable
    5959   
  • sage/rings/polynomial/polynomial_quotient_ring_element.py

    diff --git a/sage/rings/polynomial/polynomial_quotient_ring_element.py b/sage/rings/polynomial/polynomial_quotient_ring_element.py
    a b  
    130130                raise TypeError, "polynomial must be in the polynomial ring of the parent"
    131131
    132132        f = parent.modulus()
    133         if polynomial.degree() >= f.degree():
     133        if polynomial.degree() >= f.degree() and polynomial.degree() >= 0:
    134134            try:
    135135                polynomial %= f
    136136            except AttributeError:
     
    143143                while R.degree() >= B.degree():
    144144                    S = P((R.leading_coefficient()/B.leading_coefficient())) * X**(R.degree()-B.degree())
    145145                    Q = Q + S
    146                     R = R - S*B           
     146                    R = R - S*B
    147147                polynomial = R
    148148        self._polynomial = polynomial
    149149
  • sage/rings/polynomial/polynomial_ring.py

    diff --git a/sage/rings/polynomial/polynomial_ring.py b/sage/rings/polynomial/polynomial_ring.py
    a b  
    181181from polynomial_real_mpfr_dense import PolynomialRealDense
    182182from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr
    183183from sage.rings.fraction_field_element import FractionFieldElement
     184from sage.rings.finite_rings.element_base import FiniteRingElement
    184185
    185186from polynomial_element import PolynomialBaseringInjection
    186187
     
    417418                x = x.numerator() * x.denominator().inverse_of_unit()
    418419            else:
    419420                raise TypeError, "denominator must be a unit"
    420            
    421421        elif isinstance(x, pari_gen):
    422422            if x.type() == 't_RFRAC':
    423423                raise TypeError, "denominator must be a unit"
    424424            if x.type() != 't_POL':
    425425                x = x.Polrev()
     426        elif isinstance(x, FiniteRingElement):
     427            try:
     428                return self(x.polynomial())
     429            except AttributeError:
     430                pass
    426431        return C(self, x, check, is_gen, construct=construct, **kwds)
    427432
    428433    def is_integral_domain(self, proof = True):
  • sage/sets/set.py

    diff --git a/sage/sets/set.py b/sage/sets/set.py
    a b  
    401401            sage: Set(GF(2)) + Set(GF(4,'a'))
    402402            {0, 1, a, a + 1}
    403403            sage: Set(GF(8,'b')) + Set(GF(4,'a'))
    404             {0, 1, b, b + 1, b^2, b^2 + 1, b^2 + b, b^2 + b + 1, a, a + 1, 1, 0}
     404            {0, 1, b, b + 1, b^2, b^2 + 1, b^2 + b, b^2 + b + 1, a, a + 1}
    405405        """
    406406        return self.union(X)
    407407
     
    436436
    437437            sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'c')))
    438438            sage: X
    439             {}
     439            {0, 1, 2}
    440440
    441441            sage: X = Set(GF(9,'b')).intersection(Set(GF(27,'b')))
    442442            sage: X
    443             {}
     443            {0, 1, 2}
    444444        """
    445445        if is_Set(X):
    446446            if self is X:
     
    466466
    467467            sage: X = Set(GF(9,'b')).difference(Set(GF(27,'c')))
    468468            sage: X
    469             {0, 1, 2, b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2}
     469            {b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2}
    470470
    471471            sage: X = Set(GF(9,'b')).difference(Set(GF(27,'b')))
    472472            sage: X
    473             {0, 1, 2, b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2}
     473            {b, b + 1, b + 2, 2*b, 2*b + 1, 2*b + 2}
    474474        """
    475475        if is_Set(X):
    476476            if self is X: