Ticket #3664: trac_3664-1.patch
| File trac_3664-1.patch, 205.7 kB (added by mhansen, 4 months ago) |
|---|
-
a/sage/combinat/crystals/crystals.py
old new 145 145 EXAMPLES: 146 146 sage: C = CrystalOfLetters(['A', 5]) 147 147 sage: C.weight_lattice_realization() 148 Ambient lattice of the root system of type ['A', 5]148 Ambient space for the Root system of type ['A', 5] 149 149 """ 150 return self.cartan_type.root_system().ambient_ lattice()150 return self.cartan_type.root_system().ambient_space() 151 151 152 152 def Lambda(self): 153 153 """ -
a/sage/combinat/root_system/all.py
old new 1 1 from cartan_type import CartanType 2 from dynkin_diagram import dynkin_diagram2 from dynkin_diagram import DynkinDiagram, dynkin_diagram 3 3 from cartan_matrix import cartan_matrix 4 4 from coxeter_matrix import coxeter_matrix 5 5 from root_system import RootSystem, WeylDim -
/dev/null
old new 1 from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement 2 from root_lattice_realization import RootLatticeRealizationElement 3 from weight_lattice_realization import WeightLatticeRealization 4 from sage.modules.free_module import FreeModule 5 from sage.rings.all import ZZ, QQ 6 from sage.modules.free_module_element import vector 7 8 class AmbientSpace(CombinatorialFreeModule, WeightLatticeRealization): 9 r""" 10 Abstract class for ambient spaces 11 12 Any implementation of this class should implement a class method 13 smallest_base_ring as described below, and a method dimension 14 working on a partially initialized instance with just root_system 15 as attribute. There is no safe default implementation for the later, 16 so none is provided. 17 """ 18 19 # FIXME: attribute or method? 20 def dimension(self): 21 """ 22 Returns the dimension of this ambient space 23 """ 24 raise NotImplementedError 25 26 @classmethod 27 def smallest_base_ring(cls): 28 """ 29 Returns the smallest ground ring over which the ambient space can be realized 30 """ 31 return QQ; 32 33 def __init__(self, root_system, base_ring): 34 """ 35 EXAMPLES: 36 sage: e = RootSystem(['A',3]).ambient_lattice() 37 sage: e == loads(dumps(e)) 38 True 39 """ 40 self.root_system = root_system 41 basis_name = "alphacheck" if root_system.dualSide else "alpha" 42 CombinatorialFreeModule.__init__(self, base_ring,\ 43 #range(1,self.dimension()+1),\ 44 range(0,self.dimension()),\ 45 element_class = AmbientSpaceElement,\ 46 prefix='e') 47 48 # FIXME: here for backward compatibility; 49 # Should we use dimension everywhere? 50 self.n = self.dimension() 51 52 def __repr__(self): 53 """ 54 TEST: 55 sage: RootSystem(['A',4]).ambient_lattice() 56 Ambient lattice for the Root system of type ['A', 4] 57 sage: RootSystem(['B',4]).ambient_space() 58 Ambient space for the Root system of type ['B', 4] 59 60 """ 61 if self.base_ring() == ZZ: 62 space = "lattice" 63 else: 64 space = "space" 65 return "Ambient "+space+" for the %s"%self.root_system 66 67 def __call__(self, v): 68 """ 69 TESTS: 70 sage: R = RootSystem(['A',4]).ambient_lattice() 71 sage: R([1,2,3,4,5]) 72 (1, 2, 3, 4, 5) 73 """ 74 # This adds coercion from a list 75 if isinstance(v, list) or isinstance(v, tuple): 76 K = self.base_ring() 77 return self._from_dict(dict([(i,K(v[i])) for i in range(len(v))])) 78 else: 79 return CombinatorialFreeModule.__call__(self, v) 80 81 # For backward compatibility 82 def _term(self, i): 83 self.term(i) 84 85 def __getitem__(self,i): 86 """ 87 Note that indexing starts at 1. 88 89 EXAMPLES: 90 sage: e = RootSystem(['A',2]).ambient_lattice() 91 sage: e[1] 92 (1, 0, 0) 93 """ 94 return self.term(i-1) 95 96 def coroot_lattice(self): 97 return self 98 99 def simple_coroot(self, i): 100 r""" 101 Returns the i-th simple coroot, as an element of this space 102 103 EXAMPLE: 104 sage: R = RootSystem(["A",3]) 105 sage: L = R.ambient_lattice () 106 sage: L.simple_coroot(1) 107 (1, -1, 0, 0) 108 sage: L.simple_coroot(2) 109 (0, 1, -1, 0) 110 sage: L.simple_coroot(3) 111 (0, 0, 1, -1) 112 """ 113 return self.simple_root(i).associated_coroot() 114 115 def reflection(self, root, coroot=None): 116 # TODO: get rid of this as one can use the generic implementation 117 # (i.e. scalar and associated coroot are implemented) 118 return lambda v: v-2*root.inner_product(v)/root.inner_product(root)*root 119 120 def _term(self, i): 121 """ 122 Note that indexing starts at 0. 123 124 EXAMPLES: 125 sage: e = RootSystem(['A',2]).ambient_lattice() 126 sage: e._term(0) 127 (1, 0, 0) 128 """ 129 return self.term(i) 130 131 def __cmp__(self, other): 132 """ 133 EXAMPLES: 134 sage: e1 = RootSystem(['A',3]).ambient_lattice() 135 sage: e2 = RootSystem(['B',3]).ambient_lattice() 136 sage: e1 == e1 137 True 138 sage: e1 == e2 139 False 140 """ 141 if self.__class__ != other.__class__: 142 return cmp(self.__class__, other.__class__) 143 if self.root_system != other.root_system: 144 return cmp(self.root_system, other.root_system) 145 return 0 146 147 class AmbientSpaceElement(CombinatorialFreeModuleElement, RootLatticeRealizationElement): 148 149 # For backward compatibility 150 def __repr__(self): 151 return str(self.to_vector()) 152 153 def inner_product(self, lambdacheck): 154 """ 155 The scalar product with elements of the coroot lattice 156 embedded in the ambient space 157 """ 158 assert(lambdacheck.parent() == self.parent()) 159 return sum((c*self[t] for (t,c) in lambdacheck), 160 self.parent().base_ring().zero_element()) 161 162 scalar = inner_product 163 dot_product = inner_product 164 165 def associated_coroot(self): 166 # FIXME: make it work over ZZ! 167 return self * (2/self.inner_product(self)) 168 -
a/sage/combinat/root_system/cartan_matrix.py
old new 15 15 # 16 16 # http://www.gnu.org/licenses/ 17 17 #***************************************************************************** 18 from dynkin_diagram import dynkin_diagram_as_function19 18 import cartan_type 20 19 from sage.matrix.all import MatrixSpace 21 20 from sage.rings.all import ZZ 22 23 def cartan_matrix_as_function(t):24 """25 Returns a function that represents the Cartan matrix26 of type t.27 28 EXAMPLES:29 sage: from sage.combinat.root_system.cartan_matrix import cartan_matrix_as_function30 sage: f = cartan_matrix_as_function(['A',4])31 sage: matrix([[f(i,j) for j in range(1,5)] for i in range(1,5)])32 [ 2 -1 0 0]33 [-1 2 -1 0]34 [ 0 -1 2 -1]35 [ 0 0 -1 2]36 """37 ct = cartan_type.CartanType(t)38 f = dynkin_diagram_as_function(ct)39 cmf = lambda i,j: 2 if i == j else -f(j,i)40 return cmf41 21 42 22 def cartan_matrix(t): 43 23 """ … … 54 34 [-1 2 -1 0 0 0] 55 35 [ 0 -1 2 -1 0 0] 56 36 [ 0 0 -1 2 -1 0] 57 [ 0 0 0 -1 2 - 2]58 [ 0 0 0 0 - 12]37 [ 0 0 0 -1 2 -1] 38 [ 0 0 0 0 -2 2] 59 39 sage: cartan_matrix(['C', 4]) 60 40 [ 2 -1 0 0] 61 41 [-1 2 -1 0] 62 [ 0 -1 2 - 1]63 [ 0 0 - 22]42 [ 0 -1 2 -2] 43 [ 0 0 -1 2] 64 44 sage: cartan_matrix(['D', 6]) 65 45 [ 2 -1 0 0 0 0] 66 46 [-1 2 -1 0 0 0] … … 68 48 [ 0 0 -1 2 -1 -1] 69 49 [ 0 0 0 -1 2 0] 70 50 [ 0 0 0 -1 0 2] 51 sage: cartan_matrix(['E',6]) 52 [ 2 0 -1 0 0 0] 53 [ 0 2 0 -1 0 0] 54 [-1 0 2 -1 0 0] 55 [ 0 -1 -1 2 -1 0] 56 [ 0 0 0 -1 2 -1] 57 [ 0 0 0 0 -1 2] 58 sage: cartan_matrix(['E',7]) 59 [ 2 0 -1 0 0 0 0] 60 [ 0 2 0 -1 0 0 0] 61 [-1 0 2 -1 0 0 0] 62 [ 0 -1 -1 2 -1 0 0] 63 [ 0 0 0 -1 2 -1 0] 64 [ 0 0 0 0 -1 2 -1] 65 [ 0 0 0 0 0 -1 2] 71 66 sage: cartan_matrix(['E', 8]) 72 67 [ 2 0 -1 0 0 0 0 0] 73 68 [ 0 2 0 -1 0 0 0 0] … … 79 74 [ 0 0 0 0 0 0 -1 2] 80 75 sage: cartan_matrix(['F', 4]) 81 76 [ 2 -1 0 0] 82 [-1 2 -2 0] 77 [-1 2 -1 0] 78 [ 0 -2 2 -1] 79 [ 0 0 -1 2] 80 81 This is different from MuPAD-Combinat, due to different node convention? 82 83 sage: cartan_matrix(['G', 2]) 84 [ 2 -3] 85 [-1 2] 86 sage: cartan_matrix(['A', 3, 1]) 87 [ 2 -1 0 -1] 88 [-1 2 -1 0] 83 89 [ 0 -1 2 -1] 90 [-1 0 -1 2] 91 sage: cartan_matrix(['B', 3, 1]) 92 [ 2 0 -1 0] 93 [ 0 2 -1 0] 94 [-1 -1 2 -1] 95 [ 0 0 -2 2] 96 sage: cartan_matrix(['C', 3, 1]) 97 [ 2 -1 0 0] 98 [-2 2 -1 0] 99 [ 0 -1 2 -2] 84 100 [ 0 0 -1 2] 85 sage: cartan_matrix(['G', 2]) 86 [ 2 -1] 87 [-3 2] 88 101 sage: cartan_matrix(['D', 4, 1]) 102 [ 2 0 -1 0 0] 103 [ 0 2 -1 0 0] 104 [-1 -1 2 -1 -1] 105 [ 0 0 -1 2 0] 106 [ 0 0 -1 0 2] 107 sage: cartan_matrix(['E', 6, 1]) 108 [ 2 0 -1 0 0 0 0] 109 [ 0 2 0 -1 0 0 0] 110 [-1 0 2 0 -1 0 0] 111 [ 0 -1 0 2 -1 0 0] 112 [ 0 0 -1 -1 2 -1 0] 113 [ 0 0 0 0 -1 2 -1] 114 [ 0 0 0 0 0 -1 2] 115 sage: cartan_matrix(['E', 7, 1]) 116 [ 2 -1 0 0 0 0 0 0] 117 [-1 2 0 -1 0 0 0 0] 118 [ 0 0 2 0 -1 0 0 0] 119 [ 0 -1 0 2 -1 0 0 0] 120 [ 0 0 -1 -1 2 -1 0 0] 121 [ 0 0 0 0 -1 2 -1 0] 122 [ 0 0 0 0 0 -1 2 -1] 123 [ 0 0 0 0 0 0 -1 2] 124 sage: cartan_matrix(['E', 8, 1]) 125 [ 2 0 0 0 0 0 0 0 -1] 126 [ 0 2 0 -1 0 0 0 0 0] 127 [ 0 0 2 0 -1 0 0 0 0] 128 [ 0 -1 0 2 -1 0 0 0 0] 129 [ 0 0 -1 -1 2 -1 0 0 0] 130 [ 0 0 0 0 -1 2 -1 0 0] 131 [ 0 0 0 0 0 -1 2 -1 0] 132 [ 0 0 0 0 0 0 -1 2 -1] 133 [-1 0 0 0 0 0 0 -1 2] 134 sage: cartan_matrix(['F', 4, 1]) 135 [ 2 -1 0 0 0] 136 [-1 2 -1 0 0] 137 [ 0 -1 2 -1 0] 138 [ 0 0 -2 2 -1] 139 [ 0 0 0 -1 2] 140 sage: cartan_matrix(['G', 2, 1]) 141 [ 2 0 -1] 142 [ 0 2 -3] 143 [-1 -1 2] 89 144 """ 90 ct = cartan_type.CartanType(t)91 index_set = ct.index_set()92 cmf = cartan_matrix_as_function(ct)145 t = cartan_type.CartanType(t) 146 dynkin_diagram = t.dynkin_diagram() 147 index_set = t.index_set() 93 148 MS = MatrixSpace(ZZ, len(index_set), sparse=True) 94 149 m = MS(0) 95 150 for i in range(len(index_set)): 96 151 for j in range(len(index_set)): 97 m[i,j] = cmf(index_set[i],index_set[j])152 m[i,j] = dynkin_diagram[index_set[i],index_set[j]] 98 153 return m -
a/sage/combinat/root_system/cartan_type.py
old new 15 15 # 16 16 # http://www.gnu.org/licenses/ 17 17 #***************************************************************************** 18 import sage.combinat.root_system.root_system as root_system 18 #import sage.combinat.root_system.root_system as root_system 19 from sage.combinat import root_system 19 20 from cartan_matrix import cartan_matrix 21 from sage.rings.all import ZZ 20 22 21 def CartanType(t): 23 # TODO: 24 # Get rid of almost all runtype type checking by extending the class hierarchy with: 25 # - type_relabel.CartanType (in type_relabel module, together with relabelled AmbientSpace) 26 # - CartanType_crystalographic 27 # - CartanType_simply_laced 28 # - type_A.CartanType (in the type_A module) 29 # - ... 30 # - CartanType_untwisted_affine 31 # - type_A_affine.CartanType 32 # - type_BC_affine.CartanType 33 # ... 34 # Implement the Kac conventions by relabeling/dual/... of the above 35 # Implement coxeter diagrams for non crystalographic 36 # Implement dual ambient space 37 38 39 class CartanTypeFactory: 40 # Intention: we want simultaneously CartanType to be a factory for 41 # the various subtypes of CartanType_abstract, as in: 42 # CartanType(["A",4,1]) 43 # and to behaves as a "module" for some extra utilities: 44 # CartanType.samples() 45 # 46 # Implementation: CartanType is the unique instance of this class 47 # CartanTypeFactory. Is there a better/more standard way to do it? 48 49 def __call__(self, *args): 22 50 """ 23 51 Returns an object corresponding to the Cartan type t. 52 INPUT: 53 [letter, rank] 54 where letter is one of 'A','B','C','D','E','F','G' and rank 55 is the rank. An alternative string notation is allowed. 56 A third optional parameter is permitted for affine 57 types. Reducible types may be entered by giving a list of 58 irreducible types or by a single string 24 59 25 60 EXAMPLES: 26 61 sage: CartanType(['A',4]) 27 62 ['A', 4] 63 sage: CartanType("A4") 64 ['A', 4] 65 sage: CartanType(['A',2],['B',2]) 66 A2xB2 67 sage: CartanType(['A',2],['B',2]).is_reducible() 68 True 69 sage: CartanType("A2xB2") 70 A2xB2 71 sage: CartanType("A2","B2") == CartanType("A2xB2") 72 True 73 sage: CartanType(['A',4,1]) 74 ['A', 4, 1] 75 sage: CartanType(['A',4,1]).is_affine() 76 True 28 77 """ 29 if isinstance(t, CartanType_simple): 78 if len(args) == 1: 79 t = args[0] 80 else: 81 t = args 82 if isinstance(t, CartanType_abstract): 30 83 return t 31 else:32 return CartanType_simple(t)33 84 34 class CartanType_simple: 35 def __init__(self, t): 85 if type(t)==str: 86 if "x" in t: 87 return root_system.type_reducible.CartanType([CartanType(u) for u in t.split("x")]) 88 else: 89 return CartanType([t[0], eval(t[1:])]) 90 91 t = list(t) 92 93 if type(t[0]) == str and t[1] in ZZ: 94 if len(t) == 2: 95 return CartanType_simple_finite(t) 96 elif len(t) == 3: 97 return CartanType_simple_affine(t) 98 99 return root_system.type_reducible.CartanType([ CartanType(subt) for subt in t ]) 100 101 def samples(self, finite=False, affine=False, crystalographic=False): 102 """ 103 Returns a sample of the implemented cartan types 104 105 With finite=True resp. affine=True, one can restrict to finite 106 resp. affine only cartan types 107 108 EXAMPLES: 109 sage: CartanType.samples(finite=True) 110 [['A', 1], ['A', 5], ['B', 5], ['C', 5], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4]] 111 112 sage: CartanType.samples(affine=True) 113 [['A', 1, 1], ['A', 5, 1], ['B', 5, 1], ['C', 5, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['A', 2, 2], ['A', 10, 2], ['A', 9, 2], ['D', 5, 2], ['D', 4, 3], ['E', 6, 2]] 114 115 sage: CartanType.samples() 116 [['A', 1], ['A', 5], ['B', 5], ['C', 5], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['I', 5], ['H', 3], ['H', 4], ['A', 1, 1], ['A', 5, 1], ['B', 5, 1], ['C', 5, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['A', 2, 2], ['A', 10, 2], ['A', 9, 2], ['D', 5, 2], ['D', 4, 3], ['E', 6, 2]] 117 sage: CartanType.samples(crystalographic=True) 118 [['A', 1], ['A', 5], ['B', 5], ['C', 5], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['A', 1, 1], ['A', 5, 1], ['B', 5, 1], ['C', 5, 1], ['D', 5, 1], ['E', 6, 1], ['E', 7, 1], ['E', 8, 1], ['F', 4, 1], ['G', 2, 1], ['A', 2, 2], ['A', 10, 2], ['A', 9, 2], ['D', 5, 2], ['D', 4, 3], ['E', 6, 2]] 119 """ 120 if crystalographic: 121 return [ t for t in CartanType.samples(finite=finite, affine=affine) if t.is_crystalographic() ] 122 if finite: 123 return([CartanType(t) for t in [["A", 1], ["A", 5], ["B", 5], ["C", 5], ["D", 5], 124 ["E", 6], ["E", 7], ["E", 8], 125 ["F", 4], 126 ["G", 2], 127 ["I", 5], 128 ["H", 3], ["H", 4]]]) 129 elif affine: 130 return([t.affine() for t in CartanType.samples(finite=True, crystalographic=True)] + 131 [CartanType(t) for t in [["A", 2, 2], ["A", 10, 2], ["A", 9, 2], 132 ["D", 5, 2], 133 ["D", 4, 3], 134 ["E", 6, 2]]]); 135 else: 136 return CartanType.samples(finite=True) + CartanType.samples(affine=True) 137 138 CartanType = CartanTypeFactory() 139 140 class CartanType_abstract: 141 r""" 142 Abstract class for cartan types 143 144 Subclasses should implement: 145 146 type() 147 dynkin_diagram() 148 cartan_matrix() 149 is_finite() 150 is_affine() 151 is_irreducible() 152 """ 153 154 def type(self): 155 r""" 156 Returns the type of self, or None if unknown 36 157 """ 37 EXAMPLES: 38 sage: ct = CartanType(['A',4]) 39 sage: ct == loads(dumps(ct)) 40 True 41 """ 42 self.t = t 43 44 self.letter = t[0] 45 self.n = t[1] 46 47 if len(t) > 2: 48 self.affine = t[2] 49 else: 50 self.affine = None 51 52 def __hash__(self): 53 """ 54 EXAMPLES: 55 sage: ct = CartanType(['A',2]) 56 sage: hash(ct) #random 57 -5684143898951441983 58 """ 59 return hash( (self.letter,self.n,self.affine) ) 60 61 62 def __repr__(self): 63 """ 64 TESTS: 65 sage: ct = CartanType(['A',3]) 66 sage: repr(ct) 67 "['A', 3]" 68 """ 69 if self.affine is None: 70 return "['%s', %s]"%(self.letter, self.n) 71 else: 72 return "['%s', %s, %s]"%(self.letter, self.n, self.affine) 73 74 def __getitem__(self, x): 75 """ 76 EXAMPLES: 77 sage: t = CartanType(['A', 3, 1]) 78 sage: t[0] 79 'A' 80 sage: t[1] 81 3 82 sage: t[2] 83 1 84 sage: t[3] 85 Traceback (most recent call last): 86 ... 87 IndexError: list index out of range 88 """ 89 return self.t[x] 90 91 def __cmp__(self, other): 92 """ 93 EXAMPLES: 94 sage: ct1 = CartanType(['A',4]) 95 sage: ct2 = CartanType(['A',4]) 96 sage: ct3 = CartanType(['A',5]) 97 sage: ct1 == ct2 98 True 99 sage: ct1 != ct3 100 True 101 """ 102 if other.__class__ != self.__class__: 103 return cmp(self.__class__, other.__class__) 104 105 if other.letter != self.letter: 106 return cmp(self.letter, other.letter) 107 if other.affine != self.affine: 108 return cmp(self.affine, other.affine) 109 if other.n != self.n: 110 return cmp(self.n, other.n) 111 112 return 0 113 114 115 def __len__(self): 116 """ 117 EXAMPLES: 118 sage: len(CartanType(['A',4])) 119 2 120 sage: len(CartanType(['A',4,1])) 121 3 122 """ 123 if self.affine: 124 return 3 125 else: 126 return 2 127 128 def is_finite(self): 129 """ 130 Returns True if self is finite. 131 132 EXAMPLES: 133 sage: CartanType(['A',4]).is_finite() 134 True 135 sage: CartanType(['A',4,1]).is_finite() 136 False 137 """ 138 if self.affine is not None: 139 return False 140 141 if self.letter in ['A', 'B', 'C', 'D', 'I']: 142 return True 143 144 if self.letter == 'E': 145 return self.n <= 8 146 147 if self.letter == 'F': 148 return self.n <= 4 149 150 if self.letter == 'G': 151 return self.n <= 2 152 153 def is_affine(self): 154 """ 155 Returns True if self is affine. 156 157 EXAMPLES: 158 sage: CartanType(['A', 3]).is_affine() 159 False 160 sage: CartanType(['A', 3, 1]).is_affine() 161 True 162 """ 163 return self.affine is not None 164 158 return None 165 159 166 160 def rank(self): 167 161 """ … … 174 168 sage: CartanType(['I', 8]).rank() 175 169 2 176 170 """ 177 if self.is_affine(): 178 if self.affine == 3 and self.letter == 'D': 179 return self.n-1 180 elif self.affine == 2 and self.letter == 'A': 181 ## FIXME: check in the literature what should be the 182 ## appropriate definition for rank 183 return int(self.n+1)/2 184 else: 185 return self.n 186 else: 187 if self.letter == "I": 188 return 2 189 else: 190 return self.n 171 raise notImplementedError 172 173 def dual(self): 174 """ 175 Returns the dual cartan type, possibly just as a formal dual 176 177 EXAMPLES: 178 sage: CartanType(['A',3]).dual() 179 ['A', 3] 180 sage: CartanType(['D',4]).dual() 181 ['D', 4] 182 sage: CartanType(['E',8]).dual() 183 ['E', 8] 184 sage: CartanType(['B',3]).dual() 185 ['C', 3] 186 sage: CartanType(['C',2]).dual() 187 ['B', 2] 188 """ 189 return root_system.type_dual.CartanType(self) 190 191 def type_string(self): 192 r""" 193 Returns a string suitable for type-specific code dispatch 194 195 EXAMPLES: (TODO!) 196 """ 197 return "type_None" 198 199 def is_reducible(self): 200 """ 201 Report whether the root system is reducible (i.e. not simple), 202 that is whether it can be factored as a product of root 203 systems. 204 205 EXAMPLES: 206 sage: CartanType("A2xB3").is_reducible() 207 True 208 sage: CartanType(['A',2]).is_reducible() 209 False 210 """ 211 return not self.is_irreducible() 212 213 def is_irreducible(self): 214 """ 215 Report whether this Cartan type is irreducible (i.e. simple) 216 217 """ 218 raise NotImplementedError 219 220 def is_finite(self): 221 """ 222 Returns whether this Cartan type is finite. 223 224 EXAMPLES: 225 sage: CartanType(['A',4]).is_finite() 226 True 227 sage: CartanType(['A',4,1]).is_finite() 228 False 229 """ 230 raise NotImplementedError 231 232 def is_affine(self): 233 """ 234 Returns whether self is affine. 235 236 EXAMPLES: 237 sage: CartanType(['A', 3]).is_affine() 238 False 239 sage: CartanType(['A', 3, 1]).is_affine() 240 True 241 """ 242 raise NotImplementedError 243 244 def is_crystalographic(self): 245 """ 246 Returns whether this Cartan type is simple laced 247 248 EXAMPLES: 249 sage: [ [t, t.is_crystalographic() ] for t in CartanType.samples(finite=True) ] 250 [[['A', 1], True], [['A', 5], True], 251 [['B', 5], True], [['C', 5], True], [['D', 5], True], 252 [['E', 6], True], [['E', 7], True], [['E', 8], True], 253 [['F', 4], True], [['G', 2], True], 254 [['I', 5], False], [['H', 3], False], [['H', 4], False]] 255 256 TESTS: 257 sage: all(t.is_crystalographic() for t in CartanType.samples(affine=True)) 258 True 259 """ 260 raise NotImplementedError 261 262 def is_simple_laced(self): 263 """ 264 Returns whether this Cartan type is simple laced 265 266 EXAMPLES: 267 sage: [ [t, t.is_simply_laced() ] for t in CartanType.samples() ] 268 [[['A', 1], True], [['A', 5], True], 269 [['B', 5], False], [['C', 5], False], [['D', 5], True], 270 [['E', 6], True], [['E', 7], True], [['E', 8], True], 271 [['F', 4], False], [['G', 2], False], [['I', 5], False], [['H', 3], False], [['H', 4], False], 272 [['A', 1, 1], False], [['A', 5, 1], True], 273 [['B', 5, 1], False], [['C', 5, 1], False], [['D', 5, 1], True], 274 [['E', 6, 1], True], [['E', 7, 1], True], [['E', 8, 1], True], 275 [['F', 4, 1], False], [['G', 2, 1], False], 276 [['A', 2, 2], False], [['A', 10, 2], False], [['A', 9, 2], False], [['D', 5, 2], False], [['D', 4, 3], False], [['E', 6, 2], False]] 277 """ 278 raise NotImplementedError 191 279 192 280 def index_set(self): 193 281 """ … … 213 301 sage: CartanType(['A',4]).root_system() 214 302 Root system of type ['A', 4] 215 303 """ 216 return root_system.RootSystem(self) 304 return root_system.root_system.RootSystem(self) 305 306 # Maybe we want a separate class for affine 307 308 class CartanType_simple(CartanType_abstract): 309 """ 310 TESTS: 311 sage: ct1 = CartanType(['A',4]) 312 sage: ct2 = CartanType(['A',4]) 313 sage: ct3 = CartanType(['A',5]) 314 sage: ct1 == ct2 315 True 316 sage: ct1 != ct3 317 True 318 """ 319 320 def __hash__(self): 321 """ 322 EXAMPLES: 323 sage: ct = CartanType(['A',2]) 324 sage: hash(ct) #random 325 -5684143898951441983 326 """ 327 return hash(str(self)) 328 329 def __getitem__(self, x): 330 """ 331 EXAMPLES: 332 sage: t = CartanType(['A', 3, 1]) 333 sage: t[0] 334 'A' 335 sage: t[1] 336 3 337 sage: t[2] 338 1 339 sage: t[3] 340 Traceback (most recent call last): 341 ... 342 IndexError: list index out of range 343 """ 344 return self.t[x] 345 346 def is_irreducible(self): 347 return True 348 349 def dynkin_diagram(self): 350 """ 351 Returns the Dynkin diagram associated with self. 352 353 EXAMPLES: 354 sage: CartanType(['A',4]).dynkin_diagram() 355 Dynkin diagram of type ['A', 4] 356 """ 357 return root_system.dynkin_diagram.DynkinDiagram(self) 217 358 218 359 def cartan_matrix(self): 219 360 """ … … 227 368 [ 0 0 -1 2] 228 369 229 370 """ 230 return cartan_matrix(self)371 return root_system.cartan_matrix.cartan_matrix(self) 231 372 232 373 def type(self): 233 374 """ … … 236 377 EXAMPLES: 237 378 sage: CartanType(['A', 4]).type() 238 379 'A' 380 sage: CartanType(['A', 4, 1]).type() 381 'A' 239 382 """ 240 383 return self.letter 384 385 def type_string(self): 386 """ 387 Returns a string suitable for type-specific code dispatch 388 389 EXAMPLES: 390 sage: CartanType(['A', 4]).type_string() 391 'type_A' 392 sage: CartanType(['A', 4, 1]).type_string() 393 'type_A_affine' 394 """ 395 if self.is_affine(): 396 return "type_%s_affine"%self.letter 397 else: 398 return "type_%s"%self.letter 399 400 def dual(self): 401 if self.type() in ["A", "D", "E"]: 402 return self 403 else: 404 return CartanType_abstract.dual(self) 405 406 def is_irreducible(self): 407 """ 408 Report that this Cartan type is irreducible. 409 """ 410 return True 411 412 class CartanType_simple_finite(CartanType_simple): 413 r""" 414 A class for finite simple Cartan types 415 """ 416 417 def __init__(self, t): 418 """ 419 EXAMPLES: 420 sage: ct = CartanType(['A',4]) 421 sage: ct == loads(dumps(ct)) 422 True 423 """ 424 assert(len(t) == 2) 425 assert(t[0] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']) 426 assert(t[1] in ZZ and t[1] >= 0) 427 if t[0] in ['B', 'C']: 428 assert(t[1] >= 2) 429 if t[0] == 'D': 430 assert(t[1] >= 3) 431 if t[0] == 'E': 432 assert(t[1] <= 8) 433 if t[0] == 'F': 434 assert(t[1] <= 4) 435 if t[0] == 'G': 436 assert(t[1] <= 2) 437 if t[0] == 'H': 438 assert(t[1] <= 4) 439 440 self.t = t 441 self.letter = t[0] 442 self.n = t[1] 443 444 445 def __repr__(self): 446 """ 447 TESTS: 448 sage: ct = CartanType(['A',3]) 449 sage: repr(ct) 450 "['A', 3]" 451 """ 452 return "['%s', %s]"%(self.letter, self.n) 453 454 def __len__(self): 455 """ 456 EXAMPLES: 457 sage: len(CartanType(['A',4])) 458 2 459 """ 460 return 2 461 462 def __cmp__(self, other): 463 if other.__class__ != self.__class__: 464 return cmp(self.__class__, other.__class__) 465 if other.letter != self.letter: 466 return cmp(self.letter, other.letter) 467 return cmp(self.n, other.n) 468 469 def rank(self): 470 if self.letter == "I": 471 return 2 472 else: 473 return self.n 474 def is_finite(self): 475 return True 476 477 def is_affine(self): 478 return False 479 480 def is_crystalographic(self): 481 return self.letter in ["A", "B", "C", "D", "E", "F", "G"] 482 483 def is_simply_laced(self): 484 return self.letter in ["A", "D", "E"] 485 486 def affine(self): 487 """ 488 Returns the corresponding untwisted affine Cartan type 489 490 EXAMPLES: 491 sage: CartanType(['A',3]).affine() 492 ['A', 3, 1] 493 """ 494 return CartanType([self.letter, self.n, 1]) 495 496 def dual(self): 497 if self.type() == "B": 498 return CartanType(["C",self.n]) 499 elif self.type() == "C": 500 return CartanType(["B",self.n]) 501 else: 502 return CartanType_simple.dual(self) 503 504 ########################################################################## 505 class CartanType_simple_affine(CartanType_simple): 506 r""" 507 A class for affine simple Cartan types 508 """ 509 510 def __init__(self, t): 511 """ 512 EXAMPLES: 513 sage: ct = CartanType(['A',4]) 514 sage: ct == loads(dumps(ct)) 515 True 516 """ 517 assert(len(t) == 3) 518 assert(t[0] in ['A', 'B', 'C', 'D', 'E', 'F', 'G']) 519 assert(t[1] in ZZ and t[1] >= 1) 520 assert(t[2] in [1,2,3]) 521 if t[0] in ['B', 'C']: 522 assert(t[1] >= 2) 523 if t[0] == 'D': 524 assert(t[1] >= 4) 525 if t[0] == 'E': 526 assert(t[1] <= 8) 527 if t[0] == 'F': 528 assert(t[1] <= 4) 529 if t[0] == 'G': 530 assert(t[1] <= 2) 531 if t[2] == 3: 532 assert(t[0] == "D") 533 assert(t[1] == 4) 534 if t[2] == 2: 535 assert(t[0] in ['A', 'D', 'E']) 536 if t[0] == 'E': 537 assert(t[1] == 6) 538 539 self.t = t 540 self.letter = t[0] 541 self.n = t[1] 542 self.affine = t[2] 543 544 def __repr__(self): 545 """ 546 TESTS: 547 sage: ct = CartanType(['A',3, 1]) 548 sage: repr(ct) 549 "['A', 3, 1]" 550 """ 551 return "['%s', %s, %s]"%(self.letter, self.n, self.affine) 552 553 def __cmp__(self, other): 554 c = CartanType_simple_finite.cmp(self, other) 555 if c != 0: 556 return c 557 else: 558 return cmp(self.affine, other.affine) 559 560 def __len__(self): 561 """ 562 EXAMPLES: 563 sage: len(CartanType(['A',4,1])) 564 3 565 """ 566 return 3 567 568 def rank(self): 569 if self.affine == 3 and self.letter == 'D': 570 return self.n-1 571 elif self.affine == 2 and self.letter == 'A': 572 ## FIXME: check in the literature what should be the 573 ## appropriate definition for rank 574 return int(self.n+1)/2 575 else: 576 return self.n 577 578 def is_finite(self): 579 return False 580 581 def is_affine(self): 582 return True 583 584 def is_crystalographic(self): 585 return True 586 587 def is_simply_laced(self): 588 if self.affine != 1: 589 return False 590 if self.letter == "A": 591 return self.n > 1 592 return self.letter in ["D", "E"] 593 594 def classical(self): 595 r""" 596 Returns the classical Cartan type associated with self (which should be affine) 597 598 Caveat: only implemented for untwisted 599 600 EXAMPLES: 601 sage: CartanType(['A', 3, 1]).classical() 602 ['A', 3] 603 sage: CartanType(['B', 3, 1]).classical() 604 ['B', 3]