Ticket #7797: trac7797-letterplace_coercion.patch

File trac7797-letterplace_coercion.patch, 5.3 KB (added by SimonKing, 8 years ago)

Implementing coercion for letterplace algebras

  • sage/algebras/letterplace/free_algebra_letterplace.pyx

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1311780898 -7200
    # Node ID 1e0ef473808b672d9f8f95050d5d8b91f60582ef
    # Parent  f917ff51fe1d688cab1d0351483eab6117f59a56
    #7797: Coercion for free graded algebras in letterplace implementation
    
    diff --git a/sage/algebras/letterplace/free_algebra_letterplace.pyx b/sage/algebras/letterplace/free_algebra_letterplace.pyx
    a b  
    703703
    704704    ###########################
    705705    ## Coercion
    706     def _coerce_map_from_(self,S):
     706    cpdef _coerce_map_from_(self,S):
    707707        """
    708         There is only a coercion from the base ring.
     708        A ring ``R`` coerces into self, if
    709709
    710         TEST::
     710        - it coerces into the current polynomial ring, or
     711        - it is a free graded algebra in letterplace implementation,
     712          the generator names of ``R`` are a proper subset of the
     713          generator names of self, the degrees of equally named
     714          generators are equal, and the base ring of ``R`` coerces
     715          into the base ring of self.
     716
     717        TEST:
     718
     719        Coercion from the base ring::
    711720
    712721            sage: F.<x,y,z> = FreeAlgebra(GF(5), implementation='letterplace')
    713722            sage: 5 == F.zero()    # indirect doctest
    714723            True
    715724
     725        Coercion from another free graded algebra::
     726
     727            sage: F.<t,y,z> = FreeAlgebra(ZZ, implementation='letterplace', degrees=[4,2,3])
     728            sage: G = FreeAlgebra(GF(5), implementation='letterplace', names=['x','y','z','t'], degrees=[1,2,3,4])
     729            sage: t*G.0       # indirect doctest
     730            t*x
     731
    716732        """
    717         return self==S or self._current_ring.has_coerce_map_from(S)
     733        if self==S or self._current_ring.has_coerce_map_from(S):
     734            return True
     735        cdef int i
     736        # Do we have another letterplace algebra?
     737        if not isinstance(S, FreeAlgebra_letterplace):
     738            return False
     739        # Do the base rings coerce?
     740        if not self.base_ring().has_coerce_map_from(S.base_ring()):
     741            return False
     742        # Do the names match?
     743        cdef tuple degs, Sdegs, names, Snames
     744        names = self.variable_names()
     745        Snames = S.variable_names()
     746        if not set(names).issuperset(Snames):
     747            return False
     748        # Do the degrees match
     749        degs = self._degrees
     750        Sdegs = (<FreeAlgebra_letterplace>S)._degrees
     751        for i from 0<=i<S.ngens():
     752            if degs[names.index(Snames[i])] != Sdegs[i]:
     753                return False
     754        return True
    718755
    719756    def _an_element_(self):
    720757        """
     
    803840
    804841        INPUT:
    805842
    806         Something that can be interpreted in the polynomial ring that
    807         is used to implement the letterplace algebra out to the current
    808         degree bound, or a string that can be interpreted as an expression
    809         in the algebra (provided that the coefficients are numerical).
     843        An element of a free algebra with a proper subset of generator
     844        names, or anything that can be interpreted in the polynomial
     845        ring that is used to implement the letterplace algebra out to
     846        the current degree bound, or a string that can be interpreted
     847        as an expression in the algebra (provided that the
     848        coefficients are numerical).
    810849
    811850        EXAMPLE::
    812851
    813             sage: F.<x,y,z> = FreeAlgebra(GF(5), implementation='letterplace')
     852            sage: F.<t,y,z> = FreeAlgebra(ZZ, implementation='letterplace', degrees=[4,2,3])
     853
     854        Conversion of a number::
     855
    814856            sage: F(3)
    815857            3
    816             sage: F('x*z+3*y^2')
    817             x*z + (3)*y*y
     858
     859        Interpretation of a string as an algebra element::
     860
     861            sage: F('t*y+3*z^2')
     862            t*y + 3*z*z
     863
     864        Conversion from the currently underlying polynomial ring::
     865
    818866            sage: F.set_degbound(3)
    819867            sage: P = F.current_ring()
    820             sage: F(P.0*P.4*P.6-2*P.2*P.5*P.8)   # indirect doctest
    821             x*y*x + (3)*z*z*z
     868            sage: F(P.0*P.7*P.11*P.15*P.17*P.23 - 2*P.2*P.7*P.11*P.14*P.19*P.23)
     869            t*y - 2*z*z
     870
     871        Conversion from a graded sub-algebra::
     872
     873            sage: G = FreeAlgebra(GF(5), implementation='letterplace', names=['x','y','z','t'], degrees=[1,2,3,4])
     874            sage: G(t*y + 2*y^3 - 4*z^2)   # indirect doctest
     875            (2)*y*y*y + z*z + t*y
    822876
    823877        """
    824878        if isinstance(x, basestring):
     
    831885        if P is self:
    832886            (<FreeAlgebraElement_letterplace>x)._poly = self._current_ring((<FreeAlgebraElement_letterplace>x)._poly)
    833887            return x
     888        if isinstance(P, FreeAlgebra_letterplace):
     889            self.set_degbound(P.degbound())
     890            Ppoly = (<FreeAlgebra_letterplace>P)._current_ring
     891            Gens = self._current_ring.gens()
     892            Names = self._current_ring.variable_names()
     893            PNames = list(Ppoly.variable_names())
     894            # translate the slack variables
     895            PNames[P.ngens(): len(PNames): P.ngens()+1] = list(Names[self.ngens(): len(Names): self.ngens()+1])[:P.degbound()]
     896            x = Ppoly.hom([Gens[Names.index(asdf)] for asdf in PNames])(x.letterplace_polynomial())
    834897        return FreeAlgebraElement_letterplace(self,self._current_ring(x))
    835 
    836