Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
fc3945e
Add gate application via apply_operator / apply_operators
mtfishman May 15, 2026
5f67632
Refine apply_operator/apply_operators design
mtfishman May 15, 2026
6492dac
Split apply_operator into MAK-style bang / non-bang pair
mtfishman May 16, 2026
64dec18
Add cache! kwarg to apply_operators; splat pinv_kwargs
mtfishman May 16, 2026
b08d803
Simplify apply_operator_bp! via Val-dispatched n-site methods
mtfishman May 16, 2026
33c70ba
Inline BP simple-update helpers in apply_operator_bp_nsite!
mtfishman May 16, 2026
cec80c0
Restructure apply_operator(s) around NestedAlgorithm and X*Y≈Z naming
mtfishman May 16, 2026
c08cf1a
Push cache! default into AI.initialize_state; tighten type restrictions
mtfishman May 16, 2026
11aee9f
Implement BP cache initialization; fix apply_operator_bp! vcat and tests
mtfishman May 16, 2026
7eb8ec7
Store sqrt-form BP messages; update cache on each gate
mtfishman May 18, 2026
582e596
Refactor SqrtMessageCache and rename BP gate-application path
mtfishman May 18, 2026
1acc5dd
Drop apply/tensoralgebra.jl; use TensorAlgebra.svd directly
mtfishman May 18, 2026
647784f
Generalize message inversion via SVD-based inv_regularized stack
mtfishman May 18, 2026
f193b3e
Split inv_regularized stand-ins across TA and MAK namespaces
mtfishman May 18, 2026
9ac5233
Skip gauge-out inversion in Val{1} normalize path
mtfishman May 18, 2026
a92d60f
Clean up sqrt-env handling and qr/svd block in apply_gate_bp_nsite!
mtfishman May 18, 2026
4493c17
Use explicit two-arg form for dimnames intersect/setdiff in qr block
mtfishman May 18, 2026
06147f2
Tighten Val{2} qr / svd block in apply_gate_bp_nsite!
mtfishman May 18, 2026
e14d92a
Normalize singular values directly in Val{2} apply_gate_bp_nsite!
mtfishman May 18, 2026
4a37461
Drop redundant `Tuple` wrap in inv_regularized 2-arg overload
mtfishman May 18, 2026
b48d59c
Reuse `sqrt_S_left` for the new (v1, v2) cache message
mtfishman May 19, 2026
f795821
Layer cache init and √S split through `identity_map` / `sqrt_factoriz…
mtfishman May 19, 2026
c73c5f0
Pick per-direction sqrt-S factor for cache writeback
mtfishman May 19, 2026
6fa94fa
Rename SVD factors `U`, `V` to `U_v1`, `U_v2` in Val{2} apply_gate_bp…
mtfishman May 19, 2026
9fa8c6a
Clean up `inv_regularized` / `balanced_eigh_factorization` local stan…
mtfishman May 19, 2026
c5f642a
Refactor Val{2} √S split via sqrt(S, co, dom) + replacedimnames
mtfishman May 19, 2026
8d53557
Refactor initialize_cache to one(similar_operator(...)) form
mtfishman May 19, 2026
59cb2c4
Refactor messagecache.jl: drop `AbstractMessageCache` supertype
mtfishman May 19, 2026
c35f248
Rename local `initialize_subproblem` → `initialize_subsolve`
mtfishman May 19, 2026
008229e
Redesign apply_operator as plain function with strategy dispatch
mtfishman May 20, 2026
0f5de75
Reorganize apply_operators.jl to BP-style high-to-low layering
mtfishman May 20, 2026
75be709
Thread `apply_operator!` through cache + output hooks; bump to 0.4.4
mtfishman May 20, 2026
1749e9a
Rename `ApplyOperators` → `ApplyOperatorsAlgorithm`
mtfishman May 21, 2026
d113763
Compute `inv_sqrt_envs_v[12]` next to the point of use
mtfishman May 21, 2026
f59910b
Push cache resolution into `AI.initialize_state`; drop `default_cache`
mtfishman May 21, 2026
f2b8df8
Require `env_cache!` to be passed; expose `identity_sqrt_messages`
mtfishman May 21, 2026
273dbf5
Rename BP-level kwarg to `sqrt_messages!`; move `identity_sqrt_messages`
mtfishman May 21, 2026
61a9c18
Finalize apply_operator(s) design and gram factorizations
mtfishman May 27, 2026
f51af10
Add environment-preparation hook to apply_operators
mtfishman May 28, 2026
3108aa9
Rename environment-preparation hook, drop unused initialize_state!
mtfishman May 28, 2026
71cc419
Route values into default_algorithm; drop algorithm reconstruction
mtfishman May 28, 2026
55c9877
Lift gram_eigh_full and Base.one of NamedDimsOperator upstream
mtfishman May 28, 2026
f523f64
Inline similar_operator and identity_operator helpers
mtfishman May 28, 2026
9035960
Drop unused identity_messages and its helpers
mtfishman May 28, 2026
fbd8134
Drop pinv kwarg from BPApplyGate
mtfishman May 29, 2026
e57f638
Drop redundant copies on the apply_operators entry path
mtfishman May 30, 2026
0440f06
Drop [sources] pin to merged TensorAlgebra branch, bump compat
mtfishman May 30, 2026
f03382b
Revert MessageCache scaffolding refactor
mtfishman May 30, 2026
eed3bce
Drop [sources] pin to merged NamedDimsArrays branch, bump compat
mtfishman May 30, 2026
37eb68d
Add norm-messagecache constructors
mtfishman May 30, 2026
665431e
Promote beliefpropagation_normnetwork to an API function
mtfishman May 30, 2026
85dab97
Take messages as input to beliefpropagation_normnetwork
mtfishman May 31, 2026
6e68bdd
Relax similar_operator codomain type to any iterable
mtfishman May 31, 2026
834ca22
Clean up normnetwork: comprehensions, no splat, drop g binding
mtfishman May 31, 2026
4d683b8
Consolidate norm-network code; rename operator-init stand-ins
mtfishman May 31, 2026
9b18560
TODO at apply_gate_bp_nsite! env wrap noting replacedimnames blocker
mtfishman May 31, 2026
e39496b
Drop internal-tracker paths from public comments
mtfishman May 31, 2026
befe6b2
Inline _retarget_bra and _wrap_as_norm_operator into the BP wrapper
mtfishman May 31, 2026
f7a3c31
Layered Base.one(::AbstractNamedDimsOperator); drop MAK.one! method
mtfishman May 31, 2026
fe5207c
Add dual stub; move dag stub; use dual for axes in similar_operator
mtfishman May 31, 2026
ff03229
TA-style layered Base.one / one_tensor for AbstractNamedDimsOperator
mtfishman May 31, 2026
94e0b3d
Replace Dict{...,Any} loop with map + Dict(es .=> raws)
mtfishman May 31, 2026
7f07614
Use messagecache(f, edges); drop redundant Tuple wraps
mtfishman May 31, 2026
ce36038
Use the dag stub for the bra layer in normnetwork
mtfishman May 31, 2026
14800a5
Make one_tensor out-of-place; drop one_tensor! variants
mtfishman May 31, 2026
abf453a
Rename Base.one piracy to one_operator; add randn_operator! helper
mtfishman May 31, 2026
15f5430
Add rand_norm_messagecache + rand_operator!; move docstring to rng me…
mtfishman May 31, 2026
e670500
Rename *_norm_messagecache to *_norm_message_env; add norm_message_env
mtfishman May 31, 2026
59cd3fb
Replace `dag` and `dual` stubs with `Base.conj`
mtfishman Jun 2, 2026
b370442
Move local TA/NDA stand-ins upstream; complete BP convention switch
mtfishman Jun 2, 2026
beedf2d
Drop redundant [sources] pins from test/Project.toml
mtfishman Jun 2, 2026
0821a57
Declare BP and apply API public for Documenter
mtfishman Jun 2, 2026
a7dbd89
Detect tensor-network edges by dim name, not full Index
mtfishman Jun 2, 2026
3129e8f
Norm-network BP env: share one bra-name per undirected edge
mtfishman Jun 3, 2026
3cca00f
Use `fill!` and `one(eltype)` for the trivial link tensor in `insert_…
mtfishman Jun 3, 2026
59ce9ee
Convert `import` to `using` for module-as-name imports
mtfishman Jun 3, 2026
570da40
Build trivial link indices via `TensorAlgebra.trivialrange`, rename t…
mtfishman Jun 3, 2026
ac9352e
Add `randlinknames` to refresh every shared link in a tensor network
mtfishman Jun 3, 2026
66032eb
Drop the explainer comment above `randlinknames`
mtfishman Jun 3, 2026
a0adbe6
similar_norm_message_env: opposite-isdual cod on the two edge directions
mtfishman Jun 4, 2026
94af004
Docstrings and a symmetry-looped smoke test for `apply_operator`
mtfishman Jun 4, 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
18 changes: 15 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.4.3"
version = "0.4.4"
authors = ["ITensor developers <support@itensor.org> and contributors"]

