Root system data for affine Cartan types¶
- class sage.combinat.root_system.type_affine.AmbientSpace(root_system, base_ring)[source]¶
- Bases: - CombinatorialFreeModule- Ambient space for affine types. - This is constructed from the data in the corresponding classical ambient space. Namely, this space is obtained by adding two elements \(\delta\) and \(\delta^\vee\) to the basis of the classical ambient space, and by endowing it with the canonical scalar product. - The coefficient of an element in \(\delta^\vee\), thus its scalar product with \(\delta^\vee\) gives its level, and dually for the colevel. The canonical projection onto the classical ambient space (by killing \(\delta\) and \(\delta^\vee\)) maps the simple roots (except \(\alpha_0\)) onto the corresponding classical simple roots, and similarly for the coroots, fundamental weights, … Altogether, this uniquely determines the embedding of the root, coroot, weight, and coweight lattices. See - simple_root()and- fundamental_weight()for the details.- Warning - In type \(BC\), the null root is in fact: - sage: R = RootSystem(["BC",3,2]).ambient_space() sage: R.null_root() # needs sage.graphs 2*e['delta'] - >>> from sage.all import * >>> R = RootSystem(["BC",Integer(3),Integer(2)]).ambient_space() >>> R.null_root() # needs sage.graphs 2*e['delta'] - Warning - In the literature one often considers a larger affine ambient space obtained from the classical ambient space by adding four dimensions, namely for the fundamental weight \(\Lambda_0\) the fundamental coweight \(\Lambda^\vee_0\), the null root \(\delta\), and the null coroot \(c\) (aka central element). In this larger ambient space, the scalar product is degenerate: \(\langle \delta,\delta\rangle=0\) and similarly for the null coroot. - In the current implementation, \(\Lambda_0\) and the null coroot are identified: - sage: L = RootSystem(["A",3,1]).ambient_space() sage: Lambda = L.fundamental_weights() # needs sage.graphs sage: Lambda[0] # needs sage.graphs e['deltacheck'] sage: L.null_coroot() # needs sage.graphs e['deltacheck'] - >>> from sage.all import * >>> L = RootSystem(["A",Integer(3),Integer(1)]).ambient_space() >>> Lambda = L.fundamental_weights() # needs sage.graphs >>> Lambda[Integer(0)] # needs sage.graphs e['deltacheck'] >>> L.null_coroot() # needs sage.graphs e['deltacheck'] - Therefore the scalar product of the null coroot with itself differs from the larger ambient space: - sage: L.null_coroot().scalar(L.null_coroot()) # needs sage.graphs 1 - >>> from sage.all import * >>> L.null_coroot().scalar(L.null_coroot()) # needs sage.graphs 1 - In general, scalar products between two elements that do not live on “opposite sides” won’t necessarily match. - EXAMPLES: - sage: R = RootSystem(["A",3,1]) sage: e = R.ambient_space(); e Ambient space of the Root system of type ['A', 3, 1] sage: TestSuite(e).run() - >>> from sage.all import * >>> R = RootSystem(["A",Integer(3),Integer(1)]) >>> e = R.ambient_space(); e Ambient space of the Root system of type ['A', 3, 1] >>> TestSuite(e).run() - Systematic checks on all affine types: - sage: for ct in CartanType.samples(affine=True, crystallographic=True): ....: if ct.classical().root_system().ambient_space() is not None: ....: print(ct) ....: L = ct.root_system().ambient_space() ....: assert L ....: TestSuite(L).run() ['A', 1, 1] ['A', 5, 1] ['B', 1, 1] ['B', 5, 1] ['C', 1, 1] ['C', 5, 1] ['D', 3, 1] ['D', 5, 1] ['E', 6, 1] ['E', 7, 1] ['E', 8, 1] ['F', 4, 1] ['G', 2, 1] ['BC', 1, 2] ['BC', 5, 2] ['B', 5, 1]^* ['C', 4, 1]^* ['F', 4, 1]^* ['G', 2, 1]^* ['BC', 1, 2]^* ['BC', 5, 2]^* - >>> from sage.all import * >>> for ct in CartanType.samples(affine=True, crystallographic=True): ... if ct.classical().root_system().ambient_space() is not None: ... print(ct) ... L = ct.root_system().ambient_space() ... assert L ... TestSuite(L).run() ['A', 1, 1] ['A', 5, 1] ['B', 1, 1] ['B', 5, 1] ['C', 1, 1] ['C', 5, 1] ['D', 3, 1] ['D', 5, 1] ['E', 6, 1] ['E', 7, 1] ['E', 8, 1] ['F', 4, 1] ['G', 2, 1] ['BC', 1, 2] ['BC', 5, 2] ['B', 5, 1]^* ['C', 4, 1]^* ['F', 4, 1]^* ['G', 2, 1]^* ['BC', 1, 2]^* ['BC', 5, 2]^* - class Element[source]¶
- Bases: - IndexedFreeModuleElement- associated_coroot()[source]¶
- Return the coroot associated to - self.- INPUT: - self– a root
 - EXAMPLES: - sage: # needs sage.graphs sage: alpha = RootSystem(['C',2,1]).ambient_space().simple_roots() sage: alpha Finite family {0: -2*e[0] + e['delta'], 1: e[0] - e[1], 2: 2*e[1]} sage: alpha[0].associated_coroot() -e[0] + e['deltacheck'] sage: alpha[1].associated_coroot() e[0] - e[1] sage: alpha[2].associated_coroot() e[1] - >>> from sage.all import * >>> # needs sage.graphs >>> alpha = RootSystem(['C',Integer(2),Integer(1)]).ambient_space().simple_roots() >>> alpha Finite family {0: -2*e[0] + e['delta'], 1: e[0] - e[1], 2: 2*e[1]} >>> alpha[Integer(0)].associated_coroot() -e[0] + e['deltacheck'] >>> alpha[Integer(1)].associated_coroot() e[0] - e[1] >>> alpha[Integer(2)].associated_coroot() e[1] 
 - inner_product(other)[source]¶
