Entropy of Markov tree-shifts over Markov-Cayley trees

Backgrounds

Let A\mathcal{A} be a finite alphabet and KK be a kk-by-kk, 00-11 matrix. A Markov-Cayley tree TKT_K is subset of a free semigroup with generators [k]={1,2, ,k}[k] = \{1,2,\cdots,k\}:

TK={gi0[k]i:Kgi,gi+1=1, for all i1}\begin{aligned}T_K=\{g \in \cup_{i \ge 0} [k]^{i}: K_{g_i, g_{i+1}} = 1, \text{ for all } i \ge 1\}。\end{aligned}

A Markov-Cayley tree-shifts XAX_{\mathbf{A}}, associated with a kk-tuple of 00-11 matrices A=(A(1),A(2), ,A(k))\mathbf{A} = (A^{(1)}, A^{(2)}, \cdots, A^{(k)}), over TKT_K is a subset of ATK\mathcal{A}^{T_K} defined as

XA={xATK:Axg,xgi(i)=1, for all gTK,i[k] such that giTk}.\begin{aligned}X_{\mathbf{A}}=\{x \in \mathcal{A}^{T_K}: A^{(i)}_{x_g, x_{g i}} = 1, \text{ for all } g \in T_K, i \in [k] \text{ such that } g i \in T_k\}.\end{aligned}

The topological entropy of TKT_K is defined to be

h(XA)=limnhn(i)(XA):=limnlogpn(i)(XA)#Δn(i) for i[k],\begin{aligned}h(X_{\mathbf{A}}) = \lim_{n \to \infty} h^{(i)}_n(X_{\mathbf{A}}) := \lim_{n \to \infty} \frac{\log p^{(i)}_n(X_{\mathbf{A}})}{\# \Delta^{(i)}_n} \text{ for } i \in [k],\end{aligned}

where Δn(i)\Delta^{(i)}_n is the set {gTK:g is of length n with i its prefix}\{g \in T_K: g \text{ is of length } n \text{ with } i \text{ its prefix}\} and pn(i)=#{xΔn(i):xXA}p^{(i)}_n = \# \{x|_{\Delta^{(i)}_n}: x \in X_A\}. If we further define pn;a(i)=#{xΔn(i):xXA,xϵ=a}p^{(i)}_{n;a} = \# \{x|_{\Delta^{(i)}_n}: x \in X_A, x_\epsilon = a\} (so that pn(i)=apn;a(i)p^{(i)}_{n} = \sum_{a} p^{(i)}_{n;a}), one can compute hn(i)h_n^{(i)} via the following recursive relation:

