Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
34796d3
Add `QuadraticFormNetwork` and a shared bilinear-form interface
jack-dunham Sep 9, 2026
6828d4b
Move the bilinear-form networks and views to `src/bilinearforms/`
jack-dunham Sep 9, 2026
d88f133
Reject `NormNetwork` in `OperatorView` with an `ArgumentError`
jack-dunham Sep 9, 2026
54780f5
Define the NamedGraphs vertex encoding once on the abstract view type
jack-dunham Sep 9, 2026
fb44fc9
Add `ITensorNetworkOperator` and use it as the operator layer
jack-dunham Sep 14, 2026
fdeda86
Replace `KetView` and `OperatorView` with `ketnetwork` and `operatorn…
jack-dunham Sep 28, 2026
9891d03
Remove `AbstractBilinearFormNetworkView`; define its forwarding metho…
jack-dunham Sep 28, 2026
90dbabe
Move `BraView` into `abstractbilinearformnetwork.jl`
jack-dunham Sep 28, 2026
68546b0
Combine the two `DataGraphs.jl` sections of `BraView`
jack-dunham Sep 28, 2026
1d57062
Reject crossing operator pairs; read the vertex operator's pairing in…
jack-dunham Oct 8, 2026
809d403
Store the `ITensorNetworkOperator` pairing as a `Dictionary`
jack-dunham Sep 29, 2026
2e532ff
Define shared bilinear-form methods on the abstract type; remove `ind…
jack-dunham Oct 8, 2026
27d6a6b
Add `nametype` to the bilinear-form network interface
jack-dunham Oct 8, 2026
736c0ea
Reject a `QuadraticFormNetwork` operator input name absent from the k…
jack-dunham Oct 8, 2026
ee408ab
Add `factor_tensors` for `QuadraticFormNetwork`; make its indexing an…
jack-dunham Oct 8, 2026
6624d4d
Read vertex indices through `inds(tn, v)`; `BraView` overloads it
Oct 6, 2026
aff3d91
Return a `Set` from both `dimnamevertices` methods
Oct 8, 2026
b78ea29
Define `inds(tn, v)` and `names(tn, v)` on `AbstractITensorNetwork`
Oct 8, 2026
7ce3282
Replace `select_branames` with `linknames(tn)` and `getindices`
Oct 8, 2026
b77215e
Give a separate bra name to every mapped index of the ket layer
Oct 12, 2026
efe6d1d
Derive default bra names with `derivedname` and validate the name map
Oct 15, 2026
b100b45
Tag a name from `derivedname` with its key
Oct 15, 2026
dbf3ed3
Continue the `QuadraticFormNetwork` error messages with `\` instead o…
Oct 15, 2026
4149ef5
Require a bra name for every link in `NormNetwork` and `QuadraticForm…
Oct 15, 2026
bf38a26
Build the default bra-name maps with `narrow_map`
Oct 15, 2026
5eb87cf
Formatting.
Oct 19, 2026
f9b505f
Bump version to 0.11.2
Oct 19, 2026
608bde6
Minor fixes/improvements.
Oct 19, 2026
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
4 changes: 3 additions & 1 deletion 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.11.1"
version = "0.11.2"
authors = ["ITensor developers <support@itensor.org> and contributors"]

[workspace]
Expand All @@ -23,6 +23,7 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"
TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[weakdeps]
OMEinsumContractionOrders = "6f22d1fd-8eed-4bb7-9776-e7d684900715"
Expand All @@ -48,4 +49,5 @@ Random = "1.10"
SimpleTraits = "0.9.5"
SplitApplyCombine = "1.2.3"
TensorAlgebra = "0.23.1"
UUIDs = "1.10"
julia = "1.10"
4 changes: 2 additions & 2 deletions src/ITensorNetworkGenerators/ising_network.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using ..ITensorNetworksNext
using Graphs: degree, dst, edges, src
using ITensorBase: NamedTensor, name, uniquename
using ITensorBase: NamedTensor, inds, name, uniquename
using LinearAlgebra: Diagonal, eigen
using NamedGraphs: vertextype

