Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/sl2reps/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 30.10.2022 mit Größe 16 kB image not shown  

Quelle  Misc.gi   Sprache: unbekannt

 
#
# SL2Reps: Constructing symmetric representations of SL(2,Z).
#
# Miscellaneous and helper functions.
#
# Implementations
#


#----------------------------------------
# Returns a square root of the given root of unity.
#---------------------------------------
InstallGlobalFunction( _SL2SqrtOfRootOfUnity,
function(b)
    local desc;

    if b = 1 then
        return 1;
    else
        # this returns [q,p] such that b = E(q)^p
        desc := DescriptionOfRootOfUnity(b);

        return E(desc[1]*2)^desc[2];
    fi;
end );

#----------------------------------------
# Returns a quadratic non-residue mod p.
#---------------------------------------
InstallGlobalFunction( _SL2QuadNonRes,
function(p)
    local j;

    j := 2;
    while Jacobi(j, p) = 1 do
        j := j + 1;
    od;
    return j;
end );

#----------------------------------------
# Returns a list of all factorizations of n.
#---------------------------------------
InstallGlobalFunction( _SL2Factorizations,
function(n)
    local o, f, Step;

    # recursion step
    Step := function(factors)
        local c, m, o, rest, r;

        if Length(factors) <= 1 then
            return [factors];
        fi;

        o := [];

        for c in Combinations([1 .. Length(factors)]) do
            if Length(c) = 0 then
                continue;
            fi;

            m := Product(factors{c});

            rest := [1 .. Length(factors)];
            SubtractSet(rest, c);
            rest := factors{rest};

            for r in Step(rest) do
                Add(r, m);
                Add(o, r);
            od;
        od;

        return o;
    end;

    if n = 1 then
        return [[1]];
    fi;

    o := [];

    for f in Step(Factors(n)) do
        Sort(f);
        f := Reversed(f);
        Add(f, 1);
        if not f in o then
            Add(o,f);
        fi;
    od;

    Sort(o);
    return Reversed(o);
end );

#----------------------------------------
# Records an irrep into irrep_list.
#---------------------------------------
InstallGlobalFunction( _SL2RecordIrrep,
function(irrep_list, name, rho, l)
    Info(InfoSL2Reps, 1, "SL2Reps : ", name, " [level ", l, "]");
    # record rho in the form [S, T, degree, level, name]
    Add(irrep_list, rec(
        S := rho[1],
        T := rho[2],
        degree := Length(rho[1]),
        level := l,
        name := name
    ));
end );

#----------------------------------------
# Constructs a name for a tensor product.
#---------------------------------------
InstallGlobalFunction( _SL2ConcatNames,
function(a,b)
    if a = "Xi_0" then
        return b;
    elif b = "Xi_0" then
        return a;
    else
        return Concatenation(a, " tensor ", b);
    fi;
end );

#----------------------------------------
# Returns conj class representative information of SL(2, Z/p^ld Z) for p (odd prime) and ld (>= 1).
# Each conj class representative is represented by a list of length 2. To rewrite the conj class rep as products of s and t (NW notation) corresponding to a, we can compute
# Prod(a[1], n -> t^n*s) * s^(2*a[2]).
# Note that s^2 is central and can be computed easily.
# Update: 1. Merged cases, deleted size of the conj classes; 2. Simplified the expression of the word presentation of the representatives; 3. Sorted the output so that id and -id are the first two conj classes.
#---------------------------------------
InstallGlobalFunction( _SL2ConjClassesOdd,
function(p, ld)
    local l, u, uinv, Ald, aset1, type11, type1u, type12, type13, Type1, type2h, Type2, i;

    l := p^ld;

    # Find a quad non-residue u and its mult inverse mod l.
    u:=First([1..p], i->Jacobi(i,p)=-1);
    uinv := u^-1 mod l;

    # There are 2 types of conj classes.

    # Type 1.   There are 2 cases depending on whether the upper left entry is 1 or u.
    Ald := [0..l-1];
    aset1 := Filtered(Ald, a -> (a mod p = 2) or (a mod p = p-2));

    type1u := List(aset1, a -> [[uinv, u, uinv, a*u], 1]);
    type11 := List(Ald, a -> [[a], 1]);

    Type1 := Concatenation(type1u, type11);

    # Type 2. For there is a type of conj class for each 1 <= h <= ld.
    type2h := function(h)
        local ans, dset, e;
        if h = ld then
            return [ [[0, 0], 1], [[0, 0], 0] ];
        else
            ans := [];
            for e in [1, -1] do
                dset := Filtered([0..p^(ld-h)-1], x -> x mod p = 0);
                ans := Concatenation(ans, List(dset, d -> [[-e*p^h*d*uinv, -e*p^h*u],  (1+e)/2]));
                ans := Concatenation(ans, List([0..p^(ld-h)-1], d -> [[-e*p^h*d, -e*p^h], (1+e)/2]));
            od;
            return ans;
        fi;
    end;

    # Type2 is the collection of all type2h's. Among them, type2h(ld) contains id and -id.
    Type2 := type2h(ld);
    for i in [1..ld-1] do
        Type2 := Concatenation(Type2, type2h(i));
    od;

    # Finally, combine Type1 and Type2 and return. Put Type2 in the front to make sure id and -id are the first two conj classes.
    return [Concatenation(Type2, Type1), uinv, u];
end );

