Code, additonal material and Erratum for Fractal behavior of tensor powers of the two dimensional space in prime characteristic
I collected a bit of Mathematica code relevant for the paper Fractal behavior of tensor powers of the two dimensional space in prime characteristic https://arxiv.org/abs/2405.16786 on this page.
The code is in two .n files that can be downloaded from this site and you can run it with Mathematica.
After the Mathematica code we explain a Google Colab file . ipynb where we explain (or rather sektch) how machine learning and deep learning can be used to tackle the main problem recalled in the background below.
An Erratum for the paper Fractal behavior of tensor powers of the two dimensional space in prime characteristic can be found at the bottom of the page.
If you find any errors in the paper Fractal behavior of tensor powers of the two dimensional space in prime characteristic please email me:
Same goes for any errors related to this page.
Let
We write
We do not know in what generality this expression holds, but expressions of this form are very common in the theory of asymptotics of generating functions. What we know is:
- In general,
$\lambda=\dim V$ but we do not know whether the asymtotic formula holds. - When
$\Gamma$ is a finite group, then$b_{n}\sim h(n)\cdot n^{0}\cdot(\dim V)^{n}$ . This is independent of the characteristic of the underlying field. - When
$\Gamma=SL_{2}(\mathbb{C})$ and$V$ is the vector representation with$\dim V=2$ , then$b_{n}\sim\sqrt{2/\pi}\cdot n^{-1/2}\cdot 2^{n}$ . - More generally, when
$\Gamma$ is a reductive group in characterictic zero and$V$ is any finite dimensional$\Gamma$ -representation, then we have a formula of the form$b_{n}\sim h(n)\cdot n^{\alpha}\cdot(\dim V)^{n}$ with explicitly computable$h(n)$ and$\alpha$ . Moreover,$\alpha$ is in$1/2\mathbb{Z}$ .
Let
Let us define the following transcendental number:
Theorem
For any
$p>0$ there exist positive constants$C_{1}=C_{1}(p)$ and$C_{2}=C_{2}(p)$ such that we have$$C_{1}\cdot n^{\alpha_{p}}\cdot 2^{n}\leq b_{n}\leq C_{2}\cdot n^{\alpha_{p}}\cdot 2^{n},\qquad n\geq 1.$$
The aim of the code on this page is to illustrate this theorem in examples.
The Mathematica notebook recursion-for-bn.nb has one major command:
bnrecursion[n,p]
where
If you do not have Mathematica at hand, then you can use the following links to see a log plot of the growth rates (first link) or a list of the numbrs
https://www.wolframcloud.com/obj/02e25415-5c98-4dd9-84cf-8925156aeda9?_embed=iframe
https://www.wolframcloud.com/obj/de16c88e-6b99-42e3-8bb3-9fb6fb8d7d90?_embed=iframe
For the first link and depending on your resolution, you might want to increase the size and the output should look like this:
In contrast to the notebook, the online version has
The second notebook length.nb computes the length using
CountSimple[n,p]
where
Click on and you should see the following:
We will now explain the main pieces of the code.
The first main part, after setting up test data that was computed using the Mathematica code above and is brute force implemented, we see
# Create a model class
class RepTheoryModel(nn.Module): # <- almost everything in PyTorch is a nn.Module (think of this as neural network lego blocks)
def __init__(self):
super().__init__()
self.scalar = nn.Parameter(torch.randn(1, # <- start with random value (this will get adjusted as the model learns)
dtype=torch.float), # <- PyTorch loves float32 by default
requires_grad=True) # <- can we update this value with gradient descent?))
self.error = nn.Parameter(torch.randn(1, # <- start with random value (this will get adjusted as the model learns)
dtype=torch.float), # <- PyTorch loves float32 by default
requires_grad=True) # <- can we update this value with gradient descent?))
self.alpha = nn.Parameter(torch.randn(1, # <- start with random value (this will get adjusted as the model learns)
dtype=torch.float), # <- PyTorch loves float32 by default
requires_grad=True) # <- can we update this value with gradient descent?))
# Forward defines the computation in the model
def forward(self, x: torch.Tensor) -> torch.Tensor: # <- "x" is the input data (e.g. training/testing features)
return (self.scalar + self.error*(-1)**x)*(x**(self.alpha)) # <- this is our guessed formula
Here we setup a model with three parameters called self.scalar
Why is that? Well, we expect (as very often in these cases)
where
After the training, we get some reasonable answers:
The model learned the following values for our parameters are:
OrderedDict([('scalar', tensor([0.7718])), ('error', tensor([0.0245])), ('alpha', tensor([-0.6747]))])
Not so bad, e.g. we expect
The model is very naive: it is a neural network with three inputs and one output and no hidden layers. It still performs reasonably well, so one could hope that this approach (after imporving it) helps with other problems where we do not know the answer.
Empty so far.

