Documentation

TauCeti.RepresentationTheory.CharacterTable.Dixon.ClassData.Basic

Executable conjugacy-class data #

The class-algebra theory of a finite group is indexed by ConjClasses G, a quotient type: perfect for stating theorems, useless for computing with, since nothing picks a representative of a class or orders the classes. The Burnside--Dixon--Schneider character-table algorithm needs both, because its input is the array of structure constants aᵢⱼₖ and its output is a table whose rows and columns are numbered.

This file supplies the missing numbering. A TauCeti.ClassData G is a list of elements of G, one from each conjugacy class; the two fields say that no two entries are conjugate and that every element of G is conjugate to an entry. From those two facts alone the whole indexing API follows: a representative d.rep i for each i : Fin d.numClasses, an inverse d.index g computed by a list search, and the equivalence d.equivConjClasses : Fin d.numClasses ≃ ConjClasses G that transports statements about ConjClasses G to the numbering. All of these are genuine defs: the numbering data itself asks only for [Group G], the searches computed from it for a decidable conjugacy relation, the classes as Finsets for [Fintype G], and TauCeti.ClassData.ofList builds class data from any list that meets every conjugacy class.

On top of the numbering the file gives the two computational objects the algorithm consumes: the structure constants d.structureConstant i j k, counted by a single scan of the i-th class rather than by the double scan of the definition, and the class-multiplication matrices d.classMultMatrix i over Fin d.numClasses. Both are proved equal to their ConjClasses-indexed counterparts TauCeti.structureConstant and TauCeti.classMultMatrix, so the theory built on the latter — in particular the eigenrow characterization of the central characters — applies verbatim to the computed data.

TauCeti.RepresentationTheory.CharacterTable.Dixon.ClassData.Dihedral works the dihedral group of order 8 as a closed instance of everything here.

Main definitions #

Main results #

References #

This implements the object ClassData and the executable structureConstant of Layer 6 of the character theory roadmap, the layer that makes the Burnside--Dixon--Schneider algorithm executable. The Fin-indexed family classFinset is what the class-multiplication matrices are indexed by, while classes packages the same family as the executable List (Finset G) requested there. See J. D. Dixon, High speed computation of group characters, Numer. Math. 10 (1967) 446-450.

structure TauCeti.ClassData (G : Type u_2) [Group G] :
Type u_2

Executable conjugacy-class data for a group: a list reps containing exactly one element of each conjugacy class. The two fields are the two halves of "exactly one": distinct entries name distinct classes, and no class is missed. Carrying the data asks nothing of G beyond its group structure; a decidable conjugacy relation is what the searches computed from it need, and finiteness what turns the classes into Finsets.

The order of reps is the arbitrary but fixed numbering of the conjugacy classes that a computation indexes by; TauCeti.ClassData.equivConjClasses identifies it with ConjClasses G.

  • reps : List G

    The chosen representatives, in the order that numbers the classes.

  • pairwise_not_isConj : List.Pairwise (fun (x y : G) => ¬IsConj x y) self.reps

    Distinct representatives are not conjugate, so they name distinct classes.

  • exists_isConj (g : G) : ∃ x ∈ self.reps, IsConj x g

    Every element of the group is conjugate to a representative, so no class is missed.

