<#Include SYSTEM "title.xml">
Definitions
Difference Sets A \langle v, k, \lambda \rangle-difference set is a nonempty proper subset D of a finite group G such that |G| = v, |D| = k, and each nonidentity element of G can be written as d_id_j^{-1} for d_i, d_j \in D in exactly \lambda different ways. The standard example is the \langle 7, 3, 1\rangle-difference set \{1, 2, 4\} of the group \mathbb{Z}/7\mathbb{Z} under addition. Additionally, it can easily be shown that every one element subset of a group is a difference set, and the complement of any difference set is also a difference set.

We will often abuse notation and let D denote both the set D and the element D = \sum_{d \in D} d of the group ring \mathbb{Z}[G]. Then define gD = \sum_{d \in D} gd, D^\phi = \sum_{d \in D} \phi(d),D^{(-1)} = \sum_{d \in D} d^{-1}, where g \in G and \phi is a homomorphism with domain G. Using this notation, a difference set in G is an element of the group ring \mathbb{Z}[G] with coefficients from \{0, 1\} such that DD^{(-1)} = (k-\lambda) + \lambda G, where by convention the isolated coefficients (k-\lambda) are assumed to be coefficients of the identity.

Two difference sets D_1, D_2 are equivalent if both are in the same group G and D_1 = gD_2^\phi for some g \in G and \phi \in \mathrm{Aut}(G). In other words, D_1 is equivalent to D_2 if D_1 can be mapped to D_2 by translation and automorphism in the group G. We say D_1, D_2 are translationally equivalent if they are equivalent solely by translation, meaning D_1 = gD_2 for some g \in G.

In the package, difference sets are stored as lists of integers that represent the index of the elements in the difference set as found in the list of all elements in the group returned by the &GAP; function Elements(G). For example, the difference set [1, 3, 6, 9, 11, 13] in SmallGroup(16, 5) really consists of the first, third, sixth, ninth, eleventh, and thirteenth elements of the list returned by Elements(SmallGroup(16, 5)). When given as arguments, difference sets in the package are never assumed to be sorted, but many functions will return difference sets in sorted order since sorting is used internally.
Difference Sums A \langle v, k, \lambda \rangle-difference sum in a group G modulo its normal subgroup N is an element S of the group ring \mathbb{Z}[G/N] such that SS^{(-1)} = (k - \lambda) + \lambda |N|G/N and the coefficients of S have values in \{0, 1, \dots, |N|\}. Note that the original G and N are included in the definition, so it makes no sense to talk about a difference sum in some arbitrary group H. The size of a difference sum is the sum of its coefficients, and by defining the complement of S to be |N|G/N - S we can see that, similar to difference sets, size one sums and complements of difference sums are always difference sums.

Two difference sums S_1, S_2 are equivalent if both are in the same group G mod its normal subgroup N and S_1 = gS_2^\phi for some g \in G/N and \phi an automorphism of G/N induced by an automorphism of G. Note that not all automorphisms of G/N are induced by automorphisms of G, so our definition here is more restrictive than perhaps expected. As with difference sets, the sums S_1, S_2 are translationally equivalent if S_1 = gS_2 for some g \in G/N.

In the package, difference sums are stored as lists of integers that represent the values of the coefficients of the group ring elements, with position in the list given by the position of the coset in the list of elements returned by the &GAP; function Elements(G/N). For example, the difference sum [2, 4] in G := SmallGroup(16, 5) mod its normal subgroup Subgroup(G, [G.2, G.3, G.4]) has coefficient 2 on the identity coset, and coefficient 4 on the nonidentity coset.

