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[2]`

, we make the element *u _{α}(4)*
of the root subgroup

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 *E _{8}* is 32. More precisely, squaring doubles the height
of the involved roots, so in the above

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)

- UnipotentGroup
- Operations for Unipotent elements
- IsUnipotentElement
- UnipotentDecompose
- UnipotentAbelianPart

`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

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 ofhas a**U****Chevalley basis***e*indexed by roots, with the property that_{r}*[e*for some integer constants_{r},e_{s}]=N_{r,s}e_{r+s}*N*for each pair of roots whose sum is a root. The list_{r,s}`chevalleyConstants`

, of same length as`.specialPairs`

, contains the corresponding integers*N*._{r,s}

`commutatorConstants`

:

These are the constants*C*which occur in the commutator formula for two root subgroups:_{r,s,i,j} where the product is over all the roots of the given shape. The list*u*_{s}(u)u_{r}(t)=u_{r}(t)u_{s}(u)∏_{i,j>0}u_{ir+js}(C_{r,s,i,j}(-t)^{i}u^{j}),`.commutatorConstants`

is of the same length as`.specialPairs`

and contains for each pair of roots a list of quadruples*[i,j,ir+js,C*for all possible values of_{r,s,i,j}]*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(`

*r*,_{1}*c*,..,_{1}*r*,_{n}*c*)_{n}

In the first form the function creates the element *u _{r}(1)*, and in the second
form the element

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

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.

`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

`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

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) ]

`UnipotentAbelianPart(`

`u`)

If * U* is the unipotent subgroup and

`u`

on

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)