Define an ITensorNetwork struct that stores a collection of ITensors that make up a network as well as metadata about the connectivity of the network (such as an adjacency list or lattice iterator). For example, a PEPS class might be defined as an alias of an ITensorNetwork with a Square lattice:
struct ITensorNetwork{N,Lattice}
tensors::Array{ITensor,N}
lattice::Lattice
end
const MPS = ITensorNetwork{CartesianIndex{2},Chain}
const PEPS = ITensorNetwork{CartesianIndex{2},Square}
# This would be a generic, unstructured network (not fully connected, but not with any regular pattern)
const TN = ITensorNetwork{CartesianIndex{2},Unstructured}
# And other lattice definitions like `Tree`, `FullyConnected`, etc.
This could have a generic method for operations like priming the links of a network, which makes use of the lattice object to make it faster to determine the neighbors of a tensor in order to determine which indices to prime.
An example of how this would work in practice is that right now there are two "neighbors" functions which determine the neighbors of a site/node in an ITensor network. One is based on the specialized definition for a HyperCubic lattice:
|
# The neighboring sites of the specified site |
|
function neighbors(lattice::HyperCubic{N}, site::NTuple{N,Int}) where {N} |
|
lattice_size = size(lattice) |
|
site_neighbors = Vector{NTuple{N,Int}}() |
|
for dim in 1:N, dir in (-1, 1) |
|
site_neighbor = neighbor(site, dim, dir; lattice_size=lattice_size) |
|
push!(site_neighbors, neighbor) |
|
end |
|
return site_neighbors |
|
end |
and one is based on naively searching for which tensors in the network have shared indices with the specified tensor:
|
function filterneighbors(f, tn, n) |
|
neighbors_tn = keytype(tn)[] |
|
tnₙ = tn[n] |
|
for m in keys(tn) |
|
if f(n, m) && hascommoninds(tnₙ, tn[m]) |
|
push!(neighbors_tn, m) |
|
end |
|
end |
|
return neighbors_tn |
|
end |
|
neighbors(tn, n) = filterneighbors(≠, tn, n) |
|
inneighbors(tn, n) = filterneighbors(>, tn, n) |
|
outneighbors(tn, n) = filterneighbors(<, tn, n) |
Then, something like prime(linkinds, tn) would use one or the other neighbors function depending on the type of lattice.
Define an
ITensorNetworkstruct that stores a collection of ITensors that make up a network as well as metadata about the connectivity of the network (such as an adjacency list or lattice iterator). For example, a PEPS class might be defined as an alias of anITensorNetworkwith aSquarelattice:This could have a generic method for operations like priming the links of a network, which makes use of the
latticeobject to make it faster to determine the neighbors of a tensor in order to determine which indices to prime.An example of how this would work in practice is that right now there are two "neighbors" functions which determine the neighbors of a site/node in an ITensor network. One is based on the specialized definition for a HyperCubic lattice:
ITensorNetworkAD.jl/src/ITensorNetworks/tensor_networks.jl
Lines 168 to 177 in 17d1a44
ITensorNetworkAD.jl/src/ITensorNetworks/tensor_networks.jl
Lines 627 to 639 in 17d1a44
Then, something like
prime(linkinds, tn)would use one or the otherneighborsfunction depending on the type oflattice.