Expand Down Expand Up @@ -33,7 +33,7 @@ function ising_network(
fp(e) = get(() -> l̃[reverse(e)], l̃, e)
tn = delta_network(fp, elt, g)
for v in sz_vertices
tn[v] = diagonaltensor(elt[1, -1], axes(tn[v]))
tn[v] = diagonaltensor(elt[1, -1], Tuple(inds(tn, v)))
end

for e in edges(g)
Expand Down
6 changes: 4 additions & 2 deletions src/ITensorNetworksNext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ include("select_algorithm.jl")
include("AlgorithmsInterfaceExtensions/AlgorithmsInterfaceExtensions.jl")
include("abstracttensornetwork.jl")
include("tensornetwork.jl")
include("normnetwork.jl")
include("normnetworkview.jl")
include("itensornetworkoperator.jl")
include("bilinearforms/abstractbilinearformnetwork.jl")
include("bilinearforms/normnetwork.jl")
include("bilinearforms/quadraticformnetwork.jl")
include("ITensorNetworkGenerators/ITensorNetworkGenerators.jl")
include("contraction_tree.jl")
include("prod_tensors.jl")
Expand Down
44 changes: 28 additions & 16 deletions src/abstracttensornetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ using DataGraphs: DataGraphs, AbstractDataGraph, AbstractVertexDataGraph, edge_d
set_vertex_data!, underlying_graph, underlying_graph_type, vertex_data
using Graphs: Graphs, AbstractEdge, AbstractGraph, add_edge!, add_vertex!, dst, edges,
edgetype, ne, neighbors, nv, rem_edge!, src, vertices
using ITensorBase: ITensorOperator, NamedUnitRange, inds, inputnames, name, names, nametype,
prime, uniquename, unnamedtype
using ITensorBase: ITensorBase, ITensorOperator, NamedUnitRange, inds, inputnames, name,
names, nametype, prime, uniquename, unnamedtype
using LinearAlgebra: LinearAlgebra
using MacroTools: @capture
using NamedGraphs:
Expand Down Expand Up @@ -37,57 +37,63 @@ end

# ====================================== interface ======================================= #

ITensorBase.inds(tn::AbstractITensorNetwork, v) = inds(tn[v])
ITensorBase.names(tn::AbstractITensorNetwork, v) = name.(inds(tn, v))

linkinds(tn::AbstractGraph, edge::Pair) = linkinds(tn, edgetype(tn)(edge))
# Pick the link indices from the `src` side, identified by name match with `dst`.
# A range-strict intersection (`inds(src) ∩ inds(dst)`) would drop graded links
# whose two endpoints carry dual-related ranges.
function linkinds(tn::AbstractGraph, edge::AbstractEdge)
ln = linknames(tn, edge)
return [i for i in inds(tn[src(edge)]) if name(i) in ln]
return [i for i in inds(tn, src(edge)) if name(i) in ln]
end

function linkaxes(tn::AbstractGraph, edge::Pair)
return linkaxes(tn, edgetype(tn)(edge))
end
function linkaxes(tn::AbstractGraph, edge::AbstractEdge)
ln = linknames(tn, edge)
return [ax for ax in axes(tn[src(edge)]) if name(ax) in ln]
return [ax for ax in inds(tn, src(edge)) if name(ax) in ln]
end
function linknames(tn::AbstractGraph, edge::Pair)
return linknames(tn, edgetype(tn)(edge))
end
function linknames(tn::AbstractGraph, edge::AbstractEdge)
return names(tn[src(edge)]) ∩ names(tn[dst(edge)])
return names(tn, src(edge)) ∩ names(tn, dst(edge))
end
function linknames(tn::AbstractGraph)
return unique(Iterators.flatten(linknames(tn, e) for e in edges(tn)))
end

function siteinds(tn::AbstractGraph, v)
s = inds(tn[v])
s = inds(tn, v)
for v′ in neighbors(tn, v)
s = setdiff(s, inds(tn[v′]))
s = setdiff(s, inds(tn, v′))
end
return s
end
function siteaxes(tn::AbstractGraph, v)
s = axes(tn[v])
s = Tuple(inds(tn, v))
for v′ in neighbors(tn, v)
s = setdiff(s, axes(tn[v′]))
s = setdiff(s, inds(tn, v′))
end
return s
end
function sitenames(tn::AbstractGraph, v)
s = names(tn[v])
s = names(tn, v)
for v′ in neighbors(tn, v)
s = setdiff(s, names(tn[v′]))
s = setdiff(s, names(tn, v′))
end
return s
end

# Return the non-link vertices associated with an dim name
function dimnamevertices(tn::AbstractGraph, name)
sites = vertextype(tn)[]
sites = Set{vertextype(tn)}()

for v in vertices(tn)
if name ∈ names(tn[v])
if name ∈ names(tn, v)
push!(sites, v)
end
end
Expand All @@ -97,7 +103,7 @@ end

function has_dimname(tn::AbstractGraph, name)
for v in vertices(tn)
if name ∈ names(tn[v])
if name ∈ names(tn, v)
return true
end
end
Expand All @@ -107,7 +113,7 @@ end
has_ind(tn::AbstractGraph, ind) = has_dimname(tn, name(ind))

function insertlink!(tn::AbstractGraph, e)
T = eltype(inds(tn[src(e)]))
T = eltype(inds(tn, src(e)))

linkind = NamedUnitRange(trivialrange(unnamedtype(T)), uniquename(nametype(T)))

Expand All @@ -121,9 +127,15 @@ function insertlink!(tn::AbstractGraph, e)
end

function operator_support(tn::AbstractGraph, op::ITensorOperator)
return operator_support_names(tn, inputnames(op))
end

# Shared with the `ITensorNetworkOperator` method, which is defined alongside that type
# because it is not yet known at this point in the include order.
function operator_support_names(tn::AbstractGraph, opnames)
support = Indices{vertextype(tn)}()

for name in inputnames(op)
for name in opnames
vertices = dimnamevertices(tn, name)

if length(vertices) > 1
Expand Down
12 changes: 9 additions & 3 deletions src/beliefpropagation/beliefpropagation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ factor_tensors(factors, vertex) = [factors[vertex]]
function factor_tensors(factors::NormNetwork, vertex)
return [kettensor(factors, vertex), bratensor(factors, vertex)]
end
function factor_tensors(factors::QuadraticFormNetwork, vertex)
return [
kettensor(factors, vertex), operatortensor(factors, vertex),
bratensor(factors, vertex),
]
end

# Contract the incoming messages into the source factor to form the (unnormalized) new message on
# `edge`.
Expand All @@ -272,9 +278,9 @@ end
# the message is positive semidefinite and its trace is a positive normalization.
function message_update!(algorithm::SimpleMessageUpdate, cache, factors::NormNetwork, edge)
new_tensor = updated_message(algorithm, cache, factors, edge)
new_message = operator(
new_tensor, linknames(BraView(factors), edge), linknames(KetView(factors), edge)
)
branames = linknames(branetwork(factors), edge)
ketnames = linknames(ketnetwork(factors), edge)
new_message = operator(new_tensor, branames, ketnames)
if algorithm.normalize
message_norm = tr(new_message)
iszero(message_norm) || (new_message /= message_norm)
Expand Down
12 changes: 6 additions & 6 deletions src/beliefpropagation/messagecache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,16 @@ bethe_free_energy(factors, messages) = -bethe_free_entropy(factors, messages)
function similar_message_environment(nn::NormNetwork)
messages = mapmany(vertices(nn)) do vertex
return map(in_incident_edges(nn, vertex)) do edge
braview = BraView(nn)
ketview = KetView(nn)
bra = branetwork(nn)
ket = ketnetwork(nn)

ketnames = linknames(ketview, edge)
branames = linknames(braview, edge)
braaxis = unnamed.(linkaxes(braview, edge))
ketnames = linknames(ket, edge)
branames = linknames(bra, edge)
braaxis = unnamed.(linkaxes(bra, edge))

# Bra leg = operator output, ket leg = input, the bipartition in which the message
# is positive semidefinite.
message = similar_operator(ketview[vertex], braaxis, branames, ketnames)
message = similar_operator(ket[vertex], braaxis, branames, ketnames)

return edge => message
end
Expand Down
Loading
Loading