Difference sums can be thought of as a generalization of difference sets. More importantly, however, difference sums can be thought of as images of difference sets in quotients of the original group. In particular, if \theta : G \to G/N is the natural projection, then for any difference set D in \mathbb{Z}[G] we have a difference sum D^\theta in G modulo its normal subgroup N. Additionally, difference sums induce other difference sums in any further quotient. The fundamental idea of the algorithm in this package is that we can reverse this process. Starting with G mod G, where the only difference sum of size k is [k], we can successively refine this difference sum up a series of quotients of G until reaching G itself. In each step we enumerate all preimages of the difference sums and remove preimages that are not difference sums themselves. In the final step we refine to difference sets. Furthermore, since equivalent difference sums will have equivalent collections of difference sets as preimages, in each step we remove all but one representative of each equivalence class from our collection. This method dramatically decreases the search space for an exhaustive enumeration of all difference sets up to equivalence in G.
Package Contents The DifSets Package consists of a collection of functions implementing the main algorithm, and some additional functions for experimentation and testing. Several functions not appearing in this documentation are used internally for certain subtasks. See the code itself for details.
The Main Functions The purpose of this package is to provide a function that efficiently enumerates all difference sets up to equivalence in a given group. Similarly, we can also enumerate all difference sums up to equivalence. The following are these functions. Their components are described in further sections. <#Include Label="DifferenceSets"> <#Include Label="DifferenceSums">
Sizes The first step of the algorithm is to determine what possible sizes of difference sets and sums the group can contain. Each size is then handled individually since different size sets or sums will never be equivalent. <#Include Label="PossibleDifferenceSetSizes"> <#Include Label="DifferenceSetsOfSizeK"> <#Include Label="DifferenceSumsOfSizeK">
Refining Refining refers to the process of enumerating the preimages of a difference sum and filtering out preimages that are not themselves difference sets or sums. For each size k we know that the only difference sum of size k in G mod G is [k]. Starting with this difference sum, we successivly refine through a series of quotients of G to eventually reach the desired sums or sets. In the algorithm, we use and rather than and since the former are faster and we only need at least one representative of each equivalence class since additional equivalent sums or sets will just be removed anyway. <#Include Label="RefiningSeries"> <#Include Label="AllRefinedDifferenceSets"> <#Include Label="NrAllRefinedSets"> <#Include Label="SomeRefinedDifferenceSets"> <#Include Label="NrSomeRefinedSets"> <#Include Label="AllRefinedDifferenceSums"> <#Include Label="NrAllRefinedSums"> <#Include Label="SomeRefinedDifferenceSums"> <#Include Label="NrSomeRefinedSums">
Equivalence Since we are searching for all difference sets or sums up to equivalence, at each stage we remove excess equivalent sums or sets from our collection. This can be done with and . The additional functions and can be used to eliminate translate equivalent sums or sets, but they are not used in the main algorithm. Alternatively, uses the SmallestImageSet function from the GRAPE package to produce the lexicographically minimal difference set equivalent to a given set. Eliminating equivalent sets can then be done by mapping each set to its minimal representative and then simply eliminating duplicates. This is done automatically by , which is used in the last stage of the main algorithm instead of . While the full algorithm with is roughly 20% slower on average (and is almost 4x as slow on a few groups of order 64), this function is used since it is much faster on large automorphism groups (such as the automorphism group of SmallGroup(64, 267), which is impossible with ) and provides a unique minimal result at the end of the algorithm. <#Include Label="EquivalentFreeListOfDifferenceSets"> <#Include Label="TranslateFreeListOfDifferenceSets"> <#Include Label="EquivalentFreeListOfDifferenceSums"> <#Include Label="TranslateFreeListOfDifferenceSums"> <#Include Label="SmallestEquivalentDifferenceSet"> <#Include Label="SmallestEquivalentFreeListOfDifferenceSets">
Testing These additional functions are provided to check work and perform other experimentation. They are inefficient when used repeatedly. For example, when testing a large number of difference sets in a single group, it is better to precompute the needed group operations and store them in a table for lookup, but simply does the multiplication directly since it is only testing one set. <#Include Label="IsDifferenceSet"> <#Include Label="IsDifferenceSum"> <#Include Label="IsEquivalentDifferenceSet"> <#Include Label="IsEquivalentDifferenceSum">
Loading Results The data directory of the DifSets Package contains precomputed results for 1006 of the 1032 groups of order less than 100. The following two functions are the easiest way to access these precomputed lists of difference sets up to equivalence. <#Include Label="CanLoadDifferenceSets"> <#Include Label="LoadDifferenceSets">
Results The DifSets Package was designed with the goal of finding all difference sets up to equivalence in groups of order 64 and 96, a goal which was accomplished. Overall, the algorithm has successfully computed results for 1006 of the 1032 groups of order less than 100. Full results, which include timings, number of sets, and the sets themselves can be found in the data subdirectory of the package, which is organized by group order and contains a single .txt file for each computed group. A list of all timings can also be found in the file groups.csv in the data directory, and the difference sets themselves can be loaded using the function . All computations were performed using &GAP; 4.9.1 on a 4.00GHz i7-6700K using 8GB of RAM. Here we give a basic overview of results and comments on timings. Throughout this chapter we will refer to the group returned by the &GAP; function SmallGroup(v, n) as [v, n].
Order 16 and 36 Difference sets in groups of order 16 and 36 form the first nontrivial examples of the Hadamard parameters, and exhaustive enumerations are already well known. Still, computation of these sets gives a useful benchmark and check of accuracy.