[workspace]
Expand All @@ -19,8 +19,10 @@ FunctionImplementations = "7c7cc465-9c6a-495f-bdd1-f42428e86d0c"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
MatrixAlgebraKit = "6c742aac-3347-4629-af66-fc926824e5e4"
NamedDimsArrays = "60cbd0c0-df58-4cb7-918c-6f5607b73fde"
NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"
TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
Expand All @@ -31,6 +33,14 @@ WrappedUnions = "325db55a-9c6c-5b90-b1a2-ec87e7a38c44"
[weakdeps]
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"

[sources.NamedDimsArrays]
rev = "mf/gram-eigh-balanced"
url = "https://github.com/ITensor/NamedDimsArrays.jl"

[sources.TensorAlgebra]
rev = "mf/gram-eigh-balanced"
url = "https://github.com/ITensor/TensorAlgebra.jl"

[extensions]
ITensorNetworksNextTensorOperationsExt = "TensorOperations"

Expand All @@ -47,11 +57,13 @@ FunctionImplementations = "0.4.1"
Graphs = "1.13.1"
LinearAlgebra = "1.10"
MacroTools = "0.5.16"
NamedDimsArrays = "0.14.3, 0.15"
MatrixAlgebraKit = "0.6"
NamedDimsArrays = "0.15.7"
NamedGraphs = "0.11"
Random = "1.10"
SimpleTraits = "0.9.5"
SplitApplyCombine = "1.2.3"
TensorAlgebra = "0.9.2"
TensorAlgebra = "0.9.5"
TensorOperations = "5.3.1"
TermInterface = "2"
TypeParameterAccessors = "0.4.4"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module AlgorithmsInterfaceExtensions

