IP := function(T, chi, psi) # character table inner product. T is a character table, chi is a character, psi is the index of a character in T return Sum( [1 .. Length(SizesConjugacyClasses(T))], i -> SizesConjugacyClasses( T )[i] * chi[i] * ComplexConjugate( Irr(T)[psi][i] ) ) / Size( T ); end;; coeffs := function(T, chi) # coefficients of a character in terms of the characters in a table. T is a character table, chi is a character return List( [1..Length(SizesConjugacyClasses(T))], i -> IP(T, chi, i) ); end;; embed := function(U, G, H) # embeds U into H. U, G, H are all groups satisfying U \le G \cong H local phi, gens, image_gens, isom, proj; phi := IsomorphismGroups(G,H); gens := GeneratorsOfGroup(G); image_gens := List(gens,x->Image(phi,x)); isom := GroupHomomorphismByImages(G,H,gens,image_gens); return Image(isom,U); end;; lift := function(U, G, H) # lifts U up into H. U, G, H are all groups with U \le G covered by H local proj; proj := GroupHomomorphismByImages(H,G); return PreImage(proj,U); end;; IC := function(G, H) # induced characters from G to H. G, H are groups local n, ic; ic := [ ]; for n in [1..Length(Irr(G))] do Add(ic, InducedClassFunction(ClassFunction(CharacterTable(G), Irr(G)[n]), H)); od; return ic; end;; charsAppearing := function(G, H) # a list of characters of H with nonzero inner product with each irrep of G induced up to H. G, H are groups local ic, i, m, n; ic := IC(G, H); for i in [1..Length(Irr(G))] do if i < 10 then Print(" "); fi; Print(i); Print(": "); for m in [1..Length(ConstituentsOfCharacter(ic[i]))] do for n in [1..Length(Irr(H))] do if ConstituentsOfCharacter(ic[i])[m] = Irr(H)[n] then Print(n); Print(" "); break; fi; od; od; Print("\n"); od; end;; charCoeffs := function(G, H) # the coefficients resulting from each irrep of G induced up to H. G, H are groups local ic, i, x, CTH; ic := IC(G, H); CTH := CharacterTable(H); for i in [1..Length(ic)] do if i < 10 then Print(" "); fi; Print(i); Print(": "); for x in [1..Length(coeffs(CTH, ic[i]))] do if coeffs(CTH, ic[i])[x] = 0 then Print(". "); else Print(coeffs(CTH, ic[i])[x]); Print(" "); fi; od; Print("\n"); od; end;; 1twistSum := function(G, H, n) # demonstrates the result (in the same style as charCoeffs) of inducing each twist of the nth irrep of G's character table up to H. G, H are groups, n is the index of a character in G's character table local ic, rep, 1dims, twists, cth, i, m, x; ic := IC(G, H); rep := ic[n]; 1dims := [ ]; for x in Irr(H) do if x[1] = 1 then Add(1dims, x); fi; od; twists := List(1dims, x -> rep * x); cth := CharacterTable(H); for i in [1..Length(twists)] do if i < 10 then Print(" "); fi; Print(i); Print(": "); for m in [1..Length(coeffs(cth, twists[i]))] do if coeffs(cth, twists[i])[m] = 0 then Print(". "); else Print(coeffs(cth, twists[i])[m]); Print(" "); fi; od; Print("\n"); od; end;; 1twistIrreps := function(G) # demonstrates the result of twisting each higher-than-1-dimensional irrep of G by each 1-dimensional irrep. G is a group local 1dims, x, i, n, y; 1dims := [ ]; for x in Irr(G) do if x[1] = 1 then Add(1dims, x); fi; od; for x in [1..Length(1dims)] do if x < 10 then Print(" "); fi; Print(x); Print(": "); for i in [Length(1dims)+1 .. Length(Irr(G))] do y := 1dims[x] * Irr(G)[i]; for n in [Length(1dims)+1 .. Length(Irr(G))] do if Irr(G)[n] = y then if n < 10 then Print(" "); fi; Print(n); Print(" "); break; fi; od; od; Print("\n"); od; end;;