Ticket #3662: trac_3662-1.patch

File trac_3662-1.patch, 51.1 kB (added by mhansen, 4 months ago)
  • a/sage/combinat/all.py

    old new  
    44from sage.combinat.crystals.all import * 
    55from sage.combinat.dlx import * #?? 
    66 
    7 #Combinatorial Algebra 
     7# Free modules and friends 
     8from free_module import CombinatorialFreeModule 
    89from combinatorial_algebra import CombinatorialAlgebra 
    910 
    1011 
  • a/sage/combinat/combinatorial_algebra.py

    old new  
    5656#                  http://www.gnu.org/licenses/ 
    5757#***************************************************************************** 
    5858 
    59 from sage.rings.all import Ring, Integer 
    60 from sage.misc.misc import repr_lincomb 
     59from sage.rings.all import Integer 
    6160from sage.algebras.algebra import Algebra 
     61from sage.rings.ring import Ring 
    6262from sage.algebras.algebra_element import AlgebraElement 
    63 import sage.structure.parent_base 
    64 import sage.combinat.partition 
    65 from sage.modules.free_module_element import vector 
    6663from sage.matrix.all import MatrixSpace 
     64from sage.combinat.free_module import CombinatorialFreeModuleElement, CombinatorialFreeModule, CombinatorialFreeModuleInterface 
    6765 
    68 class CombinatorialAlgebraElement(AlgebraElement): 
     66class CombinatorialAlgebraElement(AlgebraElement, CombinatorialFreeModuleElement): 
    6967    def __init__(self, A, x): 
    7068        """ 
    7169        Create a combinatorial algebra element x.  This should never 
     
    8280        AlgebraElement.__init__(self, A) 
    8381        self._monomial_coefficients = x 
    8482 
    85     def __iter__(self): 
    86         """ 
    87         EXAMPLES: 
    88             sage: s = SFASchur(QQ) 
    89             sage: a = s([2,1]) + s([3]) 
    90             sage: [i for i in sorted(a)] 
    91             [([2, 1], 1), ([3], 1)] 
    9283 
    93         """ 
    94         return self._monomial_coefficients.iteritems() 
    95  
    96     def __contains__(self, x): 
    97         """ 
    98         Returns whether or not a combinatorial object x indexing a basis 
    99         element is in the support of self. 
    100          
    101         EXAMPLES: 
    102             sage: s = SFASchur(QQ) 
    103             sage: a = s([2,1]) + s([3]) 
    104             sage: Partition([2,1]) in a 
    105             True 
    106             sage: Partition([1,1,1]) in a 
    107             False 
    108         """ 
    109         return x in self._monomial_coefficients and self._monomial_coefficients[x] != 0 
    110  
    111     def monomial_coefficients(self): 
    112         """ 
    113         Return the internal dictionary which has the combinatorial 
    114         objects indexing the basis as keys and their corresponding 
    115         coefficients as values. 
    116  
    117         EXAMPLES: 
    118             sage: s = SFASchur(QQ) 
    119             sage: a = s([2,1])+2*s([3,2]) 
    120             sage: d = a.monomial_coefficients() 
    121             sage: type(d) 
    122             <type 'dict'> 
    123             sage: d[ Partition([2,1]) ] 
    124             1 
    125             sage: d[ Partition([3,2]) ] 
    126             2 
    127         """ 
    128         return self._monomial_coefficients 
    129      
    130     def __repr__(self): 
    131         """ 
    132         EXAMPLES: 
    133             sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
    134             sage: a = 2 + QS3([2,1,3]) 
    135             sage: print a.__repr__() 
    136             2*[1, 2, 3] + [2, 1, 3] 
    137         """ 
    138         v = self._monomial_coefficients.items() 
    139         v.sort() 
    140         prefix = self.parent().prefix() 
    141         mons = [ prefix + repr(m) for (m, _) in v ] 
    142         cffs = [ x for (_, x) in v ] 
    143         x = repr_lincomb(mons, cffs).replace("*1 "," ") 
    144         if x[len(x)-2:] == "*1": 
    145             return x[:len(x)-2] 
    146         else: 
    147             return x 
    148  
    149     def _latex_(self): 
    150         """ 
    151         EXAMPLES: 
    152             sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
    153             sage: a = 2 + QS3([2,1,3]) 
    154             sage: latex(a) #indirect doctest 
    155             2[1,2,3] + [2,1,3] 
    156         """ 
    157         v = self._monomial_coefficients.items() 
    158         v.sort() 
    159         prefix = self.parent().prefix() 
    160         if prefix == "": 
    161             mons = [ prefix + '[' + ",".join(map(str, m)) + ']' for (m, _) in v ] 
    162         else: 
    163             mons = [ prefix + '_{' + ",".join(map(str, m)) + '}' for (m, _) in v ] 
    164         cffs = [ x for (_, x) in v ] 
    165         x = repr_lincomb(mons, cffs, is_latex=True).replace("*1 "," ") 
    166         if x[len(x)-2:] == "*1": 
    167             return x[:len(x)-2] 
    168         else: 
    169             return x 
    170          
    171     def __cmp__(left, right): 
    172         """ 
    173         The ordering is the one on the underlying sorted list of 
    174         (monomial,coefficients) pairs. 
    175  
    176         EXAMPLES: 
    177             sage: s = SFASchur(QQ) 
    178             sage: a = s([2,1]) 
    179             sage: b = s([1,1,1]) 
    180             sage: cmp(a,b) #indirect doctest 
    181             1 
    182         """ 
    183         nonzero = lambda mc: mc[1] != 0 
    184         v = filter(nonzero, left._monomial_coefficients.items()) 
    185         v.sort() 
    186         w = filter(nonzero, right._monomial_coefficients.items()) 
    187         w.sort() 
    188         return cmp(v, w) 
    189  
    190     def _add_(self, y): 
    191         """ 
    192         EXAMPLES: 
    193             sage: s = SFASchur(QQ) 
    194             sage: s([2,1]) + s([5,4]) # indirect doctest 
    195             s[2, 1] + s[5, 4] 
    196             sage: a = s([2,1]) + 0 
    197             sage: len(a.monomial_coefficients()) 
    198             1 
    199         """ 
    200         A = self.parent() 
    201         BR = A.base_ring() 
    202         z_elt = dict(self._monomial_coefficients) 
    203         for m, c in y._monomial_coefficients.iteritems(): 
    204             if z_elt.has_key(m): 
    205                 cm = z_elt[m] + c 
    206                 if cm == 0: 
    207                     del z_elt[m] 
    208                 else: 
    209                     z_elt[m] = cm 
    210             else: 
    211                 z_elt[m] = c 
    212  
    213  
    214         #Remove all entries that are equal to 0 
    215         del_list = [] 
    216         zero = BR(0) 
    217         for m, c in z_elt.iteritems(): 
    218             if c == zero: 
    219                 del_list.append(m) 
    220         for m in del_list: 
    221             del z_elt[m] 
    222              
    223         return A._from_dict(z_elt) 
    224  
    225  
    226     def _neg_(self): 
    227         """ 
    228         EXAMPLES: 
    229             sage: s = SFASchur(QQ) 
    230             sage: -s([2,1]) # indirect doctest 
    231             -s[2, 1] 
    232         """ 
    233         return self.map_coefficients(lambda c: -c) 
    234  
    235  
    236     def _sub_(self, y): 
    237         """ 
    238         EXAMPLES: 
    239             sage: s = SFASchur(QQ) 
    240             sage: s([2,1]) - s([5,4]) # indirect doctest 
    241             s[2, 1] - s[5, 4] 
    242         """ 
    243         A = self.parent() 
    244         BR = A.base_ring() 
    245         z_elt = dict(self._monomial_coefficients) 
    246         for m, c in y._monomial_coefficients.iteritems(): 
    247             if z_elt.has_key(m): 
    248                 cm = z_elt[m] - c 
    249                 if cm == 0: 
    250                     del z_elt[m] 
    251                 else: 
    252                     z_elt[m] = cm 
    253             else: 
    254                 z_elt[m] = -c 
    255  
    256         #Remove all entries that are equal to 0 
    257         zero = BR(0) 
    258         del_list = [] 
    259         for m, c in z_elt.iteritems(): 
    260             if c == zero: 
    261                 del_list.append(m) 
    262         for m in del_list: 
    263             del z_elt[m] 
    264                  
    265         return A._from_dict(z_elt) 
    266                          
    26784    def _mul_(self, y): 
    26885        """ 
    26986        EXAMPLES: 
     
    316133            sage: s([2])^2 
    317134            s[2, 2] + s[3, 1] + s[4] 
    318135 
    319  
    320136        TESTS: 
    321137            sage: s = SFASchur(QQ) 
    322138            sage: z = s([2,1]) 
     
    339155        for _ in range(n): 
    340156            z *= self 
    341157        return z 
    342  
    343     def _coefficient_fast(self, m, default=None): 
    344         """ 
    345         Returns the coefficient of m in self, where m is key 
    346         in self._monomial_coefficients. 
    347  
    348         EXAMPLES: 
    349             sage: p = Partition([2,1]) 
    350             sage: s = SFASchur(QQ) 
    351             sage: a = s([2,1]) 
    352             sage: a._coefficient_fast([2,1]) 
    353             Traceback (most recent call last): 
    354             ... 
    355             TypeError: list objects are unhashable 
    356             sage: a._coefficient_fast(p) 
    357             1 
    358             sage: a._coefficient_fast(p, 2) 
    359             1 
    360         """ 
    361         if default is None: 
    362             default = self.base_ring()(0) 
    363         return self._monomial_coefficients.get(m, default) 
    364  
    365     def coefficient(self, m): 
    366         """ 
    367         EXAMPLES: 
    368             sage: s = SFASchur(QQ) 
    369             sage: z = s([4]) - 2*s([2,1]) + s([1,1,1]) + s([1]) 
    370             sage: z.coefficient([4]) 
    371             1 
    372             sage: z.coefficient([2,1]) 
    373             -2 
    374         """ 
    375         p = self.parent() 
    376         if isinstance(m, p._combinatorial_class.object_class): 
    377             return self._monomial_coefficients.get(m, p.base_ring().zero_element()) 
    378         if m in p._combinatorial_class: 
    379             return self._monomial_coefficients.get(p._combinatorial_class.object_class(m), p.base_ring().zero_element()) 
    380         else: 
    381             raise TypeError, "you must specify an element of %s"%p._combinatorial_class 
    382  
    383  
    384     def is_zero(self): 
    385         """ 
    386         Returns True if and only self == 0. 
    387  
    388         EXAMPLES: 
    389             sage: s = SFASchur(QQ) 
    390             sage: s([2,1]).is_zero() 
    391             False 
    392             sage: s(0).is_zero() 
    393             True 
    394             sage: (s([2,1]) - s([2,1])).is_zero() 
    395             True 
    396         """ 
    397         BR = self.parent().base_ring() 
    398         for v in self._monomial_coefficients.values(): 
    399             if v != BR(0): 
    400                 return False 
    401         return True 
    402  
    403     def __len__(self): 
    404         """ 
    405         Returns the number of basis elements of self with 
    406         nonzero coefficients. 
    407          
    408         EXAMPLES: 
    409             sage: s = SFASchur(QQ) 
    410             sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) 
    411             sage: len(z) 
    412             4 
    413         """ 
    414         return self.length() 
    415      
    416     def length(self): 
    417         """ 
    418         Returns the number of basis elements of self with 
    419         nonzero coefficients. 
    420          
    421         EXAMPLES: 
    422             sage: s = SFASchur(QQ) 
    423             sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) 
    424             sage: z.length() 
    425             4 
    426         """ 
    427         return len( filter(lambda x: self._monomial_coefficients[x] != 0, self._monomial_coefficients) ) 
    428  
    429     def support(self): 
    430         """ 
    431         Returns a pair [mons, cffs] of lists of the monomials 
    432         of self (mons) and their respective coefficients (cffs). 
    433          
    434         EXAMPLES: 
    435             sage: s = SFASchur(QQ) 
    436             sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) 
    437             sage: z.support() 
    438             [[[1], [1, 1, 1], [2, 1], [4]], [1, 1, 1, 1]] 
    439         """ 
    440         v = self._monomial_coefficients.items() 
    441         v.sort() 
    442         mons = [ m for (m, _) in v ] 
    443         cffs = [ x for (_, x) in v ] 
    444         return [mons, cffs] 
    445  
    446     def monomials(self): 
    447         """ 
    448         Returns a list of the combinatorial objects indexing 
    449         the basis elements of self which non-zero coefficients. 
    450  
    451         EXAMPLES: 
    452             sage: s = SFASchur(QQ) 
    453             sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) 
    454             sage: z.monomials() 
    455             [[1], [1, 1, 1], [2, 1], [4]] 
    456         """ 
    457         v = self._monomial_coefficients.items() 
    458         v.sort() 
    459         mons = [ m for (m, _) in v ] 
    460         return mons 
    461      
    462     def coefficients(self): 
    463         """ 
    464         Returns a list of the coefficents appearing on the 
    465         basiselements in self. 
    466  
    467         EXAMPLES: 
    468             sage: s = SFASchur(QQ) 
    469             sage: z = s([4]) + s([2,1]) + s([1,1,1]) + s([1]) 
    470             sage: z.coefficients() 
    471             [1, 1, 1, 1] 
    472         """ 
    473         v = self._monomial_coefficients.items() 
    474         v.sort() 
    475         cffs = [ c for (_, c) in v ] 
    476         return cffs 
    477      
    478     def _vector_(self, new_BR=None): 
    479         """ 
    480         Returns a vector version of self. If new_BR is specified, 
    481         then in returns a vector over new_BR. 
    482  
    483         EXAMPLES: 
    484             sage: QS3 = SymmetricGroupAlgebra(QQ, 3) 
    485             sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) 
    486             sage: a._vector_() 
    487             (2, 0, 0, 0, 0, 4) 
    488             sage: vector(a) 
    489             (2, 0, 0, 0, 0, 4) 
    490             sage: a._vector_(RDF) 
    491             (2.0, 0.0, 0.0, 0.0, 0.0, 4.0) 
    492         """ 
    493         parent = self.parent() 
    494         if parent.get_order() is None: 
    495             cc = parent._combinatorial_class 
    496         else: 
    497             cc = parent.get_order() 
    498              
    499         if new_BR is None: 
    500             new_BR = parent.base_ring() 
    501              
    502         return vector(new_BR, [new_BR(self._monomial_coefficients.get(m, 0)) for m in cc]) 
    503          
    504     def to_vector(self): 
    505         """ 
    506         Returns a vector version of self. 
    507  
    508         EXAMPLES: 
    509             sage: QS3 = SymmetricGroupAlgebra(QQ, 3) 
    510             sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) 
    511             sage: a.to_vector() 
    512             (2, 0, 0, 0, 0, 4) 
    513         """         
    514         return self._vector_() 
    515158 
    516159    def _matrix_(self, new_BR = None): 
    517160        """ 
     
    550193        if new_BR is None: 
    551194            new_BR = BR 
    552195 
    553         MS = MatrixSpace(new_BR, parent._dim, parent._dim
     196        MS = MatrixSpace(new_BR, parent.dimension(), parent.dimension()
    554197        l = [ (self*parent(m)).to_vector() for m in cc ] 
    555198        return MS(l).transpose() 
    556199     
     
    582225        """ 
    583226        return self._matrix_() 
    584227 
    585     def map_coefficients(self, f): 
    586         """ 
    587         Returns a new element of self.parent() obtained 
    588         by applying the function f to all of the coefficients 
    589         of self. 
    590  
    591         EXAMPLES: 
    592             sage: s = SFASchur(QQ) 
    593             sage: a = s([2,1])+2*s([3,2]) 
    594             sage: a.map_coefficients(lambda x: x*2) 
    595             2*s[2, 1] + 4*s[3, 2] 
    596         """ 
    597         res = self.parent()(0) 
    598         z_elt = {} 
    599         for m,c in self.monomial_coefficients().iteritems(): 
    600             z_elt[m] = f(c) 
    601         res._monomial_coefficients = z_elt 
    602         return res 
    603  
    604     def map_basis(self, f): 
    605         """ 
    606         Returns a new element of self.parent() obtained 
    607         by applying the function f to all of the combinatorial 
    608         objects indexing the basis elements. 
    609  
    610         EXAMPLES: 
    611             sage: s = SFASchur(QQ) 
    612             sage: a = s([2,1])+2*s([3,2]) 
    613             sage: a.map_basis(lambda x: x.conjugate()) 
    614             s[2, 1] + 2*s[2, 2, 1] 
    615         """ 
    616         res = self.parent()(0) 
    617         z_elt = {} 
    618         for m,c in self.monomial_coefficients().iteritems(): 
    619             z_elt[f(m)] = c 
    620         res._monomial_coefficients = z_elt 
    621         return res 
    622  
    623     def map_mc(self, f): 
    624         """ 
    625         Returns a new element of self.parent() obtained 
    626         by applying the function f to a monomial coefficient 
    627         (m,c) pair.  f returns a (new_m, new_c) pair. 
    628  
    629         EXAMPLES: 
    630             sage: s = SFASchur(QQ) 
    631             sage: f = lambda m,c: (m.conjugate(), 2*c) 
    632             sage: a = s([2,1]) + s([1,1,1]) 
    633             sage: a.map_mc(f) 
    634             2*s[2, 1] + 2*s[3] 
    635         """ 
    636         z_elt = {} 
    637         for m,c in self.monomial_coefficients().iteritems(): 
    638             new_m, new_c = f(m,c) 
    639             z_elt[new_m] = new_c 
    640         return self.parent()._from_dict(z_elt) 
    641228     
    642 class CombinatorialAlgebra(Algebra): 
    643     def __init__(self, R, element_class=None): 
     229class CombinatorialAlgebra(CombinatorialFreeModuleInterface, Algebra): 
     230    def __init__(self, R, element_class = None): 
    644231        """ 
    645232        TESTS: 
    646233            sage: s = SFASchur(QQ) 
    647234            sage: s == loads(dumps(s)) 
    648235            True 
    649236        """ 
    650         #Make sure R is a ring with unit element 
    651         if not isinstance(R, Ring): 
    652             raise TypeError, "Argument R must be a ring." 
    653         try: 
    654             z = R(Integer(1)) 
    655         except: 
    656             raise ValueError, "R must have a unit element" 
    657  
    658237        #Check to make sure that the user defines the necessary 
    659         #attributes / methods to make the combinatorial algebra 
     238        #attributes / methods to make the combinatorial module 
    660239        #work 
    661240        required = ['_combinatorial_class','_one',] 
    662241        for r in required: 
     
    676255        else: 
    677256            self._element_class = element_class 
    678257 
    679         #Set the dimension 
    680         try: 
    681             self._dim = self._combinatorial_class.count() 
    682         except (ValueError, NotImplementedError): 
    683             self._dim = None 
    684  
    685         self._order = None 
    686  
    687         #Initialize the base structure 
    688         sage.structure.parent_base.ParentWithBase.__init__(self, R) 
    689  
    690     _prefix = "" 
    691     _name   = "CombinatorialAlgebra -- change me" 
    692  
    693     def basis(self): 
    694         """ 
    695         Returns a list of the basis elements of self. 
    696  
    697         EXAMPLES: 
    698             sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
    699             sage: QS3.basis() 
    700             [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] 
    701  
    702         """ 
    703         return [self(x) for x in self._combinatorial_class] 
    704      
    705     def __call__(self, x): 
    706         """ 
    707         Coerce x into self. 
    708  
    709         EXAMPLES: 
    710             sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
    711             sage: QS3(2) 
    712             2*[1, 2, 3] 
    713             sage: QS3([2,3,1]) 
    714             [2, 3, 1] 
    715         """ 
    716         R = self.base_ring() 
    717         eclass = self._element_class 
    718  
    719         #Coerce ints to Integers 
    720         if isinstance(x, int): 
    721             x = Integer(x) 
    722  
    723  
    724         if hasattr(self, '_coerce_start'): 
    725             try: 
    726                 return self._coerce_start(x) 
    727             except TypeError: 
    728                 pass 
    729  
    730         #x is an element of the same type of combinatorial algebra 
    731         if hasattr(x, 'parent') and x.parent().__class__ is self.__class__: 
    732             P = x.parent() 
    733             #same base ring 
    734             if P is self: 
    735                 return x 
    736             #different base ring -- coerce the coefficients from into R 
    737             else: 
    738                 return eclass(self, dict([ (e1,R(e2)) for e1,e2 in x._monomial_coefficients.items()])) 
    739         #x is an element of the basis combinatorial class 
    740         elif isinstance(x, self._combinatorial_class.object_class): 
    741             return eclass(self, {x:R(1)})  
    742         elif x in self._combinatorial_class: 
    743             return eclass(self, {self._combinatorial_class.object_class(x):R(1)}) 
    744         #Coerce elements of the base ring 
    745         elif hasattr(x, 'parent') and x.parent() is R: 
    746             if x == R(0): 
    747                 return eclass(self, {}) 
    748             else: 
    749                 return eclass(self, {self._one:x}) 
    750         #Coerce things that coerce into the base ring 
    751         elif R.has_coerce_map_from(x.parent()): 
    752             rx = R(x) 
    753             if rx == R(0): 
    754                 return eclass(self, {}) 
    755             else: 
    756                 return eclass(self, {self._one:R(x)}) 
    757         else: 
    758             if hasattr(self, '_coerce_end'): 
    759                 try: 
    760                     return self._coerce_start(x) 
    761                 except TypeError: 
    762                     pass 
    763             raise TypeError, "do not know how to make x (= %s) an element of self (=%s)"%(x,self) 
    764  
    765  
    766     def _an_element_impl(self): 
    767         """ 
    768         Returns an element of self, namely the unit element. 
    769  
    770         EXAMPLES: 
    771             sage: s = SFASchur(QQ) 
    772             sage: s._an_element_impl() 
    773             s[] 
    774             sage: _.parent() is s 
    775             True 
    776         """ 
    777         return self._element_class(self, {self._one:self.base_ring()(1)}) 
    778  
    779     def __repr__(self): 
    780         """ 
    781         EXAMPLES: 
    782             sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
    783             sage: print QS3.__repr__() 
    784             Symmetric group algebra of order 3 over Rational Field 
    785  
    786         """ 
    787         return self._name + " over %s"%self.base_ring() 
    788  
    789     def combinatorial_class(self): 
    790         """ 
    791         Returns the combinatorial class that indexes the basis 
    792         elements. 
    793  
    794         EXAMPLES: 
    795             sage: s = SFASchur(QQ) 
    796             sage: s.combinatorial_class() 
    797             Partitions 
    798         """ 
    799         return self._combinatorial_class 
    800  
    801     def _coerce_impl(self, x): 
    802         """ 
    803         EXAMPLES: 
    804             sage: s = SFASchur(QQ) 
    805             sage: s._coerce_impl(2) 
    806             2*s[] 
    807         """ 
    808         try: 
    809             R = x.parent() 
    810             if R.__class__ is self.__class__: 
    811                 #Only perform the coercion if we can go from the base 
    812                 #ring of x to the base ring of self 
    813                 if self.base_ring().has_coerce_map_from( R.base_ring() ): 
    814                     return self(x) 
    815         except AttributeError: 
    816             pass 
    817          
    818         # any ring that coerces to the base ring 
    819         return self._coerce_try(x, [self.base_ring()]) 
    820                                  
    821     def dimension(self): 
    822         """ 
    823         Returns the dimension of the combinatorial algebra (which is given 
    824         by the number of elements in the associated combinatorial class). 
    825  
    826         EXAMPLES: 
    827             sage: s = SFASchur(QQ) 
    828             sage: s.dimension() 
    829             +Infinity 
    830         """ 
    831         return self._combinatorial_class.count() 
    832  
    833     def set_order(self, order): 
    834         """ 
    835         Sets the order of the elements of the combinatorial class. 
    836          
    837         If .set_order() has not been called, then the ordering is 
    838         the one used in the generation of the elements of self's 
    839         associated combinatorial class. 
    840  
    841         EXAMPLES: 
    842             sage: QS2 = SymmetricGroupAlgebra(QQ,2) 
    843             sage: b = QS2.basis() 
    844             sage: b.reverse() 
    845             sage: QS2.set_order(b) 
    846             sage: QS2.get_order() 
    847             [[2, 1], [1, 2]] 
    848  
    849         """ 
    850         self._order = order 
    851  
    852     def get_order(self): 
    853         """ 
    854         Returns the order of the elements in the basis. 
    855  
    856         EXAMPLES: 
    857             sage: QS2 = SymmetricGroupAlgebra(QQ,2) 
    858             sage: QS2.get_order() 
    859             [[1, 2], [2, 1]] 
    860         """ 
    861         if self._order is None: 
    862             self._order = self.combinatorial_class().list() 
    863         return self._order 
    864  
    865     def prefix(self): 
    866         """ 
    867         Returns the prefix used when displaying elements of self. 
    868  
    869         EXAMPLES: 
    870             sage: X = SchubertPolynomialRing(QQ) 
    871             sage: X.prefix() 
    872             'X' 
    873         """ 
    874         return self._prefix 
    875  
    876     def __cmp__(self, other): 
    877         """ 
    878         EXAMPLES: 
    879             sage: XQ = SchubertPolynomialRing(QQ) 
    880             sage: XZ = SchubertPolynomialRing(ZZ) 
    881             sage: XQ == XZ #indirect doctest 
    882             False 
    883             sage: XQ == XQ 
    884             True 
    885         """ 
    886         if not isinstance(other, self.__class__): 
    887             return -1 
    888         c = cmp(self.base_ring(), other.base_ring()) 
    889         if c: return c 
    890         return 0 
    891  
    892     def _apply_module_morphism(self, x, f): 
    893         """ 
    894         Returns the image of x under the module morphism defined by 
    895         extending f by linearity. 
    896  
    897         INPUT: 
    898             -- x : a element of self 
    899             -- f : a function that takes in a combinatorial object 
    900                    indexing a basis element and returns an element 
    901                    of the target domain 
    902  
    903         EXAMPLES: 
    904             sage: s = SFASchur(QQ) 
    905             sage: a = s([3]) + s([2,1]) + s([1,1,1]) 
    906             sage: b = 2*a 
    907             sage: f = lambda part: len(part) 
    908             sage: s._apply_module_morphism(a, f) #1+2+3 
    909             6 
    910             sage: s._apply_module_morphism(b, f) #2*(1+2+3) 
    911             12 
    912                     
     258        CombinatorialFreeModuleInterface.__init__(self, R, self._element_class) 
    913259             
    914         """ 
    915         res = 0 
    916         for m, c in x._monomial_coefficients.iteritems(): 
    917             res += c*f(m) 
    918         return res 
    919      
    920  
    921     def _apply_module_endomorphism(self, a, f): 
    922         """ 
    923         This takes in a function from the basis elements 
    924         to the elements of self and applies it linearly 
    925         to a. Note that _apply_module_endomorphism does not 
    926         require multiplication on self to be defined. 
    927  
    928         EXAMPLES: 
    929             sage: s = SFASchur(QQ) 
    930             sage: f = lambda part: 2*s(part.conjugate()) 
    931             sage: s._apply_module_endomorphism( s([2,1]) + s([1,1,1]), f) 
    932             2*s[2, 1] + 2*s[3] 
    933  
    934         """ 
    935         mcs = a.monomial_coefficients() 
    936         base_ring = self.base_ring() 
    937         zero = base_ring(0) 
    938  
    939         z_elt = {} 
    940         for basis_element in mcs: 
    941             f_mcs = f(basis_element).monomial_coefficients() 
    942             for f_basis_element in f_mcs: 
    943                 z_elt[ f_basis_element ] = z_elt.get(f_basis_element, zero) + mcs[basis_element]*f_mcs[f_basis_element] 
    944  
    945         return self._from_dict(z_elt) 
    946  
    947  
    948260    def multiply(self,left,right): 
    949261        """ 
    950262        Returns left*right where left and right are elements of self. 
     
    1006318            del z_elt[m] 
    1007319 
    1008320        return self._from_dict(z_elt) 
    1009      
    1010     def _from_dict(self, d, coerce=False): 
    1011         """ 
    1012         Given a monomial coefficient dictionary d, return the element 
    1013         of self with the dictionary. 
    1014  
    1015         EXAMPLES: 
    1016             sage: e = SFAElementary(QQ) 
    1017             sage: s = SFASchur(QQ) 
    1018             sage: a = e([2,1]) + e([1,1,1]); a 
    1019             e[1, 1, 1] + e[2, 1] 
    1020             sage: s._from_dict(a.monomial_coefficients()) 
    1021             s[1, 1, 1] + s[2, 1] 
    1022  
    1023             sage: part = Partition([2,1]) 
    1024             sage: d = {part:1} 
    1025             sage: a = s._from_dict(d,coerce=True); a 
    1026             s[2, 1] 
    1027             sage: a.coefficient(part).parent() 
    1028             Rational Field 
    1029         """ 
    1030         if coerce: 
    1031             R = self.base_ring() 
    1032             d = [ (m,R(c)) for m,c in d.iteritems() ] 
    1033             d = dict(d) 
    1034  
    1035         return self._element_class(self, d) 
  • /dev/null

    old new  
     1#***************************************************************************** 
     2#       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,  
     3# 
     4#  Distributed under the terms of the GNU General Public License (GPL) 
     5# 
     6#    This code is distributed in the hope that it will be useful, 
     7#    but WITHOUT ANY WARRANTY; without even the implied warranty of 
     8#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     9#    General Public License for more details. 
     10# 
     11#  The full text of the GPL is available at: 
     12# 
     13#                  http://www.gnu.org/licenses/ 
     14#***************************************************************************** 
     15from sage.structure.element import ModuleElement 
     16from sage.modules.free_module_element import vector 
     17from sage.misc.misc import repr_lincomb 
     18from sage.modules.module import Module 
     19from sage.rings.all import Ring, Integer 
     20import sage.structure.parent_base 
     21from sage.combinat.family import Family 
     22 
     23# TODO: 
     24# Rewrite all tests in a more self contained way 
     25 
     26class CombinatorialFreeModuleElement(ModuleElement): 
     27    def __init__(self, M, x): 
     28        """ 
     29        Create a combinatorial module element x.  This should never 
     30        be called directly, but only through the parent combinatorial 
     31        module's __call__ method. 
     32 
     33        """ 
     34        ModuleElement.__init__(self, M) 
     35        self._monomial_coefficients = x 
     36 
     37    def __iter__(self): 
     38        """ 
     39        EXAMPLES: 
     40            sage: s = SFASchur(QQ) 
     41            sage: a = s([2,1]) + s([3]) 
     42            sage: [i for i in sorted(a)] 
     43            [([2, 1], 1), ([3], 1)] 
     44 
     45        """ 
     46        return self._monomial_coefficients.iteritems() 
     47 
     48    def __contains__(self, x): 
     49        """ 
     50        Returns whether or not a combinatorial object x indexing a basis 
     51        element is in the support of self. 
     52         
     53        EXAMPLES: 
     54            sage: s = SFASchur(QQ) 
     55            sage: a = s([2,1]) + s([3]) 
     56            sage: Partition([2,1]) in a 
     57            True 
     58            sage: Partition([1,1,1]) in a 
     59            False 
     60        """ 
     61        return x in self._monomial_coefficients and self._monomial_coefficients[x] != 0 
     62 
     63    def monomial_coefficients(self): 
     64        """ 
     65        Return the internal dictionary which has the combinatorial 
     66        objects indexing the basis as keys and their corresponding 
     67        coefficients as values. 
     68 
     69        EXAMPLES: 
     70            sage: s = SFASchur(QQ) 
     71            sage: a = s([2,1])+2*s([3,2]) 
     72            sage: d = a.monomial_coefficients() 
     73            sage: type(d) 
     74            <type 'dict'> 
     75            sage: d[ Partition([2,1]) ] 
     76            1 
     77            sage: d[ Partition([3,2]) ] 
     78            2 
     79        """ 
     80        return self._monomial_coefficients 
     81     
     82    def __repr__(self): 
     83        """ 
     84        EXAMPLES: 
     85            sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
     86            sage: a = 2 + QS3([2,1,3]) 
     87            sage: print a.__repr__() 
     88            2*[1, 2, 3] + [2, 1, 3] 
     89        """ 
     90        v = self._monomial_coefficients.items() 
     91        v.sort() 
     92        prefix = self.parent().prefix() 
     93        mons = [ prefix + repr(m) for (m, _) in v ] 
     94        cffs = [ x for (_, x) in v ] 
     95        x = repr_lincomb(mons, cffs).replace("*1 "," ") 
     96        if x[len(x)-2:] == "*1": 
     97            return x[:len(x)-2] 
     98        else: 
     99            return x 
     100 
     101    def _latex_(self): 
     102        """ 
     103        EXAMPLES: 
     104            sage: QS3 = SymmetricGroupAlgebra(QQ,3) 
     105            sage: a = 2 + QS3([2,1,3]) 
     106            sage: latex(a) #indirect doctest 
     107            2[1,2,3] + [2,1,3] 
     108        """ 
     109        v = self._monomial_coefficients.items() 
     110        v.sort() 
     111        prefix = self.parent().prefix() 
     112        if prefix == "": 
     113            mons = [ prefix + '[' + ",".join(map(str, m)) + ']' for (m, _) in v ] 
     114        else: 
     115            mons = [ prefix + '_{' + ",".join(map(str, m)) + '}' for (m, _) in v ] 
     116        cffs = [ x for (_, x) in v ] 
     117        x = repr_lincomb(mons, cffs, is_latex=True).replace("*1 "," ") 
     118        if x[len(x)-2:] == "*1": 
     119            return x[:len(x)-2] 
     120        else: 
     121            return x 
     122         
     123    def __cmp__(left, right): 
     124        """ 
     125        The ordering is the one on the underlying sorted list of 
     126        (monomial,coefficients) pairs. 
     127 
     128        EXAMPLES: 
     129            sage: s = SFASchur(QQ) 
     130            sage: a = s([2,1]) 
     131            sage: b = s([1,1,1]) 
     132            sage: cmp(a,b) #indirect doctest 
     133            1 
     134        """ 
     135        nonzero = lambda mc: mc[1] != 0 
     136        v = filter(nonzero, left._monomial_coefficients.items()) 
     137        v.sort() 
     138        w = filter(nonzero, right._monomial_coefficients.items()) 
     139        w.sort() 
     140        return cmp(v, w) 
     141 
     142    def _add_(self, y): 
     143        """ 
     144        EXAMPLES: 
     145            sage: s = SFASchur(QQ) 
     146            sage: s([2,1]) + s([5,4]) # indirect doctest 
     147            s[2, 1] + s[5, 4] 
     148            sage: a = s([2,1]) + 0 
     149            sage: len(a.monomial_coefficients()) 
     150            1 
     151        """ 
     152        A = self.parent() 
     153        BR = A.base_ring() 
     154        z_elt = dict(self._monomial_coefficients) 
     155        for m, c in y._monomial_coefficients.iteritems(): 
     156            if z_elt.has_key(m): 
     157                cm = z_elt[m] + c 
     158                if cm == 0: 
     159                    del z_elt[m] 
     160                else: 
     161                    z_elt[m] = cm 
     162            else: 
     163                z_elt[m] = c 
     164 
     165 
     166        #Remove all entries that are equal to 0 
     167        del_list = [] 
     168        zero = BR(0) 
     169        for m, c in z_elt.iteritems(): 
     170            if c == zero: 
     171                del_list.append(m) 
     172        for m in del_list: 
     173            del z_elt[m] 
     174             
     175        return A._from_dict(z_elt) 
     176 
     177 
     178    def _neg_(self): 
     179        """ 
     180        EXAMPLES: 
     181            sage: s = SFASchur(QQ) 
     182            sage: -s([2,1]) # indirect doctest 
     183            -s[2, 1] 
     184        """ 
     185        return self.map_coefficients(lambda c: -c) 
     186 
     187 
     188    def _sub_(self, y): 
     189        """ 
     190        EXAMPLES: 
     191            sage: s = SFASchur(QQ) 
     192            sage: s([2,1]) - s([5,4]) # indirect doctest 
     193            s[2, 1] - s[5, 4] 
     194        """ 
     195        A = self.parent() 
     196        BR = A.base_ring() 
     197        z_elt = dict(self._monomial_coefficients) 
     198        for m, c in y._monomial_coefficients.iteritems(): 
     199            if z_elt.has_key(m): 
     200                cm = z_elt[m] - c 
     201                if cm == 0: 
     202                    del z_elt[m] 
     203                else: 
     204                    z_elt[m] = cm 
     205            else: 
     206                z_elt[m] = -c 
     207 
     208        #Remove all entries that are equal to 0 
     209        zero = BR(0) 
     210        del_list = [] 
     211        for m, c in z_elt.iteritems(): 
     212            if c == zero: 
     213                del_list.append(m) 
     214        for m in del_list: 
     215            del z_elt[m] 
     216                 
     217        return A._from_dict(z_elt) 
     218                         
     219 
     220    def _coefficient_fast(self, m, default=None): 
     221        """ 
     222        Returns the coefficient of m in self, where m is key 
     223        in self._monomial_coefficients. 
     224 
     225        EXAMPLES: 
     226            sage: p = Partition([2,1]) 
     227            sage: s = SFASchur(QQ) 
     228            sage: