# Root system data for affine Cartan types¶

class sage.combinat.root_system.type_affine.AmbientSpace(root_system, base_ring)

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()
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() sage: Lambda e[‘deltacheck’] sage: L.null_coroot() 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())
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()


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]^*

class Element

Bases: sage.modules.with_basis.indexed_element.IndexedFreeModuleElement

associated_coroot()

Return the coroot associated to self.

INPUT:

• self – a root

EXAMPLES:

sage: alpha = RootSystem(['C',2,1]).ambient_space().simple_roots()
sage: alpha
Finite family {0: -2*e + e['delta'], 1: e - e, 2: 2*e}
sage: alpha.associated_coroot()
-e + e['deltacheck']
sage: alpha.associated_coroot()
e - e
sage: alpha.associated_coroot()
e

inner_product(other)

Implement the canonical inner product of self with 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 + 2*e + 3*e
sage: x.inner_product(x)
17


scalar() is an alias for this method:

sage: x.scalar(x)
17


Todo

Lift to CombinatorialFreeModule.Element as canonical_inner_product

scalar(other)

Implement the canonical inner product of self with 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 + 2*e + 3*e
sage: x.inner_product(x)
17


scalar() is an alias for this method:

sage: x.scalar(x)
17


Todo

Lift to CombinatorialFreeModule.Element as canonical_inner_product

coroot_lattice()

EXAMPLES:

sage: RootSystem(["A",3,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)

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)
e + e + e['deltacheck']
sage: RootSystem(['A',3,1]).ambient_space().fundamental_weights()
Finite family {0: e['deltacheck'], 1: e + e['deltacheck'],
2: e + e + e['deltacheck'], 3: e + e + e + 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: RootSystem(['A',3,1]).weight_lattice().fundamental_weights().map(attrcall("level"))
Finite family {0: 1, 1: 1, 2: 1, 3: 1}

sage: RootSystem(['B',3,1]).ambient_space().fundamental_weights()
Finite family {0: e['deltacheck'], 1: e + e['deltacheck'],
2: e + e + 2*e['deltacheck'], 3: 1/2*e + 1/2*e + 1/2*e + 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: RootSystem(['B',3,1]).weight_lattice().fundamental_weights().map(attrcall("level"))
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()
Finite family {0: e['deltacheck'], 1: e + e['deltacheck'],
2: e + e + e['deltacheck'],
3: 1/2*e + 1/2*e + 1/2*e + 1/2*e['deltacheck']}
sage: R.weight_lattice().fundamental_weights().map(attrcall("level"))
Finite family {0: 2, 1: 2, 2: 2, 3: 1}
sage: R.ambient_space().null_coroot()
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']

is_extended()

Return whether this is a realization of the extended weight lattice: yes!

EXAMPLES:

sage: RootSystem(['A',3,1]).ambient_space().is_extended()
True

simple_coroot(i)

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 - e


It is built as the coroot associated to the simple root $$\alpha_i$$:

sage: RootSystem(["B",3,1]).ambient_space().simple_roots()
Finite family {0: -e - e + e['delta'], 1: e - e, 2: e - e, 3: e}
sage: RootSystem(["B",3,1]).ambient_space().simple_coroots()
Finite family {0: -e - e + e['deltacheck'], 1: e - e, 2: e - e, 3: 2*e}


Todo

Factor out this code with the classical ambient space.

simple_root(i)

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 - e


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()
Finite family {0: -e + e + e['delta'], 1: e - e, 2: e - e, 3: e - e}


Here is a twisted affine example:

sage: RootSystem(CartanType(["B",3,1]).dual()).ambient_space().simple_roots()
Finite family {0: -e - e + e['delta'], 1: e - e, 2: e - e, 3: 2*e}


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()
Finite family {0: -e + e['delta'], 1: e - e, 2: e - e, 3: 2*e}
sage: L.null_root()
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).

classmethod smallest_base_ring(cartan_type)

Return the smallest base ring the ambient space can be defined on.

This is the smallest base ring for the associated classical ambient space.

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