Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ITensorNetworksNext"
uuid = "302f2e75-49f0-4526-aef7-d8ba550cb06c"
version = "0.6.1"
version = "0.7.0"
authors = ["ITensor developers <support@itensor.org> and contributors"]

[workspace]
Expand Down Expand Up @@ -30,13 +30,13 @@ Combinatorics = "1"
DataGraphs = "0.4"
Dictionaries = "0.4.5"
Graphs = "1.13.1"
ITensorBase = "0.6.3"
ITensorBase = "0.7"
LinearAlgebra = "1.10"
MacroTools = "0.5.16"
MatrixAlgebraKit = "0.6"
NamedGraphs = "0.11"
Random = "1.10"
SimpleTraits = "0.9.5"
SplitApplyCombine = "1.2.3"
TensorAlgebra = "0.9.7"
TensorAlgebra = "0.10"
julia = "1.10"
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ path = ".."
[compat]
Documenter = "1"
ITensorFormatter = "0.2.27"
ITensorNetworksNext = "0.6"
ITensorNetworksNext = "0.7"
Literate = "2"
2 changes: 1 addition & 1 deletion docs/src/reference.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Reference

```@autodocs
Modules = [ITensorNetworksNext, ITensorNetworksNext.TensorNetworkGenerators]
Modules = [ITensorNetworksNext, ITensorNetworksNext.ITensorNetworkGenerators]
```
2 changes: 1 addition & 1 deletion examples/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ ITensorNetworksNext = "302f2e75-49f0-4526-aef7-d8ba550cb06c"
path = ".."

[compat]
ITensorNetworksNext = "0.6"
ITensorNetworksNext = "0.7"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module TensorNetworkGenerators
module ITensorNetworkGenerators

export delta_network, ising_network

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using ..ITensorNetworksNext: TensorNetwork
using ..ITensorNetworksNext: ITensorNetwork
using Graphs: AbstractGraph
using ITensorBase: NamedUnitRange, denamed, name, nameddims
using ITensorBase: NamedUnitRange, name, nameddims, unnamed
using NamedGraphs.GraphsExtensions: incident_edges

diaglength(a::AbstractArray) = minimum(size(a))
Expand Down Expand Up @@ -29,20 +29,20 @@ function diagonaltensor(
diag::AbstractVector,
is::Tuple{NamedUnitRange, Vararg{NamedUnitRange}}
)
return nameddims(diagonaltensor(diag, denamed.(is)), name.(is))
return nameddims(diagonaltensor(diag, unnamed.(is)), name.(is))
end

delta(elt::Type, is) = diagonaltensor(ones(elt, minimum(length ∘ denamed, is)), is)
delta(elt::Type, is) = diagonaltensor(ones(elt, minimum(length, is)), is)

