...
 
Commits (2)
# Various representation isomorphism functions e.g. testing for
# isomorphism and computing an explicit isomorphism.
# Finds the fixed point space of the map A -> tau(gen)*A*rho(gen^-1)
FixedSpace@ := function(rho, tau, gen)
return fail;
end;
# Picks a random (nonzero) vector in the intersection of some vector
# spaces over C
RandomVectorIntersection@ := function(spaces)
return fail;
end;
# Wraps an n^2 long list into a n long list of n long lists
WrapMatrix@ := function(vec, n)
return List([0..n-1], i -> vec{[1+n*i..n*(i+1)]});
end;
# Gives the full list of the E_ij standard basis matrices for M_n(C)
MatrixBasis@ := function(n)
local coords, make_mat;
coords := Cartesian([1..n], [1..n]);
make_mat := function(coord)
local ret;
ret := NullMat(n, n);
ret[coord[1]][coord[2]] := 1;
return ret;
end;
return List(coords, make_mat);
end;
InstallGlobalFunction( LinearRepresentationIsomorphism, function(rho, tau)
local G, n, gens, fixed_spaces, A_cand;
local G, n, matrix_basis, vector_basis, alpha, triv, fixed_space, A, A_vec, alpha_f;
if not AreRepsIsomorphic(rho, tau) then
return fail;
......@@ -29,21 +33,56 @@ InstallGlobalFunction( LinearRepresentationIsomorphism, function(rho, tau)
# We want to find a matrix A s.t. tau(g)*A = A*rho(g) for all g in
# G. We do this by finding fixed points of the linear maps A ->
# tau(g)*A*rho(g^-1) (eigenspaces for eigenvalue 1), then we
# intersect the spaces and pick a random vector (matrix). It will
# probably be invertible, if not try again.
# tau(g)*A*rho(g^-1). This is done by considering the
# representation alpha: g -> (A -> tau(g)*A*rho(g^-1)) and finding a
# vector in the canonical summand corresponding to the trivial
# irrep. i.e. a vector which is fixed by all g, which is exactly
# what we want.
# Note: we only need to do this for the generators: homomorphism
# properties mean this will then work for any g in G
gens := GeneratorsOfGroup(G);
# Standard basis for M_n(C)
matrix_basis := MatrixBasis@(n);
# The unwrapped vector versions, these are the what the matrices
# of our representation will act on
#
# We construct them in this way to keep track of the
# correspondence between the matrices and vectors
vector_basis := List(matrix_basis, Flat);
# This is the function that gives the representation alpha
alpha_f := function(g)
local matrix_imgs, vector_imgs;
matrix_imgs := List(matrix_basis, A -> Image(tau, g) * A * Image(rho, g^-1));
# unwrap them and put them in a matrix
vector_imgs := List(matrix_imgs, Flat);
# we want the images to be columns not rows (we act from the
# left), so transpose
return TransposedMat(vector_imgs);
end;
# the representation alpha
alpha := FuncToHom@(G, alpha_f);
# trivial representation on G
triv := FuncToHom@(G, g -> [[1]]);
# space of vectors fixed under alpha
fixed_space := IrrepCanonicalSummand@(alpha, triv);
fixed_spaces := List(gens, gen -> FixedSpace@(rho, tau, gen));
A := NullMat(n, n);
# Keep picking matrices until we get an invertible one. This would
# happen with probability 1 if we really picked uniformly random
# vectors over C.
repeat
A_cand := WrapMatrix@(RandomVectorIntersection@(fixed_spaces), n);
until A_cand^-1 <> fail;
# we pick a "random vector"
A_vec := Sum(Basis(fixed_space), v -> Random(Integers)*v);
A := WrapMatrix@(A_vec, n);
until RankMat(A) = n;
return A_cand;
return A;
end );
......
gap> # some random group
gap> Read("tst/utils.g");;
gap> G := DirectProduct(SymmetricGroup(3), SymmetricGroup(3));;
gap> irreps := IrreducibleRepresentations(G);;
gap> rho := DirectSumRepList([irreps[2], irreps[2], irreps[2]]);;
gap> # so the canonical summand is just the whole space
gap> summand := Cyclotomics^3;;
gap> # and each axis is an irreducible G-invariant space
gap> DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[2], summand); # should get 3 bits, 1 for each irrep
[ rec( basis := [ [ 1, 0, 0 ] ] ), rec( basis := [ [ 0, 1, 0 ] ] ), rec( basis := [ [ 0, 0, 1 ] ] ) ]
gap> # and each axis is an irreducible G-invariant space, we should get
gap> # something resembling that (all G-inv, right number of summands)
gap> decomp := DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[2], summand);;
gap> ForAll(decomp, r -> IsGInvariant(rho, VectorSpace(Cyclotomics, r.basis)));
true
gap> Length(decomp);
3
gap> # something more complicated
gap> rho := DirectSumRepList([irreps[1], irreps[2], irreps[2], irreps[3]]);;
gap> DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[2], VectorSpace(Cyclotomics, [[0,1,0,0],[0,0,1,0]]));
[ rec( basis := [ [ 0, 1, 0, 0 ] ] ), rec( basis := [ [ 0, 0, 1, 0 ] ] ) ]
gap> DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[3], VectorSpace(Cyclotomics, [[0,0,0,1]]));
[ rec( basis := [ [ 0, 0, 0, 1 ] ] ) ]
\ No newline at end of file
gap> decomp := DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[2], VectorSpace(Cyclotomics, [[0,1,0,0],[0,0,1,0]]));;
gap> ForAll(decomp, r -> IsGInvariant(rho, VectorSpace(Cyclotomics, r.basis)));
true
gap> Length(decomp);
2
gap> decomp := DecomposeCanonicalSummandFast@RepnDecomp(rho, irreps[3], VectorSpace(Cyclotomics, [[0,0,0,1]]));;
gap> ForAll(decomp, r -> IsGInvariant(rho, VectorSpace(Cyclotomics, r.basis)));
true
gap> Length(decomp);
1
\ No newline at end of file
gap> G := SymmetricGroup(4);;
gap> irreps := IrreducibleRepresentations(G);;
gap> # rho, tau, tau2 are isomorphic. We check if we can find the
gap> # isomorphisms between them
gap> tau := DirectSumRepList([irreps[3], irreps[1], irreps[3]]);;
gap> rho := DirectSumRepList([irreps[1], irreps[3], irreps[3]]);;
gap> B := RandomInvertibleMat(5);;
gap> tau2 := ComposeHomFunction(tau, x -> B^-1 * x * B);;
gap> M := LinearRepresentationIsomorphism(rho, tau);;
gap> IsRepresentationIsomorphism@RepnDecomp(rho, tau, M);
true
gap> M := LinearRepresentationIsomorphism(rho, tau2);;
gap> IsRepresentationIsomorphism@RepnDecomp(rho, tau2, M);
true
gap> M := LinearRepresentationIsomorphism(tau, tau2);;
gap> IsRepresentationIsomorphism@RepnDecomp(tau, tau2, M);
true
\ No newline at end of file