import AlgorithmsInterface as AI
using AlgorithmsInterface: AlgorithmsInterface as AI

# ============================ NestedAlgorithm =============================================

Expand Down Expand Up @@ -52,44 +52,6 @@ function Base.propertynames(state::NestedState)
return (fieldnames(typeof(state))..., :iterate)
end

# ============================ select_algorithm / default_algorithm ========================

# Like `MatrixAlgebraKit.select_algorithm` / `default_algorithm`, but
# selection-relevant inputs are packed into an `args` tuple so the value
# and type domains stay disjoint: `(1.2,)` vs `Tuple{Float64}`. Strategy
# types subtype `AbstractAlgorithm` so the passthrough overload is generic.
abstract type AbstractAlgorithm end

function default_algorithm(f, ::Type{Args}; kwargs...) where {Args <: Tuple}
return throw(MethodError(default_algorithm, (f, Args)))
end
function default_algorithm(f, args::Tuple; kwargs...)
return default_algorithm(f, typeof(args); kwargs...)
end

function select_algorithm(f, alg, args::Tuple; kwargs...)
return select_algorithm(f, alg, typeof(args); kwargs...)
end
function select_algorithm(f, ::Nothing, ::Type{Args}; kwargs...) where {Args <: Tuple}
return default_algorithm(f, Args; kwargs...)
end
function select_algorithm(f, alg::NamedTuple, ::Type{Args}; kwargs...) where {Args <: Tuple}
isempty(kwargs) || throw(
ArgumentError(
"Additional keyword arguments are not allowed when `alg` is a `NamedTuple`."
)
)
return default_algorithm(f, Args; alg...)
end
function select_algorithm(f, alg::AbstractAlgorithm, ::Type{<:Tuple}; kwargs...)
isempty(kwargs) || throw(
ArgumentError(
"Additional keyword arguments are not allowed when `alg` is an `AbstractAlgorithm` instance."
)
)
return alg
end

# ============================ StopWhenConverged ===========================================

# Stopping criterion that fires once `iterate_diff(iterate, previous_iterate) < tol`.
Expand Down
16 changes: 11 additions & 5 deletions src/ITensorNetworksNext.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
module ITensorNetworksNext

