toBase = (b, x) => {
if (x == 0) { return [0] }
let ret = [];
while (x > 0) {
ret.push(x % b);
x = Math.floor(x / b);
}
return ret;
};
// Interpret xs as an expansion in base b (ascending powers of b)
fromBase = (b, xs) => {
let plval = 1
return xs.reduce((a, x) => {
let new_a = x * plval;
plval *= b;
return a + new_a;
}, 0)
}
// Map an expansion to a complex number (as a 2-array).
// The expansion is interpreted in base `b`.
// `n` terms of the series are used, with geometric ratio `c`
adicAngles = (expansion, b, n, c) => {
return d3.range(n).reduce((a, i) => {
let angle = fromBase(b, expansion.slice(null, i + 1)) / (b ** (i + 1));
let x = c**i * Math.cos(2 * Math.PI * angle);
let y = c**i * Math.sin(2 * Math.PI * angle);
return [a[0] + x, a[1] + y];
}, [0, 0]);
}
pointCount = 1024;
expansions = d3.range(pointCount).map((x) => toBase(base, x));
embedding = expansions.map(
(x) => adicAngles(x, embedBase, 15, geometric)
);
viewof base = Inputs.range([2, 10], {
value: 2,
step: 1,
label: "Base of expansions (b)",
});
viewof embedBase = Inputs.range([1.1, 10], {
value: 2,
step: 0.1,
label: "Embedding base (p)",
});
viewof geometric = Inputs.range([0.005, 0.995], {
value: 0.9,
step: 0.005,
label: "Geometric ratio (c)",
});
plot = Plot.plot({
grid: true,
inset: 10,
// aspectRatio: 1,
width: 640,
height: 480,
marks: [
Plot.dot(embedding, { r: 1 })
]
});Complex Embedding of p-adics
interactive
algebra
Visualizing fractals generated by sending p-adics to the complex plane.
About
The Wikipedia article on the p-adic valuation contains a figure whose description provides a way to map p-adics into the complex numbers1. The gist is to construct a Fourier series over truncations of numbers. Each term of the series is weighted by a geometrically decreasing coefficient c.
[...d_2 d_1 d_0]_p \mapsto e^{2\pi i [d_0] / p} + c e^{2\pi i [d_1 d_0] / p^2} + c^2 e^{2\pi i [d_2 d_1 d_0] / p^2} + ... \\ f_N(d; p) = \sum_{n = 0}^N c^n e^{2\pi i \cdot [d_{n:0}]_p / p^{n + 1}}
Assuming the first term dominates, this can be interpreted as placing numbers evenly around the unit circle according to their one’s place. Then, we offset each by smaller circles, each centered on the last, using more and more digits. This produces a fractal pattern that looks like a wheel with p spokes. At each point on where the spokes meet the rim, there is another smaller wheel with p spokes, ad infinitum.
This is somewhat visible in the Wikimedia diagram. All of the odd numbers are at the left side of the diagram, since the leading term of the series for them is negative one. The odd numbers are further split into those of the forms 4k + 1 and 4k + 3.
Controls
Each of the inputs corresponds to something from the above formula.
- b, the base of the expansions.
- Each point is the expansion of an integer in base b, which corresponds to a sequence of digits (d in the above formula).
- p, the base used in the embedding.
- The same p that appears in the above formula.
- Truncations of digit sequences (d_{n:0}) are interpreted as strings in base p, then divided by p^{n+1}.
- c, the geometric constant.
- Smaller c means more tightly packed points.
Note that only 1024 points are calculated, and that only fifteen terms of the series are used (N = 15).
Suggestions
Invariance of b
Set b and p to 2 and c to 0.55. Slowly increase p to 3. The pattern should largely remain the same, but appear to be rotated around. Increasing p further shears the pattern into an indistinct line of points. This shows that the embedding base does matter, but the way the expansions are constructed gives rise to the pattern.
Small Changes
With c sufficiently small (about 0.3), and p fixed at 2, changing b keeps the diagram almost the same. This is because many numbers get sent to the same place as others. For example, when only considering the first term of the series, “1” and “3” are both mapped to e^{\pi i} = e^{3 \pi i}
If you make c larger, you can notice that points disappear from the case when p is 2. If the plot used a massive number of points, this difference wouldn’t be as visible.
Blooming flower, in reverse
Try cranking b and p up to 10 and set c to something around 0.2 so that you can clearly see a decagon made of decagons Then, strobe p down to its minimum value. Notice the larger decagon and smaller decagons collapse into nonagons when p hits 9.
Lesser Bases
Set b to 2 and p to 1.1, the lowest it can go. Moving c back and forth, you should be able to see an interesting fractal.
Footnotes
Taken from the paper “Fractal geometry for images of continuous embeddings of p-adic numbers and solenoids into Euclidean spaces” (DOI: 10.1007/BF02073866).↩︎