load "Subgroups/functions.txt";

/* This function takes a set of irreducible modules and computes all possible sets of composition factors
  from them with consistent traces, with CC the conjugacy classes of G. P is a special set of integers
  you want to test first, but just the traces, not the eigenvalues. This is the same if the integer is a
  prime, of course. Ans is a previously known set of dimensions for composition factors. Leave as [] if
  you want to test all of them. */

function ComputeConspicuousFactorsE8(Irr2,CC,Tr,P,Ans)

G:=Group(Irr2[1]);
p:=Characteristic(Field(Irr2[1]));

//First replace Irr2 with Irr, where the modules are self-dual and of dimension at most 248

Irr:=[];
for i in [j:j in [1..#Irr2]|Dimension(Irr2[j]) le 248] do
  nn:=IdentifyModule(Dual(Irr2[i]),Irr2);
  if(nn eq i) then Append(~Irr,Irr2[i]);
    elif(nn gt i and Dimension(Irr2[i]) le 124) then Append(~Irr,DirectSum(Irr2[i],Irr2[nn]));
  end if;
end for;
Irr:=OrderByDimension(Irr);

"Computed the self-dual set";

Br:=[BrauerCharacter(i):i in Irr];
// Now compute all of the sets of composition factors of dimension 248.

"Computed Brauer characters";
if(Ans eq []) then Ans:=RestrictedPartitions(248,{Dimension(i):i in Irr}); end if;

dims:=[Dimension(i):i in Irr];
Ans2:=[];
for CurrentDegreeSeq in Ans do
  NewAns:=[];
  for j in SequenceToSet(CurrentDegreeSeq) do
    m:=[]; for k in [1..#dims] do if(dims[k] eq j) then Append(~m,k); end if; end for;
    n:=Multiplicity(SequenceToMultiset(CurrentDegreeSeq),j);
    ThingsToAppend:=DecreasingSequences(n,m);
    if(NewAns eq []) then NewAns:=ThingsToAppend; delete ThingsToAppend;
    else
      NewAns2:=[];
      for alpha in NewAns do
        for beta in ThingsToAppend do Append(~NewAns2,alpha cat beta);
        end for;
      end for;
      delete NewAns; NewAns:=NewAns2; delete NewAns2; delete ThingsToAppend;
    end if;
  end for;
  Ans2 cat:=NewAns;
  delete NewAns;
end for;
"Found",#Ans2,"possible sets of composition factors";

for r in P do
  "Applying the check for integer",r;
  al:=Position([i[1]:i in CC],r);
  TrCheck:={i[1]:i in Tr[r]};
  Ans3:=[];
  for i in [1..#Ans2] do
    if (i mod 10000) eq 0 then i,#Ans2,#Ans3; end if;
    test:=&+[Br[k,al]:k in Ans2[i]];
    if(test in TrCheck) then Append(~Ans3,Ans2[i]); end if;
  end for;
  delete Ans2;
  Ans2:=Ans3;
  delete Ans3;
  delete TrCheck;
  "Down to",#Ans2,"sets of factors";
end for;

lim:=#[i:i in [j[1]:j in CC]|i le #Tr];
phi:=PowerMap(G);
CPM:=[[phi(j,i):i in Prune(Divisors(CC[j,1]))]:j in [1..lim]];
"Computed the conjugation power map for semisimple elements";

Ans3:=[];
for i in Ans2 do
  test:=[&+[Br[k,j]:k in i]:j in [1..lim]];
  for j in [2..#CPM] do if(CC[j,1] le #Tr and GCD(CC[j,1],p) eq 1) then
    ord:=CC[j,1]; divs:=Prune(Divisors(ord));
    tt:=[test[k]:k in CPM[j]];
    if(not(tt in Tr[ord])) then continue i; end if;
    end if;
  end for;
  Append(~Ans3,i);
end for;

"Reduced via traces to",#Ans3,"conspicuous sets of factors";
Ans3:=Sort([Sort(i):i in Ans3]);
Mods:=[DirectSum([Irr[i]:i in j]):j in Ans3];

return Ans3,Mods,Irr;

end function;










function ComputeConspicuousFactorsE8LowMemory(Irr2,CC,Tr,P,Ans)

G:=Group(Irr2[1]);
p:=Characteristic(Field(Irr2[1]));

//First replace Irr2 with Irr, where the modules are self-dual and of dimension at most 248

Irr:=[];
for i in [j:j in [1..#Irr2]|Dimension(Irr2[j]) le 248] do
  nn:=IdentifyModule(Dual(Irr2[i]),Irr2);
  if(nn eq i) then Append(~Irr,Irr2[i]);
    elif(nn gt i and Dimension(Irr2[i]) le 124) then Append(~Irr,DirectSum(Irr2[i],Irr2[nn]));
  end if;
end for;
Irr:=OrderByDimension(Irr);

"Computed the self-dual set";

Br:=[BrauerCharacter(i):i in Irr];
// Now compute all of the sets of composition factors of dimension 248.

"Computed Brauer characters";
if(Ans eq []) then Ans:=RestrictedPartitions(248,{Dimension(i):i in Irr}); end if;

dims:=[Dimension(i):i in Irr];
Ans2:=[];
for CurrentDegreeSeq in Ans do
  "On case",Position(Ans,CurrentDegreeSeq),"of",#Ans;
  NewAns:=[];
  for j in SequenceToSet(CurrentDegreeSeq) do
    m:=[]; for k in [1..#dims] do if(dims[k] eq j) then Append(~m,k); end if; end for;
    n:=Multiplicity(SequenceToMultiset(CurrentDegreeSeq),j);
    ThingsToAppend:=DecreasingSequences(n,m);
    if(NewAns eq []) then NewAns:=ThingsToAppend; delete ThingsToAppend;
    else
      NewAns2:=[];
      for alpha in NewAns do
        for beta in ThingsToAppend do Append(~NewAns2,alpha cat beta);
        end for;
      end for;
      delete NewAns; NewAns:=NewAns2; delete NewAns2; delete ThingsToAppend;
    end if;
  end for;
  "Have so far",#NewAns,"sets of factors";
  for r in P do
    al:=Position([i[1]:i in CC],r);
    TrCheck:={i[1]:i in Tr[r]};
    Ans3:=[];
    for i in [1..#NewAns] do
      if (i mod 10000) eq 0 then i,#NewAns,#Ans3; end if;
      test:=&+[Br[k,al]:k in NewAns[i]];
      if(test in TrCheck) then Append(~Ans3,NewAns[i]); end if;
    end for;
    delete NewAns;
    NewAns:=Ans3;
    delete Ans3;
    delete TrCheck;
    "Down to",#NewAns,"sets of factors";
  end for;
  Ans2 cat:=NewAns;
  delete NewAns;
end for;
"Found",#Ans2,"possible sets of composition factors";

lim:=#[i:i in [j[1]:j in CC]|i le #Tr];
phi:=PowerMap(G);
CPM:=[[phi(j,i):i in Prune(Divisors(CC[j,1]))]:j in [1..lim]];
"Computed the conjugation power map for semisimple elements";

Ans3:=[];
for i in Ans2 do
  test:=[&+[Br[k,j]:k in i]:j in [1..lim]];
  for j in [2..#CPM] do if(CC[j,1] le #Tr and GCD(CC[j,1],p) eq 1) then
    ord:=CC[j,1]; divs:=Prune(Divisors(ord));
    tt:=[test[k]:k in CPM[j]];
    if(not(tt in Tr[ord])) then continue i; end if;
    end if;
  end for;
  Append(~Ans3,i);
end for;

"Reduced via traces to",#Ans3,"conspicuous sets of factors";
Ans3:=Sort([Sort(i):i in Ans3]);
Mods:=[DirectSum([Irr[i]:i in j]):j in Ans3];

return Ans3,Mods,Irr;

end function;


load "Traces/E8/TracesE8.txt";
load "Traces/E8/Tr14E8Eigs";
Tr14E8:={EigsToTracePowers(i,14):i in Tr14E8Eigs};
delete Tr14E8Eigs;
load "Traces/E8/Tr15E8Eigs";
Tr15E8:={EigsToTracePowers(i,15):i in Tr15E8Eigs};
delete Tr15E8Eigs;
Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,Tr14E8,Tr15E8>;

/* Use if G=PSL(5,2)
load "Traces/E8/TracesE8.txt";
load "Traces/E8/Tr21E8Eigs";
Tr21E8:={EigsToTracePowers(i,21):i in Tr21E8Eigs};
delete Tr21E8Eigs;
load "Traces/E8/Tr31E8Eigs";
Tr31E8:={[&+i]:i in Tr31E8Eigs};
delete Tr31E8Eigs;
Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,{},Tr15E8,{},{},{},{},{},Tr21E8,
{},{},{},{},{},{},{},{},{},Tr31E8>;
*/

/* Use if G=PSp(8,2) or Omega^-(8,2) or 3D4(2) or PSL(4,4),G2(4), PSL(3,16),PSp(4,4)

load "Traces/E8/Tr15E8Eigs";
Tr15E8:={EigsToTracePowers(i,15):i in Tr15E8Eigs};
delete Tr15E8Eigs;
load "Traces/E8/Tr17E8Eigs";
Tr17E8:={[&+i]:i in Tr17E8Eigs};
delete Tr17E8Eigs;
load "Traces/E8/Tr21E8Eigs";
Tr21E8:={EigsToTracePowers(i,21):i in Tr21E8Eigs};
delete Tr21E8Eigs;

Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,{},Tr15E8,{},Tr17E8,{},{},{},Tr21E8>;
*/

/* Use if G=PSU(4,9), PSU(3,7)

load "Traces/E8/TracesE8.txt";
load "Traces/E8/Tr14E8Eigs";
Tr14E8:={EigsToTracePowers(i,14):i in Tr14E8Eigs};
delete Tr14E8Eigs;
load "Traces/E8/Tr16E8Eigs";
Tr16E8:={EigsToTracePowers(i,16):i in Tr16E8Eigs};
delete Tr16E8Eigs;
load "Traces/E8/Tr24E8Eigs";
Tr24E8:={EigsToTracePowers(i,24):i in Tr24E8Eigs};
delete Tr24E8Eigs;
Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,Tr14E8,{},Tr16E8,{},{},{},{},{},{},{},Tr24E8>;
*/

/* Use if G=PSU(4,4),PSU(4,8),PSL(3,8),G2(7),PSU(3,8),G2(8)

load "Traces/E8/TracesE8.txt";
load "Traces/E8/Tr16E8Eigs";
Tr16E8:={EigsToTracePowers(i,16):i in Tr16E8Eigs};
delete Tr16E8Eigs;
load "Traces/E8/Tr19E8Eigs";
Tr19E8:={EigsToTracePowers(i,19):i in Tr19E8Eigs};
delete Tr19E8Eigs;
load "Traces/E8/Tr21E8Eigs";
Tr21E8:={EigsToTracePowers(i,21):i in Tr21E8Eigs};
delete Tr21E8Eigs;

Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,{},{},Tr16E8,{},{},Tr19E8,{},Tr21E8>;
*/

/* Use if G=PSL(3,9)

load "Traces/E8/TracesE8.txt";
load "Traces/E8/Tr16E8Eigs";
Tr16E8:={EigsToTracePowers(i,16):i in Tr16E8Eigs};
delete Tr16E8Eigs;
load "Traces/E8/Tr20E8Eigs";
Tr20E8:={EigsToTracePowers(i,20):i in Tr20E8Eigs};
delete Tr20E8Eigs;

Tr:=<{[248]},Tr2E8,Tr3E8,Tr4E8,Tr5E8,Tr6E8,Tr7E8,Tr8E8,Tr9E8,Tr10E8,Tr11E8,Tr12E8,Tr13E8,{},{},Tr16E8,{},{},{},Tr20E8>;
*/

