Hello,
I am ForeverHaibara on GitHub (
https://github.com/ForeverHaibara). I am a postgraduate in data science in Fudan University and I am planning to implement code regarding group theory and character tables for SymPy. Also, I am planning to apply this for the GSoC 2026.
I have several contributions to SymPy in the past and all PRs have been merged successfully:
* #24094 (Fix roots_quintic)
* #26720 (Fix radsimp for non-Expr arguments)
* #27688 (Made solve_triangulated support extension=True for algebraic roots)
* #27809 (ensure primitive_element returns canonicalized minpoly, fix #27798)
* #28183 (ANP normalization when init, fix #28182)
* #29160 (Implement latex printing of FreeGroupElements)
I am also using SymPy heavily on my daily projects so I have got some experience with the SymPy codebase (and in particular the polys module).
### Computing the Character Tables
I am recently learning representation theory of finite groups and the character table is a very important topic. Then I notice that SymPy does not have any code to compute the character table. Although I know that it is possible to use GAP (or SAGE, which calls GAP as a backend) to compute the character table, I would like to have things done natively in Python. We would possibly not have an implementation that is as efficient as GAP, but it is still good to have one that we can manipulate in SymPy without other dependencies.
I then searched through the issues, PRs and discussions in the SymPy community and found that there are few topics concerning character tables. Some previous GSoC projects mentioned it as future work (e.g.,
https://github.com/sympy/sympy/wiki/GSoC-2012-Application-Aleksandar-Makelov%3A-Group-theory), but they were at least 5 years ago and are now inactive. The codebase of SymPy was probably not so mature at that time for implementing this. But in year 2026 SymPy has grown to be more powerful that it used to be, and I think we are ready for representation theory and character tables. The core observation is that every entry of the character table of a finite group is an element in the cyclotomic field. Hence we can benefit from:
* SymPy's polys module, which offers classes, e.g., ANP, to handle algebraic numbers in a highly structured form.
* SymPy's domainmatrix module, which enables representing a matrix with elements in a field, and provides linear algebra over Fp domains for Dixon's algorithm and its variants.
The core algorithm to compute the character tables efficiently for generic finite groups is Dixon's algorithm. This was first described in Dixon's 1967 paper
[1]. There was an improvement proposed by Schneider
[2], which is known as Dixon-Scheneider algorithm. Relevant tutorials can also be found in "Handbook of Computational Group Theory", Section 7.7. GAP mentions in its documentation
[3] that it uses precisely Dixon-Schneider algorithm (along with many improvements and tricks). I shall also remark that GAP is under GPLv2 license while SymPy under MIT, so it is probably not admissible to "copy" the code directly from GAP.
Good news is that there is a SymbolicWedderburn.jl library
[4] under MIT license that implements the naive Dixon's algorithm in Julia. I read the code several weeks ago and wrote an experimental Python implementation in my own repo:
https://github.com/ForeverHaibara/Triple-SOS/blob/ef263cc5476773b1c78559b416feb5043a80fef0/triples/sdp/wedderburn/dixon.pyI shall also apologize that the code in my repo is somehow messy as it is supporting SymPy>=1.10 and Python>=3.6 for compatibility, but I will definitely clean it up to follow the SymPy code style and latest Python typing syntax when I make it a contribution in the GSoC project. I will also further simplify the code (e.g., it seems possible to replace the CMMatrix class in the code by an iterator) so that it looks neat enough for SymPy.
[1]
https://gdz.sub.uni-goettingen.de/download/pdf/PPN362160546_0010/LOG_0046.pdf[2]
https://www.sciencedirect.com/science/article/pii/S0747717108800776[3]
https://docs.gap-system.org/doc/ref/chap71.html[4]
https://github.com/kalmarek/SymbolicWedderburn.jl/### Some Thoughts and Plans
Although I have got experimental code for computing character tables in my repo, I have some thoughts before formally contribute it as a GSoC project. I list the major parts below, which can be tasks for GSoC projects and for future work.
1. Design of the public API. My current idea is to have a file `sympy/combinatorics/character_table.py` and to have a class called CharacterTable inherited from MutableDenseMatrix:
`class CharacterTable(MutableDenseMatrix): ...`. In Python we have object oriented programming (OOP) and can define many useful methods for character tables. I am still not sure about the details, but checking the APIs of GAP could be helpful.
2. Some prerequisite polynomial/domainmatrix algorithms. SymPy has already got convenient methods for Fp/algebraic elements that will be heavily used in the algorithms, but there are still a few obstacles to be cleared. One of them is the `conjugate` method of a domainelement. SymPy currently does not support calling conjugate over a domainelement, because it might not lie in the field. See also Oscar's discussion in
https://github.com/sympy/sympy/issues/27436. However, for some fields, the conjugate method is in fact well defined, e.g., RR, CC, ZZ_I, QQ_I, and cyclotomic fields. It is really unpleasant to call `.H` (hermitian transpose) on a character table matrix over AlgebraicField (in fact, cyclotomic,) but end up with a matrix on EXRAW! I think we can have a conjugate method if the conjugate of the primitive element is still in the field. Besides, I am wondering whether we are going to have a subclass CyclotomicField for special usage, (e.g., accessing the "order" of the cyclotomic field, and fast conjugate computation). This is really a large topic that needs some in-depth discussions. There are other functionality inquiries that I would like to discuss in the GSoC proposal.
3. Support for large groups. SymPy permutation groups have a `.conjugacy_classes()` method to compute all conjugacy classes and
their elements, which costs at least `O(|G|)` time and space complexity. However, Dixon's algorithm only requires class representatives,
class sizes, and a function to judge whether an element is in the class to work, i.e., we only need something like:
```
class ConjugacyClass:
def __iter__(self): ... # only one element is required, accessible by next(iter(...))
def __len__(self) -> int: ...
def __contains__(self, x: Permutation) -> bool: ...
```
The entire conjugacy class may not be computed as long as we have this information, which saves a lot of time and space. It is common for a group to have a large number of elements but a moderate number of conjugacy classes. Hence it would be be necessary to have such abstract conjugacy classes for SymPy in the future to support large groups. This can also be made as a Protocol typing annotation for inputs to Dixon's algorithm (and currently we have `ConjugacyClass = set[Permutation]` as the output of `.conjugacy_classes()`).
4. Advanced and specialized algorithms. I have now implemented the Dixon's algorithm, but it is better to have the Dixon-Schneider's version. I am still learning it. Moreover, specialized algorithms can be implemented for particular groups. For instance, the character table of a cyclic group is the discrete Fourier transform matrix, and the character table of a symmetric group is integral, computable by Murnaghan-Nakayama rule.
5. Beyond Permutations and PermutationGroups. This is still somewhat unclear in my mind and can be a future topic for developers. As mentioned in item 3, all we need for Dixon's algorithm is the group element and information of conjugacy classes. These concepts can be highly abstract: group elements are Python objects that supports multiplication and inverse; while conjugacy classes are objects that judge the containment of group elements. Indeed in SymPy combinatorics we actually have other group algebras, e.g., the FreeGroupElement and FpGroup. I notice that bilichboris recently opened a discussion in
https://github.com/sympy/sympy/discussions/29319 about designing group actions and representations. In the future we might have code and Python classes for group actions, representations, characters and class functions (
https://en.wikipedia.org/wiki/Class_function) and provide relevant algorithms, e.g., computing irreducible decompositions of representations.
Is it good to make this a 350-h GSoC project? I am planning to formally write this as the GSoC proposal in this weekend. I am happy to discuss about the GSoC application as well as the implementation details.
Sincerely,
ForeverHaibara