#----------------------------------------
# Returns conj class representative information of SL(2, Z/2^ld Z) for ld (>= 1).
# Each conj class representative is represented by a list of length 2. To rewrite the conj class rep as products of s and t (NW notation) corresponding to a, we can compute
# Prod(a[1], n -> t^n*s) * s^(2*a[2]).
# Sorted the output so that id and -id are the first two conj classes.
#---------------------------------------
InstallGlobalFunction( _SL2ConjClassesEven,
function(ld)
    local l, 3inv, 5inv, 7inv, Type1, Type2, d, h, e1, e1inv, e2, e2inv, a;

    l := 2^ld;

    # Find the multiplicative inverse of 3, 5 and 7.
    3inv := 3^-1 mod l;
    5inv := 5^-1 mod l;
    7inv := 7^-1 mod l;

    # There are 2 types of conj classes.
    # Type 1.
    Type1 := List([0..l-1], a -> [[a], 1]);

    for a in List([0..l/2-1], x -> 2*x) do
        if ld > 1 then
            Add(Type1, [[3inv, 3, 3inv, 3*a], 1]);
        fi;

        if (ld > 2) and (a mod 4 = 2) then
            Add(Type1, [[5inv, 5, 5inv, 5*a], 1]);
            Add(Type1, [[7inv, 7, 7inv, 7*a], 1]);
        fi;
    od;

    # Type 2 are labelled by 1 <= h <= ld.
    # When h = ld, the corresponding conj classes are elements in the center. id and -id are put in the front.
    if ld = 1 then
        Type2 := [ [[0, 0], 1] ];
    elif ld = 2 then
        Type2 := [ [[0, 0], 1], [[0, 0], 0] ];
    else
        Type2 := [ [[0,0], 1], [[0, 0], 0], [[1+2^(ld-1), 1+2^(ld-1), 1+2^(ld-1)], 0], [[-(1+2^(ld-1)), -(1+2^(ld-1)), -(1+2^(ld-1))], 0] ];
    fi;

    # h = 1.
    if ld = 2 then
        Type2 := Concatenation(Type2, List([0..1], d -> [[-2*d mod l, -2 mod l], 1]));
    elif ld = 3 then
        Type2 := Concatenation(Type2, List([0..3], d -> [[-2*d mod l, -2 mod l], 1]));
        Type2 := Concatenation(Type2, List([0..1], d -> [[-2*d*3inv mod l, -2*3 mod l], 1]));
    elif ld > 3 then
        for d in [0..2^(ld-1)-1] do
            Add(Type2, [[-2*d mod l, -2 mod l], 1]);
            if (d mod 8 = 0) or (d mod 8 = 1) then
                Add(Type2, [[-2*d*3inv mod l, -2*3 mod l], 1]);
                Add(Type2, [[-2*d*5inv mod l, -2*5 mod l], 1]);
                Add(Type2, [[-2*d*7inv mod l, -2*7 mod l], 1]);
            elif (d mod 8 = 4) or (d mod 8 = 5) then
                Add(Type2, [[-2*d*3inv mod l, -2*3 mod l], 1]);
            else
                Add(Type2, [[-2*d*5inv mod l, -2*5 mod l], 1]);
            fi;
        od;
    fi;

    # ld >= 3 and h = ld - 1.
    if ld > 2 then
        for d in [0..1] do
            Add(Type2, [[-2^(ld-1)*d mod l, -2^(ld-1) mod l], 1]);
            Add(Type2, [[2^(ld-1)*d mod l, 2^(ld-1) mod l], 0]);
        od;
    fi;

    # ld >= 4 and h = ld - 2.
    if ld > 3 then
        for d in [0..3] do
            Add(Type2, [[-2^(ld-2)*d mod l, -2^(ld-2) mod l], 1]);
            Add(Type2, [[2^(ld-2)*d mod l, 2^(ld-2) mod l], 0]);
            if d = 0 or d = 1 then
                Add(Type2, [[-2^(ld-2)*d*3inv mod l, -2^(ld-2)*3 mod l], 1]);
                Add(Type2, [[2^(ld-2)*d*3inv mod l, 2^(ld-2)*3 mod l], 0]);
            fi;
        od;
    fi;

    # ld >= 5, 2 <= h <= ld - 3.
    if ld > 4 then
        for h in [2..ld-3] do
            for d in [0..2^(ld-h)-1] do
                Add(Type2, [[-2^h*d mod l, -2^h mod l], 1]);
                Add(Type2, [[2^h*d mod l, 2^h mod l], 0]);
                if (d mod 4 = 0) or (d mod 4 = 1) then
                    Add(Type2, [[-2^h*d*3inv mod l, -2^h*3 mod l], 1]);
                    Add(Type2, [[2^h*d*3inv mod l, 2^h*3 mod l], 0]);
                fi;
                if (d mod 8 = 0) or (d mod 8 = 2) or (d mod 8 = 6) then
                    Add(Type2, [[-2^h*d*5inv mod l, -2^h*5 mod l], 1]);
                    Add(Type2, [[2^h*d*5inv mod l, 2^h*5 mod l], 0]);
                fi;
                if (d mod 8 = 0) then
                    Add(Type2, [[-2^h*d*7inv mod l, -2^h*7 mod l], 1]);
                    Add(Type2, [[2^h*d*7inv mod l, 2^h*7 mod l], 0]);
                fi;
            od;
        od;
    fi;

    # ld > 3, 3 <= h <= ld - 1.
    if ld > 3 then
        for h in [3..ld-1] do
            e1 := 1 + 2^(h-1);
            e1inv := e1^(-1) mod l;
            e2 := -e1 mod l;
            e2inv := -e1inv mod l;
            for d in [0..2^(ld-h)-1] do
                Add(Type2, [[-2^h*d*e1inv mod l, e1inv, e1, e1inv, -2^h*e1inv mod l], 1]);
                Add(Type2, [[-2^h*d*e2inv mod l, e2inv, e2, e2inv, -2^h*e2inv mod l], 1]);
            od;
        od;
    fi;

    # Finally, combine Type1 and Type2 and return. Put Type2 in the front to make sure id and -id are the first two conj classes.
    return [Concatenation(Type2, Type1), 3inv, 5inv, 7inv];
end );

