From 2dcfe437701883c82646cf981542b84347e70d6f Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Tue, 7 May 2024 15:52:01 -0400 Subject: [PATCH] [ITensors] Delete ITensorNetworkMaps submodule (#1413) --- src/ITensors.jl | 1 - .../src/ITensorNetworkMaps.jl | 138 ------------------ test/lib/ITensorNetworkMaps/Project.toml | 4 - test/lib/ITensorNetworkMaps/runtests.jl | 16 -- .../test_itensornetworkmap.jl | 54 ------- .../utils/TestITensorNetworkMapsUtils.jl | 68 --------- test/runtests.jl | 1 - 7 files changed, 282 deletions(-) delete mode 100644 src/lib/ITensorNetworkMaps/src/ITensorNetworkMaps.jl delete mode 100644 test/lib/ITensorNetworkMaps/Project.toml delete mode 100644 test/lib/ITensorNetworkMaps/runtests.jl delete mode 100644 test/lib/ITensorNetworkMaps/test_itensornetworkmap.jl delete mode 100644 test/lib/ITensorNetworkMaps/utils/TestITensorNetworkMapsUtils.jl diff --git a/src/ITensors.jl b/src/ITensors.jl index 2f7a067197..2ea74b5a9e 100644 --- a/src/ITensors.jl +++ b/src/ITensors.jl @@ -164,7 +164,6 @@ include("lib/ITensorMPS/src/ITensorMPS.jl") include("lib/ITensorsNamedDimsArraysExt/src/ITensorsNamedDimsArraysExt.jl") using .ITensorsNamedDimsArraysExt: ITensorsNamedDimsArraysExt include("../ext/ITensorsChainRulesCoreExt/ITensorsChainRulesCoreExt.jl") -include("lib/ITensorNetworkMaps/src/ITensorNetworkMaps.jl") include("lib/ITensorVisualizationCore/src/ITensorVisualizationCore.jl") # TODO: `using .ITensorVisualizationCore: ITensorVisualizationCore, ...`. using .ITensorVisualizationCore diff --git a/src/lib/ITensorNetworkMaps/src/ITensorNetworkMaps.jl b/src/lib/ITensorNetworkMaps/src/ITensorNetworkMaps.jl deleted file mode 100644 index bdeaf84f5c..0000000000 --- a/src/lib/ITensorNetworkMaps/src/ITensorNetworkMaps.jl +++ /dev/null @@ -1,138 +0,0 @@ -module ITensorNetworkMaps - -using ..ITensors -using LinearMaps - -import ITensors.ITensorMPS: promote_itensor_eltype - -import Base: * - -import ITensors: contract - -export ITensorNetworkMap, input_inds, output_inds - -# convert from Tuple to Vector -tuple_to_vector(t::Tuple) = collect(t) -tuple_to_vector(v::Vector) = v - -function default_input_inds(itensors::Vector{ITensor}) - return filter(i -> plev(i) == 0, noncommoninds(itensors...)) -end - -# Represents the action of applying the -# vector of ITensors to a starting state and then mapping -# them back (from output_inds to input_inds) -struct ITensorNetworkMap{T} <: LinearMap{T} - itensors::Vector{ITensor} - input_inds::Vector{Index} - output_inds::Vector{Index} - function ITensorNetworkMap(itensors::Vector{ITensor}, input_inds, output_inds) - inds_in = tuple_to_vector(input_inds) - inds_out = tuple_to_vector(output_inds) - return new{promote_itensor_eltype(itensors)}(itensors, inds_in, inds_out) - end -end -function ITensorNetworkMap( - itensors::Vector{ITensor}; - input_inds=default_input_inds(itensors), - output_inds=dag(input_inds'), -) - return ITensorNetworkMap(itensors, input_inds, output_inds) -end - -Base.size(T::ITensorNetworkMap) = (dim(output_inds(T)), dim(input_inds(T))) -Base.eltype(T::ITensorNetworkMap) = promote_itensor_eltype(T.itensors) -input_inds(T::ITensorNetworkMap) = T.input_inds -output_inds(T::ITensorNetworkMap) = T.output_inds - -(T::ITensorNetworkMap * v::ITensor) = contract(pushfirst!(copy(T.itensors), v)) -(T::ITensorNetworkMap)(v::ITensor) = replaceinds(T * v, output_inds(T) => input_inds(T)) - -(v::ITensor * T::LinearMap) = transpose(T) * v -contract(T::LinearMap) = T * ITensor(1) - -function Base.transpose(T::ITensorNetworkMap) - return ITensorNetworkMap(reverse(T.itensors), output_inds(T), input_inds(T)) -end - -# This is actually a Hermitian conjugation, not priming -function Base.adjoint(T::ITensorNetworkMap) - return ITensorNetworkMap( - reverse(dag.(T.itensors)), dag(output_inds(T)), dag(input_inds(T)) - ) -end - -function input_inds(A::LinearMaps.LinearCombination) - in_inds = input_inds(A.maps[1]) - @assert all(M -> hassameinds(input_inds(M), in_inds), A.maps) - return in_inds -end -function output_inds(A::LinearMaps.LinearCombination) - out_inds = output_inds(A.maps[1]) - @assert all(M -> hassameinds(output_inds(M), out_inds), A.maps) - return out_inds -end - -function input_inds(A::LinearMaps.CompositeMap) - # TODO: Check it is actually an ITensorNetworkMap - return input_inds(first(A.maps)) -end -function output_inds(A::LinearMaps.CompositeMap) - # TODO: Check it is actually an ITensorNetworkMap - return output_inds(last(A.maps)) -end - -callable(x, y) = x(y) - -apply(f, A::LinearMaps.ScaledMap, v::ITensor) = (A.λ * f(A.lmap, v)) -(A::LinearMaps.ScaledMap)(v::ITensor) = apply(callable, A, v) -(A::LinearMap * v::ITensor) = apply(*, A, v) - -apply(f, A::LinearMaps.UniformScalingMap, v::ITensor) = (A.λ * v) -(A::LinearMaps.UniformScalingMap)(v::ITensor) = apply(callable, A, v) - -function apply(f, A::LinearMaps.LinearCombination, v::ITensor) - N = length(A.maps) - Av = f(A.maps[1], v) - for n in 2:N - Av += f(A.maps[n], v) - end - return Av -end -(A::LinearMaps.LinearCombination)(v::ITensor) = apply(callable, A, v) - -function _replaceinds(::typeof(callable), A::LinearMaps.CompositeMap, v::ITensor) - output_inds_A = output_inds(A) - input_inds_A = input_inds(A) - return replaceinds(v, output_inds_A => input_inds_A) -end -function _replaceinds(::typeof(*), A::LinearMaps.CompositeMap, v::ITensor) - return v -end - -function apply(f, A::LinearMaps.CompositeMap, v::ITensor) - N = length(A.maps) - Av = v - for n in 1:N - Av = A.maps[n] * Av - end - Av = _replaceinds(f, A, Av) - return Av -end -(A::LinearMaps.CompositeMap)(v::ITensor) = apply(callable, A, v) - -function apply(f, A::LinearMaps.BlockMap, v::Vector{ITensor}) - nrows = length(A.rows) - ncols = A.rows[1] - @assert all(==(ncols), A.rows) - M = reshape(collect(A.maps), nrows, ncols) - Av = fill(ITensor(), nrows) - for i in 1:nrows, j in 1:ncols - Av[i] += f(M[i, j], v[j]) - end - return Av -end -(A::LinearMaps.BlockMap)(v::Vector{ITensor}) = apply(callable, A, v) -(A::LinearMaps.BlockMap * v::Vector{ITensor}) = apply(*, A, v) - -end diff --git a/test/lib/ITensorNetworkMaps/Project.toml b/test/lib/ITensorNetworkMaps/Project.toml deleted file mode 100644 index abfe870c91..0000000000 --- a/test/lib/ITensorNetworkMaps/Project.toml +++ /dev/null @@ -1,4 +0,0 @@ -[deps] -ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5" -KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/lib/ITensorNetworkMaps/runtests.jl b/test/lib/ITensorNetworkMaps/runtests.jl deleted file mode 100644 index c2fe5a8b6f..0000000000 --- a/test/lib/ITensorNetworkMaps/runtests.jl +++ /dev/null @@ -1,16 +0,0 @@ -using ITensors -using Test - -ITensors.Strided.disable_threads() -ITensors.BLAS.set_num_threads(1) -ITensors.disable_threaded_blocksparse() - -@testset "$(@__DIR__)" begin - filenames = filter(readdir(@__DIR__)) do f - startswith("test_")(f) && endswith(".jl")(f) - end - @testset "Test $(@__DIR__)/$filename" for filename in filenames - println("Running $(@__DIR__)/$filename") - @time include(filename) - end -end diff --git a/test/lib/ITensorNetworkMaps/test_itensornetworkmap.jl b/test/lib/ITensorNetworkMaps/test_itensornetworkmap.jl deleted file mode 100644 index a9115d1b19..0000000000 --- a/test/lib/ITensorNetworkMaps/test_itensornetworkmap.jl +++ /dev/null @@ -1,54 +0,0 @@ -@eval module $(gensym()) -using Test: @test, @testset -using ITensors: ITensors, dag, prime, randomITensor -using ITensors.ITensorMPS: linkinds -using ITensors.ITensorNetworkMaps: input_inds -using KrylovKit: eigsolve -using LinearAlgebra -using Random: randn! - -include(joinpath(@__DIR__, "utils", "TestITensorNetworkMapsUtils.jl")) -using .TestITensorNetworkMapsUtils: infmps, transfer_matrices, transfer_matrix - -@testset "ITensorNetworkMaps.jl" begin - N = 3 # Number of sites in the unit cell - e⃗ = [n => mod1(n + 1, N) for n in 1:N] - χ⃗ = Dict() - χ⃗[1 => 2] = 3 - χ⃗[2 => 3] = 4 - χ⃗[3 => 1] = 5 - d = 2 - ψ = infmps(N; χ⃗=χ⃗, d=d) - randn!.(ψ.data) - T = transfer_matrix(ψ) - v = randomITensor(input_inds(T)) - Tv_expected = ITensors.contract([v, reverse(ψ)..., prime(linkinds, dag(reverse(ψ)))...]) - T′v_expected = ITensors.contract([v, ψ..., prime(linkinds, dag(ψ))...]) - @test T(v) ≈ Tv_expected - @test (2T)(v) ≈ 2Tv_expected - @test (2T + I)(v) ≈ 2Tv_expected + v - @test (2T + 3I)(v) ≈ 2Tv_expected + 3v - @test (T + T)(v) ≈ 2Tv_expected - @test T'(v) ≈ T′v_expected - @test (T + T')(v) ≈ Tv_expected + T′v_expected - @test (T + T)'(v) ≈ 2T′v_expected - @test all([T T; T T]([v; v]) .≈ [2Tv_expected; 2Tv_expected]) - - T⃗ = transfer_matrices(ψ) - - @test (T⃗[1] * T⃗[2] * T⃗[3])(v) ≈ Tv_expected - @test (T⃗[1] * T⃗[2] * T⃗[3] + 3I)(v) ≈ Tv_expected + 3v - @test (T⃗[1] * T⃗[2] * T⃗[3])'(v) ≈ T′v_expected - @test (I * T⃗[1] * T⃗[2] * T⃗[3])(v) ≈ Tv_expected - @test (2T⃗[1] * T⃗[2] * T⃗[3])(v) ≈ 2Tv_expected - @test (T⃗[1] * T⃗[2] * T⃗[3] + 2I)(v) ≈ Tv_expected + 2v - @test ((T⃗[1] * T⃗[2] + T⃗[1] * T⃗[2]) * T⃗[3])(v) ≈ 2Tv_expected - @test ((T⃗[1] * T⃗[2] + T⃗[1] * T⃗[2]) * T⃗[3])'(v) ≈ 2T′v_expected - @test ((T⃗[1] * T⃗[2] + T⃗[1] * T⃗[2]) * T⃗[3] + 3I)(v) ≈ 2Tv_expected + 3v - - dk, vk = eigsolve(T, v) - for n in 1:length(dk) - @test norm((T - dk[n]I)(vk[n])) ≈ 0 atol = 1e-10 - end -end -end diff --git a/test/lib/ITensorNetworkMaps/utils/TestITensorNetworkMapsUtils.jl b/test/lib/ITensorNetworkMaps/utils/TestITensorNetworkMapsUtils.jl deleted file mode 100644 index 7467cc60cb..0000000000 --- a/test/lib/ITensorNetworkMaps/utils/TestITensorNetworkMapsUtils.jl +++ /dev/null @@ -1,68 +0,0 @@ -module TestITensorNetworkMapsUtils -using ITensors: ITensors, Index, ITensor, commonind, commoninds, dag, prime -using ITensors.ITensorMPS: linkind, linkinds -using ITensors.ITensorNetworkMaps: ITensorNetworkMap - -struct InfTN - data::Vector{ITensor} -end -Base.length(m::InfTN) = length(m.data) -Base.copy(m::InfTN) = InfTN(copy(m.data)) -Base.reverse(m::InfTN) = InfTN(reverse(m.data)) -Base.iterate(m::InfTN, args...) = iterate(m.data, args...) -Base.getindex(m::InfTN, args...) = getindex(m.data, args...) -Base.setindex!(m::InfTN, args...) = setindex!(m.data, args...) - -function infmps(N; χ⃗, d) - n⃗ = 1:N - e⃗ = [n => mod1(n + 1, N) for n in 1:N] - linkindex(χ⃗, e) = Index(χ⃗[e], "l=$(e[1])↔$(e[2])") - l⃗ = Dict([e .=> linkindex(χ⃗, e) for e in e⃗]) - s⃗ = [Index(d, "s=$n") for n in n⃗] - neighbors(n, N) = [mod1(n - 1, N) => n, n => mod1(n + 1, N)] - return InfTN([ITensor(getindex.(Ref(l⃗), neighbors(n, N))..., s⃗[n]) for n in n⃗]) -end - -ITensors.dag(tn::InfTN) = InfTN(dag.(tn.data)) -function ITensors.prime(::typeof(linkinds), tn::InfTN) - tn_p = copy(tn) - N = length(tn) - for i in 1:N, j in (i + 1):N - l = commoninds(tn[i], tn[j]) - tn_p[i] = prime(tn_p[i]; inds=l) - tn_p[j] = prime(tn_p[j]; inds=l) - end - return tn_p -end - -interleave(x::Vector, y::Vector) = Base.permutedims([x y])[:] - -function ITensors.linkind(tn::InfTN, e) - return commonind(tn[e[1]], tn[e[2]]) -end - -function transfer_matrix(ψ::InfTN) - N = length(ψ) - ψ′ = prime(linkinds, dag(ψ)) - tn = interleave(reverse(ψ.data), reverse(ψ′.data)) - right_inds = [linkind(ψ, N => 1), linkind(ψ′, N => 1)] - left_inds = [linkind(ψ, N => 1), linkind(ψ′, N => 1)] - T = ITensorNetworkMap(tn; input_inds=right_inds, output_inds=left_inds) - return T -end - -function transfer_matrices(ψ::InfTN) - N = length(ψ) - ψ′ = prime(linkinds, dag(ψ)) - # Build from individual transfer matrices - T⃗ = Vector{ITensorNetworkMap}(undef, N) - for n in 1:N - n⁺¹ = mod1(n + 1, N) - n⁻¹ = mod1(n - 1, N) - right_inds = [linkind(ψ, n => n⁺¹), linkind(ψ′, n => n⁺¹)] - left_inds = [linkind(ψ, n⁻¹ => n), linkind(ψ′, n⁻¹ => n)] - T⃗[n] = ITensorNetworkMap([ψ[n], ψ′[n]]; input_inds=right_inds, output_inds=left_inds) - end - return T⃗ -end -end diff --git a/test/runtests.jl b/test/runtests.jl index 98ee176326..60782dca54 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -20,7 +20,6 @@ ITensors.disable_threaded_blocksparse() "threading", "lib/ContractionSequenceOptimization", "ext/ITensorsChainRulesCoreExt", - "lib/ITensorNetworkMaps", "ext/ITensorsVectorInterfaceExt", ] @time for dir in dirs