Almost all groups in these orders take less than a second. The group [36, 9], however, takes several orders of magnitude longer than other groups of order 36. This is because [36, 9] does not have small normal subgroups (in particular, its smallest nontrivial normal subgroup has order 9), and refining across a large gap in sizes, expecially near the end of the algorithm, requires checking significantly more preimages.

Group Difference Sets Time (seconds)
[16, 1] 0 0.030
[16, 2] 3 0.103
[16, 3] 4 0.100
[16, 4] 3 0.100
[16, 5] 2 0.061
[16, 6] 2 0.071
[16, 7] 0 0.072
[16, 8] 2 0.070
[16, 9] 2 0.082
[16, 10] 2 0.187
[16, 11] 2 0.121
[16, 12] 2 0.195
[16, 13] 2 0.117
[16, 14] 1 0.059

Group Difference Sets Time (seconds)
[36, 1] 0 0.335
[36, 2] 0 0.201
[36, 3] 0 0.407
[36, 4] 0 0.322
[36, 5] 0 0.218
[36, 6] 6 0.412
[36, 7] 1 0.795
[36, 8] 4 0.340
[36, 9] 5 340.989
[36, 10] 6 1.137
[36, 11] 3 0.699
[36, 12] 6 0.417
[36, 13] 1 0.801
[36, 14] 3 0.434

Order 64 and 96 Difference sets in groups of order 64 also satisfy the Hadamard parameters, while difference sets in groups of order 96 satisfy the McFarland parameters. Since there are many groups of both orders, here we just give some examples and summaries. In particular, the tables below list the fastest, slowest, and median five groups of each order, sorted by time.

Groups of order 64 are p-groups, and thus always have enough normal subgroups to form long refining series. This means the refining steps are relatively efficient for all groups in this order. The main difference between groups is the size of the automorphism group, and, in particular, four of the five groups taking the largest amount of time are four of the five groups with the largest automorphism groups in this order. The additional group in the top five, [64, 235], has a relatively large number of difference sets, but is otherwise unremarkable. In general, smaller numbers of difference sets correspond to faster times, and in fact the eight groups with no difference sets were computed the fastest, beating the next fastest groups by an order of magnitude. Overall, the mean computation time for a group of order 64 was 3988.476 seconds, with a median time of 1493.175 seconds. This means that the total computer time to compute all difference sets in groups of order 64 was roughly 12 days.

In groups of order 96 we do not always have large numbers of normal subgroups, and, as with [36, 9], this can substantially slow down computation. In fact, the five groups taking the longest computation time are five of the six groups with fewest normal subgroups in this order. We are helped, however, by the fact that the only valid choice of k is 20, which is relatively small and thus does not lead to large numbers of preimages even across large gaps in the refining series. Many groups in this order have no difference sets, but even for these groups computation can be slow. While the fastest groups contain no difference sets, many groups with no difference sets actually take much longer than other groups that do contain difference sets. Overall, the mean computation time for a group of order 96 was 24447.991 seconds, with a median time of 11278.765 seconds. This means that the total computer time to compute all difference sets in groups of order 96 was roughly 65 days.