#----------------------------------------
# Returns conj class representative information of SL(2, Z/p^ld Z) for ld (>= 1) using ConjClassesOdd or ConjClassesEven.
#---------------------------------------
f := MemoizePosIntFunction(function(l)
    local v;
    v := PrimePowersInt(l);
    if not Length(v) = 2 then
        Error("level must be a prime power.");
    else
        if v[1] = 2 then
            return _SL2ConjClassesEven(v[2]);
        elif v[1] > 2 then
            return _SL2ConjClassesOdd(v[1], v[2]);
        fi;
    fi;
end);

InstallGlobalFunction( _SL2ConjClasses, f );

#-----------------------------------------------
# Irreducibility check
# Input: p, ld, S, and T for a rep of SL(2,Z/p^ldZ), given by RepN, RepD and RepRs. Returns the inner product of the character of this representation with itself. If needed, we can also list the character values on conjugacy classes.
#-----------------------------------------------
# InstallGlobalFunction( _SL2Reps_CharNorm,
# function(S, T)
#     local s2, chi, Csize, G, n, p, ld, CC, TS, Du, c, i, primepower;
#     # Size of SL(2, Z/p^ldZ).
#     n := Order(T);
#     primepower := Factors(n);
#     if Length(AsSet(primepower)) > 1 then
#         Error("The level is not a prime power. We cannot proceed!");
#     fi;
#     p := primepower[1];
#     ld := Length(primepower);
#     G := p^(3*ld) - p^(3*ld-2);

