The **Lie software** from the 1990's (still available here) can do this easily. One of its fundamental functions is to compute weight multiplicities for characters of irreducible modules, as specified by their highest weight. The function `domchar`

combines these multiplicities at all dominant weights; by the $W$-symmetry of the character this is really all information one needs, but provided you've got the memory to store the result, the software can compute the full formal character as well (a usually huge polynomial with natural number coefficients and weights as exponents). Note that while this is the same formal character you would get from the Weyl character formula (doing the division as an exact division of polynomials), LiE uses a different method (Freudenthal's recursion) to compute it.

Now a torus element of finite order$~n$ can be represented as a rational co-weight, modulo the lattice of integral co-weights. Evaluating this co-weight on each of the exponents of the formal character, and reducing the results modulo$~1$, gives a formal linear combination of elements in $\Bbb Q/\Bbb Z$ that through the exponential mapping $\exp_1: t\mapsto\exp(2\pi\mathbf i t)$ correspond do roots of unity; their sum is the trace you asked for. The LiE function `spectrum`

gives you the linear combination of elements in $\Bbb Q/\Bbb Z$, but scaled by the order$~n$ of the element to values in $\Bbb Z/n\Bbb Z$ so that the combination can be represented as a polynomial with integer exponents.

One can represent this trace as an element of the cyclotomic field for$~n$, for which one takes the remainder of the output from `spectrum`

by the $n$-th cyclotomic polynomial. Doing that in the LiE user programming language is not a hard exercise; for completeness I'll give below the code that does this (badly, but improving the efficiency of cyclotomic polynomials was not necessary to get satisfactory results).

```
# first some univariate polynomial division stuff
monic_quotient (pol dividend, divisor) =
{ loc quot = 0X[0]; loc d=degree(divisor)
; if divisor|[d] != 1 then error("Division by non monic polynomial") fi
; while degree(dividend)>=d
do loc dd=degree(dividend); loc c = dividend|[dd]
; loc term = c*X[dd-d]
; quot += term; dividend += -term*divisor
od
; quot
}
modulo (pol dividend, divisor) =
{ loc quot = 0X[0]; loc d=degree(divisor)
; if divisor|[d] != 1 then error("Division by non monic polynomial") fi
; while degree(dividend)>=d
do loc dd=degree(dividend); loc c = dividend|[dd]
; loc term = c*X[dd-d]
; quot += term; dividend += -term*divisor
od
; dividend
}
# the set of divisors of a number, needed for cyclotomic polynomials
Cartesian (vec v, w) =
{ loc sv=size(v); loc result = null(sv*size(w))
; for i=1 to size(v) do for j=1 to size(w)
do result[i+sv*(j-1)] = v[i]*w[j]
od od
; result
}
divisors (int b,n) = # divisors of n, assuming it has only 1 less than b
{ if b*b>n then [1,n]
; else loc r=n%b
; if r!=0 then divisors(b+1,n)
else loc l=[1]
; while n%b==0 do l = 1 + b*l; n=n/b od
; if n>b then Cartesian(l,divisors(b+1,n)) else l fi
fi
fi
}
divisors(int n) = if n>=2 then divisors(2,n) else all_one(n) fi
Phi(int n) = # cyclotomic polynomial, very inefficient version
{ loc divs=divisors(n); loc result=X[n]-X[0]
; for i=1 to size(divs)-1
do result=monic_quotient(result,Phi(divs[i])) od
; result
}
trace (vec lambda, t; grp g) =
{ loc denom=t[size(t)]; modulo(spectrum(lambda,t,g),Phi(denom)) }
```