"""
delta_network(f, elt::Type = Float64, g::AbstractGraph)

Construct a TensorNetwork on the graph `g` with element type `elt` that has delta tensors
Construct a ITensorNetwork on the graph `g` with element type `elt` that has delta tensors
on each vertex. Link dimensions are defined using the function `f(e)` that should take an
edge `e` as an input and should output the link index on that edge.
"""
function delta_network(f, elt::Type, g::AbstractGraph)
return tn = TensorNetwork(g) do v
return tn = ITensorNetwork(g) do v
is = Tuple(f.(incident_edges(g, v)))
return delta(elt, is)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ end
"""
ising_network(f, β::Number, g::AbstractGraph)

Construct a TensorNetwork on the graph `g` with inverse temperature `β` that has Ising
Construct a ITensorNetwork on the graph `g` with inverse temperature `β` that has Ising
partition function tensors on each vertex. Link dimensions are defined using the function
`f(e)` that should take an edge `e` as an input and should output the link index on that
edge.
Expand Down
2 changes: 1 addition & 1 deletion src/ITensorNetworksNext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ include("select_algorithm.jl")
include("AlgorithmsInterfaceExtensions/AlgorithmsInterfaceExtensions.jl")
include("abstracttensornetwork.jl")
include("tensornetwork.jl")
include("TensorNetworkGenerators/TensorNetworkGenerators.jl")
include("ITensorNetworkGenerators/ITensorNetworkGenerators.jl")
include("contract_network.jl")

include("beliefpropagation/messagecache.jl")
Expand Down
54 changes: 29 additions & 25 deletions src/abstracttensornetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ using NamedGraphs.GraphsExtensions: directed_graph, incident_edges, rem_edges!,
using NamedGraphs.OrdinalIndexing: OrdinalSuffixedInteger
using NamedGraphs: NamedGraphs, NamedGraph, not_implemented, similar_graph

abstract type AbstractTensorNetwork{V, VD} <: AbstractDataGraph{V, VD, Nothing} end
abstract type AbstractITensorNetwork{V, VD} <: AbstractDataGraph{V, VD, Nothing} end

# Need to be careful about removing edges from tensor networks in case there is a bond
Graphs.rem_edge!(::AbstractTensorNetwork, edge) = not_implemented()
Graphs.rem_edge!(::AbstractITensorNetwork, edge) = not_implemented()

# Graphs.jl overloads
function Graphs.weights(graph::AbstractTensorNetwork)
function Graphs.weights(graph::AbstractITensorNetwork)
V = vertextype(graph)
es = Tuple.(edges(graph))
ws = Dictionary{Tuple{V, V}, Float64}(es, undef)
Expand All @@ -29,28 +29,28 @@ function Graphs.weights(graph::AbstractTensorNetwork)
end

# Copy
Base.copy(::AbstractTensorNetwork) = not_implemented()
Base.copy(::AbstractITensorNetwork) = not_implemented()

# Iteration
Base.iterate(tn::AbstractTensorNetwork, args...) = iterate(vertex_data(tn), args...)
Base.keys(tn::AbstractTensorNetwork) = vertices(tn)
Base.iterate(tn::AbstractITensorNetwork, args...) = iterate(vertex_data(tn), args...)
Base.keys(tn::AbstractITensorNetwork) = vertices(tn)

# TODO: This contrasts with the `DataGraphs.AbstractDataGraph` definition,
# where it is defined as the `vertextype`. Does that cause problems or should it be changed?
Base.eltype(tn::AbstractTensorNetwork) = eltype(vertex_data(tn))
Base.eltype(tn::AbstractITensorNetwork) = eltype(vertex_data(tn))

# Overload if needed
Graphs.is_directed(::Type{<:AbstractTensorNetwork}) = false
Graphs.is_directed(::Type{<:AbstractITensorNetwork}) = false

DataGraphs.underlying_graph(::AbstractTensorNetwork) = not_implemented()
function NamedGraphs.vertex_positions(tn::AbstractTensorNetwork)
DataGraphs.underlying_graph(::AbstractITensorNetwork) = not_implemented()
function NamedGraphs.vertex_positions(tn::AbstractITensorNetwork)
return NamedGraphs.vertex_positions(underlying_graph(tn))
end
function NamedGraphs.ordered_vertices(tn::AbstractTensorNetwork)
function NamedGraphs.ordered_vertices(tn::AbstractITensorNetwork)
return NamedGraphs.ordered_vertices(underlying_graph(tn))
end

function Adapt.adapt_structure(to, tn::AbstractTensorNetwork)
function Adapt.adapt_structure(to, tn::AbstractITensorNetwork)
# TODO: Define and use:
#
# @preserve_graph map_vertex_data(adapt(to), tn)
Expand Down Expand Up @@ -135,14 +135,14 @@ macro preserve_graph(expr)
return :(setindex_preserve_graph!($(esc(array)), $(esc(value)), $(esc.(indices)...)))
end

# Update the graph of the TensorNetwork `tn` to include
# Update the graph of the ITensorNetwork `tn` to include
# edges that should exist based on the tensor connectivity.
function add_missing_edges!(tn::AbstractGraph)
foreach(v -> add_missing_edges!(tn, v), vertices(tn))
return tn
end

# Update the graph of the TensorNetwork `tn` to include
# Update the graph of the ITensorNetwork `tn` to include
# edges that should be incident to the vertex `v`
# based on the tensor connectivity.
function add_missing_edges!(tn::AbstractGraph, v)
Expand All @@ -157,13 +157,13 @@ function add_missing_edges!(tn::AbstractGraph, v)
return tn
end

# Fix the edges of the TensorNetwork `tn` to match
# Fix the edges of the ITensorNetwork `tn` to match
# the tensor connectivity.
function fix_edges!(tn::AbstractGraph)
foreach(v -> fix_edges!(tn, v), vertices(tn))
return tn
end
# Fix the edges of the TensorNetwork `tn` to match
# Fix the edges of the ITensorNetwork `tn` to match
# the tensor connectivity at vertex `v`.
function fix_edges!(tn::AbstractGraph, v)
for e in incident_edges(tn, v)
Expand All @@ -176,12 +176,12 @@ function fix_edges!(tn::AbstractGraph, v)
return tn
end

using ITensorBase: denamedtype, named, nametype, uniquename
using ITensorBase: named, nametype, uniquename, unnamedtype
using TensorAlgebra: trivialrange
function insertlink!(tn, e)
add_edge!(tn, e)
T = eltype(inds(tn[src(e)]))
l = named(trivialrange(denamedtype(T)), uniquename(nametype(T)))
l = named(trivialrange(unnamedtype(T)), uniquename(nametype(T)))
x = fill!(similar(tn[src(e)], (l,)), one(eltype(tn[src(e)])))
@preserve_graph tn[src(e)] = tn[src(e)] * x
@preserve_graph tn[dst(e)] = tn[dst(e)] * conj(x)
Expand All @@ -202,28 +202,32 @@ function randlinknames(tn)
return new_tn
end

function Base.setindex!(tn::AbstractTensorNetwork, value, v)
function Base.setindex!(tn::AbstractITensorNetwork, value, v)
@preserve_graph tn[v] = value
fix_edges!(tn, v)
return tn
end
# Fix ambiguity error.
function Base.setindex!(graph::AbstractTensorNetwork, value, vertex::OrdinalSuffixedInteger)
function Base.setindex!(
graph::AbstractITensorNetwork,
value,
vertex::OrdinalSuffixedInteger
)
graph[vertices(graph)[vertex]] = value
return graph
end
Base.setindex!(tn::AbstractTensorNetwork, value, edge::AbstractEdge) = not_implemented()
Base.setindex!(tn::AbstractTensorNetwork, value, edge::Pair) = not_implemented()
Base.setindex!(tn::AbstractITensorNetwork, value, edge::AbstractEdge) = not_implemented()
Base.setindex!(tn::AbstractITensorNetwork, value, edge::Pair) = not_implemented()
# Fix ambiguity error.
function Base.setindex!(
tn::AbstractTensorNetwork,
tn::AbstractITensorNetwork,
value,
edge::Pair{<:OrdinalSuffixedInteger, <:OrdinalSuffixedInteger}
)
return not_implemented()
end

function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractTensorNetwork)
function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractITensorNetwork)
println(io, "$(typeof(graph)) with $(nv(graph)) vertices:")
show(io, mime, vertices(graph))
println(io, "\n")
Expand All @@ -238,4 +242,4 @@ function Base.show(io::IO, mime::MIME"text/plain", graph::AbstractTensorNetwork)
return nothing
end

Base.show(io::IO, graph::AbstractTensorNetwork) = show(io, MIME"text/plain"(), graph)
Base.show(io::IO, graph::AbstractITensorNetwork) = show(io, MIME"text/plain"(), graph)
27 changes: 14 additions & 13 deletions src/apply/apply_operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ using Graphs: dst, src, vertices
using ITensorBase:
ITensorBase as ITB, AbstractITensor, dimnames, domainnames, operator, replacedimnames
using LinearAlgebra: norm
using MatrixAlgebraKit: qr_compact, svd_trunc
using NamedGraphs.GraphsExtensions: all_edges, boundary_edges
using TensorAlgebra: TensorAlgebra as TA, gram_eigh_full, gram_eigh_full_with_pinv
using TensorAlgebra.MatrixAlgebra: gram_eigh_full, gram_eigh_full_with_pinv

# === Top-level user entry point ===

Expand All @@ -15,7 +16,7 @@ using TensorAlgebra: TensorAlgebra as TA, gram_eigh_full, gram_eigh_full_with_pi

Apply each operator in `operators` (a sequence of single-tensor or two-tensor
operators) to `state` in turn, updating `env` to reflect each application.
`state` is an `AbstractTensorNetwork`, `env` is a per-edge environment cache
`state` is an `AbstractITensorNetwork`, `env` is a per-edge environment cache
(typically built by `identity_norm_message_env(state)` or one of the related
`*_norm_message_env` constructors), and the returned `(state, env)` pair has
the operators applied. `kwargs` are forwarded to the per-operator algorithm
Expand Down Expand Up @@ -205,8 +206,8 @@ end
# === BP simple-update implementation ===

function apply_gate_bp!(
dest::AbstractTensorNetwork, op::AbstractITensor,
state::AbstractTensorNetwork, env; kwargs...
dest::AbstractITensorNetwork, op::AbstractITensor,
state::AbstractITensorNetwork, env; kwargs...
)
op_in = domainnames(op)
vs = [v for v in vertices(state) if !isempty(intersect(op_in, sitenames(state, v)))]
Expand All @@ -217,15 +218,15 @@ function apply_gate_bp!(
end

function apply_gate_bp_nsite!(
::Val{N}, dest::AbstractTensorNetwork, op::AbstractITensor,
state::AbstractTensorNetwork, env, vs; kwargs...
::Val{N}, dest::AbstractITensorNetwork, op::AbstractITensor,
state::AbstractITensorNetwork, env, vs; kwargs...
) where {N}
return throw(ArgumentError("$N-site gate decomposition not implemented"))
end

function apply_gate_bp_nsite!(
::Val{1}, dest::AbstractTensorNetwork, op::AbstractITensor,
state::AbstractTensorNetwork, env, vs;
::Val{1}, dest::AbstractITensorNetwork, op::AbstractITensor,
state::AbstractITensorNetwork, env, vs;
normalize, kwargs...
)
v = only(vs)
Expand All @@ -242,8 +243,8 @@ function apply_gate_bp_nsite!(
end

function apply_gate_bp_nsite!(
::Val{2}, dest::AbstractTensorNetwork, op::AbstractITensor,
state::AbstractTensorNetwork, env, vs;
::Val{2}, dest::AbstractITensorNetwork, op::AbstractITensor,
state::AbstractITensorNetwork, env, vs;
trunc, normalize
)
v1, v2 = vs
Expand All @@ -258,10 +259,10 @@ function apply_gate_bp_nsite!(
ψ_v1 = prod([[state[v1]]; gauges_v1])
ψ_v2 = prod([[state[v2]]; gauges_v2])

Q_v1, R_v1 = TA.qr(ψ_v1, setdiff(dimnames(ψ_v1), dimnames(ψ_v2), dimnames(op)))
Q_v2, R_v2 = TA.qr(ψ_v2, setdiff(dimnames(ψ_v2), dimnames(ψ_v1), dimnames(op)))
Q_v1, R_v1 = qr_compact(ψ_v1, setdiff(dimnames(ψ_v1), dimnames(ψ_v2), dimnames(op)))
Q_v2, R_v2 = qr_compact(ψ_v2, setdiff(dimnames(ψ_v2), dimnames(ψ_v1), dimnames(op)))
op_R_v1v2 = ITB.apply(op, R_v1 * R_v2)
U_v1, S, U_v2 = TA.svd(op_R_v1v2, setdiff(dimnames(R_v1), dimnames(R_v2)); trunc)
U_v1, S, U_v2 = svd_trunc(op_R_v1v2, setdiff(dimnames(R_v1), dimnames(R_v2)); trunc)
if normalize
S = S / norm(S)
end
Expand Down
8 changes: 4 additions & 4 deletions src/beliefpropagation/normnetwork.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using DataGraphs: underlying_graph
using Graphs: dst, edges, edgetype, src
using ITensorBase: codomainnames, denamed, domainnames, name, operator, replacedimnames,
similar_operator, state, uniquename
using ITensorBase: codomainnames, domainnames, name, operator, replacedimnames,
similar_operator, state, uniquename, unnamed
using NamedGraphs.GraphsExtensions: all_edges, incident_edges
using Random: Random, rand!, randn!

Expand Down Expand Up @@ -38,7 +38,7 @@ function similar_norm_message_env(tn)
v1, v2 = src(e), dst(e)
ket_axes = linkinds(tn, e)
ket_names = name.(ket_axes)
unnamed_axes = denamed.(ket_axes)
unnamed_axes = unnamed.(ket_axes)
bra_names = uniquename.(ket_names)
# Message axes are dual to the link they contract against in the factor.
push!(
Expand Down Expand Up @@ -146,7 +146,7 @@ function normnetwork(tn)
for e in edges(tn)
)
merge!(linknames_map, Dict(reverse(e) => m for (e, m) in linknames_map))
norm_tn = TensorNetwork(underlying_graph(tn)) do v
norm_tn = ITensorNetwork(underlying_graph(tn)) do v
t = tn[v]
ket_to_bra = Dict(p for e in incident_edges(tn, v) for p in linknames_map[e])
return t * replacedimnames(n -> get(ket_to_bra, n, n), conj(t))
Expand Down
Loading
Loading