Group Difference Sets Time (seconds)
[64, 52] 0 3.451
[64, 54] 0 3.463
[64, 47] 0 3.594
[64, 186] 0 3.940
[64, 1] 0 3.950
[64, 166] 2312 1424.692
[64, 134] 342 1439.484
[64, 135] 540 1493.175
[64, 7] 1320 1515.710
[64, 160] 3192 1518.693
[64, 192] 222 21131.394
[64, 267] 4 23662.500
[64, 235] 4317 24566.186
[64, 260] 30 144338.020
[64, 262] 148 229488.988

Group Difference Sets Time (seconds)
[96, 2] 0 8.731
[96, 59] 0 8.791
[96, 189] 0 29.378
[96, 66] 0 29.777
[96, 46] 0 44.478
[96, 209] 4 10809.673
[96, 133] 16 11198.052
[96, 224] 0 11278.765
[96, 89] 0 11349.466
[96, 102] 0 11415.688
[96, 227] 42 308246.830
[96, 64] 14 310447.407
[96, 70] 28 514559.313
[96, 72] 2 515196.547
[96, 71] 8 871439.024

Comments Overall, the algorithm spends almost all of its time performing four operations: refining sums to sums in several stages using , refining sums to sets in the final stage using , removing equivalent difference sums in several stages using , and removing equivalent difference sets in the final stage using . On typical groups of order 16 and order 36 (i.e., not [36, 9]), each of these four operations takes roughly the same time. On groups of order 64, some testing indicates that one or two orders of magnitude more time are spent in the final stage, when the algorithm uses and . This discrepency is likely to remain or increase for larger order groups, as the number of preimages to check increases exponentially with the number of cosets. For the tested groups of order 64, roughly 60% of the time in the final stage was spent refining, with the remaining 40% spent removing equivalent sets.

Large automorphism groups make removing equivalents time-consuming and large jumps in the size of the normal subgroups used, especially near the end of the algorithm, make refining difficult. So, in general, the algorithm seems to work well when the group has a small automorphism group and many (small) normal subgroups. In addition, the algorithm does better when the values of k that need to be checked are small, as this limits both the number of preimages to check as well as the amount of time required for checking sets and equivalences. It is also generally faster when the final result is a smaller number of difference sets.

There are twenty-six groups of order less than 100 in which the algorithm was not able to complete a search. Fourteen of these groups are prime order cyclic. As simple groups, these groups have no normal subgroups and thus no possibility for refining, which means the algorithm must search every possible subset of size k to find all difference sets of size k. Even for groups of relatively small order, such as order 31, this is infeasible, and with current implementation will overflow memory before even starting the search (one of these groups, [37, 1] is actually feasible to search without this implementation issue, but the others have too many sets to check). The remaining groups have either too few normal subgroups, large jumps in the refining series, large possible values of k, or a combination of these problems.

The next natural cases for exhaustive search are groups of order 100 and order 144, which give the next Hadamard parameters. Unfortunately, preliminary testing indicates that this algorithm is not likely to be able to compute all difference sets for these groups. For example, a typical difference sum in [100, 9] is [5, 4, 3, 3, 0, 3, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, 3], which has roughly 6 \times 10^{16} preimage sets to check. In the search for difference sets in [36, 9] the single difference sum [6, 3, 3, 3], with around 3 \times 10^7 preimages, takes around 300 seconds to search. Thus even if we could check sets in [100, 9] as fast as in [36, 9], the search would take roughly 20000 years. Some testing suggests that coding pieces of the algorithm in C could give one or two orders of magnitude of speedup, but even further speedup is required to make the search feasible, so some other improvements, either in theory or implementation, are needed as well.