## Unipotent elements in reductive groups

I have written a couple of functions for dealing with elements of the unipotent radical of a Borel subgroup of any reductive group. They are now included in the CHEVIE package, which you can find here. I am indebted to Jean Michel for improving the first version of these functions and for writing the corresponding entry on the GAP3 manual, which I reproduce here.

The unipotent radical of a Borel subgroup is the product in any order of root subgroups associated to the positive roots. We fix an order, which gives a canonical form to display elements and to compare them.

The computations use the Steinberg relations between root subgroups, which come from the choice of a Chevalley basis of the Lie algebra. The reference we follow is chapters 4 to 6 of the book Simple groups of Lie type by R. W. Carter (Wiley 1972).

We start with a root datum specified by a CHEVIE Coxeter group record `W` and build a record which contains information about the maximal unipotent subgroup of the corresponding reductive group, that is the unipotent radical of the Borel subgroup determined by the positive roots.

```   gap> W:=CoxeterGroup("E",6);; U:=UnipotentGroup(W);
UnipotentGroup(CoxeterGroup("E",6))```

Now, if α=`W.roots`, we make the element uα(4) of the root subgroup uα:

```   gap> U.Element(2,4);
u2(4)```

If we do not specify the coefficient we make by default uα(1), so we have also:

```   gap> U.Element(2)^4;
u2(4)```

We can make more complicated elements:

```   gap> U.Element(2,4)*U.Element(4,5);
u2(4) * u4(5)
gap> U.Element(2,4,4,5);
u2(4) * u4(5)```

If the roots are not in order the element is normalized:

```   gap> u:=U.Element(4,5,2,4);
u2(4) * u4(5) * u8(-20)```

It is possible to display the decomposition of the roots in simple roots instead of their index:

```   gap> Display(u,rec(root:=true));
u010000(4) * u000100(5) * u010100(-20)```

The coefficients in the root subgroups can be elements of arbitrary rings. Here is an example using the package vkcurve:

```   gap>  W:=CoxeterGroup("E",8);; U:=UnipotentGroup(W);
UnipotentGroup(CoxeterGroup("E",8))
gap> u:=U.Element(List([1..8],i->[i,Z(2)*Mvp(SPrint("x",i))]));
u1(Z(2)^0x1) * u2(Z(2)^0x2) * u3(Z(2)^0x3) * u4(Z(2)^0x4) * u5(Z(2)^0x5)\
* u6(Z(2)^0x6) * u7(Z(2)^0x7) * u8(Z(2)^0x8)
gap> Display(u^16,rec(root:=true));
u22343210(Z(2)^0x1^2x2^2x3^3x4^4x5^3x6^2x7) *
u12343211(Z(2)^0x1x2^2x3^3x4^4x5^3x6^2x7x8) *
u12243221(Z(2)^0x1x2^2x3^2x4^4x5^3x6^2x7^2x8) *
u12233321(Z(2)^0x1x2^2x3^2x4^3x5^3x6^3x7^2x8) *
u22343211(Z(2)^0x1^2x2^2x3^3x4^4x5^3x6^2x7x8) *
u12243321(Z(2)^0x1x2^2x3^2x4^4x5^3x6^3x7^2x8) *
u12244321(Z(2)^0x1x2^2x3^2x4^4x5^4x6^3x7^2x8) *
u22343321(Z(2)^0x1^2x2^2x3^3x4^4x5^3x6^3x7^2x8) *
u12344321(Z(2)^0x1x2^2x3^3x4^4x5^4x6^3x7^2x8) *
u22344321(Z(2)^0x1^2x2^2x3^3x4^4x5^4x6^3x7^2x8) *
u23354321(Z(2)^0x1^2x2^3x3^3x4^5x5^4x6^3x7^2x8) *
u22454321(Z(2)^0x1^2x2^2x3^4x4^5x5^4x6^3x7^2x8) *
u23465432(Z(2)^0x1^2x2^3x3^4x4^6x5^5x6^4x7^3x8^2)
gap> u^32;
()```

The above computation shows that in characteristic 2 the exponent of the unipotent group of E8 is 32. More precisely, squaring doubles the height of the involved roots, so in the above u16 involves only roots of height 16 or more.

