diff --git a/Project.toml b/Project.toml index 0a8e3193..0df19b54 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ITensorNetworks" uuid = "2919e153-833c-4bdc-8836-1ea460a35fc7" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.15.1" +version = "0.15.2" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/ITensorNetworks.jl b/src/ITensorNetworks.jl index 339e900e..672eec25 100644 --- a/src/ITensorNetworks.jl +++ b/src/ITensorNetworks.jl @@ -65,7 +65,6 @@ include("solvers/operator_map.jl") include("solvers/abstract_problem.jl") include("solvers/eigsolve.jl") include("solvers/applyexp.jl") -include("solvers/fitting.jl") include("apply.jl") include("inner.jl") diff --git a/src/solvers/fitting.jl b/src/solvers/fitting.jl deleted file mode 100644 index ffd127ec..00000000 --- a/src/solvers/fitting.jl +++ /dev/null @@ -1,123 +0,0 @@ -using Graphs: vertices -using NamedGraphs: AbstractNamedGraph, NamedEdge -using NamedGraphs.PartitionedGraphs: partitionedges -using Printf: @printf - -@kwdef mutable struct FittingProblem{State <: AbstractBeliefPropagationCache} <: - AbstractProblem - state::State - ket_graph::AbstractNamedGraph - overlap::Number = 0 - gauge_region -end - -state(F::FittingProblem) = F.state -ket_graph(F::FittingProblem) = F.ket_graph -overlap(F::FittingProblem) = F.overlap -gauge_region(F::FittingProblem) = F.gauge_region - -function ket(F::FittingProblem) - ket_vertices = vertices(ket_graph(F)) - return first(induced_subgraph(tensornetwork(state(F)), ket_vertices)) -end - -function extract!(region_iter::RegionIterator{<:FittingProblem}) - prob = problem(region_iter) - - region = current_region(region_iter) - prev_region = gauge_region(prob) - tn = state(prob) - path = edge_sequence_between_regions(ket_graph(prob), prev_region, region) - tn = gauge_walk(Algorithm("orthogonalize"), tn, path) - pe_path = partitionedges(partitioned_tensornetwork(tn), path) - tn = update( - Algorithm("bp"), tn, pe_path; message_update_function_kwargs = (; normalize = false) - ) - local_tensor = environment(tn, region) - sequence = contraction_sequence(local_tensor; alg = "optimal") - local_tensor = dag(contract(local_tensor; sequence)) - #problem, local_tensor = subspace_expand(problem, local_tensor, region; sweep, kws...) - - prob.state = tn - prob.gauge_region = region - - return region_iter, local_tensor -end - -function update!( - region_iter::RegionIterator{<:FittingProblem}, local_tensor; outputlevel = 0 - ) - F = problem(region_iter) - - region = current_region(region_iter) - - n = (local_tensor * dag(local_tensor))[] - F.overlap = n / sqrt(n) - - if outputlevel >= 2 - @printf(" Region %s: squared overlap = %.12f\n", region, overlap(F)) - end - - return region_iter, local_tensor -end - -function region_plan(F::FittingProblem; nsites, sweep_kwargs...) - return euler_sweep(ket_graph(F); nsites, sweep_kwargs...) -end - -function fit_tensornetwork( - overlap_network, - args...; - nsweeps = 25, - nsites = 1, - outputlevel = 0, - normalize = true, - factorize_kwargs, - extra_sweep_kwargs..., - ) - bpc = BeliefPropagationCache(overlap_network, args...) - ket_graph = first( - induced_subgraph(underlying_graph(overlap_network), ket_vertices(overlap_network)) - ) - init_prob = FittingProblem(; - ket_graph, state = bpc, gauge_region = collect(vertices(ket_graph)) - ) - - insert!_kwargs = (; normalize, set_orthogonal_region = false) - update!_kwargs = (; outputlevel) - - sweep_kwargs = (; nsites, outputlevel, update!_kwargs, insert!_kwargs, factorize_kwargs) - kwargs_array = [(; sweep_kwargs..., extra_sweep_kwargs..., sweep) for sweep in 1:nsweeps] - - sweep_iter = SweepIterator(init_prob, kwargs_array) - converged_prob = problem(sweep_solve!(sweep_iter)) - - return rename_vertices(inv_vertex_map(overlap_network), ket(converged_prob)) -end - -function fit_tensornetwork(tn, init_state, args...; kwargs...) - return fit_tensornetwork(inner_network(tn, init_state), args; kwargs...) -end - -#function truncate(tn; maxdim=default_maxdim(), cutoff=default_cutoff(), kwargs...) -# init_state = ITensorNetwork( -# v -> inds -> delta(inds), siteinds(tn); link_space=maxdim -# ) -# overlap_network = inner_network(tn, init_state) -# insert_kwargs = (; trunc=(; cutoff, maxdim)) -# return fit_tensornetwork(overlap_network; insert_kwargs, kwargs...) -#end - -function ITensors.apply( - A::AbstractITensorNetwork, - x::AbstractITensorNetwork; - maxdim = typemax(Int), - cutoff = 0.0, - sweep_kwargs..., - ) - init_state = ITensorNetwork(v -> inds -> delta(inds), siteinds(x); link_space = maxdim) - overlap_network = inner_network(x, A, init_state) - return fit_tensornetwork( - overlap_network; factorize_kwargs = (; maxdim, cutoff), sweep_kwargs... - ) -end diff --git a/test/runtests.jl b/test/runtests.jl index ef560104..2124a45f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,29 +7,32 @@ const pat = r"(?:--group=)(\w+)" arg_id = findfirst(contains(pat), ARGS) const GROUP = uppercase( if isnothing(arg_id) - get(ENV, "GROUP", "ALL") + arg = get(ENV, "GROUP", "ALL") + # For some reason `ENV["GROUP"]` is set to `""` + # when running via GitHub Actions, so handle that case: + arg == "" ? "ALL" : arg else only(match(pat, ARGS[arg_id]).captures) end, ) "match files of the form `test_*.jl`, but exclude `*setup*.jl`" -function istestfile(fn) +function istestfile(path) + fn = basename(path) return endswith(fn, ".jl") && startswith(basename(fn), "test_") && !contains(fn, "setup") end "match files of the form `*.jl`, but exclude `*_notest.jl` and `*setup*.jl`" -function isexamplefile(fn) +function isexamplefile(path) + fn = basename(path) return endswith(fn, ".jl") && !endswith(fn, "_notest.jl") && !contains(fn, "setup") end @time begin # tests in groups based on folder structure - for testgroup in filter(f -> isdir(joinpath(@__DIR__, f)), readdir(@__DIR__)) - if GROUP == "ALL" || GROUP == uppercase(testgroup) - groupdir = joinpath(@__DIR__, testgroup) - for file in filter(istestfile, readdir(groupdir)) - filename = joinpath(groupdir, file) - @eval @safetestset $file begin + for testgroup in filter(isdir, readdir(@__DIR__; join = true)) + if GROUP == "ALL" || GROUP == uppercase(basename(testgroup)) + for filename in filter(istestfile, readdir(testgroup; join = true)) + @eval @safetestset $(basename(filename)) begin include($filename) end end @@ -37,9 +40,9 @@ end end # single files in top folder - for file in filter(istestfile, readdir(@__DIR__)) - (file == basename(@__FILE__)) && continue # exclude this file to avoid infinite recursion - @eval @safetestset $file begin + for file in filter(istestfile, readdir(@__DIR__; join = true)) + (basename(file) == basename(@__FILE__)) && continue # exclude this file to avoid infinite recursion + @eval @safetestset $(basename(file)) begin include($file) end end diff --git a/test/solvers/test_fitting.jl b/test/solvers/test_fitting.jl deleted file mode 100644 index 593784fd..00000000 --- a/test/solvers/test_fitting.jl +++ /dev/null @@ -1,47 +0,0 @@ -using ITensors: apply, inner -using ITensorNetworks: ITensorNetwork, siteinds, ttn, random_tensornetwork -using ITensorNetworks.ModelHamiltonians: heisenberg -using NamedGraphs.NamedGraphGenerators: named_comb_tree -using Test: @test, @testset -using StableRNGs: StableRNG -using TensorOperations: TensorOperations #For contraction order finding - -@testset "Fitting Tests" begin - for elt in (Float32, Float64, Complex{Float32}, Complex{Float64}) - (outputlevel >= 1) && println("\nFitting tests with elt = ", elt) - g = named_comb_tree((3, 2)) - s = siteinds("S=1/2", g) - - rng = StableRNG(1234) - - ##One-site truncation - #a = random_tensornetwork(rng, elt, s; link_space=3) - #b = truncate(a; maxdim=3) - #f = - # inner(a, b; alg="exact") / - # sqrt(inner(a, a; alg="exact") * inner(b, b; alg="exact")) - #@test abs(abs(f) - 1.0) <= 10*eps(real(elt)) - - ##Two-site truncation - #a = random_tensornetwork(rng, elt, s; link_space=3) - #b = truncate(a; maxdim=3, cutoff=1e-16, nsites=2) - #f = - # inner(a, b; alg="exact") / - # sqrt(inner(a, a; alg="exact") * inner(b, b; alg="exact")) - #@test abs(abs(f) - 1.0) <= 10*eps(real(elt)) - - # #One-site apply (no normalization) - a = random_tensornetwork(rng, elt, s; link_space = 2) - H = ITensorNetwork(ttn(heisenberg(g), s)) - Ha = apply(H, a; maxdim = 4, nsites = 1, normalize = false) - f = inner(Ha, a; alg = "exact") / inner(a, H, a; alg = "exact") - @test abs(f - 1.0) <= 500 * eps(real(elt)) - - # #Two-site apply (no normalization) - a = random_tensornetwork(rng, elt, s; link_space = 2) - H = ITensorNetwork(ttn(heisenberg(g), s)) - Ha = apply(H, a; maxdim = 4, cutoff = 1.0e-16, nsites = 2, normalize = false) - f = inner(Ha, a; alg = "exact") / inner(a, H, a; alg = "exact") - @test abs(f - 1.0) <= 500 * eps(real(elt)) - end -end