#     CC := _SL2Reps_ConjClassesOdd(p, ld);
#     s2 := S^2;
#          s2 := s2[1][1];
#          TS:=[S];
#     for i in [1..n-1] do
#         Add(TS, T*TS[i]);
#     od;
#          Du := TS[CC[2]+1]*TS[CC[3]+1]*TS[CC[2]+1];

#     chi := []; Csize := [];
#     for c in CC[1] do
#         Add(Csize, c[3]);
#         if Length(c[1])=4 and c[1][1]=1 then
#             Add(chi, Trace(TS[(c[1][4] mod n) + 1] * s2^(c[2])));
#         elif Length(c[1])=4 and c[1][1]<>1 then
#             Add(chi, Trace(Du*TS[(c[1][4] mod n) + 1] * s2^(c[2])));
#         elif Length(c[1])=2 then
#             Add(chi, Trace(Product(c[1], m -> TS[(m mod n) + 1]) * s2^(c[2])));
#                 fi;
#     od;

#     return ComplexConjugate(chi)*ListN(chi, Csize, \*)/G;
# end );

#-----------------------------------------------
# TODO
#-----------------------------------------------
# InstallGlobalFunction( _SL2Reps_RepChi,
# function(S, T)
#     local id, TS, Du, Dh, h, Dhmap, DS, DR, e1, e1inv, e2, e2inv, CC, ccl, s2, n, G, s, t,  C1, o, chi, i, j, jinv, c, pos, primepower, p, ld, ProdTrace;

#     # S,T are normalized S and T matrices
#     n := Order(T);
#     primepower := Factors(n);
#     if Length(AsSet(primepower))>1 then
#         Error("The level is not a prime power. We cannot proceed!");
#     fi;
#     p := primepower[1]; ld := Length(primepower);
#     CC := _SL2Reps_ConjClasses(p, ld);
#     o := ZmodnZObj(1,n);
#     s := [[0,1],[-1,0]] * o;
#     t := [[1,1],[0,1]] * o;
#     id := s^0;
#     G := Group([s,t]);

#     s2 := S^2;
#     s2 := s2[1][1];
#     TS := [S];
#     for i in [1..n-1] do
#         Add(TS, T*TS[i]);
#     od;

#     ProdTrace := function(A, B)
#         # assumes they are both square matrices of same size
#         return Sum([1..Length(A)], x -> Sum([1..Length(A)], y -> A[x][y]*B[y][x]));
#     end;

#     C1 := [];
#     if p > 2 then
#         Du := TS[CC[2]+1]*TS[CC[3]+1]*TS[CC[2]+1];
#         for c in CC[1] do
#             if Length(c[1])=1  then
#                 Add(C1, [t^(c[1][1]) * s * (-1)^(c[2]), Trace(TS[(c[1][1] mod n) + 1] * s2^(c[2]))]);
#             elif Length(c[1])=4 and c[1][1]<>1 then
#                 Add(C1, [Product(c[1], m -> t^m * s) * (-1)^(c[2]), ProdTrace(Du,TS[(c[1][4] mod n) + 1]) * s2^(c[2])]);
#             elif Length(c[1])=2 then
#                 Add(C1, [Product(c[1], m -> t^m * s) * (-1)^(c[2]), ProdTrace(TS[(c[1][1] mod n)+1], TS[(c[1][2] mod n) + 1]) * s2^(c[2])]);
#             fi;
#         od;
#     fi;