Various actions are defined on unipotent elements. Elements of the Weyl group act (through certain representatives) as long as no root subgroup is in their inversion set:

```   gap> W:=CoxeterGroup("G",2);
CoxeterGroup("G",2)
gap> U:=UnipotentGroup(W);
UnipotentGroup(CoxeterGroup("G",2))
gap> u:=U.Element(1,Mvp("x"),3,Mvp("y"));
u1(x) * u3(y)
gap> u^(W.2*W.1);
u4(y) * u5(x)
gap> u^W.1;
Error, u1(x) * u3(y) should have no coefficient on root 1
in
<rec1> ^ <rec2> called from
main loop
brk>```

Semisimple elements act by conjugation:

```   gap> s:=SemisimpleElement(W,[E(3),2]);
<E(3),2>
gap> u^s;
u1(E3x) * u3(2E3y)```

As well as unipotent elements:

```   gap> u^U.Element(2);
u1(x) * u3(x+y) * u4(-x-2y) * u5(x+3y) * u6(3xy+x^2+3y^2)```

## 1. UnipotentGroup

`UnipotentGroup(W)`

W should be a Coxeter group record representing a Weyl group. This function returns a record representing the unipotent radical U of a Borel subgroup of the reductive group of Weyl group W.

The result is a record with the following fields:

`weylGroup`:

contains W.

`specialPairs`:

Let < be the order on the roots of W resulting from some total order on the ambient vector space. A pair (r,s) of roots is special if r<s and r+s. The field `.specialPairs` contains twice the list of triples (r,s,r+s) for special pairs: it contains first this list, sorted by (r+s,r), then it contains a copy of the list in the order (s,r,r+s). Roots in these triples are representated as their index in `Parent(W).roots`. Thanks to the repetition, each ordered pair of positive roots whose sum is a root appears exactly once in `.specialPairs`.

`chevalleyConstants`:

The Lie algebra of U has a Chevalley basis er indexed by roots, with the property that [er,es]=Nr,s er+s for some integer constants Nr,s for each pair of roots whose sum is a root. The list `chevalleyConstants`, of same length as `.specialPairs`, contains the corresponding integers Nr,s.

`commutatorConstants`:

These are the constants Cr,s,i,j which occur in the commutator formula for two root subgroups:
 us(u)ur(t)=ur(t)us(u)∏i,j>0 uir+js(Cr,s,i,j(-t)iuj),
where the product is over all the roots of the given shape. The list `.commutatorConstants` is of the same length as `.specialPairs` and contains for each pair of roots a list of quadruples [i,j,ir+js,Cr,s,i,j] for all possible values of i,j for this pair.

`order`:

An order on the roots, used to give a canonical form to unipotent elements by listing the root subgroups in that order. `.order` is the list of indices of roots in `Parent(W)`, listed in the desired order.

```   gap> W:=CoxeterGroup("G",2);
CoxeterGroup("G",2)
gap> U:=UnipotentGroup(W);
UnipotentGroup(CoxeterGroup("G",2))
gap> U.specialPairs;
[ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 2, 4, 5 ], [ 1, 5, 6 ], [ 3, 4, 6 ],
[ 2, 1, 3 ], [ 3, 2, 4 ], [ 4, 2, 5 ], [ 5, 1, 6 ], [ 4, 3, 6 ] ]
gap> U.chevalleyConstants;
[ 1, 2, 3, 1, 3, -1, -2, -3, -1, -3 ]
gap> U.commutatorConstants;
[ [ [ 1, 1, 3, 1 ], [ 1, 2, 4, -1 ], [ 1, 3, 5, 1 ], [ 2, 3, 6, 2 ] ],
[ [ 1, 1, 4, 2 ], [ 2, 1, 5, 3 ], [ 1, 2, 6, -3 ] ], [ [ 1, 1, 5, 3 ] ],
[ [ 1, 1, 6, 1 ] ], [ [ 1, 1, 6, 3 ] ],
[ [ 1, 1, 3, -1 ], [ 2, 1, 4, -1 ], [ 3, 1, 5, -1 ], [ 3, 2, 6, -1 ] ],
[ [ 1, 1, 4, -2 ], [ 2, 1, 6, -3 ], [ 1, 2, 5, 3 ] ], [ [ 1, 1, 5, -3 ]],
[ [ 1, 1, 6, -1 ] ], [ [ 1, 1, 6, -3 ] ] ]```