{pn+1;a(i)=j:Ki,j=1b:Aa,b(i)=1pn;b(j)(#Δn+1(i)1)=1+j:Ki,j=1(#Δn(j)1)\begin{aligned}\begin{cases}p^{(i)}_{n+1;a} = \prod_{j: K_{i,j}=1}\sum_{b:A^{(i)}_{a,b}=1} p^{(j)}_{n;b} \\ (\# \Delta^{(i)}_{n+1} - 1) = 1 + \prod_{j: K_{i,j}=1} (\# \Delta^{(j)}_{n} - 1) \end{cases}\end{aligned}

We remark that pn;a(i)p^{(i)}_{n;a}, at fastest, grows superexponentially in nn, and is too large to store as a number. To address the issue, a naive solution is to normalize pn;a(i)p^{(i)}_{n;a} by Dn(i)=maxbpn;b(i)D^{(i)}_n = \max_{b} p^{(i)}_{n;b}, which we denote by pn;a(i)=pn;a(i)/Dn(i)\overline{p}^{(i)}_{n;a} = p^{(i)}_{n;a} / D^{(i)}_n, and rephrase the recursion in terms of pn;a(i)\overline{p}^{(i)}_{n;a}:

{pn+1;a(i)Cn+1(i)=j:Ki,j=1b:Aa,b(i)=1pn;b(j)logDn+1(i)=logCn+1(i)+j:Ki,j=1logDn(j)(#Δn+1(i)1)=1+j:Ki,j=1(#Δn(j)1),\begin{aligned}\begin{cases} \overline{p}^{(i)}_{n+1;a} \cdot C^{(i)}_{n+1} = \prod_{j: K_{i,j}=1} \sum_{b:A^{(i)}_{a,b}=1} \overline{p}^{(j)}_{n;b} \\ \log D^{(i)}_{n+1} = \log C^{(i)}_{n+1} + \sum_{j: K_{i,j} = 1} \log D^{(j)}_{n} \\ (\# \Delta^{(i)}_{n+1} - 1) = 1 + \prod_{j: K_{i,j}=1} (\# \Delta^{(j)}_{n} - 1) \end{cases},\end{aligned}

where Cn+1(i):=maxaj:Ki,j=1b:Aa,b(i)=1C^{(i)}_{n+1}:=\max_a \prod_{j: K_{i,j}=1} \sum_{b:A^{(i)}_{a,b}=1}. Note that we now can approximate entropy using Dn(i)D^{(i)}_n since logDn(i)/logpn(i)(XA)1\log D^{(i)}_n / \log p^{(i)}_n(X_{\mathbf{A}}) \to 1, and that logDn(i)\log D^{(i)}_n grows only exponentially in nn.

Program

K=[1 1;1 1]
2×2 Matrix{Int64}:
 1  1
 1  1
A = ([0 1 1;1 0 0;1 0 0], [1 1 1;1 0 0;1 0 1])
([0 1 1; 1 0 0; 1 0 0], [1 1 1; 1 0 0; 1 0 1])
"""
`function mctree_entropy(K, A, max_iter=50)`
The function returns the entropy \$h^{(i)}_n(X_{\\mathbf{A}}) \$ of the Markov tree-shifts \$X_{\\mathbf{A}}\$ over the Markov-Cayley tree \$T_K\$ associated with matrix ``K``, where
- `K` is the defining `k`-by-`k` matrix for the Markov-Cayley tree
- `A` is a vector of `k` adjacency matrices
- `max_iter` is the maximal number of iterations
"""
function mctree_entropy(K, A, max_iter=50)
    norm_pattern_num = ones(size(K,2), size(A[1],2), max_iter) # normalized number of patterns
    log_pattern_num = zeros(size(K,2), max_iter) # logarithm of pattern numbers (D^{(i)}_n)
    entropy = zeros(size(K,2), max_iter) # n-order approximation of entropy
    norm_const = ones(size(K,2), max_iter) # normalization constant (C^{(i)}_n)
    lattice_point_num = ones(size(K,2), max_iter) # numbers of lattice points (\# \Delta^{(i)}_n - 1)
    break_flag = false # break flag: terminate iteration if converged
    end_iter = 0 # number of executed iterations
    for i in 2:max_iter
        lattice_point_num[:,i] = K * lattice_point_num[:,i-1] .+ 1;
        for j in 1:size(K,2)
            temp = ones(size(A[1],2),1);
            for k in 1:size(K,2)
                if K[j,k] == 1
                    temp = temp .* (A[k] * norm_pattern_num[k,:,i-1]);
                end
            end
            norm_const[j,i] = maximum(temp);
            norm_pattern_num[j,:,i] = temp / norm_const[j,i];
            log_pattern_num[j,i] = K[j,:]' * log_pattern_num[:,i-1] + log10(norm_const[j,i]);
            entropy[j,i] = log_pattern_num[j,i] / lattice_point_num[j,i];
            if log_pattern_num[j,i] == -Inf
                break_flag = true;
                break;
            elseif abs(entropy[j,i] - entropy[j,i-1]) / entropy[j,i] < 1E-11 || entropy[j,i] < 1E-11
                break_flag = true;
                break;
            end
        end
        end_iter = i
        if break_flag
            end_iter = i-1;
            break
        end
    end
    return maximum(entropy[:,1:end_iter], dims = 1)
end
mctree_entropy
mctree_entropy(K,A)
1×36 Matrix{Float64}:
 0.0  0.259384  0.240177  0.26464  0.258857  0.264113  0.262379  0.26366  0.263177  0.263501  0.263375  0.263457  0.263425  0.263446  0.263438  0.263443  0.263441  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442  0.263442