# Imported as a name only so that the `[compat] TensorAlgebra = "0.9.2"` floor
# (needed for a `bipermutedimsopadd!` fix in `TensorAlgebra` 0.9.2 that affects
# `NamedDimsArrays`-mediated tensor multiplication) isn't reported as a stale
# dependency by Aqua.
using TensorAlgebra: TensorAlgebra
if VERSION >= v"1.11.0-DEV.469"
eval(
Meta.parse(
"public apply_operator, apply_operators, beliefpropagation_normnetwork, identity_norm_message_env, normnetwork, norm_message_env, ones_norm_message_env, rand_norm_message_env, randn_norm_message_env, similar_norm_message_env"
)
)
end

include("select_algorithm.jl")
include("AlgorithmsInterfaceExtensions/AlgorithmsInterfaceExtensions.jl")
include("LazyNamedDimsArrays/LazyNamedDimsArrays.jl")
include("abstracttensornetwork.jl")
Expand All @@ -15,5 +18,8 @@ include("contract_network.jl")

include("beliefpropagation/messagecache.jl")
include("beliefpropagation/beliefpropagation.jl")
include("beliefpropagation/normnetwork.jl")

include("apply/apply_operators.jl")

end
54 changes: 32 additions & 22 deletions src/abstracttensornetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,20 @@ function Adapt.adapt_structure(to, tn::AbstractTensorNetwork)
end

linkinds(tn::AbstractGraph, edge::Pair) = linkinds(tn, edgetype(tn)(edge))
linkinds(tn::AbstractGraph, edge::AbstractEdge) = inds(tn[src(edge)]) ∩ inds(tn[dst(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]
end

function linkaxes(tn::AbstractGraph, edge::Pair)
return linkaxes(tn, edgetype(tn)(edge))
end
function linkaxes(tn::AbstractGraph, edge::AbstractEdge)
return axes(tn[src(edge)]) ∩ axes(tn[dst(edge)])
ln = linknames(tn, edge)
return [ax for ax in axes(tn[src(edge)]) if name(ax) in ln]
end
function linknames(tn::AbstractGraph, edge::Pair)
return linknames(tn, edgetype(tn)(edge))
Expand Down Expand Up @@ -143,7 +150,7 @@ function add_missing_edges!(tn::AbstractGraph, v)
for v′ in vertices(tn)
if v ≠ v′
e = v => v′
if !isempty(linkinds(tn, e))
if !isempty(linknames(tn, e))
add_edge!(tn, e)
end
end
Expand All @@ -162,37 +169,40 @@ end
function fix_edges!(tn::AbstractGraph, v)
for e in incident_edges(tn, v)
# Remove an edge if there is no index on that edge.
if isempty(linkinds(tn, e))
if isempty(linknames(tn, e))
rem_edge!(tn, e)
end
end
add_missing_edges!(tn, v)
return tn
end

# Customization point.
using NamedDimsArrays: AbstractNamedUnitRange, namedunitrange, nametype, randname
function trivial_unitrange(type::Type{<:AbstractUnitRange})
return Base.oneto(one(eltype(type)))
end
function rand_trivial_namedunitrange(
::Type{<:AbstractNamedUnitRange{<:Any, R, N}}
) where {R, N}
return namedunitrange(trivial_unitrange(R), randname(N))
end

dag(x) = x

function insert_trivial_link!(tn, e)
using NamedDimsArrays: denamedtype, named, nametype, randname
using TensorAlgebra: trivialrange
function insertlink!(tn, e)
add_edge!(tn, e)
l = rand_trivial_namedunitrange(eltype(inds(tn[src(e)])))
x = similar(tn[src(e)], (l,))
x[1] = 1
T = eltype(inds(tn[src(e)]))
l = named(trivialrange(denamedtype(T)), randname(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)] * dag(x)
@preserve_graph tn[dst(e)] = tn[dst(e)] * conj(x)
return tn
end

using NamedDimsArrays: replacedimnames
function randlinknames(tn)
new_tn = copy(tn)
for e in edges(new_tn)
u, v = src(e), dst(e)
for n in intersect(dimnames(new_tn[u]), dimnames(new_tn[v]))
n′ = randname(n)
new_tn[u] = replacedimnames(new_tn[u], n => n′)
new_tn[v] = replacedimnames(new_tn[v], n => n′)
end
end
return new_tn
end

function Base.setindex!(tn::AbstractTensorNetwork, value, v)
@preserve_graph tn[v] = value
fix_edges!(tn, v)
Expand Down
Loading
Loading