A unipotent group record also contains functions for creating and normalizing unipotent elements.

`U.Element(r)`

`U.Element(r1,c1,..,rn,cn)`

In the first form the function creates the element ur(1), and in the second form the element ur1(c1)... urn(cn)

```   gap> U.Element(2);
u2(1)
gap> U.Element(1,2,2,4);
u1(2) * u2(4)
gap> U.Element(2,4,1,2);
u1(2) * u2(4) * u3(-8) * u4(32) * u5(-128) * u6(512)```

`U.CanonicalForm(l[,order])`

The function takes a list of pairs `[r,c]` representing a unipotent element, where `r` is a root and `c` the corresponding coefficient, and puts it in canoncal form, reordering the terms to agree with `U.order` using the commutation relations. If a second argument is given, this is used instead of `U.order`.

```   gap> U.CanonicalForm([[2,4],[1,2]]);
[ [ 1, 2 ], [ 2, 4 ], [ 3, -8 ], [ 4, 32 ], [ 5, -128 ], [ 6, 512 ] ]
gap> U.CanonicalForm(last,[6,5..1]);
[ [ 2, 4 ], [ 1, 2 ] ]```

## 2. Operations for Unipotent elements

The arithmetic operations `*`, `/` and `^` work for unipotent elements. They also have `Print` and `String` methods.

```   gap> u:=U.Element(1,4,3,-6);
u1(4) * u3(-6)
gap> u^-1;
u1(-4) * u3(6)
gap> u:=U.Element(1,4,2,-6);
u1(4) * u2(-6)
gap> u^-1;
u1(-4) * u2(6) * u3(24) * u4(-144) * u5(864) * u6(6912)
gap> u^0;
()
gap> u*u;
u1(8) * u2(-12) * u3(24) * u4(432) * u5(6048) * u6(-17280)
gap> String(u);
"u1(4) * u2(-6)"
gap> Format(u^2,rec(root:=true));
"u10(8) * u01(-12) * u11(24) * u12(432) * u13(6048) * u23(-17280)"```

`u^n` gives the `n`-th power of `u` when `n` is an integer and `u` conjugate by `n` when `n` is a unipotent element, a semisimple element or an element of the Weyl group.

## 3. IsUnipotentElement

`IsUnipotentElement(u)`

This function returns `true` if `u` is a unipotent element and `false` otherwise.

```   gap> IsUnipotentElement(U.Element(2));
true
gap> IsUnipotentElement(2);
false```

## 4. UnipotentDecompose

`UnipotentDecompose(w,u)`

`u` should be a unipotent element and `w` an element of the corresponding Weyl group. If U is the unipotent radical of the Borel subgroup determined by the positive roots, and U- the unipotent radical of the opposite Borel, this function decomposes u into its component in UwU- and its component in UwU.

```   gap> u:=U.Element(2,Mvp("y"),1,Mvp("x"));
u1(x) * u2(y) * u3(-xy) * u4(xy^2) * u5(-xy^3) * u6(2x^2y^3)
gap> UnipotentDecompose(W.1,u);
[ u1(x), u2(y) * u3(-xy) * u4(xy^2) * u5(-xy^3) * u6(2x^2y^3) ]
gap> UnipotentDecompose(W.2,u);
[ u2(y), u1(x) ]```

## 5. UnipotentAbelianPart

`UnipotentAbelianPart(u)`

If U is the unipotent subgroup and D(U) its derived subgroup, this function returns the projection of the unipotent element `u` on U/D(U), that is its coefficients on the simple roots.

```   gap> u:=U.Element(2,Mvp("y"),1,Mvp("x"));
u1(x) * u2(y) * u3(-xy) * u4(xy^2) * u5(-xy^3) * u6(2x^2y^3)
gap> UnipotentAbelianPart(u);
u1(x) * u2(y)```