You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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::Latticeendconst 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:
An alternative design is to have a type hierarchy like:
abstract type AbstractITensorNetwork endstruct HyperCubicITensorNetwork{N} <:AbstractITensorNetwork
tensors::Array{ITensor,N}end# The lattice is determined by overloading the `lattice` functionlattice(::HyperCubicITensorNetwork{N}) where {N} =HyperCubic{N}()
const MPS = HyperCubicITensorNetwork{1}
const PEPS = HyperCubicITensorNetwork{2}
struct UnstructuredITensorNetwork <:AbstractITensorNetwork
tensors::Array{ITensor,N}endconst TN = UnstructuredITensorNetwork
lattice(::UnstructuredITensorNetwork) =Unstructured()
I'm not sure which design would be better. The second design based on a type hierarchy and function overloading is a bit more flexible because different lattice types could store different types of information about the network connectivity. For example, in practice the UnstructuredITensorNetwork could store an adjacency list that caches the actual network structure based on shared indices, which it could do once when it is constructed and then update if ITensors in the network are modified.
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 anITensorNetwork
with aSquare
lattice: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:
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 otherneighbors
function depending on the type oflattice
.The text was updated successfully, but these errors were encountered: