  
  [1X5 [33X[0;0YComputing decompositions of representations[133X[101X
  
  
  [1X5.1 [33X[0;0YBlock diagonalizing[133X[101X
  
  [33X[0;0YGiven  a  representation [23X\rho : G \to GL(V)[123X, it is often desirable to find a
  basis  for [23XV[123X that block diagonalizes each [23X\rho(g)[123X with the block sizes being
  as  small  as possible. This speeds up matrix algebra operations, since they
  can now be done block-wise.[133X
  
  [1X5.1-1 BlockDiagonalBasisOfRepresentation[101X
  
  [33X[1;0Y[29X[2XBlockDiagonalBasisOfRepresentation[102X( [3Xrho[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10YBasis for [23XV[123X that block diagonalizes [23X\rho[123X.[133X
  
  [33X[0;0YLet  [23XG[123X  have  irreducible  representations  [23X\rho_i[123X,  with  dimension [23Xd_i[123X and
  multiplicity [23Xm_i[123X. The basis returned by this operation gives each [23X\rho(g)[123X as
  a block diagonal matrix which has [23Xm_i[123X blocks of size [23Xd_i \times d_i[123X for each
  [23Xi[123X.[133X
  
  [1X5.1-2 BlockDiagonalRepresentation[101X
  
  [33X[1;0Y[29X[2XBlockDiagonalRepresentation[102X( [3Xrho[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10YRepresentation  of  [23XG[123X  isomorphic to [23X\rho[123X where the images [23X\rho(g)[123X
            are block diagonalized.[133X
  
  [33X[0;0YThis      is      just     a     convenience     operation     that     uses
  [2XBlockDiagonalBasisOfRepresentation[102X  ([14X5.1-1[114X)  to  calculate  the basis change
  matrix and applies it to put [23X\rho[123X into the block diagonalised form.[133X
  
  
  [1X5.2 [33X[0;0YAlgorithms due to the authors[133X[101X
  
  [1X5.2-1 REPN_ComputeUsingMyMethod[101X
  
  [33X[1;0Y[29X[2XREPN_ComputeUsingMyMethod[102X( [3Xrho[103X ) [32X attribute[133X
  [6XReturns:[106X  [33X[0;10YA record in the same format as [2XREPN_ComputeUsingSerre[102X ([14X5.3-4[114X)[133X
  
  [33X[0;0YComputes  the same values as [2XREPN_ComputeUsingSerre[102X ([14X5.3-4[114X), taking the same
  options.    The    heavy    lifting    of    this    method   is   done   by
  [2XLinearRepresentationIsomorphism[102X   ([14X2.1-1[114X),  where  there  are  some  further
  options that can be passed to influence algorithms used.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XG := SymmetricGroup(4);;[127X[104X
    [4X[25Xgap>[125X [27Xirreps := IrreducibleRepresentations(G);;[127X[104X
    [4X[25Xgap>[125X [27Xrho := DirectSumOfRepresentations([irreps[4], irreps[5]]);;[127X[104X
    [4X[25Xgap>[125X [27X# Jumble rho up a bit so it's not so easy for the library.[127X[104X
    [4X[25X>[125X [27XA := [ [ 3, -3, 2, -4, 0, 0 ], [ 4, 0, 1, -5, 1, 0 ], [ -3, -1, -2, 4, -1, -2 ],[127X[104X
    [4X[25X>[125X [27X       [ 4, -4, -1, 5, -3, -1 ], [ 3, -2, 1, 0, 0, 0 ], [ 4, 2, 4, -1, -2, 1 ] ];;[127X[104X
    [4X[25Xgap>[125X [27Xrho := ComposeHomFunction(rho, B -> A^-1 * B * A);;[127X[104X
    [4X[25Xgap>[125X [27X# We've constructed rho from two degree 3 irreps, so there are a few[127X[104X
    [4X[25X>[125X [27X# things we can check for correctness:[127X[104X
    [4X[25X>[125X [27Xdecomposition := REPN_ComputeUsingMyMethod(rho);;[127X[104X
    [4X[25Xgap>[125X [27X# Two distinct irreps, so the centralizer has dimension 2[127X[104X
    [4X[25X>[125X [27XLength(decomposition.centralizer_basis) = 2;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27X# Two distinct irreps i.e. two invariant subspaces[127X[104X
    [4X[25X>[125X [27XLength(decomposition.decomposition) = 2;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27X# All subspaces are dimension 3[127X[104X
    [4X[25X>[125X [27XForAll(decomposition.decomposition, Vs -> Length(Vs) = 1 and Dimension(Vs[1]) = 3);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27X# And finally, check that the block diagonalized representation[127X[104X
    [4X[25X>[125X [27X# computed is actually isomorphic to rho:[127X[104X
    [4X[25X>[125X [27XAreRepsIsomorphic(rho, decomposition.diagonal_rep);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [1X5.2-2 REPN_ComputeUsingMyMethodCanonical[101X
  
  [33X[1;0Y[29X[2XREPN_ComputeUsingMyMethodCanonical[102X( [3Xrho[103X ) [32X attribute[133X
  [6XReturns:[106X  [33X[0;10YA record in the same format as [2XREPN_ComputeUsingMyMethod[102X ([14X5.2-1[114X).[133X
  
  [33X[0;0YPerforms  the  same  computation  as  [2XREPN_ComputeUsingMyMethod[102X ([14X5.2-1[114X), but
  first    splits   the   representation   into   canonical   summands   using
  [2XCanonicalDecomposition[102X  ([14X5.3-1[114X).  This might reduce the size of the matrices
  we need to work with significantly, so could be much faster.[133X
  
  [33X[0;0YIf  the  option  [10Xparallel[110X  is given, the decomposition of canonical summands
  into irreps is done in parallel, which could be much faster.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27X# This is the same example as before, but splits into canonical[127X[104X
    [4X[25X>[125X [27X# summands internally. It gives exactly the same results, up to[127X[104X
    [4X[25X>[125X [27X# isomorphism.[127X[104X
    [4X[25X>[125X [27Xother_decomposition := REPN_ComputeUsingMyMethodCanonical(rho);;[127X[104X
    [4X[25Xgap>[125X [27XLength(other_decomposition.centralizer_basis) = 2;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XLength(other_decomposition.decomposition) = 2;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XForAll(other_decomposition.decomposition, Vs -> Length(Vs) = 1 and Dimension(Vs[1]) = 3);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XAreRepsIsomorphic(rho, other_decomposition.diagonal_rep);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X5.3 [33X[0;0YAlgorithms due to Serre[133X[101X
  
  [33X[0;0YNote:  all  computation  in  this  section  is actually done in the function
  [2XREPN_ComputeUsingSerre[102X ([14X5.3-4[114X), the other functions are wrappers around it.[133X
  
  [1X5.3-1 CanonicalDecomposition[101X
  
  [33X[1;0Y[29X[2XCanonicalDecomposition[102X( [3Xrho[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10YList  of  vector  spaces [23XV_i[123X, each [23XG[123X-invariant and a direct sum of
            isomorphic  irreducibles.  That is, for each [23Xi[123X, [23XV_i \cong \oplus_j
            W_i[123X  (as  representations) where [23XW_i[123X is an irreducible [23XG[123X-invariant
            vector space.[133X
  
  [33X[0;0YComputes  the  canonical  decomposition  of  [23XV[123X  into [23X\oplus_i\;V_i[123X using the
  formulas  for projections [23XV \to V_i[123X due to Serre. You can pass in the option
  [10Xirreps[110X  with  a  list  of  irreps  of  [23XG[123X,  and  this will be used instead of
  computing  a  complete list ourselves. If you already know which irreps will
  appear in [23X\rho[123X, for instance, this will save time.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27X# This is the trivial group[127X[104X
    [4X[25X>[125X [27XG := Group(());;[127X[104X
    [4X[25Xgap>[125X [27X# The trivial group has only one representation per degree, so a[127X[104X
    [4X[25X>[125X [27X# degree d representation decomposes into a single canonical summand[127X[104X
    [4X[25X>[125X [27X# containing the whole space[127X[104X
    [4X[25X>[125X [27Xrho := FuncToHom@RepnDecomp(G, g -> IdentityMat(3));;[127X[104X
    [4X[25Xgap>[125X [27Xcanonical_summands_G := CanonicalDecomposition(rho);[127X[104X
    [4X[28X[ ( Cyclotomics^3 ) ][128X[104X
    [4X[25Xgap>[125X [27X# More interesting example, S_3[127X[104X
    [4X[25X>[125X [27XH := SymmetricGroup(3);;[127X[104X
    [4X[25Xgap>[125X [27X# The standard representation: a permutation to the corresponding[127X[104X
    [4X[25X>[125X [27X# permutation matrix.[127X[104X
    [4X[25X>[125X [27Xtau := FuncToHom@RepnDecomp(H, h -> PermutationMat(h, 3));;[127X[104X
    [4X[25Xgap>[125X [27X# Two canonical summands corresponding to the degree 2 and[127X[104X
    [4X[25X>[125X [27X# trivial irreps (in that order)[127X[104X
    [4X[25X>[125X [27XList(CanonicalDecomposition(tau), Dimension);[127X[104X
    [4X[28X[ 2, 1 ][128X[104X
  [4X[32X[104X
  
  [1X5.3-2 IrreducibleDecomposition[101X
  
  [33X[1;0Y[29X[2XIrreducibleDecomposition[102X( [3Xrho[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10YList  of vector spaces [23XW_j[123X such that [23XV = \oplus_j W_j[123X and each [23XW_j[123X
            is an irreducible [23XG[123X-invariant vector space.[133X
  
  [33X[0;0YComputes the decomposition of [23XV[123X into irreducible subprepresentations.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27X# The trivial group has 1 irrep of degree 1, so rho decomposes into 3[127X[104X
    [4X[25X>[125X [27X# lines.[127X[104X
    [4X[25X>[125X [27Xirred_decomp_G := IrreducibleDecomposition(rho);[127X[104X
    [4X[28X[ rec( basis := [ [ 1, 0, 0 ] ] ), rec( basis := [ [ 0, 1, 0 ] ] ),[128X[104X
    [4X[28X  rec( basis := [ [ 0, 0, 1 ] ] ) ][128X[104X
    [4X[25Xgap>[125X [27X# The spaces are returned in this format - explicitly keeping the[127X[104X
    [4X[25X>[125X [27X# basis - since this basis block diagonalises rho into the irreps,[127X[104X
    [4X[25X>[125X [27X# which are the smallest possible blocks. This is more obvious with[127X[104X
    [4X[25X>[125X [27X# H.[127X[104X
    [4X[25X>[125X [27Xirred_decomp_H := IrreducibleDecomposition(tau);[127X[104X
    [4X[28X[ rec( basis := [ [ 1, 1, 1 ] ] ),[128X[104X
    [4X[28X  rec( basis := [ [ 1, E(3), E(3)^2 ], [ 1, E(3)^2, E(3) ] ] ) ][128X[104X
    [4X[25Xgap>[125X [27X# Using the basis vectors given there block diagonalises tau into[127X[104X
    [4X[25X>[125X [27X# the two blocks corresponding to the two irreps:[127X[104X
    [4X[25X>[125X [27Xnice_basis := [ [ 1, 1, 1 ], [ 1, E(3), E(3)^2 ], [ 1, E(3)^2, E(3) ] ];;[127X[104X
    [4X[25Xgap>[125X [27Xtau_diag := ComposeHomFunction(tau, X -> nice_basis^-1 * X * nice_basis);[127X[104X
    [4X[28X[ (1,2,3), (1,2) ] -> [ [ [ 1, 0, 0 ], [ 0, E(3), 0 ], [ 0, 0, E(3)^2 ] ],[128X[104X
    [4X[28X  [ [ 1, 0, 0 ], [ 0, 0, E(3)^2 ], [ 0, E(3), 0 ] ] ][128X[104X
  [4X[32X[104X
  
  [1X5.3-3 IrreducibleDecompositionCollected[101X
  
  [33X[1;0Y[29X[2XIrreducibleDecompositionCollected[102X( [3Xrho[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10YList  of  lists [23XV_i[123X of vector spaces [23XV_{ij}[123X such that [23XV = \oplus_i
            \oplus_j  V_{ij}[123X  and  [23XV_{ik}  \cong V_{il}[123X for all [23Xi[123X, [23Xk[123X and [23Xl[123X (as
            representations).[133X
  
  [33X[0;0YComputes   the  decomposition  of  [23XV[123X  into  irreducible  subrepresentations,
  grouping together the isomorphic subrepresentations.[133X
  
  [1X5.3-4 REPN_ComputeUsingSerre[101X
  
  [33X[1;0Y[29X[2XREPN_ComputeUsingSerre[102X( [3Xrho[103X ) [32X attribute[133X
  [6XReturns:[106X  [33X[0;10YA record, in the format described below[133X
  
  [33X[0;0YThis  function  does  all  of the computation and (since it is an attribute)
  saves  the  results.  Doing all of the calculations at the same time ensures
  consistency  when  it  comes  to  irrep  ordering,  block ordering and basis
  ordering. There is no canonical ordering of irreps, so this is crucial.[133X
  
  [33X[0;0Y[3Xirreps[103X   is  the  complete  list  of  irreps  involved  in  the  direct  sum
  decomposition of [3Xrho[103X, this can be given in case the default (running Dixon's
  algorithm)  is  too  expensive,  or e.g. you don't want representations over
  Cyclotomics.[133X
  
  [33X[0;0YThe return value of this function is a record with fields:[133X
  
  [30X    [33X[0;6Y[10Xbasis[110X:    The    basis    that    block    diagonalises    [23X\rho[123X,   see
        [2XBlockDiagonalBasisOfRepresentation[102X ([14X5.1-1[114X).[133X
  
  [30X    [33X[0;6Y[10Xdiagonal_rep[110X:  [23X\rho[123X,  block  diagonalised  with  the  basis above. See
        [2XBlockDiagonalRepresentation[102X ([14X5.1-2[114X)[133X
  
  [30X    [33X[0;6Y[10Xdecomposition[110X:   The   irreducible  [23XG[123X-invariant  subspaces,  collected
        according   to   isomorphism,   see  [2XIrreducibleDecompositionCollected[102X
        ([14X5.3-3[114X)[133X
  
  [30X    [33X[0;6Y[10Xcentralizer_basis[110X:  An  orthonormal  basis for the centralizer ring of
        [23X\rho[123X,  written  in  block  form. See [2XCentralizerBlocksOfRepresentation[102X
        ([14X6.1-1[114X)[133X
  
  [33X[0;0YPass  the  option  [10Xparallel[110X  for  the  computations  per-irrep to be done in
  parallel.[133X
  
  [33X[0;0YPass  the  option  [10Xirreps[110X  with the complete list of irreps of [23X\rho[123X to avoid
  recomputing this list (could be very expensive)[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27X# Does the same thing we have done in the examples above, but all in[127X[104X
    [4X[25X>[125X [27X# one step, with as many subcomputations reused as possible[127X[104X
    [4X[25X>[125X [27XREPN_ComputeUsingSerre(tau);[127X[104X
    [4X[28Xrec( basis := [ [ 1, 1, 1 ], [ 1, E(3), E(3)^2 ], [ 1, E(3)^2, E(3) ] ],[128X[104X
    [4X[28X  centralizer_basis := [ [ [ [ 1 ] ], [ [ 0, 0 ], [ 0, 0 ] ] ],[128X[104X
    [4X[28X      [ [ [ 0 ] ], [ [ 1, 0 ], [ 0, 1 ] ] ] ],[128X[104X
    [4X[28X  decomposition := [ [ rec( basis := [ [ 1, 1, 1 ] ] ) ], [  ],[128X[104X
    [4X[28X      [ rec( basis := [ [ 1, E(3), E(3)^2 ], [ 1, E(3)^2, E(3) ] ] ) ] ],[128X[104X
    [4X[28X  diagonal_rep := [ (1,2,3), (1,2) ] ->[128X[104X
    [4X[28X    [ [ [ 1, 0, 0 ], [ 0, E(3), 0 ], [ 0, 0, E(3)^2 ] ],[128X[104X
    [4X[28X      [ [ 1, 0, 0 ], [ 0, 0, E(3)^2 ], [ 0, E(3), 0 ] ] ] )[128X[104X
    [4X[25Xgap>[125X [27X# You can also do the computation in parallel:[127X[104X
    [4X[25X>[125X [27XREPN_ComputeUsingSerre(tau : parallel);;[127X[104X
    [4X[25Xgap>[125X [27X# Or specify the irreps if you have already computed them:[127X[104X
    [4X[25X>[125X [27Xirreps_H := IrreducibleRepresentations(H);;[127X[104X
    [4X[25Xgap>[125X [27XREPN_ComputeUsingSerre(tau : irreps := irreps_H);;[127X[104X
  [4X[32X[104X
  
