diff --git a/Project.toml b/Project.toml index 09ec644b..ef17927d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,10 +1,11 @@ name = "ITensorNetworks" uuid = "2919e153-833c-4bdc-8836-1ea460a35fc7" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.13.17" +version = "0.14.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" DataGraphs = "b5a273c3-7e6c-41f6-98bd-8d7f1525a36a" @@ -33,7 +34,6 @@ TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" [weakdeps] -Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" EinExprs = "b1794770-133b-4de1-afb4-526377e9f4c5" GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" OMEinsumContractionOrders = "6f22d1fd-8eed-4bb7-9776-e7d684900715" @@ -41,7 +41,6 @@ Observers = "338f10d5-c7f1-4033-a7d1-f9dec39bcaa0" TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2" [extensions] -ITensorNetworksAdaptExt = "Adapt" ITensorNetworksEinExprsExt = "EinExprs" ITensorNetworksGraphsFlowsExt = "GraphsFlows" ITensorNetworksOMEinsumContractionOrdersExt = "OMEinsumContractionOrders" @@ -82,7 +81,6 @@ TupleTools = "1.4" julia = "1.10" [extras] -Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" EinExprs = "b1794770-133b-4de1-afb4-526377e9f4c5" GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" OMEinsumContractionOrders = "6f22d1fd-8eed-4bb7-9776-e7d684900715" diff --git a/docs/Project.toml b/docs/Project.toml index 55b577dd..8fbc4729 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -5,5 +5,5 @@ Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" [compat] Documenter = "1.10.0" -ITensorNetworks = "0.13.0" +ITensorNetworks = "0.14.0" Literate = "2.20.1" diff --git a/examples/Project.toml b/examples/Project.toml index f8109c92..a3538ac6 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -2,4 +2,4 @@ ITensorNetworks = "2919e153-833c-4bdc-8836-1ea460a35fc7" [compat] -ITensorNetworks = "0.13.2" +ITensorNetworks = "0.14.0" diff --git a/ext/ITensorNetworksAdaptExt/ITensorNetworksAdaptExt.jl b/ext/ITensorNetworksAdaptExt/ITensorNetworksAdaptExt.jl deleted file mode 100644 index 0051da93..00000000 --- a/ext/ITensorNetworksAdaptExt/ITensorNetworksAdaptExt.jl +++ /dev/null @@ -1,14 +0,0 @@ -module ITensorNetworksAdaptExt -using Adapt: Adapt, adapt -using ITensorNetworks: AbstractITensorNetwork, map_vertex_data_preserve_graph -function Adapt.adapt_structure(to, tn::AbstractITensorNetwork) - # TODO: Define and use: - # - # @preserve_graph map_vertex_data(adapt(to), tn) - # - # or just: - # - # @preserve_graph map(adapt(to), tn) - return map_vertex_data_preserve_graph(adapt(to), tn) -end -end diff --git a/src/abstractitensornetwork.jl b/src/abstractitensornetwork.jl index 96162346..7ce29b54 100644 --- a/src/abstractitensornetwork.jl +++ b/src/abstractitensornetwork.jl @@ -1,3 +1,4 @@ +using Adapt: Adapt, adapt, adapt_structure using DataGraphs: DataGraphs, edge_data, underlying_graph, underlying_graph_type, vertex_data using Dictionaries: Dictionary @@ -86,6 +87,10 @@ function DataGraphs.underlying_graph_type(G::Type{<:AbstractITensorNetwork}) return underlying_graph_type(data_graph_type(G)) end +function ITensors.datatype(tn::AbstractITensorNetwork) + return mapreduce(v -> datatype(tn[v]), promote_type, vertices(tn)) +end + # AbstractDataGraphs overloads function DataGraphs.vertex_data(graph::AbstractITensorNetwork, args...) return vertex_data(data_graph(graph), args...) @@ -102,6 +107,17 @@ function NamedGraphs.ordered_vertices(tn::AbstractITensorNetwork) return NamedGraphs.ordered_vertices(underlying_graph(tn)) end +function Adapt.adapt_structure(to, tn::AbstractITensorNetwork) + # TODO: Define and use: + # + # @preserve_graph map_vertex_data(adapt(to), tn) + # + # or just: + # + # @preserve_graph map(adapt(to), tn) + return map_vertex_data_preserve_graph(adapt(to), tn) +end + # # Iteration # diff --git a/src/caches/abstractbeliefpropagationcache.jl b/src/caches/abstractbeliefpropagationcache.jl index 093acb5c..eadcd295 100644 --- a/src/caches/abstractbeliefpropagationcache.jl +++ b/src/caches/abstractbeliefpropagationcache.jl @@ -1,3 +1,4 @@ +using Adapt: Adapt, adapt, adapt_structure using Graphs: Graphs, IsDirected using SplitApplyCombine: group using LinearAlgebra: diag, dot @@ -24,16 +25,6 @@ function data_graph_type(bpc::AbstractBeliefPropagationCache) end data_graph(bpc::AbstractBeliefPropagationCache) = data_graph(tensornetwork(bpc)) -function default_message_update(contract_list::Vector{ITensor}; normalize=true, kwargs...) - sequence = contraction_sequence(contract_list; alg="optimal") - updated_messages = contract(contract_list; sequence, kwargs...) - message_norm = norm(updated_messages) - if normalize && !iszero(message_norm) - updated_messages /= message_norm - end - return ITensor[updated_messages] -end - #TODO: Take `dot` without precontracting the messages to allow scaling to more complex messages function message_diff(message_a::Vector{ITensor}, message_b::Vector{ITensor}) lhs, rhs = contract(message_a), contract(message_b) @@ -41,7 +32,13 @@ function message_diff(message_a::Vector{ITensor}, message_b::Vector{ITensor}) return 1 - f end -default_message(elt, inds_e) = ITensor[denseblocks(delta(elt, i)) for i in inds_e] +function default_message(datatype::Type{<:AbstractArray}, inds_e) + return [adapt(datatype, denseblocks(delta(i))) for i in inds_e] +end + +function default_message(elt::Type{<:Number}, inds_e) + return default_message(Vector{elt}, inds_e) +end default_messages(ptn::PartitionedGraph) = Dictionary() @traitfn default_bp_maxiter(g::::(!IsDirected)) = is_tree(g) ? 1 : nothing @traitfn function default_bp_maxiter(g::::IsDirected) @@ -59,15 +56,13 @@ function default_message( ) return not_implemented() end +default_update_alg(bpc::AbstractBeliefPropagationCache) = not_implemented() default_message_update_alg(bpc::AbstractBeliefPropagationCache) = not_implemented() Base.copy(bpc::AbstractBeliefPropagationCache) = not_implemented() default_bp_maxiter(alg::Algorithm, bpc::AbstractBeliefPropagationCache) = not_implemented() function default_edge_sequence(alg::Algorithm, bpc::AbstractBeliefPropagationCache) return not_implemented() end -function default_message_update_kwargs(alg::Algorithm, bpc::AbstractBeliefPropagationCache) - return not_implemented() -end function environment(bpc::AbstractBeliefPropagationCache, verts::Vector; kwargs...) return not_implemented() end @@ -80,21 +75,8 @@ end partitions(bpc::AbstractBeliefPropagationCache) = not_implemented() PartitionedGraphs.partitionedges(bpc::AbstractBeliefPropagationCache) = not_implemented() -function default_edge_sequence( - bpc::AbstractBeliefPropagationCache; alg=default_message_update_alg(bpc) -) - return default_edge_sequence(Algorithm(alg), bpc) -end -function default_bp_maxiter( - bpc::AbstractBeliefPropagationCache; alg=default_message_update_alg(bpc) -) - return default_bp_maxiter(Algorithm(alg), bpc) -end -function default_message_update_kwargs( - bpc::AbstractBeliefPropagationCache; alg=default_message_update_alg(bpc) -) - return default_message_update_kwargs(Algorithm(alg), bpc) -end +default_bp_edge_sequence(bpc::AbstractBeliefPropagationCache) = not_implemented() +default_bp_maxiter(bpc::AbstractBeliefPropagationCache) = not_implemented() function tensornetwork(bpc::AbstractBeliefPropagationCache) return unpartitioned_graph(partitioned_tensornetwork(bpc)) @@ -144,6 +126,36 @@ function incoming_messages( return incoming_messages(bpc, [partition_vertex]; kwargs...) end +#Adapt interface for changing device +function map_messages( + f, bpc::AbstractBeliefPropagationCache, pes=collect(keys(messages(bpc))) +) + bpc = copy(bpc) + for pe in pes + set_message!(bpc, pe, f.(message(bpc, pe))) + end + return bpc +end +function map_factors(f, bpc::AbstractBeliefPropagationCache, vs=vertices(bpc)) + bpc = copy(bpc) + for v in vs + @preserve_graph bpc[v] = f(bpc[v]) + end + return bpc +end +function adapt_messages(to, bpc::AbstractBeliefPropagationCache, args...) + return map_messages(adapt(to), bpc, args...) +end +function adapt_factors(to, bpc::AbstractBeliefPropagationCache, args...) + return map_factors(adapt(to), bpc, args...) +end + +function Adapt.adapt_structure(to, bpc::AbstractBeliefPropagationCache) + bpc = adapt_messages(to, bpc) + bpc = adapt_factors(to, bpc) + return bpc +end + #Forward from partitioned graph for f in [ :(PartitionedGraphs.partitioned_graph), @@ -234,44 +246,63 @@ function delete_message(bpc::AbstractBeliefPropagationCache, pe::PartitionEdge) return delete_messages(bpc, [pe]) end -""" -Compute message tensor as product of incoming mts and local state -""" function updated_message( - bpc::AbstractBeliefPropagationCache, - edge::PartitionEdge; - message_update_function=default_message_update, - message_update_function_kwargs=(;), + alg::Algorithm"contract", bpc::AbstractBeliefPropagationCache, edge::PartitionEdge ) vertex = src(edge) incoming_ms = incoming_messages(bpc, vertex; ignore_edges=PartitionEdge[reverse(edge)]) state = factors(bpc, vertex) + contract_list = ITensor[incoming_ms; state] + sequence = contraction_sequence(contract_list; alg=alg.kwargs.sequence_alg) + updated_messages = contract(contract_list; sequence) + message_norm = norm(updated_messages) + if alg.kwargs.normalize && !iszero(message_norm) + updated_messages /= message_norm + end + return ITensor[updated_messages] +end - return message_update_function( - ITensor[incoming_ms; state]; message_update_function_kwargs... +function updated_message( + alg::Algorithm"adapt_update", bpc::AbstractBeliefPropagationCache, edge::PartitionEdge +) + incoming_pes = setdiff( + boundary_partitionedges(bpc, [src(edge)]; dir=:in), [reverse(edge)] ) + adapted_bpc = adapt_messages(alg.kwargs.adapt, bpc, incoming_pes) + adapted_bpc = adapt_factors(alg.kwargs.adapt, bpc, vertices(bpc, src(edge))) + updated_messages = updated_message(alg.kwargs.alg, adapted_bpc, edge) + dtype = mapreduce(datatype, promote_type, message(bpc, edge)) + return map(adapt(dtype), updated_messages) +end + +function updated_message( + bpc::AbstractBeliefPropagationCache, + edge::PartitionEdge; + alg=default_message_update_alg(bpc), + kwargs..., +) + return updated_message(set_default_kwargs(Algorithm(alg; kwargs...)), bpc, edge) end -function update( - alg::Algorithm"bp", bpc::AbstractBeliefPropagationCache, edge::PartitionEdge; kwargs... +function update_message( + message_update_alg::Algorithm, bpc::AbstractBeliefPropagationCache, edge::PartitionEdge ) - return set_message(bpc, edge, updated_message(bpc, edge; kwargs...)) + return set_message(bpc, edge, updated_message(message_update_alg, bpc, edge)) end """ Do a sequential update of the message tensors on `edges` """ -function update( - alg::Algorithm, +function update_iteration( + alg::Algorithm"bp", bpc::AbstractBeliefPropagationCache, edges::Vector; (update_diff!)=nothing, - kwargs..., ) bpc = copy(bpc) for e in edges prev_message = !isnothing(update_diff!) ? message(bpc, e) : nothing - bpc = update(alg, bpc, e; kwargs...) + bpc = update_message(alg.kwargs.message_update_alg, bpc, e) if !isnothing(update_diff!) update_diff![] += message_diff(message(bpc, e), prev_message) end @@ -284,15 +315,15 @@ Do parallel updates between groups of edges of all message tensors Currently we send the full message tensor data struct to update for each edge_group. But really we only need the mts relevant to that group. """ -function update( - alg::Algorithm, +function update_iteration( + alg::Algorithm"bp", bpc::AbstractBeliefPropagationCache, edge_groups::Vector{<:Vector{<:PartitionEdge}}; - kwargs..., + (update_diff!)=nothing, ) new_mts = empty(messages(bpc)) for edges in edge_groups - bpc_t = update(alg, bpc, edges; kwargs...) + bpc_t = update_iteration(alg.kwargs.message_update_alg, bpc, edges; (update_diff!)) for e in edges set!(new_mts, e, message(bpc_t, e)) end @@ -303,24 +334,16 @@ end """ More generic interface for update, with default params """ -function update( - alg::Algorithm, - bpc::AbstractBeliefPropagationCache; - edges=default_edge_sequence(alg, bpc), - maxiter=default_bp_maxiter(alg, bpc), - message_update_kwargs=default_message_update_kwargs(alg, bpc), - tol=nothing, - verbose=false, -) - compute_error = !isnothing(tol) - if isnothing(maxiter) +function update(alg::Algorithm"bp", bpc::AbstractBeliefPropagationCache) + compute_error = !isnothing(alg.kwargs.tol) + if isnothing(alg.kwargs.maxiter) error("You need to specify a number of iterations for BP!") end - for i in 1:maxiter + for i in 1:alg.kwargs.maxiter diff = compute_error ? Ref(0.0) : nothing - bpc = update(alg, bpc, edges; (update_diff!)=diff, message_update_kwargs...) - if compute_error && (diff.x / length(edges)) <= tol - if verbose + bpc = update_iteration(alg, bpc, alg.kwargs.edge_sequence; (update_diff!)=diff) + if compute_error && (diff.x / length(alg.kwargs.edge_sequence)) <= alg.kwargs.tol + if alg.kwargs.verbose println("BP converged to desired precision after $i iterations.") end break @@ -329,12 +352,8 @@ function update( return bpc end -function update( - bpc::AbstractBeliefPropagationCache; - alg::String=default_message_update_alg(bpc), - kwargs..., -) - return update(Algorithm(alg), bpc; kwargs...) +function update(bpc::AbstractBeliefPropagationCache; alg=default_update_alg(bpc), kwargs...) + return update(set_default_kwargs(Algorithm(alg; kwargs...), bpc), bpc) end function rescale_messages( diff --git a/src/caches/beliefpropagationcache.jl b/src/caches/beliefpropagationcache.jl index 8e4ace5e..9444ddc5 100644 --- a/src/caches/beliefpropagationcache.jl +++ b/src/caches/beliefpropagationcache.jl @@ -14,7 +14,7 @@ using NamedGraphs.PartitionedGraphs: unpartitioned_graph, which_partition using SimpleTraits: SimpleTraits, Not, @traitfn -using NDTensors: NDTensors +using NDTensors: NDTensors, Algorithm function default_cache_construction_kwargs(alg::Algorithm"bp", ψ::AbstractITensorNetwork) return (; partitioned_vertices=default_partitioned_vertices(ψ)) @@ -51,7 +51,6 @@ end function cache(alg::Algorithm"bp", tn; kwargs...) return BeliefPropagationCache(tn; kwargs...) end -default_cache_update_kwargs(alg::Algorithm"bp") = (; maxiter=25, tol=1e-8) function partitioned_tensornetwork(bp_cache::BeliefPropagationCache) return bp_cache.partitioned_tensornetwork @@ -60,7 +59,7 @@ end messages(bp_cache::BeliefPropagationCache) = bp_cache.messages function default_message(bp_cache::BeliefPropagationCache, edge::PartitionEdge) - return default_message(scalartype(bp_cache), linkinds(bp_cache, edge)) + return default_message(datatype(bp_cache), linkinds(bp_cache, edge)) end function Base.copy(bp_cache::BeliefPropagationCache) @@ -69,19 +68,38 @@ function Base.copy(bp_cache::BeliefPropagationCache) ) end -default_message_update_alg(bp_cache::BeliefPropagationCache) = "bp" +default_update_alg(bp_cache::BeliefPropagationCache) = "bp" +default_message_update_alg(bp_cache::BeliefPropagationCache) = "contract" +default_normalize(::Algorithm"contract") = true +default_sequence_alg(::Algorithm"contract") = "optimal" +function set_default_kwargs(alg::Algorithm"contract") + normalize = get(alg.kwargs, :normalize, default_normalize(alg)) + sequence_alg = get(alg.kwargs, :sequence_alg, default_sequence_alg(alg)) + return Algorithm("contract"; normalize, sequence_alg) +end +function set_default_kwargs(alg::Algorithm"adapt_update") + _alg = set_default_kwargs(get(alg.kwargs, :alg, Algorithm("contract"))) + return Algorithm("adapt_update"; adapt=alg.kwargs.adapt, alg=_alg) +end +default_verbose(::Algorithm"bp") = false +default_tol(::Algorithm"bp") = nothing +function set_default_kwargs(alg::Algorithm"bp", bp_cache::BeliefPropagationCache) + verbose = get(alg.kwargs, :verbose, default_verbose(alg)) + maxiter = get(alg.kwargs, :maxiter, default_bp_maxiter(bp_cache)) + edge_sequence = get(alg.kwargs, :edge_sequence, default_bp_edge_sequence(bp_cache)) + tol = get(alg.kwargs, :tol, default_tol(alg)) + message_update_alg = set_default_kwargs( + get(alg.kwargs, :message_update_alg, Algorithm(default_message_update_alg(bp_cache))) + ) + return Algorithm("bp"; verbose, maxiter, edge_sequence, tol, message_update_alg) +end -function default_bp_maxiter(alg::Algorithm"bp", bp_cache::BeliefPropagationCache) +function default_bp_maxiter(bp_cache::BeliefPropagationCache) return default_bp_maxiter(partitioned_graph(bp_cache)) end -function default_edge_sequence(alg::Algorithm"bp", bp_cache::BeliefPropagationCache) +function default_bp_edge_sequence(bp_cache::BeliefPropagationCache) return default_edge_sequence(partitioned_tensornetwork(bp_cache)) end -function default_message_update_kwargs( - alg::Algorithm"bp", bpc::AbstractBeliefPropagationCache -) - return (;) -end Base.setindex!(bpc::BeliefPropagationCache, factor::ITensor, vertex) = not_implemented() partitions(bpc::BeliefPropagationCache) = partitionvertices(partitioned_tensornetwork(bpc)) diff --git a/src/contract.jl b/src/contract.jl index 3fe8a915..34d03728 100644 --- a/src/contract.jl +++ b/src/contract.jl @@ -53,7 +53,7 @@ function logscalar( (cache!)=nothing, cache_construction_kwargs=default_cache_construction_kwargs(alg, tn), update_cache=isnothing(cache!), - cache_update_kwargs=default_cache_update_kwargs(alg), + cache_update_kwargs=(;), ) if isnothing(cache!) cache! = Ref(cache(alg, tn; cache_construction_kwargs...)) diff --git a/src/environment.jl b/src/environment.jl index cec13f21..b5f8b178 100644 --- a/src/environment.jl +++ b/src/environment.jl @@ -25,7 +25,7 @@ function environment( (cache!)=nothing, update_cache=isnothing(cache!), cache_construction_kwargs=default_cache_construction_kwargs(alg, ptn), - cache_update_kwargs=default_cache_update_kwargs(alg), + cache_update_kwargs=(;), ) if isnothing(cache!) cache! = Ref(cache(alg, ptn; cache_construction_kwargs...)) diff --git a/src/expect.jl b/src/expect.jl index 47636d73..142ea61a 100644 --- a/src/expect.jl +++ b/src/expect.jl @@ -25,7 +25,7 @@ function expect( ops; (cache!)=nothing, update_cache=isnothing(cache!), - cache_update_kwargs=default_cache_update_kwargs(alg), + cache_update_kwargs=(;), cache_construction_kwargs=(;), kwargs..., ) diff --git a/src/formnetworks/bilinearformnetwork.jl b/src/formnetworks/bilinearformnetwork.jl index 7d662162..d34bd58d 100644 --- a/src/formnetworks/bilinearformnetwork.jl +++ b/src/formnetworks/bilinearformnetwork.jl @@ -1,5 +1,6 @@ +using Adapt: adapt using ITensors: ITensor, Op, prime, sim -using ITensors.NDTensors: denseblocks +using ITensors.NDTensors: datatype, denseblocks default_dual_site_index_map = prime default_dual_link_index_map = sim @@ -76,6 +77,7 @@ function BilinearFormNetwork( O = ITensorNetwork(operator_inds; link_space) do v return inds -> itensor_identity_map(scalartype(ket), s[v] .=> s_mapped[v]) end + O = adapt(promote_type(datatype(bra), datatype(ket)), O) return BilinearFormNetwork(O, bra, ket; dual_site_index_map, kwargs...) end diff --git a/src/gauging.jl b/src/gauging.jl index 7a1f2e73..d51842d9 100644 --- a/src/gauging.jl +++ b/src/gauging.jl @@ -128,7 +128,7 @@ function VidalITensorNetwork( ψ::ITensorNetwork; (cache!)=nothing, update_cache=isnothing(cache!), - cache_update_kwargs=default_cache_update_kwargs(Algorithm("bp")), + cache_update_kwargs=(;), kwargs..., ) if isnothing(cache!) diff --git a/src/normalize.jl b/src/normalize.jl index 3612ca29..c9dc4a9a 100644 --- a/src/normalize.jl +++ b/src/normalize.jl @@ -19,7 +19,7 @@ function rescale( (cache!)=nothing, cache_construction_kwargs=default_cache_construction_kwargs(alg, tn), update_cache=isnothing(cache!), - cache_update_kwargs=default_cache_update_kwargs(alg), + cache_update_kwargs=(;), kwargs..., ) if isnothing(cache!) @@ -56,7 +56,7 @@ function LinearAlgebra.normalize( cache_construction_function=tn -> cache(alg, tn; default_cache_construction_kwargs(alg, tn)...), update_cache=isnothing(cache!), - cache_update_kwargs=default_cache_update_kwargs(alg), + cache_update_kwargs=(;), cache_construction_kwargs=(;), ) norm_tn = inner_network(tn, tn) diff --git a/test/Project.toml b/test/Project.toml index 858ce24a..2dc51a5d 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -44,7 +44,7 @@ Glob = "1.3.1" Graphs = "1.12.0" GraphsFlows = "0.1.1" ITensorMPS = "0.3.6" -ITensorNetworks = "0.13.0" +ITensorNetworks = "0.14.0" ITensors = "0.7, 0.8, 0.9" KrylovKit = "0.8, 0.9, 0.10" LinearAlgebra = "1.10.0" diff --git a/test/test_apply.jl b/test/test_apply.jl index 92793a28..d7f0d85e 100644 --- a/test/test_apply.jl +++ b/test/test_apply.jl @@ -11,7 +11,7 @@ using ITensorNetworks: random_tensornetwork, siteinds, update -using ITensors: ITensors, ITensor, inner, op +using ITensors: ITensors, ITensor, Algorithm, inner, op using NamedGraphs.NamedGraphGenerators: named_grid using NamedGraphs.PartitionedGraphs: PartitionVertex using SplitApplyCombine: group @@ -32,7 +32,7 @@ using Test: @test, @testset bp_cache = BeliefPropagationCache(ψψ, group(v -> v[1], vertices(ψψ))) bp_cache = update(bp_cache; maxiter=20) envsSBP = environment(bp_cache, [(v1, "bra"), (v1, "ket"), (v2, "bra"), (v2, "ket")]) - ψv = VidalITensorNetwork(ψ) + ψv = VidalITensorNetwork(ψ; cache_update_kwargs=(; maxiter=20)) #This grouping will correspond to calculating the environments exactly (each column of the grid is a partition) bp_cache = BeliefPropagationCache(ψψ, group(v -> v[1][1], vertices(ψψ))) bp_cache = update(bp_cache; maxiter=20) diff --git a/test/test_belief_propagation.jl b/test/test_belief_propagation.jl index bfe67da5..3aa55ed4 100644 --- a/test/test_belief_propagation.jl +++ b/test/test_belief_propagation.jl @@ -25,7 +25,8 @@ using ITensorNetworks: update_factor, updated_message, message_diff -using ITensors: ITensors, ITensor, combiner, dag, inds, inner, op, prime, random_itensor +using ITensors: + ITensors, ITensor, Algorithm, combiner, dag, inds, inner, op, prime, random_itensor using ITensorNetworks.ModelNetworks: ModelNetworks using ITensors.NDTensors: array using LinearAlgebra: eigvals, tr @@ -62,7 +63,7 @@ using Test: @test, @testset @test bpc[vket] == new_A @test bpc[vbra] == new_A_dag - bpc = update(bpc; maxiter=25, tol=eps(real(elt))) + bpc = update(bpc; alg="bp", maxiter=25, tol=eps(real(elt))) #Test messages are converged for pe in partitionedges(bpc) @test message_diff(updated_message(bpc, pe), message(bpc, pe)) < 10 * eps(real(elt)) diff --git a/test/test_expect.jl b/test/test_expect.jl index f3b8c869..92579434 100644 --- a/test/test_expect.jl +++ b/test/test_expect.jl @@ -36,7 +36,9 @@ using Test: @test, @testset cache_construction_kwargs = (; partitioned_vertices=group(v -> first(first(v)), quadratic_form_vertices) ) - sz_bp = expect(ψ, "Sz"; alg="bp", cache_construction_kwargs) + sz_bp = expect( + ψ, "Sz"; alg="bp", cache_construction_kwargs, cache_update_kwargs=(; maxiter=20) + ) sz_exact = expect(ψ, "Sz"; alg="exact") @test sz_bp ≈ sz_exact @@ -47,7 +49,7 @@ using Test: @test, @testset ψ = ITensorNetwork(v -> isodd(sum(v)) ? "↑" : "↓", s) - sz_bp = expect(ψ, "Sz"; alg="bp") + sz_bp = expect(ψ, "Sz"; alg="bp", cache_update_kwargs=(; maxiter=20)) sz_exact = expect(ψ, "Sz"; alg="exact") @test sz_bp ≈ sz_exact end diff --git a/test/test_gauging.jl b/test/test_gauging.jl index b56f1b93..a9906465 100644 --- a/test/test_gauging.jl +++ b/test/test_gauging.jl @@ -10,7 +10,7 @@ using ITensorNetworks: siteinds, update using ITensors: diag_itensor, inds, inner -using ITensors.NDTensors: vector +using ITensors.NDTensors: Algorithm, vector using LinearAlgebra: diag using NamedGraphs.NamedGraphGenerators: named_grid using StableRNGs: StableRNG @@ -28,7 +28,9 @@ using Test: @test, @testset ψ = random_tensornetwork(rng, s; link_space=χ) # Move directly to vidal gauge - ψ_vidal = VidalITensorNetwork(ψ; cache_update_kwargs=(; maxiter=30, verbose=true)) + ψ_vidal = VidalITensorNetwork( + ψ; cache_update_kwargs=(; alg="bp", maxiter=30, verbose=true) + ) @test gauge_error(ψ_vidal) < 1e-8 # Move to symmetric gauge @@ -37,7 +39,9 @@ using Test: @test, @testset bp_cache = cache_ref[] # Test we just did a gauge transform and didn't change the overall network - @test inner(ψ_symm, ψ) / sqrt(inner(ψ_symm, ψ_symm) * inner(ψ, ψ)) ≈ 1.0 atol = 1e-8 + @test inner(ψ_symm, ψ; alg="exact") / + sqrt(inner(ψ_symm, ψ_symm; alg="exact") * inner(ψ, ψ; alg="exact")) ≈ 1.0 atol = + 1e-8 #Test all message tensors are approximately diagonal even when we keep running BP bp_cache = update(bp_cache; maxiter=10) diff --git a/test/test_normalize.jl b/test/test_normalize.jl index 1c30c20c..955ef285 100644 --- a/test/test_normalize.jl +++ b/test/test_normalize.jl @@ -29,7 +29,7 @@ using Test: @test, @testset tn_r = rescale(tn; alg="exact") @test scalar(tn_r; alg="exact") ≈ 1.0 - tn_r = rescale(tn; alg="bp") + tn_r = rescale(tn; alg="bp", cache_update_kwargs=(; maxiter=20)) @test scalar(tn_r; alg="exact") ≈ 1.0 #Now a state on a loopy graph @@ -45,10 +45,12 @@ using Test: @test, @testset @test scalar(norm_sqr_network(ψ); alg="exact") ≈ 1.0 ψIψ_bpc = Ref(BeliefPropagationCache(QuadraticFormNetwork(x))) - ψ = normalize(x; alg="bp", (cache!)=ψIψ_bpc, update_cache=true) + ψ = normalize( + x; alg="bp", (cache!)=ψIψ_bpc, update_cache=true, cache_update_kwargs=(; maxiter=20) + ) ψIψ_bpc = ψIψ_bpc[] @test all(x -> x ≈ 1.0, edge_scalars(ψIψ_bpc)) @test all(x -> x ≈ 1.0, vertex_scalars(ψIψ_bpc)) - @test scalar(QuadraticFormNetwork(ψ); alg="bp") ≈ 1.0 + @test scalar(QuadraticFormNetwork(ψ); alg="bp", cache_update_kwargs=(; maxiter=20)) ≈ 1.0 end end