Instances For
    theorem TauCeti.ClassData.ext {G : Type u_1} [Group G] {d₁ d₂ : ClassData G} (h : d₁.reps = d₂.reps) :
    d₁ = d₂

    Class data is determined by its representatives: the two remaining fields are proofs.

    theorem TauCeti.ClassData.ext_iff {G : Type u_1} [Group G] {d₁ d₂ : ClassData G} :
    d₁ = d₂ ↔ d₁.reps = d₂.reps
    def TauCeti.ClassData.ofList {G : Type u_1} [Group G] [DecidableRel IsConj] (l : List G) (hl : ∀ (g : G), ∃ x ∈ l, IsConj x g) :

    Class data extracted from a list l that meets every conjugacy class: keep an entry exactly when it is not conjugate to any entry kept from the part of l after it. Since List.pwFilter recurses from the right, this keeps the last representative of each class, in the order those representatives occur in l.

    The hypothesis, rather than Finset.univ.toList, is what keeps this computable: Finset.toList is noncomputable, whereas a concrete finite group can supply concrete representatives.

    Equations
    Instances For
      @[simp]
      theorem TauCeti.ClassData.reps_ofList {G : Type u_1} [Group G] [DecidableRel IsConj] (l : List G) (hl : ∀ (g : G), ∃ x ∈ l, IsConj x g) :
      (ofList l hl).reps = List.pwFilter (fun (x y : G) => ¬IsConj x y) l

      The representatives extracted from l are the entries of l that are not conjugate to any later retained entry: the characteristic property of TauCeti.ClassData.ofList, so that a client never has to unfold the filtering itself.

      @[instance_reducible]
      noncomputable instance TauCeti.ClassData.instInhabitedOfFinite {G : Type u_1} [Group G] [Finite G] :

      Every finite group has class data; the witness is noncomputable only because Finset.toList is.

      Equations

      The number of conjugacy classes of G, as numbered by d.

      Equations
      Instances For
        def TauCeti.ClassData.rep {G : Type u_1} [Group G] (d : ClassData G) (i : Fin d.numClasses) :
        G

        The chosen representative of the i-th conjugacy class.

        Equations
        Instances For

          The i-th conjugacy class, as an element of ConjClasses G.

          Equations
          Instances For
            theorem TauCeti.ClassData.classOf_eq_mk {G : Type u_1} [Group G] (d : ClassData G) (i : Fin d.numClasses) :

            The i-th class is the class of the i-th representative. This is not a simp lemma: it would rewrite past TauCeti.ClassData.classOf_index, which is the normal form wanted.

            theorem TauCeti.ClassData.not_isConj_rep {G : Type u_1} [Group G] (d : ClassData G) {i j : Fin d.numClasses} (hij : i ≠ j) :
            ¬IsConj (d.rep i) (d.rep j)

            Distinct numbers name distinct classes: the Fin-indexed reading of the pairwise_not_isConj field.

            theorem TauCeti.ClassData.nodup_reps {G : Type u_1} [Group G] (d : ClassData G) :

            The representatives are distinct, conjugacy being reflexive.

            Rows of a numbered matrix #

            def TauCeti.ClassData.rowsOfMap {G : Type u_1} [Group G] (d : ClassData G) {R : Type u_2} {S : Type u_3} [DecidableEq S] (f : R → S) (M : Matrix (Fin d.numClasses) (Fin d.numClasses) R) :

            The rows of a numbered matrix, mapped entrywise by f and collected without an ordering.

            Equations
            Instances For
              @[simp]
              theorem TauCeti.ClassData.mem_rowsOfMap_iff {G : Type u_1} [Group G] (d : ClassData G) {R : Type u_2} {S : Type u_3} [DecidableEq S] (f : R → S) (M : Matrix (Fin d.numClasses) (Fin d.numClasses) R) {a : Fin d.numClasses → S} :
              a ∈ d.rowsOfMap f M ↔ ∃ (i : Fin d.numClasses), (fun (j : Fin d.numClasses) => f (M i j)) = a

              A row is displayed exactly when it is the mapped image of a matrix row.

              The number of the conjugacy class of g, found by searching d.reps for a representative conjugate to g. The search succeeds because some representative is conjugate to g.

              Equations
              Instances For
                theorem TauCeti.ClassData.isConj_rep_index {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] (g : G) :
                IsConj (d.rep (d.index g)) g

                The representative found by TauCeti.ClassData.index is conjugate to g.

                theorem TauCeti.ClassData.index_eq_iff {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] {g : G} {i : Fin d.numClasses} :
                d.index g = i ↔ IsConj (d.rep i) g

                The numbering is characterized by conjugacy: g has number i exactly when it is conjugate to the i-th representative.

                @[simp]
                theorem TauCeti.ClassData.index_rep {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] (i : Fin d.numClasses) :
                d.index (d.rep i) = i
                theorem TauCeti.ClassData.index_eq_index_iff {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] {g h : G} :
                d.index g = d.index h ↔ IsConj g h

                Two elements get the same number exactly when they are conjugate.

                @[simp]

                The number of a conjugacy class: TauCeti.ClassData.index is constant on classes, so it descends to ConjClasses G.

                Equations
                Instances For

                  The numbering of the conjugacy classes is a bijection. The forward map sends a number to the class it names; the inverse is the computable search TauCeti.ClassData.index.

                  Equations
                  Instances For

                    The numbering has the expected length: d.reps lists as many elements as G has conjugacy classes. The bijection is the one underlying TauCeti.ClassData.equivConjClasses, but it is exhibited here from the two fields directly, since the count itself needs neither a finite G nor a decidable conjugacy.

                    Reindexing numbered tables #

                    noncomputable def TauCeti.ClassData.reindexTableOfMap {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] {R : Type u_2} {S : Type u_3} (f : R → S) (table : Matrix (Fin d.numClasses) (Fin d.numClasses) R) :

                    Map the entries of a numbered table with f, reindexing its rows by the cardinality of the conjugacy classes and its columns by the conjugacy classes themselves.

                    Equations
                    Instances For
                      @[simp]
                      theorem TauCeti.ClassData.reindexTableOfMap_apply {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] {R : Type u_2} {S : Type u_3} (f : R → S) (table : Matrix (Fin d.numClasses) (Fin d.numClasses) R) (i : Fin (Nat.card (ConjClasses G))) (C : ConjClasses G) :
                      d.reindexTableOfMap f table i C = f (table ((finCongr ⋯).symm i) (d.equivConjClasses.symm C))

                      The mapped and reindexed table, evaluated at arbitrary row and column indices.

                      theorem TauCeti.ClassData.reindexTableOfMap_apply_classOf {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] {R : Type u_2} {S : Type u_3} (f : R → S) (table : Matrix (Fin d.numClasses) (Fin d.numClasses) R) (i j : Fin d.numClasses) :
                      d.reindexTableOfMap f table ((finCongr ⋯) i) (d.classOf j) = f (table i j)

                      The mapped and reindexed table evaluated at a numbered row and numbered class.

                      The i-th conjugacy class, as a Finset of G.

                      Equations
                      Instances For
                        @[simp]
                        theorem TauCeti.ClassData.mem_classFinset {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] [Fintype G] {i : Fin d.numClasses} {g : G} :
                        g ∈ d.classFinset i ↔ d.index g = i

                        The i-th class consists of the elements conjugate to the i-th representative.

                        The i-th representative lies in the i-th class.

                        The numbered class is the carrier of the class it names. This is the compatibility that lets the Finset be used in a computation and ConjClasses.carrier in a proof.

                        The size of the i-th class is the size of the class it names.

                        Distinct numbered classes are disjoint.

                        The conjugacy classes, in the order determined by d.

                        Equations
                        Instances For
                          @[simp]

                          There is one entry of classes for each class number.

                          @[simp]

                          Looking up the i-th entry of classes gives the i-th numbered class.

                          theorem TauCeti.ClassData.exists_mem_classes {G : Type u_1} [Group G] (d : ClassData G) [DecidableRel IsConj] [Fintype G] (g : G) :
                          ∃ C ∈ d.classes, g ∈ C

                          The list classes covers every element of the group.

                          The numbered classes partition the group: their sizes sum to |G|. This is the Fin-indexed reading of the class equation sum_conjClasses_card_eq_card.

                          The structure constant aᵢⱼₖ of the class algebra, computed by a single scan: it counts the elements x of the i-th class whose complementary factor x⁻¹ * gₖ lies in the j-th class, where gₖ is the k-th representative.

                          TauCeti.ClassData.structureConstant_eq identifies this with TauCeti.structureConstant, which counts the factorizations x * y = gₖ themselves.

                          Equations
                          Instances For

                            The class-multiplication matrix Mᵢ of the i-th class, numbered by d. As in TauCeti.classMultMatrix, the entry (Mᵢ)ⱼₖ is aᵢₖⱼ; that transposed index order is what makes Mᵢ the matrix of multiplication by the i-th class sum on the centre of the group algebra, and so what makes the central-character rows left eigenvectors of the family.

                            Equations
                            Instances For

                              The structure constants of d, tabulated: the k-th entry of the j-th entry of the i-th entry is aᵢⱼₖ. This nested list is the whole input to the Dixon--Schneider algorithm for G, and, unlike the matrices it assembles, it can be compared with a literal by the kernel.

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                @[simp]

                                The i-th row of the table is the table of the structure constants with first index i. Together with List.getElem_map and List.getElem_finRange this reduces a lookup at any depth: in particular simp sends the depth-three entry d.structureConstantTable[i][j][k] to aᵢⱼₖ, so no separate entry lemma is needed.

                                Reading the tabulated structure constants at three valid indices recovers the corresponding computed structure constant. This getD form is convenient when a whole literal table is rewritten at once.

                                The computed structure constants are the structure constants: recording a factorization by its first factor matches the single scan with the double scan of the definition.

                                The numbered class-multiplication matrix is a renumbering of the class-indexed one. Every statement about TauCeti.classMultMatrix therefore transports to the numbered family.

                                The numbered class-multiplication matrices commute pairwise, the centre of the group algebra being commutative.