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 4 4 from sage.combinat.crystals.all import * 5 5 from sage.combinat.dlx import * #?? 6 6 7 #Combinatorial Algebra 7 # Free modules and friends 8 from free_module import CombinatorialFreeModule 8 9 from combinatorial_algebra import CombinatorialAlgebra 9 10 10 11 -
a/sage/combinat/combinatorial_algebra.py
old new 56 56 # http://www.gnu.org/licenses/ 57 57 #***************************************************************************** 58 58 59 from sage.rings.all import Ring, Integer 60 from sage.misc.misc import repr_lincomb 59 from sage.rings.all import Integer 61 60 from sage.algebras.algebra import Algebra 61 from sage.rings.ring import Ring 62 62 from sage.algebras.algebra_element import AlgebraElement 63 import sage.structure.parent_base64 import sage.combinat.partition65 from sage.modules.free_module_element import vector66 63 from sage.matrix.all import MatrixSpace 64 from sage.combinat.free_module import CombinatorialFreeModuleElement, CombinatorialFreeModule, CombinatorialFreeModuleInterface 67 65 68 class CombinatorialAlgebraElement(AlgebraElement ):66 class CombinatorialAlgebraElement(AlgebraElement, CombinatorialFreeModuleElement): 69 67 def __init__(self, A, x): 70 68 """ 71 69 Create a combinatorial algebra element x. This should never … … 82 80 AlgebraElement.__init__(self, A) 83 81 self._monomial_coefficients = x 84 82 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)]92 83 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 basis99 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 a105 True106 sage: Partition([1,1,1]) in a107 False108 """109 return x in self._monomial_coefficients and self._monomial_coefficients[x] != 0110 111 def monomial_coefficients(self):112 """113 Return the internal dictionary which has the combinatorial114 objects indexing the basis as keys and their corresponding115 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 1125 sage: d[ Partition([3,2]) ]126 2127 """128 return self._monomial_coefficients129 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 x148 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 doctest155 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 x170 171 def __cmp__(left, right):172 """173 The ordering is the one on the underlying sorted list of174 (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 doctest181 1182 """183 nonzero = lambda mc: mc[1] != 0184 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 doctest195 s[2, 1] + s[5, 4]196 sage: a = s([2,1]) + 0197 sage: len(a.monomial_coefficients())198 1199 """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] + c206 if cm == 0:207 del z_elt[m]208 else:209 z_elt[m] = cm210 else:211 z_elt[m] = c212 213 214 #Remove all entries that are equal to 0215 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 doctest231 -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 doctest241 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] - c249 if cm == 0:250 del z_elt[m]251 else:252 z_elt[m] = cm253 else:254 z_elt[m] = -c255 256 #Remove all entries that are equal to 0257 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 267 84 def _mul_(self, y): 268 85 """ 269 86 EXAMPLES: … … 316 133 sage: s([2])^2 317 134 s[2, 2] + s[3, 1] + s[4] 318 135 319 320 136 TESTS: 321 137 sage: s = SFASchur(QQ) 322 138 sage: z = s([2,1]) … … 339 155 for _ in range(n): 340 156 z *= self 341 157 return z 342 343 def _coefficient_fast(self, m, default=None):344 """345 Returns the coefficient of m in self, where m is key346 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 unhashable356 sage: a._coefficient_fast(p)357 1358 sage: a._coefficient_fast(p, 2)359 1360 """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 1372 sage: z.coefficient([2,1])373 -2374 """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_class382 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 False392 sage: s(0).is_zero()393 True394 sage: (s([2,1]) - s([2,1])).is_zero()395 True396 """397 BR = self.parent().base_ring()398 for v in self._monomial_coefficients.values():399 if v != BR(0):400 return False401 return True402 403 def __len__(self):404 """405 Returns the number of basis elements of self with406 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 4413 """414 return self.length()415 416 def length(self):417 """418 Returns the number of basis elements of self with419 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 4426 """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 monomials432 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 indexing449 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 mons461 462 def coefficients(self):463 """464 Returns a list of the coefficents appearing on the465 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 cffs477 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_class496 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_()515 158 516 159 def _matrix_(self, new_BR = None): 517 160 """ … … 550 193 if new_BR is None: 551 194 new_BR = BR 552 195 553 MS = MatrixSpace(new_BR, parent. _dim, parent._dim)196 MS = MatrixSpace(new_BR, parent.dimension(), parent.dimension()) 554 197 l = [ (self*parent(m)).to_vector() for m in cc ] 555 198 return MS(l).transpose() 556 199 … … 582 225 """ 583 226 return self._matrix_() 584 227 585 def map_coefficients(self, f):586 """587 Returns a new element of self.parent() obtained588 by applying the function f to all of the coefficients589 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_elt602 return res603 604 def map_basis(self, f):605 """606 Returns a new element of self.parent() obtained607 by applying the function f to all of the combinatorial608 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)] = c620 res._monomial_coefficients = z_elt621 return res622 623 def map_mc(self, f):624 """625 Returns a new element of self.parent() obtained626 by applying the function f to a monomial coefficient627 (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_c640 return self.parent()._from_dict(z_elt)641 228 642 class CombinatorialAlgebra( Algebra):643 def __init__(self, R, element_class =None):229 class CombinatorialAlgebra(CombinatorialFreeModuleInterface, Algebra): 230 def __init__(self, R, element_class = None): 644 231 """ 645 232 TESTS: 646 233 sage: s = SFASchur(QQ) 647 234 sage: s == loads(dumps(s)) 648 235 True 649 236 """ 650 #Make sure R is a ring with unit element651 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 658 237 #Check to make sure that the user defines the necessary 659 #attributes / methods to make the combinatorial algebra238 #attributes / methods to make the combinatorial module 660 239 #work 661 240 required = ['_combinatorial_class','_one',] 662 241 for r in required: … … 676 255 else: 677 256 self._element_class = element_class 678 257 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) 913 259 914 """915 res = 0916 for m, c in x._monomial_coefficients.iteritems():917 res += c*f(m)918 return res919 920 921 def _apply_module_endomorphism(self, a, f):922 """923 This takes in a function from the basis elements924 to the elements of self and applies it linearly925 to a. Note that _apply_module_endomorphism does not926 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 948 260 def multiply(self,left,right): 949 261 """ 950 262 Returns left*right where left and right are elements of self. … … 1006 318 del z_elt[m] 1007 319 1008 320 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 element1013 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]); a1019 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); a1026 s[2, 1]1027 sage: a.coefficient(part).parent()1028 Rational Field1029 """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 #***************************************************************************** 15 from sage.structure.element import ModuleElement 16 from sage.modules.free_module_element import vector 17 from sage.misc.misc import repr_lincomb 18 from sage.modules.module import Module 19 from sage.rings.all import Ring, Integer 20 import sage.structure.parent_base 21 from sage.combinat.family import Family 22 23 # TODO: 24 # Rewrite all tests in a more self contained way 25 26 class 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: