Appendix A
Appendix A. Computations
Kakeya Sets with Multiplicity
Sections in this chapter
All computations were performed in JavaScript (Node.js 22) on a laptop. The fields were represented as , , , , with an element encoded as the integer ; the witnesses in §5.4 use this encoding. Lines of direction are and lines of direction are .
A.1 Exhaustive search for
The program enumerates -fold configurations direction by direction, choosing an -subset of the lines of each direction, maintaining the multiplicity of every point and the current union size, and abandoning a branch as soon as the union is at least the best size found (the union can only grow). Symmetry is used in the two coordinate directions: the maps , , permute the parallel classes and preserve union sizes, and they act on the lines of direction through the affine group of , which is transitive on ordered pairs of distinct elements; so for the chosen lines in that direction may be assumed to include and , and independently those in direction may be assumed to include and ; for , translations give and . The number of configurations examined is therefore before pruning.
| result | status | time | ||
|---|---|---|---|---|
| 3 | 1, 2 | 7, 8 | exhaustive | ms |
| 4 | 1, 2, 3 | 10, 14, 15 | exhaustive | ms |
| 5 | 1, 2, 3, 4 | 17, 21, 23, 24 | exhaustive | ms |
| 7 | 2 | 40 | exhaustive | 0.3 s |
| 7 | 3 | 44 | exhaustive | 1.4 s |
| 7 | 4 | 46 | exhaustive | 0.5 s |
| 8 | 2 | 51 | exhaustive | 35 s |
| 8 | 4 | stopped after 600 s in the first branch | ||
| 9 | 2 | stopped after 600 s |
The pruning is effective when is small relative to ; for , the subsets per direction defeat it. The extremal configurations reported in Chapter 7 are, in the notation "" listing the chosen -values per direction :
- , : ;
- , : ;
- , : ;
- , : ;
- , : ;
- , (65 points): .
A.2 Denniston arcs and their duals
For and the program finds with , takes to be the span of (as -subspace of dimension ), forms , and checks and that every affine line meets in or points. It then forms the dual lines for , whose direction is in characteristic , verifies that there are per direction, and computes the union and its multiplicities. Results: : , dual union , all multiplicities . : , , all . : , , line intersections , dual union , all multiplicities . : (i.e. ), , intersections , dual union , all multiplicities . Sub-configurations with lines per direction chosen inside the dual arc were minimised exhaustively over choices: : : ; : . : : ; : .
A.3 Pencils of conics
For odd the program takes the least non-square , the conics , and, for even , every choice of squares and non-squares as ; it forms the dual lines of the points of , checks that there are per direction, and records the smallest union. The values are in §7.3.
A.4 The direction-determination number
Since the affine group is transitive on ordered pairs of distinct points, a determining set may be assumed to contain and . For the program searches depth-first for -sets containing these two points that determine all directions, maintaining a count of determined directions and pruning a branch when the remaining points cannot determine enough new directions (a -th point adds at most ). All runs took under a second; is the least for which a set is found, and its non-existence for smaller is exhaustive.
A.5 Vanishing degrees
For the prime fields and and a configuration given by its choice string, the program lists the reduced monomials (, ), forms the evaluation matrix at the points of , and computes its rank by Gaussian elimination modulo . A nonzero reduced polynomial of degree vanishing on exists iff the rank is less than the number of monomials, and the kernel dimension is the difference. The results are in §7.4.
A.6 Program (core of the search)
// r-fold Kakeya sets in AG(2,q): minimum union of r lines per direction (core; field tables omitted)
const q = Number(process.argv[2]), r = Number(process.argv[3]);
// lines[d][b]: point indices of the b-th line in direction d (d = 0..q-1 slopes, d = q vertical)
function subsets(mustContain) { // r-subsets of {0..q-1}, optionally forced to contain 0 and 1
const out = [], fixed = mustContain ? (r === 1 ? [0] : [0, 1]) : [];
(function rec(start, cur) {
if (cur.length === r) { out.push(cur.slice()); return; }
for (let b = start; b < q; b++) { cur.push(b); rec(b + 1, cur); cur.pop(); }
})(fixed.length, fixed.slice());
return out;
}
const allSubs = subsets(false), fixedSubs = subsets(true);
const cnt = new Int32Array(q * q); let size = 0, best = Infinity;
(function rec(d) {
if (size >= best) return; // the union only grows
if (d === q + 1) { best = size; return; }
const subs = (d === 0 || d === q) ? fixedSubs : allSubs; // symmetry in the two axis directions
for (const S of subs) {
for (const b of S) for (const P of lines[d][b]) if (cnt[P]++ === 0) size++;
rec(d + 1);
for (const b of S) for (const P of lines[d][b]) if (--cnt[P] === 0) size--;
}
})(0);
console.log(q, r, best);