- Implement the canonical inner product of - selfwith- other.- EXAMPLES: - sage: e = RootSystem(['B',3,1]).ambient_space() sage: B = e.basis() sage: matrix([[x.inner_product(y) for x in B] for y in B]) [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] sage: x = e.an_element(); x 2*e[0] + 2*e[1] + 3*e[2] sage: x.inner_product(x) 17 - >>> from sage.all import * >>> e = RootSystem(['B',Integer(3),Integer(1)]).ambient_space() >>> B = e.basis() >>> matrix([[x.inner_product(y) for x in B] for y in B]) [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] >>> x = e.an_element(); x 2*e[0] + 2*e[1] + 3*e[2] >>> x.inner_product(x) 17 - scalar()is an alias for this method:- sage: x.scalar(x) 17 - >>> from sage.all import * >>> x.scalar(x) 17 - Todo - Lift to CombinatorialFreeModule.Element as canonical_inner_product 
 - scalar(other)[source]¶
- Implement the canonical inner product of - selfwith- other.- EXAMPLES: - sage: e = RootSystem(['B',3,1]).ambient_space() sage: B = e.basis() sage: matrix([[x.inner_product(y) for x in B] for y in B]) [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] sage: x = e.an_element(); x 2*e[0] + 2*e[1] + 3*e[2] sage: x.inner_product(x) 17 - >>> from sage.all import * >>> e = RootSystem(['B',Integer(3),Integer(1)]).ambient_space() >>> B = e.basis() >>> matrix([[x.inner_product(y) for x in B] for y in B]) [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] >>> x = e.an_element(); x 2*e[0] + 2*e[1] + 3*e[2] >>> x.inner_product(x) 17 - scalar()is an alias for this method:- sage: x.scalar(x) 17 - >>> from sage.all import * >>> x.scalar(x) 17 - Todo - Lift to CombinatorialFreeModule.Element as canonical_inner_product 
 
 - coroot_lattice()[source]¶
- EXAMPLES: - sage: RootSystem(["A",3,1]).ambient_lattice().coroot_lattice() Ambient lattice of the Root system of type ['A', 3, 1] - >>> from sage.all import * >>> RootSystem(["A",Integer(3),Integer(1)]).ambient_lattice().coroot_lattice() Ambient lattice of the Root system of type ['A', 3, 1] - Todo - Factor out this code with the classical ambient space. 
 - fundamental_weight(i)[source]¶