#     if p = 2 then
#         Dh := [];
#         for h in [3..ld] do
#             e1 := 1 + 2^(h-1);
#             e1inv := e1^-1 mod n;
#             Add(Dh, [e1inv,TS[e1inv + 1] * TS[e1 + 1] * TS[e1inv + 1]]);
#                     e2 := (-e1) mod n;
#             e2inv := (-e1inv) mod n;
#             Add(Dh, [e2inv,TS[e2inv + 1] * TS[e2 + 1] * TS[e2inv + 1]]);
#         od;
#         for i in [3,5,7] do
#             j := i mod n;
#             jinv := j^-1 mod n;
#             Add(Dh, [jinv,TS[jinv + 1] * TS[j + 1] * TS[jinv + 1]]);
#         od;
#         Dh := AsSet(Dh);

#         Dhmap := function(uinv)
#             local x;
#             x := First(Dh, y -> y[1] = uinv);
#             return x[2];
#         end;

#         for c in CC[1] do
#             if Length(c[1]) = 4 and c[1][1] <> 1 then
#                 Add(C1, [Product(c[1], m -> t^m * s) * (-1)^(c[2]), ProdTrace(Dhmap(c[1][1]), TS[(c[1][4] mod n) + 1]) * s2^(c[2])]);
#             elif Length(c[1]) = 2 then
#                 Add(C1, [Product(c[1], m -> t^m*s)*(-1)^(c[2]), ProdTrace(TS[(c[1][1] mod n)+1], TS[(c[1][2] mod n)+1])*s2^(c[2])]);
#             elif Length(c[1])=3 then
#                 Add(C1, [Product(c[1], m -> t^m*s)*(-1)^(c[2]), Trace(Dhmap(c[1][1] mod n))*s2^(c[2])]);
#             elif Length(c[1])=5 then
#                 Add(C1, [Product(c[1], m -> t^m*s)*(-1)^(c[2]), ProdTrace((TS[(c[1][1] mod n)+1]*Dhmap(c[1][2] mod n)), TS[(c[1][5] mod n)+1])*s2^(c[2])]);
#             elif Length(c[1])=1 then
#                 Add(C1, [Product(c[1], m -> t^m*s)*(-1)^(c[2]), Trace(TS[(c[1][1] mod n)+1])*s2^(c[2])]);
#             fi;
#         od;
#     fi;

#     chi := List(C1, x -> x[2]);
#     ccl := List(C1, x -> ConjugacyClass( G, x[1] ) );
#     if Sum(ccl, x -> Size(x)) <> Size(G) then
#         Error("Wrong conjugacy classes.");
#     fi;

#     SetConjugacyClasses( G, ccl );

#     return Character(G, chi);
# end );

#-----------------------------------------------
# Let G be SL(2, Z/nZ),  C a list of Conjugacy Classes of G,
# and CC a list of representatives of Conjugacy classes of G
# The function return a list pos such that C[i]=CC[pos[i]]^G.
#-----------------------------------------------
# InstallGlobalFunction( _SL2Reps_ClassMap,
# function(C, CC)

#     local  rep, c, C1, u, v, traces, tracelist, traceu, vlist, i, pos, PowTrace, urep, perm;


#     PowTrace:=function(x)
#         local j, temp, power;
#         temp:=[]; power:=x;
#         for j in [1..Order(x)-1] do
#             Add(temp, Trace(power));
#             power:=power*x;
#         od;
#         return temp;
#     end;

#     C1:=List(CC, c->[c, PowTrace(c)]);
#     traces:=Set(C1, c->c[2]);
#     tracelist:=Set(traces, x->[x, Filtered(C1, c->c[2]=x)]);
#     perm:=[];

#     for u in C do
#         urep:=Representative(u);
#         traceu:=PowTrace(urep);
#         vlist:=First(tracelist, x->traceu=x[1]);
#         if Length(vlist[2])=1 then
#             Add(perm, Position(CC, vlist[2][1][1]));
#             RemoveSet(tracelist, vlist);
#         elif Length(vlist[2])>1 then
#             v:=First(vlist[2], x->x[1] in u);
#             Add(perm, Position(CC, v[1]));
#             pos:=Position(vlist[2], v);
#             Remove(vlist[2], pos);
#         fi;
#     od;

#     return perm;
# end );

#-----------------------------------------------
# Find the position of the given representation among the irreducibles of its underlying group.
#-----------------------------------------------
# InstallGlobalFunction( _SL2Reps_ChiTest,
# function(chi)
#     local G;
#     G := UnderlyingGroup(chi);
#     return Position(Irr(G), chi);
# end );

[ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ]