Section 4 - dimension computation in the limit case

4. Lie polynomials and Lie groups

Let \(C(n)\) be the collection of compositions of \(n\), and \(\mu\left(k\right)\) the Möbius function of \(k\).

Theorem 4.3 claims that the dimension of the discrete signature variety \(\mathcal V_{d, h, N}\) approaches for growing \(N\) the value:

\[\lambda_{d, h} = \sum_{k|h} \frac{\mu\left(k\right)}{k} \sum_{\alpha\in C(h/k)} \frac{1}{\ell (\alpha)} \prod_{i=1}^{\ell(\alpha)} \binom{\alpha_i + d - 1}{d - 1} \, .\]

The following code prints the value of \(\lambda_{d, h}\) for all integers \(d, h \in [1, 10)\).

def initialize_arithmetic_functions(LIM=500):
        """
        Initialize arithmetic functions for binomial coefficients and the Möbius function.
        """
        # Initialize a 2D list `binom` to store binomial coefficients
        binom = [[0 for i in range(LIM)] for j in range(LIM)]
        binom[0][0] = 1

        # Compute binomial coefficients using Pascal's triangle
        for i in range(1, LIM-1):
                binom[i][0] = 1
                for j in range(1, i+1):
                        binom[i][j] = binom[i-1][j] + binom[i-1][j-1]

        # Initialize the Möbius function `mu` and a list `primeQ` to track prime numbers
        mu = [1 for _ in range(LIM+1)]
        primeQ = [True for _ in range(LIM+1)]

        # Set initial values for `mu` and `primeQ`
        mu[0] = 0
        primeQ[0] = False
        primeQ[1] = False

        # Compute the Möbius function and mark non-prime numbers
        for i in range(2, LIM+1):
                if primeQ[i]:
                        # Mark multiples of `i` as non-prime and update `mu`
                        for j in range(i, LIM+1, i):
                                primeQ[j] = False
                                mu[j] *= -1
                        # Set `mu[j]` to 0 for multiples of `i^2`
                        for j in range(i*i, LIM+1, i*i):
                                mu[j] = 0

        return mu, primeQ, binom

def initialize_compositions(lim = 15):
        """
        Initialize compositions of integers.
        """
        # Initialize a list to store compositions
        compositions = []

        # Start with compositions of 0
        new_compositions = [[]]  # Compositions of 0
        compositions.append(new_compositions[:])

        # Add compositions of 1
        new_compositions = [[1]]  # Compositions of 1
        compositions.append(new_compositions[:])

        # Generate compositions for integers up to `lim`
        for i in range(2, lim):
                old_compositions = new_compositions[:]
                new_compositions = []
                for alpha in old_compositions:
                        # Add a new part of size 1 to the composition
                        new_alpha = alpha[:]
                        new_compositions.append(new_alpha[:] + [1])
                        # Increment the last part of the composition
                        new_alpha[-1] += 1
                        new_compositions.append(new_alpha[:])
                compositions.append(new_compositions[:])

        return compositions

def lbd(d, h, verbose=False):
        """
        Compute the lambda function λ_{d, h}.

        Args:
                d (int): The degree parameter.
                h (int): The height parameter.
                verbose (bool): If True, print intermediate calculations.

        Returns:
                int: The computed value of λ_{d, h}.
        """
        sum_part_1 = 0
        for k in range(1, h+1):
                if h % k == 0:
                        sum_part_2 = 0
                        for alpha in compositions[h//k]:
                                prod_part = 1
                                for a in alpha:
                                        # Compute the product of binomial coefficients
                                        prod_part *= binom[a+d-1][d-1]
                                if verbose:
                                        print(d, h, k, alpha, "=", prod_part)
                                # Divide by the length of the composition
                                prod_part /= len(alpha)
                                sum_part_2 += prod_part
                        # Multiply by the Möbius function and divide by `k`
                        sum_part_1 += round(mu[k] * sum_part_2 / k)
        return sum_part_1

if __name__ == "__main__":
        mu, primeQ, binom = initialize_arithmetic_functions()
        compositions = initialize_compositions()

        # Limit for lambda function calculations
        lim = 10

        # Compute and print λ_{d, h} for all d, h in the range [1, lim)
        for d in range(1, lim):
                for h in range(1, lim):
                        print("lambda_{", d, ", ", h, "} =  ", lbd(d, h))

This gives us the following output:

Table with dimension values d, h in [1, 10)