- Return the fundamental weight \(\Lambda_i\) in this ambient space. - It is constructed by taking the corresponding fundamental weight of the classical ambient space (or \(0\) for \(\Lambda_0\)) and raising it to the appropriate level by adding a suitable multiple of \(\delta^\vee\). - EXAMPLES: - sage: RootSystem(['A',3,1]).ambient_space().fundamental_weight(2) # needs sage.graphs e[0] + e[1] + e['deltacheck'] sage: RootSystem(['A',3,1]).ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + e['deltacheck'], 3: e[0] + e[1] + e[2] + e['deltacheck']} sage: RootSystem(['A',3]).ambient_space().fundamental_weights() Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0)} sage: A31wl = RootSystem(['A',3,1]).weight_lattice() sage: A31wl.fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 1, 1: 1, 2: 1, 3: 1} sage: RootSystem(['B',3,1]).ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + 2*e['deltacheck'], 3: 1/2*e[0] + 1/2*e[1] + 1/2*e[2] + e['deltacheck']} sage: RootSystem(['B',3]).ambient_space().fundamental_weights() Finite family {1: (1, 0, 0), 2: (1, 1, 0), 3: (1/2, 1/2, 1/2)} sage: B31wl = RootSystem(['B',3,1]).weight_lattice() sage: B31wl.fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 1, 1: 1, 2: 2, 3: 1} - >>> from sage.all import * >>> RootSystem(['A',Integer(3),Integer(1)]).ambient_space().fundamental_weight(Integer(2)) # needs sage.graphs e[0] + e[1] + e['deltacheck'] >>> RootSystem(['A',Integer(3),Integer(1)]).ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + e['deltacheck'], 3: e[0] + e[1] + e[2] + e['deltacheck']} >>> RootSystem(['A',Integer(3)]).ambient_space().fundamental_weights() Finite family {1: (1, 0, 0, 0), 2: (1, 1, 0, 0), 3: (1, 1, 1, 0)} >>> A31wl = RootSystem(['A',Integer(3),Integer(1)]).weight_lattice() >>> A31wl.fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 1, 1: 1, 2: 1, 3: 1} >>> RootSystem(['B',Integer(3),Integer(1)]).ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + 2*e['deltacheck'], 3: 1/2*e[0] + 1/2*e[1] + 1/2*e[2] + e['deltacheck']} >>> RootSystem(['B',Integer(3)]).ambient_space().fundamental_weights() Finite family {1: (1, 0, 0), 2: (1, 1, 0), 3: (1/2, 1/2, 1/2)} >>> B31wl = RootSystem(['B',Integer(3),Integer(1)]).weight_lattice() >>> B31wl.fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 1, 1: 1, 2: 2, 3: 1} - In type \(BC\) dual, the coefficient of ‘delta^vee’ is the level divided by \(2\) to take into account that the null coroot is \(2\delta^\vee\): - sage: R = CartanType(['BC',3,2]).dual().root_system() sage: R.ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + e['deltacheck'], 3: 1/2*e[0] + 1/2*e[1] + 1/2*e[2] + 1/2*e['deltacheck']} sage: R.weight_lattice().fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 1} sage: R.ambient_space().null_coroot() # needs sage.graphs 2*e['deltacheck'] - >>> from sage.all import * >>> R = CartanType(['BC',Integer(3),Integer(2)]).dual().root_system() >>> R.ambient_space().fundamental_weights() # needs sage.graphs Finite family {0: e['deltacheck'], 1: e[0] + e['deltacheck'], 2: e[0] + e[1] + e['deltacheck'], 3: 1/2*e[0] + 1/2*e[1] + 1/2*e[2] + 1/2*e['deltacheck']} >>> R.weight_lattice().fundamental_weights().map(attrcall("level")) # needs sage.graphs Finite family {0: 2, 1: 2, 2: 2, 3: 1} >>> R.ambient_space().null_coroot() # needs sage.graphs 2*e['deltacheck'] - By a slight naming abuse this function also accepts “delta” as input so that it can be used to implement the embedding from the extended weight lattice: - sage: RootSystem(['A',3,1]).ambient_space().fundamental_weight("delta") e['delta'] - >>> from sage.all import * >>> RootSystem(['A',Integer(3),Integer(1)]).ambient_space().fundamental_weight("delta") e['delta'] 
 - is_extended()[source]¶
- Return whether this is a realization of the extended weight lattice: yes! - See also - EXAMPLES: - sage: RootSystem(['A',3,1]).ambient_space().is_extended() True - >>> from sage.all import * >>> RootSystem(['A',Integer(3),Integer(1)]).ambient_space().is_extended() True 
 - simple_coroot(i)[source]¶
