Tensor Node Notation
Plain Networks
In a plain network, each node must not have dublicate mode names and every mode name must appear in at most two nodes. Furthermore, the network must corresponding to a tree graph.
d = 4
alpha = mna('alpha',1:d);
n_alpha = assign_mode_size(alpha,5);
Root-to-leaf graph creation - TT-format
If we do not want to specify the mode names of a specific format manually, we can use the algorithm RTLGRAPH.
type RTLGRAPH.m
As input, the algorithm expects a sequence S of subsets of a set of outer mode names, for example of α. These subsets generate a graph G, and a mode name map m, which corresponds to a plain network N. Each edge in G splits the outer mode names α in two parts, one of which always is one element in the sequence S.
For the TT-format, S is quite simple:
S = linear_tree(alpha);
S{:}
We only have to specify the name scheme for the, to be created, inner mode names:
[G,m,~,~,beta] = RTLGRAPH(alpha,S,'beta')
m{:}
plot(G)
n_beta = assign_mode_size(beta,2);
n = merge_fields(n_alpha,n_beta);
We can use m to initialize the network:
NTT = init_net(m,n)
net_view(NTT)
Creating a binary HT-format
The same process can be repeated for a binary HT-formats. However, in order to fit into the scheme of plain networks, there is not root transfer tensor.
alpha = mna('alpha',1:d);
S = binary_tree(alpha);
S{:}
[G,m,~,~,gamma] = RTLGRAPH(alpha,S,'gamma');
plot(G)
n_gamma = assign_mode_size(gamma,2);
n = merge_fields(n_alpha,n_gamma);
NHT = init_net(m,n);
net_view(NHT)
Random plain networks
The function random_tree(alpha,k) provides an artificially random tree that restricts single nodes to at most kconnections:
alpha = mna('alpha',1:d);
rng(2)
S = random_tree(alpha,4);
[G,m,~,~,delta] = RTLGRAPH(alpha,S,'delta');
plot(G)
n_delta = assign_mode_size(delta,2);
n = merge_fields(n_alpha,n_delta);
NR = init_net(m,n);
net_view(NR)
Computations between arbitrary plain networks
The function boxtimes allows us to do computations between these networks, even if we would have used the same inner mode for all three.
Their outer mode names tell boxtimes which edges are to be connected. The resulting networks can however become complicated.
NTT = randomize_net(NTT);
NHT = randomize_net(NHT);
NR = randomize_net(NR);
save('random-format','NR');
net_view(NTT,NTT)
net_view(NHT,NHT,'Layout','force3')
view([171.30 12.40])
net_view(NR,NR,'Layout','force3')
view([-145.50 20.40])
The two networks do not necessarily need to be of the same type:
net_view(NTT,NHT,'Layout','force3')
view([1.70 -26.00])
Scalar products
We can either take scalar products between the tensor being represented, or measure their distance.
TTT = boxtimes(NTT)
THT = boxtimes(NHT)
get_data(boxtimes(TTT,THT,'mode','show'))
get_data(boxtimes(NTT,NHT,'mode','show'))
In this case, a search for the optimal contraction order will require too many iterations if we increase d.
try
get_data(boxtimes(NTT,NHT,'mode','optimal_show'))
catch ME
ME.message
end
We can restrict us to solutions which in the worst case will be 5 times as complex. We might however be lucky:
try
get_data(boxtimes(NTT,NHT,'mode','optimal_show_optfac_0.2'))
catch ME
ME.message
end
Distances
The distance of two networks is defined as the distance of the tensors which they represent.
Since the addition of networks which are not of the same type is troublesome, but scalar products are usually not, net_dist evaluates it using
net_dist(NTT,NTT)
net_dist(NHT,NTT)
net_dist(THT,TTT)
norm(unfold(TTT,alpha)-unfold(THT,alpha),'fro')