Ticket #11726: trac_11726-univariate_Laurent_polynomials-ts.patch

File trac_11726-univariate_Laurent_polynomials-ts.patch, 88.5 KB (added by tscrim, 8 years ago)
  • sage/algebras/iwahori_hecke_algebra.py

    # HG changeset patch
    # Parent f4e436887a4752799ac31dffec9ecf643faac3ba
    #11726: Implement univariate Laurent polynomial rings
    
    diff --git a/sage/algebras/iwahori_hecke_algebra.py b/sage/algebras/iwahori_hecke_algebra.py
    a b from sage.structure.parent import Parent 
    2323from sage.structure.unique_representation import UniqueRepresentation
    2424from sage.categories.realizations import Realizations, Category_realization_of_parent
    2525from sage.categories.all import AlgebrasWithBasis, FiniteDimensionalAlgebrasWithBasis, CoxeterGroups
    26 from sage.rings.polynomial.polydict import ETuple
    2726from sage.rings.all import ZZ
    2827
    2928from sage.combinat.root_system.weyl_group import WeylGroup
    class IwahoriHeckeAlgebra(Parent, Unique 
    8685        sage: T1 + T2
    8786        T1 + T2
    8887        sage: T1*T1
    89         (v^2-1)*T1 + v^2
     88        -(1-v^2)*T1 + v^2
    9089        sage: (T1 + T2)*T3 + T1*T1 - (v + v^-1)*T2
    91         T3*T1 + (v^2-1)*T1 + T2*T3 + (-v-v^-1)*T2 + v^2
     90        T3*T1 - (1-v^2)*T1 + T2*T3 - (v^-1+v)*T2 + v^2
    9291        sage: Cp(T1)
    93         v*Cp[s1] + (-1)
     92        v*Cp[s1] - 1
    9493        sage: Cp((v^1 - 1)*T1*T2 - T3)
    95         (v^3-v^2)*Cp[s1*s2] + (-v^2+v)*Cp[s1] + (-v^2+v)*Cp[s2] + (-v)*Cp[s3] + v
     94        -(v^2-v^3)*Cp[s1*s2] + (v-v^2)*Cp[s1] + (v-v^2)*Cp[s2] - v*Cp[s3] + v
    9695        sage: C(T1)
    9796        v*C[s1] + v^2
    9897        sage: p = C(T2*T3 - v*T1); p
    99         (-v^2)*C[s1] + v^2*C[s2*s3] + v^3*C[s2] + v^3*C[s3] + (v^4-v^3)
     98        -v^2*C[s1] + v^2*C[s2*s3] + v^3*C[s2] + v^3*C[s3] - (v^3-v^4)
    10099        sage: Cp(p)
    101         (-v^2)*Cp[s1] + v^2*Cp[s2*s3] + (-v)*Cp[s2] + (-v)*Cp[s3] + (v+1)
     100        -v^2*Cp[s1] + v^2*Cp[s2*s3] - v*Cp[s2] - v*Cp[s3] + (1+v)
    102101        sage: Cp(T2*T3 - v*T1)
    103         (-v^2)*Cp[s1] + v^2*Cp[s2*s3] + (-v)*Cp[s2] + (-v)*Cp[s3] + (v+1)
     102        -v^2*Cp[s1] + v^2*Cp[s2*s3] - v*Cp[s2] - v*Cp[s3] + (1+v)
    104103
    105104    In addition to explicitly creating generators, we have two shortcuts to
    106105    basis elements. The first is by using elements of the underlying Coxeter
    class IwahoriHeckeAlgebra(Parent, Unique 
    139138        sage: T(Cp[1])
    140139        (v^-1)*T1 + (v^-1)
    141140        sage: T(C[1])
    142         (v^-1)*T1 + (-v)
     141        (v^-1)*T1 - v
    143142        sage: C(Cp[1])
    144         C[s1] + (v+v^-1)
     143        C[s1] + (v^-1+v)
    145144        sage: Cp(C[1])
    146         Cp[s1] + (-v-v^-1)
     145        Cp[s1] - (v^-1+v)
    147146        sage: all(C[x] == C[x].bar() for x in W) # long time
    148147        True
    149148        sage: all(Cp[x] == Cp[x].bar() for x in W) # long time
    class IwahoriHeckeAlgebra(Parent, Unique 
    461460                sage: V1,V2 = H1.algebra_generators()
    462461                sage: W1,W2 = H1.inverse_generators()
    463462                sage: [W1,W2]
    464                 [(q^-1)*V1 + (-1+q^-1), (q^-1)*V2 + (-1+q^-1)]
     463                [(q^-1)*V1 + (q^-1-1), (q^-1)*V2 + (q^-1-1)]
    465464                sage: V1*W1, W2*V2
    466465                (1, 1)
    467466            """
    class IwahoriHeckeAlgebra(Parent, Unique 
    548547                sage: C(v^-1*T(s1) - v)
    549548                C[s1]
    550549                sage: C(T(s1*s2)+T(s1)+T(s2)+1)
    551                 v^2*C[s1*s2] + (v^3+v)*C[s1] + (v^3+v)*C[s2] + (v^4+2*v^2+1)
     550                v^2*C[s1*s2] + (v+v^3)*C[s1] + (v+v^3)*C[s2] + (1+2*v^2+v^4)
    552551                sage: C(T(s1*s2*s1))
    553552                v^3*C[s1*s2*s1] + v^4*C[s1*s2] + v^4*C[s2*s1] + v^5*C[s1] + v^5*C[s2] + v^6
    554553            """
    class IwahoriHeckeAlgebra(Parent, Unique 
    589588                sage: T = H.T()
    590589                sage: Cp = H.Cp()
    591590                sage: T.to_C_prime_basis(s1)
    592                 v*Cp[s1] + (-1)
     591                v*Cp[s1] - 1
    593592                sage: Cp(T(s1))
    594                 v*Cp[s1] + (-1)
     593                v*Cp[s1] - 1
    595594                sage: Cp(T(s1)+1)
    596595                v*Cp[s1]
    597596                sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)
    598597                v^2*Cp[s1*s2]
    599598                sage: Cp(T(s1*s2*s1))
    600                 v^3*Cp[s1*s2*s1] + (-v^2)*Cp[s1*s2] + (-v^2)*Cp[s2*s1] + v*Cp[s1] + v*Cp[s2] + (-1)
     599                v^3*Cp[s1*s2*s1] - v^2*Cp[s1*s2] - v^2*Cp[s2*s1] + v*Cp[s1] + v*Cp[s2] - 1
    601600            """
    602601            A = self.realization_of()
    603602            Cp = A.C_prime()
    class IwahoriHeckeAlgebra(Parent, Unique 
    628627                sage: s1,s2,s3 = W.simple_reflections()
    629628                sage: T = H.T()
    630629                sage: b = T.bar_on_basis(s1*s2*s3); b
    631                 (v^-6)*T1*T2*T3 + (-v^-4+v^-6)*T1*T2 + (-v^-4+v^-6)*T3*T1
    632                  + (v^-2-2*v^-4+v^-6)*T1 + (-v^-4+v^-6)*T2*T3 + (v^-2-2*v^-4+v^-6)*T2
    633                  + (v^-2-2*v^-4+v^-6)*T3 + (-1+3*v^-2-3*v^-4+v^-6)
     630                (v^-6)*T1*T2*T3 + (v^-6-v^-4)*T1*T2 + (v^-6-v^-4)*T3*T1
     631                 + (v^-6-2*v^-4+v^-2)*T1 + (v^-6-v^-4)*T2*T3 + (v^-6-2*v^-4+v^-2)*T2
     632                 + (v^-6-2*v^-4+v^-2)*T3 + (v^-6-3*v^-4+3*v^-2-1)
    634633                sage: b.bar()
    635634                T1*T2*T3
    636635            """
    class IwahoriHeckeAlgebra(Parent, Unique 
    696695                    sage: H = IwahoriHeckeAlgebra("A2", q).T()
    697696                    sage: [T1,T2] = H.algebra_generators()
    698697                    sage: x = (T1*T2).inverse(); x
    699                     (q^-2)*T2*T1 + (-q^-1+q^-2)*T1 + (-q^-1+q^-2)*T2 + (1-2*q^-1+q^-2)
     698                    (q^-2)*T2*T1 + (q^-2-q^-1)*T1 + (q^-2-q^-1)*T2 + (q^-2-2*q^-1+1)
    700699                    sage: x*T1*T2
    701700                    1
    702701
    class IwahoriHeckeAlgebra(Parent, Unique 
    709708                    sage: H = IwahoriHeckeAlgebra("A2", q).T()
    710709                    sage: T1,T2 = H.algebra_generators()
    711710                    sage: ~(T1*T2)
    712                     (q^-2)*T2*T1 + (-q^-1+q^-2)*T1 + (-q^-1+q^-2)*T2 + (1-2*q^-1+q^-2)
     711                    (q^-2)*T2*T1 + (q^-2-q^-1)*T1 + (q^-2-q^-1)*T2 + (q^-2-2*q^-1+1)
    713712                    sage: (T1*T2)^(-1)
    714                     (q^-2)*T2*T1 + (-q^-1+q^-2)*T1 + (-q^-1+q^-2)*T2 + (1-2*q^-1+q^-2)
     713                    (q^-2)*T2*T1 + (q^-2-q^-1)*T1 + (q^-2-q^-1)*T2 + (q^-2-2*q^-1+1)
    715714                """
    716715                if len(self) != 1:
    717716                    raise NotImplementedError("inverse only implemented for basis elements (monomials in the generators)"%self)
    class IwahoriHeckeAlgebra(Parent, Unique 
    741740                    sage: T = H.T()
    742741                    sage: T1,T2,T3 = T.algebra_generators()
    743742                    sage: elt = T1.hecke_involution(); elt
    744                     (-v^-2)*T1
     743                    -(v^-2)*T1
    745744                    sage: elt.hecke_involution()
    746745                    T1
    747746                    sage: elt = T1*T2 + (v^3 - v^-1 + 2)*T3*T1*T2*T3
    748747                    sage: elt.hecke_involution()
    749                     (-v^-7+2*v^-8+v^-11)*T1*T2*T3*T2 + (v^-4)*T1*T2
     748                    (v^-11+2*v^-8-v^-7)*T1*T2*T3*T2 + (v^-4)*T1*T2
    750749                    sage: elt.hecke_involution().hecke_involution() == elt
    751750                    True
    752751                """
    class IwahoriHeckeAlgebra(Parent, Unique 
    826825                sage: H = IwahoriHeckeAlgebra(['A',2], v**2, v)
    827826                sage: s1,s2 = H.coxeter_group().simple_reflections()
    828827                sage: [H.Cp().product_on_basis(s1,x) for x in [s1,s2]]
    829                 [(v+v^-1)*Cp[s1], Cp[s1*s2]]
     828                [(v^-1+v)*Cp[s1], Cp[s1*s2]]
    830829                sage: [H.C().product_on_basis(s1,x) for x in [s1,s2]]
    831                 [(-v-v^-1)*C[s1], C[s1*s2]]
     830                [-(v^-1+v)*C[s1], C[s1*s2]]
    832831            """
    833832            return self(self.to_T_basis(w1) * self.to_T_basis(w2))
    834833
    class IwahoriHeckeAlgebra(Parent, Unique 
    873872            sage: T = H.T()
    874873            sage: Cp = H.Cp()
    875874            sage: T(s1)**2
    876             (v^2-1)*T1 + v^2
     875            -(1-v^2)*T1 + v^2
    877876            sage: T(Cp(s1))
    878877            (v^-1)*T1 + (v^-1)
    879878            sage: T(Cp(s1)*Cp(s2)*Cp(s1))
    880             (v^-3)*T1*T2*T1 + (v^-3)*T1*T2 + (v^-3)*T2*T1 + (v^-1+v^-3)*T1 + (v^-3)*T2 + (v^-1+v^-3)
     879            (v^-3)*T1*T2*T1 + (v^-3)*T1*T2 + (v^-3)*T2*T1 + (v^-3+v^-1)*T1 + (v^-3)*T2 + (v^-3+v^-1)
    881880
    882881        ::
    883882
    class IwahoriHeckeAlgebra(Parent, Unique 
    890889            sage: Cp(s1*s2*s1)
    891890            Cp[s1*s2*s1]
    892891            sage: Cp(s1)**2
    893             (v+v^-1)*Cp[s1]
     892            (v^-1+v)*Cp[s1]
    894893            sage: Cp(s1)*Cp(s2)*Cp(s1)
    895894            Cp[s1*s2*s1] + Cp[s1]
    896895            sage: Cp(s1)*Cp(s2)*Cp(s3)*Cp(s1)*Cp(s2)
    class IwahoriHeckeAlgebra(Parent, Unique 
    960959                sage: T(Cp(s1*s2*s1))
    961960                (v^-3)*T1*T2*T1 + (v^-3)*T1*T2 + (v^-3)*T2*T1 + (v^-3)*T1 + (v^-3)*T2 + (v^-3)
    962961                sage: T(Cp(s2*s1*s3*s2))
    963                 (v^-4)*T2*T3*T1*T2 + (v^-4)*T1*T2*T1 + (v^-4)*T3*T1*T2 + (v^-4)*T1*T2 + (v^-4)*T2*T3*T1 + (v^-4)*T2*T1 + (v^-4)*T3*T1 + (v^-4)*T1 + (v^-4)*T2*T3*T2 + (v^-4)*T2*T3 + (v^-4)*T3*T2 + (v^-2+v^-4)*T2 + (v^-4)*T3 + (v^-2+v^-4)
     962                (v^-4)*T2*T3*T1*T2 + (v^-4)*T1*T2*T1 + (v^-4)*T3*T1*T2 + (v^-4)*T1*T2
     963                 + (v^-4)*T2*T3*T1 + (v^-4)*T2*T1 + (v^-4)*T3*T1 + (v^-4)*T1 + (v^-4)*T2*T3*T2
     964                 + (v^-4)*T2*T3 + (v^-4)*T3*T2 + (v^-4+v^-2)*T2 + (v^-4)*T3 + (v^-4+v^-2)
    964965            """
    965966            A = self.realization_of()
    966967            T = A.T()
    class IwahoriHeckeAlgebra(Parent, Unique 
    979980            while i < len(result):
    980981                (x,c) = result.terms()[i].leading_item()
    981982
    982                 deg = ETuple([-x.length()])
    983                 if deg in c.dict().keys():
    984                     mu = c.dict()[deg]
    985                 else:
    986                     mu = 0
    987 
    988                 if (mu != 0):
     983                mu = c[-x.length()]
     984                if mu != 0:
    989985                    result = result - mu * self.to_T_basis(x)
    990986                else:
    991987                    i = i + 1
    class IwahoriHeckeAlgebra(Parent, Unique 
    10411037            sage: T = H.T()
    10421038            sage: C = H.C()
    10431039            sage: T(s1)**2
    1044             (v^2-1)*T1 + v^2
     1040            -(1-v^2)*T1 + v^2
    10451041            sage: T(C(s1))
    1046             (v^-1)*T1 + (-v)
     1042            (v^-1)*T1 - v
    10471043            sage: T(C(s1)*C(s2)*C(s1))
    1048             (v^-3)*T1*T2*T1 + (-v^-1)*T1*T2 + (-v^-1)*T2*T1 + (v+v^-1)*T1 + v*T2 + (-v^3-v)
     1044            (v^-3)*T1*T2*T1 - (v^-1)*T1*T2 - (v^-1)*T2*T1 + (v^-1+v)*T1 + v*T2 - (v+v^3)
    10491045
    10501046        ::
    10511047
    class IwahoriHeckeAlgebra(Parent, Unique 
    10571053            sage: C(s1*s2*s1)
    10581054            C[s1*s2*s1]
    10591055            sage: C(s1)**2
    1060             (-v-v^-1)*C[s1]
     1056            -(v^-1+v)*C[s1]
    10611057            sage: C(s1)*C(s2)*C(s1)
    10621058            C[s1*s2*s1] + C[s1]
    10631059
    class IwahoriHeckeAlgebra(Parent, Unique 
    10771073        Check the defining property between `C` and `C^{\prime}`::
    10781074 
    10791075            sage: T(C[1])
    1080             (v^-1)*T1 + (-v)
     1076            (v^-1)*T1 - v
    10811077            sage: -T(Cp[1]).hecke_involution()
    1082             (v^-1)*T1 + (-v)
     1078            (v^-1)*T1 - v
    10831079            sage: T(Cp[1] + Cp[2]).hecke_involution()
    1084             (-v^-1)*T1 + (-v^-1)*T2 + 2*v
     1080            -(v^-1)*T1 - (v^-1)*T2 + 2*v
    10851081            sage: -T(C[1] + C[2])
    1086             (-v^-1)*T1 + (-v^-1)*T2 + 2*v
     1082            -(v^-1)*T1 - (v^-1)*T2 + 2*v
    10871083            sage: Cp(-C[1].hecke_involution())
    10881084            Cp[s1]
    10891085            sage: Cp(-C[1,2,3].hecke_involution()) 
    class IwahoriHeckeAlgebra(Parent, Unique 
    11341130                sage: T = H.T()
    11351131                sage: C = H.C()
    11361132                sage: C.to_T_basis(s1)
    1137                 (v^-1)*T1 + (-v)
     1133                (v^-1)*T1 - v
    11381134                sage: C.to_T_basis(s1*s2)
    1139                 (v^-2)*T1*T2 + (-1)*T1 + (-1)*T2 + v^2
     1135                (v^-2)*T1*T2 - T1 - T2 + v^2
    11401136                sage: C.to_T_basis(s1*s2*s1)
    1141                 (v^-3)*T1*T2*T1 + (-v^-1)*T1*T2 + (-v^-1)*T2*T1 + v*T1 + v*T2 + (-v^3)
     1137                (v^-3)*T1*T2*T1 - (v^-1)*T1*T2 - (v^-1)*T2*T1 + v*T1 + v*T2 - v^3
    11421138                sage: T(C(s1*s2*s1))
    1143                 (v^-3)*T1*T2*T1 + (-v^-1)*T1*T2 + (-v^-1)*T2*T1 + v*T1 + v*T2 + (-v^3)
     1139                (v^-3)*T1*T2*T1 - (v^-1)*T1*T2 - (v^-1)*T2*T1 + v*T1 + v*T2 - v^3
    11441140                sage: T(C(s2*s1*s3*s2))
    1145                 (v^-4)*T2*T3*T1*T2 + (-v^-2)*T1*T2*T1 + (-v^-2)*T3*T1*T2 + T1*T2
    1146                  + (-v^-2)*T2*T3*T1 + T2*T1 + T3*T1 + (-v^2)*T1 + (-v^-2)*T2*T3*T2
    1147                  + T2*T3 + T3*T2 + (-v^2-1)*T2 + (-v^2)*T3 + (v^4+v^2)
     1141                (v^-4)*T2*T3*T1*T2 - (v^-2)*T1*T2*T1 - (v^-2)*T3*T1*T2 + T1*T2
     1142                 - (v^-2)*T2*T3*T1 + T2*T1 + T3*T1 - v^2*T1 - (v^-2)*T2*T3*T2
     1143                 + T2*T3 + T3*T2 - (1+v^2)*T2 - v^2*T3 + (v^2+v^4)
    11481144            """
    11491145            # Treat our index as in the C' and then perform the Hecke
    11501146            #   involution since computationally they are the same
    class IwahoriHeckeAlgebraBases(Category_ 
    14331429                sage: T = H.T()
    14341430                sage: T1,T2,T3 = T.algebra_generators()
    14351431                sage: T1.bar()
    1436                 (q^-1)*T1 + (-1+q^-1)
     1432                (q^-1)*T1 + (q^-1-1)
    14371433                sage: T1.bar().bar() == T1
    14381434                True
    14391435
    14401436            Next on a multiple of generators::
    14411437
    14421438                sage: b = (T1*T2*T1).bar(); b
    1443                 (q^-3)*T1*T2*T1 + (-q^-2+q^-3)*T1*T2
    1444                  + (-q^-2+q^-3)*T2*T1 + (q^-1-2*q^-2+q^-3)*T1
    1445                  + (q^-1-2*q^-2+q^-3)*T2 + (-1+2*q^-1-2*q^-2+q^-3)
     1439                (q^-3)*T1*T2*T1 + (q^-3-q^-2)*T1*T2 + (q^-3-q^-2)*T2*T1 + (q^-3-2*q^-2+q^-1)*T1
     1440                 + (q^-3-2*q^-2+q^-1)*T2 + (q^-3-2*q^-2+2*q^-1-1)
    14461441                sage: b.bar() == T1*T2*T1
    14471442                True
    14481443
    class IwahoriHeckeAlgebraBases(Category_ 
    14501445
    14511446                sage: s = T1 + T2
    14521447                sage: b = s.bar(); b
    1453                 (q^-1)*T1 + (q^-1)*T2 + (-2+2*q^-1)
     1448                (q^-1)*T1 + (q^-1)*T2 + (2*q^-1-2)
    14541449                sage: b.bar() == s
    14551450                True
    14561451
    class IwahoriHeckeAlgebraBases(Category_ 
    14581453
    14591454                sage: p = T1*T2 + (1-q+q^-1)*T3 - q^3*T1*T3
    14601455                sage: p.bar()
    1461                 (q^-2)*T1*T2 + (-q^-5)*T3*T1
    1462                  + (-q^-1+q^-2+q^-4-q^-5)*T1 + (-q^-1+q^-2)*T2
    1463                  + (1+q^-1-q^-2+q^-4-q^-5)*T3 + (-q+1-q^-3+2*q^-4-q^-5)
     1456                (q^-2)*T1*T2 - (q^-5)*T3*T1 - (q^-5-q^-4-q^-2+q^-1)*T1 + (q^-2-q^-1)*T2
     1457                 - (q^-5-q^-4+q^-2-q^-1-1)*T3 - (q^-5-2*q^-4+q^-3-1+q)
    14641458                sage: p.bar().bar() == p
    14651459                True
    14661460
    class IwahoriHeckeAlgebraBases(Category_ 
    15401534                sage: Cp = H.Cp()
    15411535                sage: p = Cp[1]*Cp[3] + Cp[2]
    15421536                sage: q = p.hecke_involution(); q
    1543                 Cp[s3*s1] + (-v-v^-1)*Cp[s1] + (-1)*Cp[s2] + (-v-v^-1)*Cp[s3] + (v^2+v+2+v^-1+v^-2)
     1537                Cp[s3*s1] - (v^-1+v)*Cp[s1] - Cp[s2] - (v^-1+v)*Cp[s3] + (v^-2+v^-1+2+v+v^2)
    15441538                sage: q.hecke_involution() == p
    15451539                True
    15461540
    class IwahoriHeckeAlgebraBases(Category_ 
    15491543                sage: C = H.C()
    15501544                sage: p = C[1]*C[3] + C[2]
    15511545                sage: q = p.hecke_involution(); q
    1552                 C[s3*s1] + (v+v^-1)*C[s1] + (-1)*C[s2] + (v+v^-1)*C[s3] + (v^2-v+2-v^-1+v^-2)
     1546                C[s3*s1] + (v^-1+v)*C[s1] - C[s2] + (v^-1+v)*C[s3] + (v^-2-v^-1+2-v+v^2)
    15531547                sage: q.hecke_involution() == p
    15541548                True
    15551549            """
  • sage/categories/pushout.py

    diff --git a/sage/categories/pushout.py b/sage/categories/pushout.py
    a b class LaurentPolynomialFunctor(Construct 
    13771377                  Defn: x |--> x + 2*y
    13781378                        y |--> 3*x - y
    13791379        sage: F(f)(x*F(P).gen()^-2+y*F(P).gen()^3)
    1380         (3*x - y)*t^3 + (x + 2*y)*t^-2
     1380        (x + 2*y)*t^-2 + (3*x - y)*t^3
    13811381
    13821382    """
    13831383    rank = 9
  • sage/combinat/kazhdan_lusztig.py

    diff --git a/sage/combinat/kazhdan_lusztig.py b/sage/combinat/kazhdan_lusztig.py
    a b class KazhdanLusztigPolynomial(UniqueRep 
    4646        sage: R.<q> = LaurentPolynomialRing(QQ)
    4747        sage: KL = KazhdanLusztigPolynomial(W,q)
    4848        sage: KL.P(s2,s3*s2*s3*s1*s2)
    49         q + 1
     49        1 + q
    5050
    5151    A faster implementation (using the optional package Coxeter 3) is given by::
    5252
    5353        sage: W = CoxeterGroup(['B', 3], implementation='coxeter3') # optional - coxeter3
    5454        sage: W.kazhdan_lusztig_polynomial([2], [3,2,3,1,2])        # optional - coxeter3
    55         q + 1
     55        1 + q
    5656    """
    5757    def __init__(self, W, q, trace=False):
    5858        """
    class KazhdanLusztigPolynomial(UniqueRep 
    161161                return self._base_ring.zero()
    162162        p = sum(-self.R(x,t)*self.P(t,y) for t in self._coxeter_group.bruhat_interval(x,y) if t != x)
    163163        tr = floor((y.length()-x.length()+1)/2)
    164         try:
    165             ret = p.truncate(tr)
    166         except StandardError:
    167             ret = laurent_polynomial_truncate(p, tr)
     164        ret = p.truncate(tr)
    168165        if self._trace:
    169166            print "    P(%s,%s)=%s"%(x, y, ret)
    170167        return ret
    171168
    172 def laurent_polynomial_truncate(p, n):
    173     """
    174     Truncate the Laurent polynomial ``p``, returning only terms of degree
    175     less than ``n``, similar to the truncate method for polynomials.
    176 
    177     EXAMPLES::
    178 
    179         sage: from sage.combinat.kazhdan_lusztig import laurent_polynomial_truncate
    180         sage: P.<q> = LaurentPolynomialRing(QQ)
    181         sage: laurent_polynomial_truncate((q+q^-1)^3+q^2*(q+q^-1)^4,3)
    182         6*q^2 + 3*q + 4 + 3*q^-1 + q^-2 + q^-3
    183     """
    184     pdict = p._dict()
    185     dict = {}
    186     for k in pdict:
    187         if k[0] < n:
    188             dict[k] = pdict[k]
    189     return p.parent()(dict)
    190 
  • sage/rings/laurent_series_ring_element.pyx

    diff --git a/sage/rings/laurent_series_ring_element.pyx b/sage/rings/laurent_series_ring_element.pyx
    a b import sage.rings.polynomial.polynomial_ 
    6363import sage.misc.latex
    6464import sage.rings.ring_element as ring_element
    6565from sage.rings.integer import Integer
     66from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_univariate
    6667
    6768from sage.structure.element cimport Element, ModuleElement, RingElement, AlgebraElement
    6869
    def is_LaurentSeries(x): 
    7778cdef class LaurentSeries(AlgebraElement):
    7879    """
    7980    A Laurent Series.
     81
     82    We consider a Laurent series of the form `t^n \cdot f` where `f` is a
     83    power series.
     84
     85    INPUT:
     86
     87    - ``parent`` -- a Laurent series ring
     88
     89    - ``f`` -- a power series (or something can be coerced
     90      to one); note that ``f`` does *not* have to be a unit
     91
     92    - ``n`` -- (default: 0) integer
    8093    """
    81        
    8294    def __init__(self, parent, f, n=0):
    8395        r"""
    84         Create the Laurent series `t^n \cdot f`. The default is
    85         n=0.
    86        
    87         INPUT:
    88        
    89        
    90         -  ``parent`` - a Laurent series ring
    91        
    92         -  ``f`` - a power series (or something can be coerced
    93            to one); note that f does *not* have to be a unit.
    94        
    95         -  ``n`` - integer (default 0)
    96        
     96        Initialize ``self``.
    9797       
    9898        OUTPUT: a Laurent series
    9999       
    cdef class LaurentSeries(AlgebraElement) 
    118118        """
    119119        AlgebraElement.__init__(self, parent)
    120120
    121         if PY_TYPE_CHECK(f, LaurentSeries):
     121        if isinstance(f, LaurentSeries):
    122122            n += (<LaurentSeries>f).__n
    123123            if (<LaurentSeries>f).__u._parent is parent.power_series_ring():
    124124                f = (<LaurentSeries>f).__u
    125125            else:
    126126                f = parent.power_series_ring()((<LaurentSeries>f).__u)
    127         elif not PY_TYPE_CHECK(f, PowerSeries):
     127        elif isinstance(f, LaurentPolynomial_univariate):
     128            f = f(parent.gen())
     129        elif not isinstance(f, PowerSeries):
    128130            f = parent.power_series_ring()(f)
    129131        ## now this is a power series, over a different ring ...
    130132        ## requires that power series rings with same vars over the
    cdef class LaurentSeries(AlgebraElement) 
    481483            sage: R.<t> = LaurentSeriesRing(QQ)
    482484            sage: f = t^-3 + t + 7*t^2 + O(t^5)
    483485            sage: g = f.laurent_polynomial(); g
    484             7*t^2 + t + t^-3
     486            t^-3 + t + 7*t^2
    485487            sage: g.parent()
    486488            Univariate Laurent Polynomial Ring in t over Rational Field
    487489        """
    cdef class LaurentSeries(AlgebraElement) 
    730732       
    731733    def shift(self, k):
    732734        r"""
    733         Returns this laurent series multiplied by the power `t^n`.
     735        Returns this Laurent series multiplied by the power `t^n`.
    734736        Does not change this series.
    735737       
    736         .. note::
     738        .. NOTE::
    737739
    738740           Despite the fact that higher order terms are printed to the
    739741           right in a power series, right shifting decreases the
  • sage/rings/polynomial/laurent_polynomial.pxd

    diff --git a/sage/rings/polynomial/laurent_polynomial.pxd b/sage/rings/polynomial/laurent_polynomial.pxd
    a b from sage.rings.polynomial.polydict cimp 
    44from sage.rings.polynomial.multi_polynomial cimport MPolynomial
    55from sage.rings.polynomial.polynomial_element cimport Polynomial
    66
     7
     8cdef class LaurentPolynomial_univariate(CommutativeAlgebraElement):
     9    cpdef ModuleElement __u
     10    cdef long __n
     11
    712cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement):
    813    cdef ETuple _mon
    914    cdef MPolynomial _poly
  • sage/rings/polynomial/laurent_polynomial.pyx

    diff --git a/sage/rings/polynomial/laurent_polynomial.pyx b/sage/rings/polynomial/laurent_polynomial.pyx
    a b Elements of Laurent polynomial rings 
    33"""
    44include "sage/ext/stdsage.pxi"
    55
    6 import re
    76from sage.rings.integer import Integer
    8 from sage.structure.element import is_Element
     7from sage.structure.element import is_Element, coerce_binop
    98from sage.misc.latex import latex
     9import sage.misc.latex
    1010from sage.misc.misc import union
    1111from sage.structure.factorization import Factorization
     12from sage.misc.derivative import multi_derivative
     13from sage.rings.polynomial.polynomial_element import Polynomial
    1214
     15cdef class LaurentPolynomial_univariate(CommutativeAlgebraElement):
     16    """
     17    A univariate Laurent polynomial in the form of `t^n \cdot f`
     18    where `f` is a polynomial in `t`.
     19
     20    INPUT:
     21
     22    -  ``parent`` -- a Laurent polynomial ring
     23
     24    -  ``f`` -- a polynomial (or something can be coerced to one)
     25
     26    -  ``n`` -- (default: 0) an integer
     27
     28    AUTHORS::
     29
     30    - Tom Boothby (2011) copied this class almost verbatim from
     31      ``laurent_series_ring_element.pyx``, so most of the credit goes to
     32      William Stein, David Joyner, and Robert Bradshaw
     33    - Travis Scrimshaw (09-2013): Cleaned-up and added a few extra methods
     34    """
     35    def __init__(self, parent, f, n=0):
     36        r"""
     37        Create the Laurent polynomial `t^n \cdot f`.
     38
     39        EXAMPLES::
     40
     41            sage: R.<q> = LaurentPolynomialRing(ZZ)
     42            sage: R([1,2,3])
     43            1 + 2*q + 3*q^2
     44            sage: TestSuite(q^-3 + 3*q + 2).run()
     45
     46        ::
     47
     48            sage: S.<s> = LaurentPolynomialRing(GF(5))
     49            sage: T.<t> = PolynomialRing(pAdicRing(5))
     50            sage: S(t)
     51            s
     52            sage: parent(S(t))
     53            Univariate Laurent Polynomial Ring in s over Finite Field of size 5
     54            sage: parent(S(t)[1])
     55            Finite Field of size 5
     56        """
     57        CommutativeAlgebraElement.__init__(self, parent)
     58
     59        if isinstance(f, LaurentPolynomial_univariate):
     60            n += (<LaurentPolynomial_univariate>f).__n
     61            if (<LaurentPolynomial_univariate>f).__u._parent is parent.polynomial_ring():
     62                f = (<LaurentPolynomial_univariate>f).__u
     63            else:
     64                f = parent.polynomial_ring()((<LaurentPolynomial_univariate>f).__u)
     65        elif (not isinstance(f, Polynomial)) or (parent is not f.parent()):
     66            if isinstance(f, dict):
     67                v = min(f.keys())
     68                f = dict((i-v,c) for i,c in f.items())
     69                n += v
     70            f = parent.polynomial_ring()(f)
     71
     72        # self is that t^n * u:
     73        cdef long val
     74        self.__u = f
     75        self.__n = n
     76        self.__normalize()
     77
     78    def __reduce__(self):
     79        """
     80        Used in pickling.
     81
     82        EXAMPLES::
     83
     84            sage: R.<q> = LaurentPolynomialRing(ZZ)
     85            sage: elt = q^-3 + 2 + q
     86            sage: loads(dumps(elt)) == elt
     87            True
     88        """
     89        return LaurentPolynomial_univariate, (self._parent, self.__u, self.__n)
     90
     91    def change_ring(self, R):
     92        """
     93        Return a copy of this Laurent polynomial, with coefficients in ``R``.
     94
     95        EXAMPLES::
     96
     97            sage: R.<x> = LaurentPolynomialRing(QQ)
     98            sage: a = x^2 + 3*x^3 + 5*x^-1
     99            sage: a.change_ring(GF(3))
     100            2*x^-1 + x^2
     101        """
     102        return self.parent().change_ring(R)(self)
     103
     104    def is_unit(self):
     105        """
     106        Return ``True`` if this Laurent polynomial is a unit in this ring.
     107
     108        EXAMPLES::
     109
     110            sage: R.<t> = LaurentPolynomialRing(QQ)
     111            sage: (2+t).is_unit()
     112            False
     113            sage: f = 2*t
     114            sage: f.is_unit()
     115            True
     116            sage: 1/f
     117            1/2*t^-1
     118            sage: R(0).is_unit()
     119            False
     120            sage: R.<s> = LaurentPolynomialRing(ZZ)
     121            sage: g = 2*s
     122            sage: g.is_unit()
     123            False
     124            sage: 1/g
     125            1/(2*s)
     126
     127        ALGORITHM: A Laurent polynomial is a unit if and only if its "unit
     128        part" is a unit.
     129        """
     130        return self.__u.is_term() and self.__u.coefficients()[0].is_unit()
     131
     132    def is_zero(self):
     133        """
     134        Return ``1`` if ``self`` is 0, else return ``0``.
     135
     136        EXAMPLES::
     137
     138            sage: R.<x> = LaurentPolynomialRing(QQ)
     139            sage: f = 1/x + x + x^2 + 3*x^4
     140            sage: f.is_zero()
     141            0
     142            sage: z = 0*f
     143            sage: z.is_zero()
     144            1
     145        """
     146        return self.__u.is_zero()
     147
     148    def __nonzero__(self):
     149        """
     150        Check if ``self`` is non-zero.
     151
     152        EXAMPLES::
     153
     154            sage: R.<x> = LaurentPolynomialRing(QQ)
     155            sage: f = 1/x + x + x^2 + 3*x^4
     156            sage: not f
     157            False
     158            sage: z = 0*f
     159            sage: not z
     160            True
     161        """
     162        return not not self.__u
     163
     164    def _im_gens_(self, codomain, im_gens):
     165        """
     166        Return the image of ``self`` under the morphism defined by
     167        ``im_gens`` in ``codomain``.
     168
     169        EXAMPLES::
     170
     171            sage: R.<t> = LaurentPolynomialRing(QQ)
     172            sage: H = Hom(R, QQ)
     173            sage: mor = H(2)
     174            sage: mor(t^2 + t^-2)
     175            17/4
     176            sage: 4 + 1/4
     177            17/4
     178        """
     179        return codomain(self(im_gens[0]))
     180
     181    def __normalize(self):
     182        r"""
     183        A Laurent series is a pair `(u(t), n)`, where either `u = 0`
     184        (to some precision) or `u` is a unit. This pair corresponds to
     185        `t^n \cdot u(t)`.
     186
     187        EXAMPLES::
     188
     189            sage: R.<t> = LaurentPolynomialRing(QQ)
     190            sage: elt = t^2 + t^4 # indirect doctest
     191            sage: elt.polynomial_construction()
     192            (t^2 + 1, 2)
     193        """
     194        from sage.rings.infinity import infinity
     195        if self.is_zero():
     196            return
     197        v = self.__u.valuation()
     198        if v != 0 and v != infinity:
     199            self.__n += v
     200            self.__u = self.__u >> v
     201
     202    def _repr_(self):
     203        """
     204        Return a string representation of ``self``.
     205
     206        EXAMPLES::
     207
     208            sage: R.<t> = LaurentPolynomialRing(QQ)
     209            sage: 2 + (2/3)*t^3
     210            2 + 2/3*t^3
     211        """
     212        if self.is_zero():
     213            return "0"
     214        s = " "
     215        v = self.__u.list()
     216        valuation = self.__n
     217        m = len(v)
     218        X = self._parent.variable_name()
     219        atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
     220        first = True
     221        for n in xrange(m):
     222            x = v[n]
     223            e = n + valuation
     224            x = str(x)
     225            if x != '0':
     226                if not first:
     227                    s += " + "
     228                if not atomic_repr and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
     229                    x = "(%s)"%x
     230                if e == 1:
     231                    var = "*%s"%X
     232                elif e == 0:
     233                    var = ""
     234                else:
     235                    var = "*%s^%s"%(X,e)
     236                s += "%s%s"%(x,var)
     237                first = False
     238        s = s.replace(" + -", " - ")
     239        s = s.replace(" 1*"," ")
     240        s = s.replace(" -1*", " -")
     241        return s[1:]
     242
     243    def _latex_(self):
     244        r"""
     245        EXAMPLES::
     246
     247            sage: R.<x> = LaurentPolynomialRing(QQ)
     248            sage: f = (17/2)*x^-2 + x + x^2 + 3*x^4
     249            sage: latex(f)
     250            \frac{\frac{17}{2}}{x^{2}} + x + x^{2} + 3x^{4}
     251
     252        Verify that :trac:`6656` has been fixed::
     253
     254            sage: R.<a,b>=PolynomialRing(QQ)
     255            sage: T.<x>=LaurentPolynomialRing(R)
     256            sage: y = a*x+b*x
     257            sage: y._latex_()
     258            '\\left(a + b\\right)x'
     259            sage: latex(y)
     260            \left(a + b\right)x
     261        """
     262        if self.is_zero():
     263            return "0"
     264        s = " "
     265        v = self.__u.list()
     266        valuation = self.__n
     267        m = len(v)
     268        X = self._parent.latex_variable_names()[0]
     269        atomic_repr = self._parent.base_ring()._repr_option('element_is_atomic')
     270        first = True
     271        for n in xrange(m):
     272            x = v[n]
     273            e = n + valuation
     274            x = sage.misc.latex.latex(x)
     275            if x != '0':
     276                if not first:
     277                    s += " + "
     278                if not atomic_repr and e > 0 and (x[1:].find("+") != -1 or x[1:].find("-") != -1):
     279                    x = "\\left(%s\\right)"%x
     280                if e == 1:
     281                    var = "|%s"%X
     282                elif e == 0:
     283                    var = ""
     284                elif e > 0:
     285                    var = "|%s^{%s}"%(X,e)
     286                if e >= 0:
     287                    s += "%s%s"%(x,var)
     288                else: # negative e
     289                    if e == -1:
     290                        s += "\\frac{%s}{%s}"%(x, X)
     291                    else:
     292                        s += "\\frac{%s}{%s^{%s}}"%(x, X,-e)
     293                first = False
     294        s = s.replace(" + -", " - ")
     295        s = s.replace(" 1|"," ")
     296        s = s.replace(" -1|", " -")
     297        s = s.replace("|","")
     298
     299        return s[1:]
     300
     301    def __hash__(self):
     302        """
     303        Return the hash of ``self``.
     304
     305        EXAMPLES::
     306
     307            sage: R.<t> = LaurentPolynomialRing(QQ)
     308            sage: f = -5/t^(10) + t + t^2 - 10/3*t^3
     309            sage: hash(f) == hash(f)
     310            True
     311        """
     312        return hash(self.__u) ^ self.__n
     313
     314    def __getitem__(self, i):
     315        """
     316        Return the coefficient of `t^i`.
     317
     318        EXAMPLES::
     319
     320            sage: R.<t> = LaurentPolynomialRing(QQ)
     321            sage: f = -5/t^(10) + t + t^2 - 10/3*t^3; f
     322            -5*t^-10 + t + t^2 - 10/3*t^3
     323            sage: f[-10]
     324            -5
     325            sage: f[1]
     326            1
     327            sage: f[3]
     328            -10/3
     329            sage: f[-9]
     330            0
     331        """
     332        return self.__u[i-self.__n]
     333
     334    def __getslice__(self, i, j):
     335        """
     336        Return the Laurent polynomial `\sum_{k=i}^{j-1} c_k t^k`
     337        where ``self`` is `\sum_k c_k t^k`.
     338
     339        EXAMPLES::
     340
     341            sage: R.<t> = LaurentPolynomialRing(QQ)
     342            sage: f = -5/t^(10) + 1/3 + t + t^2 - 10/3*t^3; f
     343            -5*t^-10 + 1/3 + t + t^2 - 10/3*t^3
     344            sage: f[-10:2]
     345            -5*t^-10 + 1/3 + t
     346            sage: f[0:]
     347            1/3 + t + t^2 - 10/3*t^3
     348        """
     349        if j > self.__u.degree():
     350            j = self.__u.degree()
     351        f = self.__u[i-self.__n:j-self.__n]
     352        return LaurentPolynomial_univariate(self._parent, f, self.__n)
     353
     354    def __iter__(self):
     355        """
     356        Iterate through the coefficients from the first nonzero one to the
     357        last nonzero one.
     358
     359        EXAMPLES::
     360
     361            sage: R.<t> = LaurentPolynomialRing(QQ)
     362            sage: f = -5/t^(2) + t + t^2 - 10/3*t^3; f
     363            -5*t^-2 + t + t^2 - 10/3*t^3
     364            sage: for a in f: print a
     365            -5
     366            0
     367            0
     368            1
     369            1
     370            -10/3
     371        """
     372        return iter(self.__u)
     373
     374    def dict(self):
     375        """
     376        Return a dictionary representing ``self``.
     377
     378        EXAMPLES::
     379            sage: R.<x,y> = ZZ[]
     380            sage: Q.<t> = LaurentPolynomialRing(R)
     381            sage: f = (x^3 + y/t^3)^3 + t^2; f
     382            y^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2
     383            sage: f.dict()
     384            {0: x^9, -6: 3*x^3*y^2, 2: 1, -3: 3*x^6*y, -9: y^3}
     385        """
     386        return dict(zip(self.exponents(), self.coefficients()))
     387
     388    def coefficients(self):
     389        """
     390        Return the nonzero coefficients of ``self``.
     391
     392        EXAMPLES::
     393
     394            sage: R.<t> = LaurentPolynomialRing(QQ)
     395            sage: f = -5/t^(2) + t + t^2 - 10/3*t^3
     396            sage: f.coefficients()
     397            [-5, 1, 1, -10/3]
     398        """
     399        return self.__u.coefficients()
     400
     401    def exponents(self):
     402        """
     403        Return the exponents appearing in ``self`` with nonzero coefficients.
     404
     405        EXAMPLES::
     406
     407            sage: R.<t> = LaurentPolynomialRing(QQ)
     408            sage: f = -5/t^(2) + t + t^2 - 10/3*t^3
     409            sage: f.exponents()
     410            [-2, 1, 2, 3]
     411        """
     412        return [i+self.__n for i in self.__u.exponents()]
     413
     414    def __setitem__(self, n, value):
     415        """
     416        EXAMPLES::
     417
     418            sage: R.<t> = LaurentPolynomialRing(QQ)
     419            sage: f = t^2 + t^-3
     420            sage: f[2] = 5
     421            Traceback (most recent call last):
     422            ...
     423            IndexError: Laurent polynomials are immutable
     424        """
     425        raise IndexError("Laurent polynomials are immutable")
     426
     427    def _unsafe_mutate(self, i, value):
     428        """
     429        Sage assumes throughout that commutative ring elements are
     430        immutable. This is relevant for caching, etc. But sometimes you
     431        need to change a Laurent polynomial and you really know what you're
     432        doing. That's when this function is for you.
     433
     434        EXAMPLES::
     435
     436            sage: R.<t> = LaurentPolynomialRing(QQ)
     437            sage: f = t^2 + t^-3
     438            sage: f._unsafe_mutate(2, 3)
     439            sage: f
     440            t^-3 + 3*t^2
     441        """
     442        j = i - self.__n
     443        if j >= 0:
     444            self.__u._unsafe_mutate(j, value)
     445        else: # off to the left
     446            if value != 0:
     447                self.__n = self.__n + j
     448                R = self._parent.base_ring()
     449                coeffs = [value] + [R(0) for _ in range(1,-j)] + self.__u.list()
     450                self.__u = self.__u._parent(coeffs)
     451        self.__normalize()
     452
     453    cpdef ModuleElement _add_(self, ModuleElement right_m):
     454        """
     455        Add two Laurent polynomials with the same parent.
     456
     457        EXAMPLES::
     458
     459            sage: R.<t> = LaurentPolynomialRing(QQ)
     460            sage: t + t
     461            2*t
     462            sage: f = 1/t + t^2 + t^3 - 17/3 * t^4
     463            sage: g = 2/t + t^3
     464            sage: f + g
     465            3*t^-1 + t^2 + 2*t^3 - 17/3*t^4
     466            sage: f + 0
     467            t^-1 + t^2 + t^3 - 17/3*t^4
     468            sage: 0 + f
     469            t^-1 + t^2 + t^3 - 17/3*t^4
     470            sage: R(0) + R(0)
     471            0
     472            sage: t^3 + t^-3
     473            t^-3 + t^3
     474
     475        ALGORITHM: Shift the unit parts to align them, then add.
     476        """
     477        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_m
     478        cdef long m
     479
     480        # 1. Special case when one or the other is 0.
     481        if not right:
     482            return self
     483        if not self:
     484            return right
     485
     486        # 2. Align the unit parts.
     487        if self.__n < right.__n:
     488            m = self.__n
     489            f1 = self.__u
     490            f2 = right.__u << right.__n - m
     491        elif self.__n > right.__n:
     492            m = right.__n
     493            f1 = self.__u << self.__n - m
     494            f2 = right.__u
     495        else:
     496            m = self.__n
     497            f1 = self.__u
     498            f2 = right.__u
     499        # 3. Add
     500        return LaurentPolynomial_univariate(self._parent, f1 + f2, m)
     501
     502    cpdef ModuleElement _iadd_(self, ModuleElement right_m):
     503        """
     504        EXAMPLES::
     505
     506            sage: R.<t> = LaurentPolynomialRing(QQ)
     507            sage: f = t+t
     508            sage: f += t; f
     509            3*t
     510            sage: f += t*t; f
     511            3*t + t^2
     512        """
     513        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_m
     514        if self.__n == right.__n:
     515            self.__u += right.__u
     516            return self
     517        else:
     518            return self._add_(right)
     519
     520    cpdef ModuleElement _sub_(self, ModuleElement right_m):
     521        """
     522        Subtract two Laurent polynomials with the same parent.
     523
     524        EXAMPLES::
     525
     526            sage: R.<t> = LaurentPolynomialRing(QQ)
     527            sage: t - t
     528            0
     529            sage: t^5 + 2 * t^-5
     530            2*t^-5 + t^5
     531
     532        ALGORITHM: Shift the unit parts to align them, then subtract.
     533        """
     534        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_m
     535        cdef long m
     536
     537        # 1. Special case when one or the other is 0.
     538        if not right:
     539            return self
     540        if not self:
     541            return -right
     542
     543        # 2. Align the unit parts.
     544        if self.__n < right.__n:
     545            m = self.__n
     546            f1 = self.__u
     547            f2 = right.__u << right.__n - m
     548        else:
     549            m = right.__n
     550            f1 = self.__u << self.__n - m
     551            f2 = right.__u
     552        # 3. Subtract
     553        return LaurentPolynomial_univariate(self._parent, f1 - f2, m)
     554
     555    def degree(self):
     556        """
     557        Return the degree of this polynomial.
     558
     559        EXAMPLES::
     560
     561            sage: R.<x> = LaurentPolynomialRing(ZZ)
     562            sage: g = x^2 - x^4
     563            sage: g.degree()
     564            4
     565            sage: g = -10/x^5 + x^2 - x^7
     566            sage: g.degree()
     567            7
     568        """
     569        return self.__u.degree() + self.__n
     570
     571    def __neg__(self):
     572        """
     573        Return the negative of ``self``.
     574
     575        EXAMPLES::
     576
     577            sage: R.<t> = LaurentPolynomialRing(ZZ)
     578            sage: -(1+t^5)
     579            -1 - t^5
     580        """
     581        return LaurentPolynomial_univariate(self._parent, -self.__u, self.__n)
     582
     583    cpdef RingElement _mul_(self, RingElement right_r):
     584        """
     585        EXAMPLES::
     586
     587            sage: R.<x> = LaurentPolynomialRing(GF(2))
     588            sage: f = 1/x^3 + x + x^2 + 3*x^4
     589            sage: g = 1 - x + x^2 - x^4
     590            sage: f*g
     591            x^-3 + x^-2 + x^-1 + x^8
     592        """
     593        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_r
     594        return LaurentPolynomial_univariate(self._parent,
     595                             self.__u * right.__u,
     596                             self.__n + right.__n)
     597
     598    cpdef RingElement _imul_(self, RingElement right_r):
     599        """
     600        EXAMPLES::
     601
     602            sage: R.<x> = LaurentPolynomialRing(ZZ)
     603            sage: f = 1/x^3 + x + x^2 + 3*x^4
     604            sage: g = 1 - x + x^2 - x^4
     605            sage: f *= g; f
     606            x^-3 - x^-2 + x^-1 + 4*x^4 - 4*x^5 + 2*x^6 - 3*x^8
     607        """
     608        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_r
     609        self.__u *= right.__u
     610        self.__n += right.__n
     611        return self
     612
     613    cpdef ModuleElement _rmul_(self, RingElement c):
     614        """
     615        EXAMPLES::
     616
     617            sage: R.<x> = LaurentPolynomialRing(ZZ)
     618            sage: f = 1/x^3 + x + x^2 + 3*x^4
     619            sage: 3 * f
     620            3*x^-3 + 3*x + 3*x^2 + 9*x^4
     621        """
     622        return LaurentPolynomial_univariate(self._parent, self.__u._rmul_(c), self.__n)
     623
     624    cpdef ModuleElement _lmul_(self, RingElement c):
     625        """
     626        EXAMPLES::
     627
     628            sage: R.<x> = LaurentPolynomialRing(ZZ)
     629            sage: f = 1/x^3 + x + x^2 + 3*x^4
     630            sage: f * 3
     631            3*x^-3 + 3*x + 3*x^2 + 9*x^4
     632        """
     633        return LaurentPolynomial_univariate(self._parent, self.__u._lmul_(c), self.__n)
     634
     635    cpdef ModuleElement _ilmul_(self, RingElement c):
     636        """
     637        EXAMPLES::
     638
     639            sage: R.<x> = LaurentPolynomialRing(ZZ)
     640            sage: f = 1/x^3 + x + x^2 + 3*x^4
     641            sage: f *= 3
     642        """
     643        self.__u *= c
     644        return self
     645
     646    def __pow__(_self, r, dummy):
     647        """
     648        EXAMPLES::
     649
     650            sage: x = LaurentPolynomialRing(QQ,'x').0
     651            sage: f = x + x^2 + 3*x^4
     652            sage: g = 1/x^10 - x
     653            sage: f^3
     654            x^3 + 3*x^4 + 3*x^5 + 10*x^6 + 18*x^7 + 9*x^8 + 27*x^9 + 27*x^10 + 27*x^12
     655            sage: g^4
     656            x^-40 - 4*x^-29 + 6*x^-18 - 4*x^-7 + x^4
     657        """
     658        cdef LaurentPolynomial_univariate self = _self
     659        right=int(r)
     660        if right != r:
     661            raise ValueError("exponent must be an integer")
     662        return LaurentPolynomial_univariate(self._parent, self.__u**right, self.__n*right)
     663
     664    def shift(self, k):
     665        r"""
     666        Return this Laurent polynomial multiplied by the power `t^n`.
     667        Does not change this polynomial.
     668
     669        EXAMPLES::
     670
     671            sage: R.<t> = LaurentPolynomialRing(QQ['y'])
     672            sage: f = (t+t^-1)^4; f
     673            t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
     674            sage: f.shift(10)
     675            t^6 + 4*t^8 + 6*t^10 + 4*t^12 + t^14
     676            sage: f >> 10
     677            t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6
     678            sage: f << 4
     679            1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8
     680        """
     681        return LaurentPolynomial_univariate(self._parent, self.__u, self.__n + k)
     682
     683    def __lshift__(LaurentPolynomial_univariate self, k):
     684        """
     685        Return the left shift of ``self``.
     686
     687        EXAMPLES::
     688
     689            sage: R.<t> = LaurentPolynomialRing(QQ)
     690            sage: f = (t+t^-1)^4; f
     691            t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
     692            sage: f << 4
     693            1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8
     694        """
     695        return LaurentPolynomial_univariate(self._parent, self.__u, self.__n + k)
     696
     697    def __rshift__(LaurentPolynomial_univariate self, k):
     698        """
     699        Return the right shift of ``self``.
     700
     701        EXAMPLES::
     702
     703            sage: R.<t> = LaurentPolynomialRing(QQ)
     704            sage: f = (t+t^-1)^4; f
     705            t^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
     706            sage: f >> 10
     707            t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6
     708        """
     709        return LaurentPolynomial_univariate(self._parent, self.__u, self.__n - k)
     710
     711    cpdef RingElement _div_(self, RingElement right_r):
     712        """
     713        EXAMPLES::
     714
     715            sage: R.<x> = LaurentPolynomialRing(QQ)
     716            sage: f = x + x^2 + 3*x^4
     717            sage: g = 1/x^7 - x + x^2 - x^4
     718            sage: f / x
     719            1 + x + 3*x^3
     720            sage: f / g
     721            (x + x^2 + 3*x^4)/(x^-7 - x + x^2 - x^4)
     722            sage: (x^-2 + x)*(x^-2 + 1) / ((x^5 + x^8)*(x + 2))
     723            (1 + x^2)/(2*x^9 + x^10)
     724            sage: (x^-2 + x)*(x^-2 + 1) / ((x^-5 + x^-8)*(x + 2))
     725            (x^4 + x^6)/(2 + x)
     726        """
     727        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_r
     728        if right.__u.is_zero():
     729            raise ZeroDivisionError
     730
     731        try:
     732            return LaurentPolynomial_univariate(self._parent,
     733                             self.__u / right.__u,
     734                             self.__n - right.__n)
     735        except TypeError:
     736            # If that didn't work, try the fraction field
     737            return RingElement._div_(self, right)
     738
     739    def __invert__(self):
     740        """
     741        Return the inverse of ``self``.
     742
     743        EXAMPLES::
     744
     745            sage: R.<t> = LaurentPolynomialRing(QQ)
     746            sage: i = ~(t^-2); i
     747            t^2
     748            sage: i.parent() is R
     749            True
     750            sage: i = ~(2*t^2); i
     751            1/2*t^-2
     752            sage: i.parent() is R
     753            True
     754            sage: i = ~(t^-2 + 2 + t^2); i
     755            1/(t^-2 + 2 + t^2)
     756            sage: i.parent()
     757            Fraction Field of Univariate Laurent Polynomial Ring in t over Rational Field
     758        """
     759        if self.__u.is_constant():
     760            return LaurentPolynomial_univariate(self._parent, ~self.__u, -self.__n)
     761        if self.__u.is_unit():
     762            return LaurentPolynomial_univariate(self._parent, self.__u.inverse_of_unit(), -self.__n)
     763        return self._parent.one() / self
     764
     765    def inverse_of_unit(self):
     766        """
     767        Return the inverse of ``self`` if a unit.
     768
     769        EXAMPLES::
     770
     771            sage: R.<t> = LaurentPolynomialRing(QQ)
     772            sage: (t^-2).inverse_of_unit()
     773            t^2
     774            sage: (t + 2).inverse_of_unit()
     775            Traceback (most recent call last):
     776            ...
     777            ArithmeticError: element is not a unit
     778        """
     779        if self.is_unit():
     780            return self.__invert__()
     781        raise ArithmeticError("element is not a unit")
     782
     783    def gcd(self, right):
     784        """
     785        Return the gcd of ``self`` with ``right`` where the common divisor
     786        ``d`` makes both ``self`` and ``right`` into polynomials with
     787        the lowest possible degree.
     788
     789        EXAMPLES::
     790
     791            sage: R.<t> = LaurentPolynomialRing(QQ)
     792            sage: t.gcd(2)
     793            1
     794            sage: gcd(t^-2 + 1, t^-4 + 3*t^-1)
     795            t^-4
     796            sage: gcd((t^-2 + t)*(t + t^-1), (t^5 + t^8)*(1 + t^-2))
     797            t^-3 + t^-1 + 1 + t^2
     798        """
     799        b = <LaurentPolynomial_univariate>self._parent(right)
     800        return LaurentPolynomial_univariate(self._parent, self.__u.gcd(b.__u), min(self.__n, b.__n))
     801
     802    @coerce_binop
     803    def quo_rem(self, right_r):
     804        """
     805        Attempts to divide ``self`` by ``right`` and returns a quotient and
     806        a remainder.
     807
     808        EXAMPLES::
     809
     810            sage: R.<t> = LaurentPolynomialRing(QQ)
     811            sage: (t^-3 - t^3).quo_rem(t^-1 - t)
     812            (t^-2 + 1 + t^2, 0)
     813            sage: (t^-2 + 3 + t).quo_rem(t^-4)
     814            (t^2 + 3*t^4 + t^5, 0)
     815            sage: (t^-2 + 3 + t).quo_rem(t^-4 + t)
     816            (0, 1 + 3*t^2 + t^3)
     817        """
     818        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_r
     819        q,r = self.__u.quo_rem(right.__u)
     820        ql = LaurentPolynomial_univariate(self._parent, q, self.__n - right.__n)
     821        rl = LaurentPolynomial_univariate(self._parent, r, 0)
     822        return (ql, rl)
     823
     824    def __richcmp__(left, right, int op):
     825        """
     826        Return the rich comparison of ``left`` and ``right`` defined by ``op``.
     827
     828        EXAMPLES::
     829
     830            sage: R.<x> = LaurentPolynomialRing(QQ)
     831            sage: f = x^(-1) + 1 + x
     832            sage: g = x^(-1) + 2
     833            sage: f == g
     834            False
     835            sage: f != g
     836            True
     837            sage: f < g
     838            True
     839            sage: f <= g
     840            True
     841            sage: f > g
     842            False
     843            sage: f >= g
     844            False
     845        """
     846        return (<Element>left)._richcmp(right, op)
     847
     848    cdef int _cmp_c_impl(self, Element right_r) except -2:
     849        r"""
     850        Comparison of ``self`` and ``right_r``.
     851
     852        EXAMPLES::
     853
     854            sage: R.<x> = LaurentPolynomialRing(QQ)
     855            sage: f = x^(-1) + 1 + x
     856            sage: g = x^(-1) + 1
     857            sage: f == g
     858            False
     859
     860        ::
     861
     862            sage: f = x^(-1) + 1 + x
     863            sage: g = x^(-1) + 2
     864            sage: f == g
     865            False
     866            sage: f < g
     867            True
     868            sage: f > g
     869            False
     870
     871        ::
     872
     873            sage: f = x^(-2) + 1 + x
     874            sage: g = x^(-1) + 2
     875            sage: f == g
     876            False
     877            sage: f < g
     878            False
     879            sage: f > g
     880            True
     881        """
     882        cdef LaurentPolynomial_univariate right = <LaurentPolynomial_univariate>right_r
     883
     884        zero = self.base_ring()(0)
     885
     886        if not self and not right:
     887            if self.__n < right.__n:
     888                return cmp(self.__u[0], zero)
     889            elif self.__n > right.__n:
     890                return cmp(zero, right.__u[0])
     891
     892        # zero pad coefficients on the left, to line them up for comparison
     893        cdef long n = min(self.__n, right.__n)
     894        x = [zero] * (self.__n - n) + self.__u.list()
     895        y = [zero] * (right.__n - n) + right.__u.list()
     896
     897        # zero pad on right to make the lists the same length
     898        # (this is necessary since the power series list() function just
     899        # returns the coefficients of the underlying polynomial, which may
     900        # have zeroes in the high coefficients)
     901        if len(x) < len(y):
     902            x.extend([zero] * (len(y) - len(x)))
     903        elif len(y) < len(x):
     904            y.extend([zero] * (len(x) - len(y)))
     905
     906        return cmp(x,y)
     907
     908    def valuation(self, p=None):
     909        """
     910        Return the valuation of ``self``.
     911
     912        The valuation of a Laurent polynomial `t^n u` is `n` plus the
     913        valuation of `u`.
     914
     915        EXAMPLES::
     916
     917            sage: R.<x> = LaurentPolynomialRing(ZZ)
     918            sage: f = 1/x + x^2 + 3*x^4
     919            sage: g = 1 - x + x^2 - x^4
     920            sage: f.valuation()
     921            -1
     922            sage: g.valuation()
     923            0
     924        """
     925        return self.__n + self.__u.valuation(p)
     926
     927    def truncate(self, n):
     928        """
     929        Return a polynomial with degree at most `n-1` whose `j`-th coefficients
     930        agree with ``self`` for all `j < n`.
     931
     932        EXAMPLES::
     933
     934            sage: R.<x> = LaurentPolynomialRing(QQ)
     935            sage: f = 1/x^12 + x^3 + x^5 + x^9
     936            sage: f.truncate(10)
     937            x^-12 + x^3 + x^5 + x^9
     938            sage: f.truncate(5)
     939            x^-12 + x^3
     940            sage: f.truncate(-16)
     941            0
     942        """
     943        if n <= self.valuation():
     944            return self._parent(0)
     945        return LaurentPolynomial_univariate(self._parent, self.__u.truncate(n-self.__n), self.__n)
     946
     947    def variable_name(self):
     948        """
     949        Return the name of variable of ``self`` as a string.
     950
     951        EXAMPLES::
     952
     953            sage: R.<x> = LaurentPolynomialRing(QQ)
     954            sage: f = 1/x + x^2 + 3*x^4
     955            sage: f.variable_name()
     956            'x'
     957        """
     958        return self._parent.variable_name()
     959
     960    def variables(self):
     961        """
     962        Return the tuple of variables occuring in this Laurent polynomial.
     963
     964        EXAMPLES::
     965
     966            sage: R.<x> = LaurentPolynomialRing(QQ)
     967            sage: f = 1/x + x^2 + 3*x^4
     968            sage: f.variables()
     969            (x,)
     970            sage: R.one().variables()
     971            ()
     972        """
     973        if self.is_constant():
     974            return ()
     975        return self._parent.gens()
     976
     977    def polynomial_construction(self):
     978        """
     979        Return the polynomial and the shift in power used to construct the
     980        Laurent polynomial `t^n u`.
     981
     982        OUTPUT:
     983
     984        A tuple ``(u, n)`` where ``u`` is the underlying polynomial and ``n``
     985        is the power of the exponent shift.
     986
     987        EXAMPLES::
     988
     989            sage: R.<x> = LaurentPolynomialRing(QQ)
     990            sage: f = 1/x + x^2 + 3*x^4
     991            sage: f.polynomial_construction()
     992            (3*x^5 + x^3 + 1, -1)
     993        """
     994        return (self.__u, self.__n)
     995
     996    def is_constant(self):
     997        """
     998        Return ``True`` if ``self`` is constant.
     999
     1000        EXAMPLES::
     1001
     1002            sage: R.<x> = LaurentPolynomialRing(QQ)
     1003            sage: x.is_constant()
     1004            False
     1005            sage: R.one().is_constant()
     1006            True
     1007            sage: (x^-2).is_constant()
     1008            False
     1009            sage: (x^2).is_constant()
     1010            False
     1011            sage: (x^-2 + 2).is_constant()
     1012            False
     1013        """
     1014        return self.__n == 0 and self.__u.is_constant()
     1015
     1016    def __copy__(self):
     1017        """
     1018        Return a copy of ``self``.
     1019
     1020        EXAMPLES::
     1021
     1022            sage: R.<x> = LaurentPolynomialRing(QQ)
     1023            sage: f = 1/x + x^2 + 3*x^4
     1024            sage: cf = copy(f)
     1025            sage: cf == f
     1026            True
     1027            sage: cf is not f
     1028            True
     1029        """
     1030        from copy import copy
     1031        return LaurentPolynomial_univariate(self._parent, copy(self.__u), self.__n)
     1032
     1033    def derivative(self, *args):
     1034        """
     1035        The formal derivative of this Laurent polynomial, with respect
     1036        to variables supplied in args.
     1037
     1038        Multiple variables and iteration counts may be supplied; see
     1039        documentation for the global :func`derivative()` function for more
     1040        details.
     1041
     1042        .. SEEALSO::
     1043
     1044           :meth:`_derivative`
     1045
     1046        EXAMPLES::
     1047
     1048            sage: R.<x> = LaurentPolynomialRing(QQ)
     1049            sage: g = 1/x^10 - x + x^2 - x^4
     1050            sage: g.derivative()
     1051            -10*x^-11 - 1 + 2*x - 4*x^3
     1052            sage: g.derivative(x)
     1053            -10*x^-11 - 1 + 2*x - 4*x^3
     1054
     1055        ::
     1056
     1057            sage: R.<t> = PolynomialRing(ZZ)
     1058            sage: S.<x> = LaurentPolynomialRing(R)
     1059            sage: f = 2*t/x + (3*t^2 + 6*t)*x
     1060            sage: f.derivative()
     1061            -2*t*x^-2 + (3*t^2 + 6*t)
     1062            sage: f.derivative(x)
     1063            -2*t*x^-2 + (3*t^2 + 6*t)
     1064            sage: f.derivative(t)
     1065            2*x^-1 + (6*t + 6)*x
     1066        """
     1067        return multi_derivative(self, args)
     1068
     1069    def _derivative(self, var=None):
     1070        """
     1071        The formal derivative of this Laurent series with respect to ``var``.
     1072
     1073        If ``var`` is ``None`` or the generator of this ring, it's the formal
     1074        derivative as expected. Otherwise, ``_derivative(var)`` gets called
     1075        recursively on each coefficient.
     1076
     1077        .. SEEALSO::
     1078
     1079           :meth:`derivative`
     1080
     1081        EXAMPLES::
     1082
     1083            sage: R.<x> = LaurentPolynomialRing(ZZ)
     1084            sage: f = x^2 + 3*x^4
     1085            sage: f._derivative()
     1086            2*x + 12*x^3
     1087            sage: f._derivative(x)
     1088            2*x + 12*x^3
     1089            sage: g = 1/x^10 - x + x^2 - x^4
     1090            sage: g._derivative()
     1091            -10*x^-11 - 1 + 2*x - 4*x^3
     1092
     1093        Differentiating with respect to something other than the generator
     1094        gets recursed into the base ring::
     1095
     1096            sage: R.<t> = PolynomialRing(ZZ)
     1097            sage: S.<x> = LaurentPolynomialRing(R)
     1098            sage: f = 2*t/x + (3*t^2 + 6*t)*x
     1099            sage: f._derivative(t)
     1100            2*x^-1 + (6*t + 6)*x
     1101        """
     1102        if var is not None and var is not self._parent.gen():
     1103            # call _derivative() recursively on coefficients
     1104            u = [coeff._derivative(var) for coeff in self.__u.list()]
     1105            u = self._parent.polynomial_ring()(u)
     1106            return LaurentPolynomial_univariate(self._parent, u, self.__n)
     1107
     1108        # compute formal derivative with respect to generator
     1109        if self.is_zero():
     1110            return LaurentPolynomial_univariate(self._parent, 0)
     1111        cdef long m, n = self.__n
     1112        a = self.__u.list()
     1113        v = [(n+m)*a[m] for m from 0 <= m < len(a)]
     1114        u = self._parent.polynomial_ring()(v)
     1115        return LaurentPolynomial_univariate(self._parent, u, n-1)
     1116
     1117    def integral(self):
     1118        r"""
     1119        The formal integral of this Laurent series with 0 constant term.
     1120
     1121        EXAMPLES:
     1122
     1123        The integral may or may not be defined if the base ring
     1124        is not a field.
     1125
     1126        ::
     1127
     1128            sage: t = LaurentPolynomialRing(ZZ, 't').0
     1129            sage: f = 2*t^-3 + 3*t^2
     1130            sage: f.integral()
     1131            -t^-2 + t^3
     1132
     1133        ::
     1134
     1135            sage: f = t^3
     1136            sage: f.integral()
     1137            Traceback (most recent call last):
     1138            ...
     1139            ArithmeticError: coefficients of integral cannot be coerced into the base ring
     1140
     1141        The integral of `1/t` is `\log(t)`, which is not given by a
     1142        Laurent polynomial::
     1143
     1144            sage: t = LaurentPolynomialRing(ZZ,'t').0
     1145            sage: f = -1/t^3 - 31/t
     1146            sage: f.integral()
     1147            Traceback (most recent call last):
     1148            ...
     1149            ArithmeticError: the integral of is not a Laurent polynomial, since t^-1 has nonzero coefficient
     1150
     1151        Another example with just one negative coefficient::
     1152
     1153            sage: A.<t> = LaurentPolynomialRing(QQ)
     1154            sage: f = -2*t^(-4)
     1155            sage: f.integral()
     1156            2/3*t^-3
     1157            sage: f.integral().derivative() == f
     1158            True
     1159        """
     1160        cdef long i, n = self.__n
     1161        a = self.__u.list()
     1162        if self[-1] != 0:
     1163            raise ArithmeticError(
     1164                  "the integral of is not a Laurent polynomial, since t^-1 has nonzero coefficient")
     1165
     1166        if n < 0:
     1167            v = [a[i]/(n+i+1) for i in range(min(-1-n,len(a)))] + [0]
     1168        else:
     1169            v = []
     1170        v += [a[i]/(n+i+1) for i in range(max(-n,0), len(a))]
     1171        try:
     1172            u = self._parent.polynomial_ring()(v)
     1173        except TypeError:
     1174            raise ArithmeticError("coefficients of integral cannot be coerced into the base ring")
     1175        return LaurentPolynomial_univariate(self._parent, u, n+1)
     1176
     1177    def __call__(self, *x):
     1178        """
     1179        Compute value of this Laurent polynomial at ``x``.
     1180
     1181        EXAMPLES::
     1182
     1183            sage: R.<t> = LaurentPolynomialRing(ZZ)
     1184            sage: f = t^(-2) + t^2
     1185            sage: f(2)
     1186            17/4
     1187            sage: f(-1)
     1188            2
     1189            sage: f(1/3)
     1190            82/9
     1191        """
     1192        if isinstance(x[0], tuple):
     1193            x = x[0]
     1194        return self.__u(x) * (x[0]**self.__n)
     1195
     1196    def factor(self):
     1197        """
     1198        Return a Laurent monomial (the unit part of the factorization) and
     1199        a factored polynomial.
     1200
     1201        EXAMPLES::
     1202
     1203            sage: R.<t> = LaurentPolynomialRing(ZZ)
     1204            sage: f = 4*t^-7 + 3*t^3 + 2*t^4 + t^-6
     1205            sage: f.factor()
     1206            (t^-7) * (4 + t + 3*t^10 + 2*t^11)
     1207        """
     1208        pf = self.__u.factor()
     1209        u = LaurentPolynomial_univariate(self._parent, pf.unit(), self.__n)
     1210
     1211        f = []
     1212        for t in pf:
     1213            d = LaurentPolynomial_univariate(self._parent, t[0], 0)
     1214            if d.is_unit():
     1215                u *= d**t[1]
     1216            else:
     1217                f.append( (d, t[1]) )
     1218
     1219        return Factorization(f, unit=u)
     1220
     1221    def residue(self):
     1222        """
     1223        Return the residue of ``self``.
     1224
     1225        The residue is the coefficient of `t^-1`.
     1226
     1227        EXAMPLES::
     1228
     1229            sage: R.<t> = LaurentPolynomialRing(QQ)
     1230            sage: f = 3*t^-2 - t^-1 + 3 + t^2
     1231            sage: f.residue()
     1232            -1
     1233            sage: g = -2*t^-2 + 4 + 3*t
     1234            sage: g.residue()
     1235            0
     1236            sage: f.residue().parent()
     1237            Rational Field
     1238        """
     1239        return self[-1]
     1240
     1241    def constant_coefficient(self):
     1242        """
     1243        Return the coefficient of the constant term of ``self``.
     1244
     1245        EXAMPLES::
     1246
     1247            sage: R.<t> = LaurentPolynomialRing(QQ)
     1248            sage: f = 3*t^-2 - t^-1 + 3 + t^2
     1249            sage: f.constant_coefficient()
     1250            3
     1251            sage: g = -2*t^-2 + t^-1 + 3*t
     1252            sage: g.constant_coefficient()
     1253            0
     1254        """
     1255        return self[0]
    131256
    141257cdef class LaurentPolynomial_mpair(CommutativeAlgebraElement):
    151258    def __init__(self, parent, x, reduce=True):
    cdef class LaurentPolynomial_mpair(Commu 
    291272            sage: L(1/2)
    301273            1/2
    311274        """
    32         if isinstance(x, PolyDict):
     1275        if isinstance(x, LaurentPolynomial_mpair):
     1276            x = x.dict()
     1277        elif isinstance(x, PolyDict):
    331278            x = x.dict()
    341279        if isinstance(x, dict):
    351280            self._mon = ETuple({},int(parent.ngens()))
    361281            for k in x.keys(): # ETuple-ize keys, set _mon
    37                 if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens(): 
     1282                if not isinstance(k, (tuple, ETuple)) or len(k) != parent.ngens():
    381283                    self._mon = ETuple({}, int(parent.ngens()))
    391284                    break
    40                 if isinstance(k, tuple): 
     1285                if isinstance(k, tuple):
    411286                    a = x[k]
    421287                    del x[k]
    431288                    k = ETuple(k)
    cdef class LaurentPolynomial_mpair(Commu 
    821327    def _normalize(self, i = None):
    831328        """
    841329        Removes the common monomials from self._poly and stores them in self._mon
    85        
     1330
    861331        INPUT:
    871332
    881333        - ``i`` -- an integer
    cdef class LaurentPolynomial_mpair(Commu 
    901335        EXAMPLES::
    911336
    921337            sage: L.<x,y> = LaurentPolynomialRing(QQ)
    93             sage: f = x*y + 2*y*x^2 + y
    94             sage: f.factor() #Notice the y has been factored out.
     1338            sage: f = x*y + 2*y*x^2 + y # indirect doctest
     1339            sage: f.factor() # Notice the y has been factored out.
    951340            (y) * (2*x^2 + x + 1)
    96 
    971341        """
    981342        D = self._poly._mpoly_dict_recursive(self.parent().variable_names(), self.parent().base_ring())
    991343        if i is None:
    cdef class LaurentPolynomial_mpair(Commu 
    1141358            if e > 0:
    1151359                self._poly = self._poly / self._poly.parent().gen(i)
    1161360                self._mon = self._mon.eadd_p(e, i)
    117                    
     1361
    1181362
    1191363    def _dict(self):
    1201364        """
    cdef class LaurentPolynomial_mpair(Commu 
    1331377
    1341378        """
    1351379        D = self._poly._mpoly_dict_recursive(self.parent().variable_names(), self.parent().base_ring())
    136         if len(self._mon.nonzero_positions()) > 0:           
     1380        if len(self._mon.nonzero_positions()) > 0:
    1371381            DD = {}
    1381382            for k in D.keys():
    1391383                DD[k.eadd(self._mon)] = D[k]
    cdef class LaurentPolynomial_mpair(Commu 
    1671411        except AttributeError:
    1681412            cmpfn = None
    1691413        atomic = self.parent().base_ring()._repr_option('element_is_atomic')
    170         return self._prod.poly_repr(self.parent().variable_names(), 
     1414        return self._prod.poly_repr(self.parent().variable_names(),
    1711415                                    atomic_coefficients=atomic, cmpfn=cmpfn)
    1721416
    1731417    def _latex_(self):
    cdef class LaurentPolynomial_mpair(Commu 
    1881432        except AttributeError:
    1891433            cmpfn = None
    1901434        atomic = self.parent().base_ring()._repr_option('element_is_atomic')
    191         return self._prod.latex(self.parent().variable_names(), 
     1435        return self._prod.latex(self.parent().variable_names(),
    1921436                                atomic_coefficients=atomic, cmpfn=cmpfn)
    1931437
    1941438    def __pow__(LaurentPolynomial_mpair self, n, m):
    cdef class LaurentPolynomial_mpair(Commu 
    3791623        and neither `x \cdot m(x,y)` nor `y \cdot m(x,y)` divides `f(x,y)`.
    3801624
    3811625        INPUT:
    382        
     1626
    3831627        - ``mon`` -- a monomial
    3841628
    3851629        OUTPUT:
    cdef class LaurentPolynomial_mpair(Commu 
    3991643        this case, ``P``.
    4001644
    4011645        ::
    402        
     1646
    4031647            sage: f = 2 * x * y
    4041648            sage: c = f.coefficient(x*y); c
    4051649            2
    4061650            sage: c.parent()
    4071651            Multivariate Laurent Polynomial Ring in x, y over Rational Field
    408            
     1652
    4091653            sage: P.<x,y> = LaurentPolynomialRing(QQ)
    4101654            sage: f = (y^2 - x^9 - 7*x*y^2 + 5*x*y)*x^-3; f
    4111655            -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2
    cdef class LaurentPolynomial_mpair(Commu 
    4191663            -7*y^2 + 5*y
    4201664            sage: f.coefficient(x^-2*y^2)
    4211665            -7
    422             sage: f.coefficient(1)       
     1666            sage: f.coefficient(1)
    4231667            -x^6 - 7*x^-2*y^2 + 5*x^-2*y + x^-3*y^2
    4241668        """
    4251669        if mon.parent() is not self.parent():
    cdef class LaurentPolynomial_mpair(Commu 
    4391683        EXAMPLES::
    4401684
    4411685            sage: L.<x,y,z> = LaurentPolynomialRing(QQ,order='degrevlex')
    442             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7       
    443             sage: f.coefficients()                                 
     1686            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
     1687            sage: f.coefficients()
    4441688            [4, 3, 2, 1]
    445             sage: L.<x,y,z> = LaurentPolynomialRing(QQ,order='lex')     
    446             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
    447             sage: f.coefficients()                                 
     1689            sage: L.<x,y,z> = LaurentPolynomialRing(QQ,order='lex')
     1690            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
     1691            sage: f.coefficients()
    4481692            [4, 1, 2, 3]
    4491693        """
    4501694        return self._poly.coefficients()
    cdef class LaurentPolynomial_mpair(Commu 
    4601704        EXAMPLES::
    4611705
    4621706            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    463             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     1707            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    4641708            sage: f.variables()
    4651709            (z, y, x)
    4661710            sage: f.variables(sort=False) #random
    cdef class LaurentPolynomial_mpair(Commu 
    4841728        EXAMPLES::
    4851729
    4861730            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    487             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     1731            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    4881732            sage: list(sorted(f.dict().iteritems()))
    4891733            [((3, 1, 0), 3), ((4, 0, -2), 2), ((6, -7, 0), 1), ((7, 0, -1), 4)]
    4901734        """
    4911735        if self._prod is None:
    4921736            self._compute_polydict()
    4931737        return self._prod.dict()
    494        
     1738
    4951739    cpdef ModuleElement _add_(self, ModuleElement _right):
    4961740        """
    4971741        Returns the Laurent polynomial self + right.
    498        
     1742
    4991743        EXAMPLES::
    5001744
    5011745            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    5161760        else:
    5171761            ans._poly += right._poly
    5181762        return ans
    519            
     1763
    5201764    cpdef ModuleElement _sub_(self, ModuleElement _right):
    5211765        """
    5221766        Returns the Laurent polynomial self - right.
    523        
     1767
    5241768        EXAMPLES::
    5251769
    5261770            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    5291773            sage: f - g
    5301774            -y - z + y^-1
    5311775
    532         """       
     1776        """
    5331777        cdef LaurentPolynomial_mpair ans = self._new_c()
    5341778        cdef LaurentPolynomial_mpair right = <LaurentPolynomial_mpair>_right
    5351779        cdef ETuple a, b
    cdef class LaurentPolynomial_mpair(Commu 
    5601804        ans._mon = self._mon
    5611805        ans._poly = -self._poly
    5621806        return ans
    563        
     1807
    5641808    cpdef ModuleElement _lmul_(self, RingElement right):
    5651809        """
    5661810        Returns self * right where right is in self's base ring.
    567        
     1811
    5681812        EXAMPLES::
    5691813
    5701814            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    5771821        ans._mon = self._mon
    5781822        ans._poly = self._poly * right
    5791823        return ans
    580    
     1824
    5811825    cpdef ModuleElement _rmul_(self, RingElement left):
    5821826        """
    5831827        Returns left*self where left is in self's base ring.
    584        
     1828
    5851829        EXAMPLES::
    5861830
    5871831            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    5981842    cpdef RingElement _mul_(self, RingElement right):
    5991843        """
    6001844        Return self*right.
    601        
     1845
    6021846        EXAMPLES::
    6031847
    6041848            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    6351879    def exponents(self):
    6361880        """
    6371881        Returns a list of the exponents of self.
    638        
     1882
    6391883        EXAMPLES::
    6401884
    6411885            sage: L.<w,z> = LaurentPolynomialRing(QQ)
    cdef class LaurentPolynomial_mpair(Commu 
    6551899        EXAMPLES::
    6561900
    6571901            sage: R.<x,y,z> = LaurentPolynomialRing(QQ)
    658             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     1902            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    6591903            sage: f.degree(x)
    6601904            7
    6611905            sage: f.degree(y)
    cdef class LaurentPolynomial_mpair(Commu 
    6681912            return self._poly.total_degree() + sum(self._mon)
    6691913
    6701914        g = self.parent().gens()
    671         no_generator_found = True 
     1915        no_generator_found = True
    6721916        for i in range(len(g)):
    6731917            if g[i] is x:
    6741918                no_generator_found = False
    cdef class LaurentPolynomial_mpair(Commu 
    6761920        if no_generator_found:
    6771921            raise TypeError, "x must be a generator of parent"
    6781922        return self._poly.degree(self.parent().polynomial_ring().gens()[i]) + self._mon[i]
    679        
     1923
    6801924
    6811925
    6821926    def has_inverse_of(self, i):
    cdef class LaurentPolynomial_mpair(Commu 
    6841928        INPUT:
    6851929
    6861930        - ``i`` -- The index of a generator of ``self.parent()``
    687            
     1931
    6881932        OUTPUT:
    6891933
    6901934        Returns True if self contains a monomial including the inverse of
    cdef class LaurentPolynomial_mpair(Commu 
    6931937        EXAMPLES::
    6941938
    6951939            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    696             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     1940            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    6971941            sage: f.has_inverse_of(0)
    6981942            False
    6991943            sage: f.has_inverse_of(1)
    cdef class LaurentPolynomial_mpair(Commu 
    7171961        EXAMPLES::
    7181962
    7191963            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    720             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     1964            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    7211965            sage: f.has_any_inverse()
    7221966            True
    7231967            sage: g = x^2 + y^2
    cdef class LaurentPolynomial_mpair(Commu 
    7281972            if m < 0:
    7291973                return True
    7301974        return False
    731        
     1975
    7321976    def __call__(self, *x, **kwds):
    7331977        """
    7341978
    cdef class LaurentPolynomial_mpair(Commu 
    7431987            Traceback (most recent call last):
    7441988            ...
    7451989            ZeroDivisionError
    746            
     1990
    7471991        TESTS::
    7481992
    7491993            sage: f = x + 2*y + 3*z
    cdef class LaurentPolynomial_mpair(Commu 
    7592003            6
    7602004        """
    7612005        n = self.parent().ngens()
    762        
     2006
    7632007        if len(kwds) > 0:
    7642008            f = self.subs(**kwds)
    7652009            if len(x) > 0:
    cdef class LaurentPolynomial_mpair(Commu 
    7682012                return f
    7692013
    7702014        cdef int l = len(x)
    771        
     2015
    7722016        if l == 1 and (PY_TYPE_CHECK(x[0], tuple) or PY_TYPE_CHECK(x[0], list)):
    7732017            x = x[0]
    7742018            l = len(x)
    775            
     2019
    7762020        if l != n:
    7772021            raise TypeError, "number of arguments does not match the number of generators in parent."
    7782022
    cdef class LaurentPolynomial_mpair(Commu 
    8272071        """
    8282072        if in_dict is not None and kwds:
    8292073            raise ValueError, "you cannot specify both a dictionary and keyword arguments"
    830        
     2074
    8312075        g = self.parent().gens()
    8322076        repr_g = [repr(i) for i in g]
    8332077        vars = []
    cdef class LaurentPolynomial_mpair(Commu 
    8522096                    term *= kwds[repr_g[i]]**mon[i]
    8532097                else:
    8542098                    term *= g[i]**mon[i]
     2099
    8552100            out += term
    856        
     2101
    8572102        return out
    8582103
     2104    def is_univariate(self):
     2105        """
     2106        Return ``True`` if this is a univariate or constant Laurent polynomial,
     2107        and ``False`` otherwise.
     2108
     2109        EXAMPLES::
     2110
     2111            sage: R.<x,y,z> = LaurentPolynomialRing(QQ)
     2112            sage: f = (x^3 + y^-3)*z
     2113            sage: f.is_univariate()
     2114            False
     2115            sage: g = f(1,y,4)
     2116            sage: g.is_univariate()
     2117            True
     2118            sage: R(1).is_univariate()
     2119            True
     2120        """
     2121        return len(self.variables()) < 2
     2122
     2123    def univariate_polynomial(self, R=None):
     2124        """
     2125        Returns a univariate polynomial associated to this
     2126        multivariate polynomial.
     2127
     2128        INPUT:
     2129
     2130        - ``R`` - (default: ``None``) PolynomialRing
     2131
     2132        If this polynomial is not in at most one variable, then a
     2133        ``ValueError`` exception is raised.  The new polynomial is over
     2134        the same base ring as the given ``LaurentPolynomial`` and in the
     2135        variable ``x`` if no ring ``R`` is provided.
     2136
     2137        EXAMPLES::
     2138
     2139            sage: R.<x, y> = LaurentPolynomialRing(ZZ)
     2140            sage: f = 3*x^2 - 2*y^-1 + 7*x^2*y^2 + 5
     2141            sage: f.univariate_polynomial()
     2142            Traceback (most recent call last):
     2143            ...
     2144            TypeError: polynomial must involve at most one variable
     2145            sage: g = f(10,y); g
     2146            700*y^2 + 305 - 2*y^-1
     2147            sage: h = g.univariate_polynomial(); h
     2148            -2*y^-1 + 305 + 700*y^2
     2149            sage: h.parent()
     2150            Univariate Laurent Polynomial Ring in y over Rational Field
     2151            sage: g.univariate_polynomial(LaurentPolynomialRing(QQ,'z'))
     2152            -2*z^-1 + 305 + 700*z^2
     2153
     2154        Here's an example with a constant multivariate polynomial::
     2155
     2156            sage: g = R(1)
     2157            sage: h = g.univariate_polynomial(); h
     2158            1
     2159            sage: h.parent()
     2160            Univariate Laurent Polynomial Ring in x over Integer Ring
     2161        """
     2162        from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
     2163        v = self.variables()
     2164        if len(v) > 1:
     2165            raise TypeError, "polynomial must involve at most one variable"
     2166        elif len(v) == 1:
     2167            x = v[0]
     2168            i = self._parent.gens().index(x)
     2169        else:
     2170            x = 'x'
     2171            i = 0
     2172
     2173        #construct ring if none
     2174        if R is None:
     2175            R = LaurentPolynomialRing(self.base_ring(),x)
     2176
     2177        return R(dict((m[i],c) for m,c in self.dict().items()))
    8592178
    8602179    def factor(self):
    8612180        """
    cdef class LaurentPolynomial_mpair(Commu 
    8642183        EXAMPLES::
    8652184
    8662185            sage: L.<x,y,z> = LaurentPolynomialRing(QQ)
    867             sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7 
     2186            sage: f = 4*x^7*z^-1 + 3*x^3*y + 2*x^4*z^-2 + x^6*y^-7
    8682187            sage: f.factor()
    8692188            (x^3*y^-7*z^-2) * (4*x^4*y^7*z + 3*y^8*z^2 + 2*x*y^7 + x^3*z^2)
    8702189        """
    8712190        pf = self._poly.factor()
    8722191        u = self.parent(pf.unit().dict()) # self.parent won't currently take polynomials
    873        
     2192
    8742193        g = self.parent().gens()
    8752194        for i in self._mon.nonzero_positions():
    8762195            u *= g[i]**self._mon[i]
  • sage/rings/polynomial/laurent_polynomial_ring.py

    diff --git a/sage/rings/polynomial/laurent_polynomial_ring.py b/sage/rings/polynomial/laurent_polynomial_ring.py
    a b  
    11"""
    22Ring of Laurent Polynomials
    33
    4 If `R` is a commutative ring, then the ring of Laurent polynomials in `n` variables
    5 over `R` is `R[x_1^{\pm 1}, x_2^{\pm 1}, \ldots, x_n^{\pm 1}]`.  We implement
    6 it as a quotient ring
     4If `R` is a commutative ring, then the ring of Laurent polynomials in `n`
     5variables over `R` is `R[x_1^{\pm 1}, x_2^{\pm 1}, \ldots, x_n^{\pm 1}]`.
     6We implement it as a quotient ring
    77
    8 .. math::
     8.. MATH::
    99
    1010    R[x_1, y_1, x_2, y_2, \ldots, x_n, y_n] / (x_1 y_1 - 1, x_2 y_2 - 1, \ldots, x_n y_n - 1).
    1111
    from sage.structure.parent_gens import n 
    4343from sage.structure.element import is_Element
    4444from sage.rings.ring import is_Ring
    4545from sage.rings.integer import Integer
     46from sage.rings.polynomial.polynomial_ring_constructor import _single_variate as _single_variate_poly
    4647from sage.rings.polynomial.polynomial_ring_constructor import _multi_variate as _multi_variate_poly
    4748from sage.misc.latex import latex
    48 from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair
     49from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair, LaurentPolynomial_univariate
    4950from sage.rings.ring import CommutativeRing
    5051from sage.structure.parent_gens import ParentWithGens
    5152
    5253def is_LaurentPolynomialRing(R):
    5354    """
    5455    Returns True if and only if R is a Laurent polynomial ring.
    55    
     56
    5657    EXAMPLES::
    5758
    5859        sage: from sage.rings.polynomial.laurent_polynomial_ring import is_LaurentPolynomialRing
    def LaurentPolynomialRing(base_ring, arg 
    8283    named, and the other arguments must be given positionally.
    8384
    8485    INPUT:
    85    
     86
    8687    - ``base_ring`` -- a commutative ring
    8788    - ``name`` -- a string
    8889    - ``names`` -- a list or tuple of names, or a comma separated string
    def LaurentPolynomialRing(base_ring, arg 
    9091    - ``sparse`` -- bool (default: False), whether or not elements are sparse
    9192    - ``order`` -- string or
    9293      :class:`~sage.rings.polynomial.term_order.TermOrder`, e.g.,
    93        
     94
    9495        - ``'degrevlex'`` (default) -- degree reverse lexicographic
    9596        - ``'lex'`` -- lexicographic
    9697        - ``'deglex'`` -- degree lexicographic
    9798        - ``TermOrder('deglex',3) + TermOrder('deglex',3)`` -- block ordering
    98                  
     99
    99100    OUTPUT:
    100101
    101102    ``LaurentPolynomialRing(base_ring, name, sparse=False)`` returns a
    def LaurentPolynomialRing(base_ring, arg 
    119120    that polynomial ring.
    120121
    121122    ::
    122    
     123
    123124        sage: R._assign_names(['z','w'])
    124125        Traceback (most recent call last):
    125126        ...
    126127        ValueError: variable names cannot be changed after object creation.
    127128
    128            
     129
    129130    EXAMPLES:
    130131
    131132    1. ``LaurentPolynomialRing(base_ring, name, sparse=False)``
    def LaurentPolynomialRing(base_ring, arg 
    140141
    141142           sage: R.<w> = LaurentPolynomialRing(QQ)
    142143           sage: (1 + w)^3
    143            w^3 + 3*w^2 + 3*w + 1
    144        
     144           1 + 3*w + 3*w^2 + w^3
     145
    145146       You must specify a name::
    146            
     147
    147148           sage: LaurentPolynomialRing(QQ)
    148149           Traceback (most recent call last):
    149150           ...
    def LaurentPolynomialRing(base_ring, arg 
    159160
    160161           sage: LaurentPolynomialRing(QQ, 'x') == LaurentPolynomialRing(QQ, 'y')
    161162           False
    162        
     163
    163164    2. ``LaurentPolynomialRing(base_ring, names,   order='degrevlex')``
    164165
    165166       ::
    166        
     167
    167168           sage: R = LaurentPolynomialRing(QQ, 'a,b,c'); R
    168169           Multivariate Laurent Polynomial Ring in a, b, c over Rational Field
    169170
    def LaurentPolynomialRing(base_ring, arg 
    176177       All three rings are identical.
    177178
    178179       ::
    179            
     180
    180181           sage: (R is S) and  (S is T)
    181182           True
    182183
    def LaurentPolynomialRing(base_ring, arg 
    201202
    202203           sage: LaurentPolynomialRing(QQ, 'x', 10)
    203204           Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field
    204            
     205
    205206           sage: LaurentPolynomialRing(GF(7), 'y', 5)
    206207           Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7
    207208
    def LaurentPolynomialRing(base_ring, arg 
    213214       method, all those variable names are available for interactive use::
    214215
    215216           sage: R = LaurentPolynomialRing(GF(7),15,'w'); R
    216            Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7       
     217           Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7
    217218           sage: R.inject_variables()
    218219           Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14
    219220           sage: (w0 + 2*w8 + w13)^2
    def LaurentPolynomialRing(base_ring, arg 
    268269            n = len(names)
    269270            R = _multi_variate(base_ring, names, n, sparse, order)
    270271    elif isinstance(arg1, (list, tuple)):
    271         # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'):       
     272        # LaurentPolynomialRing(base_ring, names (list or tuple), order='degrevlex'):
    272273        names = arg1
    273274        n = len(names)
    274275        R = _multi_variate(base_ring, names, n, sparse, order)
    def _get_from_cache(key): 
    296297        if _cache.has_key(key):
    297298            return _cache[key]   # put () here to re-enable weakrefs
    298299    except TypeError, msg:
    299         raise TypeError, 'key = %s\n%s'%(key,msg)       
     300        raise TypeError, 'key = %s\n%s'%(key,msg)
    300301    return None
    301302
    302303def _save_in_cache(key, R):
    def _save_in_cache(key, R): 
    312313        True
    313314    """
    314315    try:
    315         # We disable weakrefs since they cause segfault at the end of doctesting. 
     316        # We disable weakrefs since they cause segfault at the end of doctesting.
    316317        #weakref.ref(R)
    317         _cache[key] = R   
     318        _cache[key] = R
    318319    except TypeError, msg:
    319320        raise TypeError, 'key = %s\n%s'%(key,msg)
    320321
    def _single_variate(base_ring, names, sp 
    326327        sage: _single_variate(QQ, ('x',), False)
    327328        Univariate Laurent Polynomial Ring in x over Rational Field
    328329    """
    329     ############################################################
    330     # This should later get moved to an actual single variate  #
    331     # implementation with valuation tracking,                  #
    332     # but I don't want to right now.                           #
    333     ############################################################
    334     # We need to come up with a name for the inverse that is easy to search
    335     # for in a string *and* doesn't overlap with the name that we already have.
    336     # For now, I'm going to use a name mangling with checking method.
    337330    names = normalize_names(1, names)
    338331    key = (base_ring, names, sparse)
    339332    P = _get_from_cache(key)
    def _single_variate(base_ring, names, sp 
    345338            prepend_string += 'k'
    346339        else:
    347340            break
    348     R = _multi_variate_poly(base_ring, names, 1, sparse, 'degrevlex', None)
    349     P = LaurentPolynomialRing_mpair(R, prepend_string, names)
     341    R = _single_variate_poly(base_ring, names, sparse, None)
     342    P = LaurentPolynomialRing_univariate(R, names)
    350343    _save_in_cache(key, P)
    351344    return P
    352345
    def _multi_variate(base_ring, names, n,  
    371364    elif isinstance(names, str):
    372365        if ',' in names:
    373366            names = tuple(names.split(','))
    374            
     367
    375368    key = (base_ring, names, n, sparse, order)
    376369    P = _get_from_cache(key)
    377370    if P is not None:
    class LaurentPolynomialRing_generic(Comm 
    416409        self._R = R
    417410        self._prepend_string = prepend_string
    418411        CommutativeRing.__init__(self, R.base_ring(), names=names)
    419         self._populate_coercion_lists_(element_constructor=self._element_constructor_, 
     412        self._populate_coercion_lists_(element_constructor=self._element_constructor_,
    420413                                       init_no_parent=True)
    421414
    422415
    class LaurentPolynomialRing_generic(Comm 
    470463        """
    471464        if i < 0 or i >= self._n:
    472465            raise ValueError, "generator not defined"
    473         return self(self._R.gen(i))
     466        try:
     467            return self.__generators[i]
     468        except AttributeError:
     469            self.__generators = tuple(self(x) for x in self._R.gens())
     470            return self.__generators[i]
     471
    474472
    475473    def is_integral_domain(self, proof = True):
    476474        """
    477475        Returns True if self is an integral domain.
    478        
     476
    479477        EXAMPLES::
    480478
    481479            sage: LaurentPolynomialRing(QQ,2,'x').is_integral_domain()
    class LaurentPolynomialRing_generic(Comm 
    501499            NotImplementedError
    502500        """
    503501        raise NotImplementedError
    504    
     502
    505503    def construction(self):
    506504        """
    507505        Returns the construction of self.
    508        
     506
    509507        EXAMPLES::
    510508
    511509            sage: LaurentPolynomialRing(QQ,2,'x,y').construction()
    class LaurentPolynomialRing_generic(Comm 
    520518        else:
    521519            return LaurentPolynomialFunctor(vars[-1], True), LaurentPolynomialRing(self.base_ring(), vars[:-1])
    522520
     521
     522
    523523    def completion(self, p, prec=20, extras=None):
    524524        """
    525525        EXAMPLES::
    526526
    527             sage: LaurentPolynomialRing(QQ,2,'x').completion(3)
    528             Traceback (most recent call last):
    529             ...
    530             NotImplementedError
     527            sage: P.<x>=LaurentPolynomialRing(QQ)
     528            sage: P
     529            Univariate Laurent Polynomial Ring in x over Rational Field
     530            sage: PP=P.completion(x)
     531            sage: PP
     532            Laurent Series Ring in x over Rational Field
     533            sage: f=1-1/x
     534            sage: PP(f)
     535            -x^-1 + 1
     536            sage: 1/PP(f)
     537            -x - x^2 - x^3 - x^4 - x^5 - x^6 - x^7 - x^8 - x^9 - x^10 - x^11 - x^12 - x^13 - x^14 - x^15 - x^16 - x^17 - x^18 - x^19 - x^20 + O(x^21)
    531538        """
    532         raise NotImplementedError
     539        if str(p) == self._names[0] and self._n == 1:
     540            from sage.rings.laurent_series_ring import LaurentSeriesRing
     541            return LaurentSeriesRing(self.base_ring(), name=self._names[0])
     542        else:
     543            raise TypeError, "Cannot complete %s with respect to %s" % (self, p)
     544
     545
     546
    533547
    534548    def remove_var(self, var):
    535549        """
    class LaurentPolynomialRing_generic(Comm 
    562576                      From: Multivariate Polynomial Ring in x, y over Rational Field
    563577                      To:   Multivariate Laurent Polynomial Ring in x, y over Rational Field
    564578        """
    565        
     579
    566580        if R is self._R:
    567581            from sage.structure.coerce_maps import CallableConvertMap
    568582            return CallableConvertMap(R, self, self._element_constructor_,
    569583                                      parent_as_first_arg=False)
     584        elif isinstance(R, LaurentPolynomialRing_generic) and \
     585             R.variable_names() == self.variable_names() and \
     586             self.base_ring().has_coerce_map_from(R.base_ring()):
     587            return True
    570588        else:
    571589            f = self._R.coerce_map_from(R)
    572590            if f is not None:
    class LaurentPolynomialRing_generic(Comm 
    614632            Traceback (most recent call last):
    615633            ...
    616634            NotImplementedError
    617         """       
     635        """
    618636        # One may eventually want ideals in these guys.
    619637        raise NotImplementedError
    620638
    class LaurentPolynomialRing_generic(Comm 
    655673
    656674            sage: LaurentPolynomialRing(QQ,2,'x').term_order()
    657675            Degree reverse lexicographic term order
    658            
     676
    659677        """
    660678        return self._R.term_order()
    661679
    class LaurentPolynomialRing_generic(Comm 
    665683
    666684            sage: LaurentPolynomialRing(QQ,2,'x').is_finite()
    667685            False
    668            
     686
    669687        """
    670688        return False
    671689
    class LaurentPolynomialRing_generic(Comm 
    681699    def polynomial_ring(self):
    682700        """
    683701        Returns the polynomial ring associated with self.
    684        
     702
    685703        EXAMPLES::
    686704
    687705            sage: LaurentPolynomialRing(QQ,2,'x').polynomial_ring()
    class LaurentPolynomialRing_generic(Comm 
    752770            base_ring = self.base_ring()
    753771        if names is None:
    754772            names = self.variable_names()
    755         if order is None:
    756             order = self.polynomial_ring().term_order()
    757773        if self._n == 1:
    758774            return LaurentPolynomialRing(base_ring, names[0], sparse = sparse)
    759775        else:
     776            if order is None:
     777                order = self.polynomial_ring().term_order()
    760778            return LaurentPolynomialRing(base_ring, self._n, names, order = order)
    761779
    762780
     781class LaurentPolynomialRing_univariate(LaurentPolynomialRing_generic):
     782    def __init__(self, R, names):
     783        """
     784        EXAMPLES::
     785
     786            sage: L = LaurentPolynomialRing(QQ,'x')
     787            sage: type(L)
     788            <class 'sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_univariate_with_category'>
     789            sage: L == loads(dumps(L))
     790            True
     791        """
     792        if R.ngens() != 1:
     793            raise ValueError("must be 1 generator")
     794        if not R.base_ring().is_integral_domain():
     795            raise ValueError("base ring must be an integral domain")
     796        LaurentPolynomialRing_generic.__init__(self, R, '', names)
     797
     798    def _element_constructor_(self, x):
     799        """
     800        EXAMPLES::
     801
     802            sage: L = LaurentPolynomialRing(QQ, 'x')
     803            sage: L(1/2)
     804            1/2
     805        """
     806        return LaurentPolynomial_univariate(self, x)
     807
     808    def __reduce__(self):
     809        """
     810        Used in pickling.
     811
     812        EXAMPLES::
     813
     814            sage: L = LaurentPolynomialRing(QQ, 'x')
     815            sage: loads(dumps(L)) == L
     816            True
     817        """
     818        return LaurentPolynomialRing_univariate, (self._R, self._names)
     819
    763820class LaurentPolynomialRing_mpair(LaurentPolynomialRing_generic):
    764821    def __init__(self, R, prepend_string, names):
    765822        """
    class LaurentPolynomialRing_mpair(Lauren 
    787844            1/2
    788845        """
    789846        return LaurentPolynomial_mpair(self, x)
    790    
     847
     848    def __reduce__(self):
     849        """
     850        Used in pickling.
     851
     852        EXAMPLES::
     853
     854            sage: L = LaurentPolynomialRing(QQ,2,'x')
     855            sage: loads(dumps(L)) == L
     856            True
     857        """
     858        return LaurentPolynomialRing_mpair, (self._R, self._prepend_string, self._names)
     859
     860