- Return the \(i\)-th simple coroot \(\alpha_i^\vee\) of this affine ambient space. - EXAMPLES: - sage: RootSystem(["A",3,1]).ambient_space().simple_coroot(1) e[0] - e[1] - >>> from sage.all import * >>> RootSystem(["A",Integer(3),Integer(1)]).ambient_space().simple_coroot(Integer(1)) e[0] - e[1] - It is built as the coroot associated to the simple root \(\alpha_i\): - sage: RootSystem(["B",3,1]).ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: e[2]} sage: RootSystem(["B",3,1]).ambient_space().simple_coroots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['deltacheck'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} - >>> from sage.all import * >>> RootSystem(["B",Integer(3),Integer(1)]).ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: e[2]} >>> RootSystem(["B",Integer(3),Integer(1)]).ambient_space().simple_coroots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['deltacheck'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} - Todo - Factor out this code with the classical ambient space. 
 - simple_root(i)[source]¶
- Return the \(i\)-th simple root of this affine ambient space. - EXAMPLES: - It is built straightforwardly from the corresponding simple root \(\alpha_i\) in the classical ambient space: - sage: RootSystem(["A",3,1]).ambient_space().simple_root(1) e[0] - e[1] - >>> from sage.all import * >>> RootSystem(["A",Integer(3),Integer(1)]).ambient_space().simple_root(Integer(1)) e[0] - e[1] - For the special node (typically \(i=0\)), \(\alpha_0\) is built from the other simple roots using the column annihilator of the Cartan matrix and adding \(\delta\), where \(\delta\) is the null root: - sage: RootSystem(["A",3]).ambient_space().simple_roots() Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)} sage: RootSystem(["A",3,1]).ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] + e[3] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: e[2] - e[3]} - >>> from sage.all import * >>> RootSystem(["A",Integer(3)]).ambient_space().simple_roots() Finite family {1: (1, -1, 0, 0), 2: (0, 1, -1, 0), 3: (0, 0, 1, -1)} >>> RootSystem(["A",Integer(3),Integer(1)]).ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] + e[3] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: e[2] - e[3]} - Here is a twisted affine example: - sage: B31v = RootSystem(CartanType(["B",3,1]).dual()) sage: B31v.ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} - >>> from sage.all import * >>> B31v = RootSystem(CartanType(["B",Integer(3),Integer(1)]).dual()) >>> B31v.ambient_space().simple_roots() # needs sage.graphs Finite family {0: -e[0] - e[1] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} - In fact \(\delta\) is really \(1/a_0\) times the null root (see the discussion in - WeightSpace) but this only makes a difference in type \(BC\):- sage: L = RootSystem(CartanType(["BC",3,2])).ambient_space() sage: L.simple_roots() # needs sage.graphs Finite family {0: -e[0] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} sage: L.null_root() # needs sage.graphs 2*e['delta'] - >>> from sage.all import * >>> L = RootSystem(CartanType(["BC",Integer(3),Integer(2)])).ambient_space() >>> L.simple_roots() # needs sage.graphs Finite family {0: -e[0] + e['delta'], 1: e[0] - e[1], 2: e[1] - e[2], 3: 2*e[2]} >>> L.null_root() # needs sage.graphs 2*e['delta'] - Note - An alternative would have been to use the default implementation of the simple roots as linear combinations of the fundamental weights. However, as in type \(A_n\) it is preferable to take a slight variant to avoid rational coefficient (the usual \(GL_n\) vs \(SL_n\) issue). - See also 
- CartanType.col_annihilator()
- null_root()
 
 - classmethod smallest_base_ring(cartan_type)[source]¶
- Return the smallest base ring the ambient space can be defined on. - This is the smallest base ring for the associated classical ambient space. - See also - EXAMPLES: - sage: cartan_type = CartanType(["A",3,1]) sage: cartan_type.AmbientSpace.smallest_base_ring(cartan_type) Integer Ring sage: cartan_type = CartanType(["B",3,1]) sage: cartan_type.AmbientSpace.smallest_base_ring(cartan_type) Rational Field - >>> from sage.all import * >>> cartan_type = CartanType(["A",Integer(3),Integer(1)]) >>> cartan_type.AmbientSpace.smallest_base_ring(cartan_type) Integer Ring >>> cartan_type = CartanType(["B",Integer(3),Integer(1)]) >>> cartan_type.AmbientSpace.smallest_base_ring(cartan_type) Rational Field