Skip to content

Commit 9aca427

Browse files
authored
Update correlation length normalization (#212)
* Update correlation length normalization * Fix typo * Fix and update tests * Format * Add sectortype/spacetype * Add missing space/sectortypes
1 parent c2a32f2 commit 9aca427

File tree

4 files changed

+55
-11
lines changed

4 files changed

+55
-11
lines changed

src/algorithms/toolbox.jl

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,26 +275,50 @@ in a specific symmetry sector).
275275
MPSKit.correlation_length(state, env::CTMRGEnv; num_vals=2, kwargs...) =
276276
_correlation_length(env; num_vals, kwargs...)
277277
278-
function _correlation_length(env::CTMRGEnv; num_vals=2, kwargs...)
278+
function _correlation_length(
279+
env::CTMRGEnv; num_vals=2, sector=one(sectortype(env)), kwargs...
280+
)
279281
_, n_rows, n_cols = size(env)
280282
281283
# Horizontal
282284
λ_h = map(1:n_rows) do r
283285
above = InfiniteMPS(env.edges[NORTH, r, :])
284286
below = InfiniteMPS(_dag.(env.edges[SOUTH, _next(r, n_rows), :]))
285-
vals = MPSKit.transfer_spectrum(above; below, num_vals, kwargs...)
286-
return vals ./ abs(vals[1]) # normalize largest eigenvalue
287+
vals = MPSKit.transfer_spectrum(above; below, num_vals, sector, kwargs...)
288+
289+
# normalize using largest eigenvalue in trivial sector
290+
if isone(sector)
291+
N = first(vals)
292+
else
293+
vals_triv = MPSKit.transfer_spectrum(above; below, num_vals=1, kwargs...)
294+
N = first(vals_triv)
295+
end
296+
return vals ./ N # normalize largest eigenvalue
287297
end
288-
ξ_h = map(λ -> -1 / log(abs(λ[2])), λ_h)
289298
290299
# Vertical
291300
λ_v = map(1:n_cols) do c
292301
above = InfiniteMPS(env.edges[EAST, :, c])
293302
below = InfiniteMPS(_dag.(env.edges[WEST, :, _next(c, n_cols)]))
294-
vals = MPSKit.transfer_spectrum(above; below, num_vals, kwargs...)
295-
return vals ./ abs(vals[1]) # normalize largest eigenvalue
303+
vals = MPSKit.transfer_spectrum(above; below, num_vals, sector, kwargs...)
304+
305+
# normalize using largest eigenvalue in trivial sector
306+
if isone(sector)
307+
N = first(vals)
308+
else
309+
vals_triv = MPSKit.transfer_spectrum(above; below, num_vals=1, kwargs...)
310+
N = first(vals_triv)
311+
end
312+
return vals ./ N # normalize largest eigenvalue
313+
end
314+
315+
if isone(sector)
316+
ξ_h = map(λ -> -1 / log(abs(λ[2])), λ_h)
317+
ξ_v = map(λ -> -1 / log(abs(λ[2])), λ_v)
318+
else
319+
ξ_h = map(λ -> -1 / log(abs(λ[1])), λ_h)
320+
ξ_v = map(λ -> -1 / log(abs(λ[1])), λ_v)
296321
end
297-
ξ_v = map(λ -> -1 / log(abs(λ[2])), λ_v)
298322
299323
return ξ_h, ξ_v, λ_h, λ_v
300324
end

src/environments/ctmrg_environments.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,16 @@ end
379379
Base.real(env::CTMRGEnv) = CTMRGEnv(real.(env.corners), real.(env.edges))
380380
Base.complex(env::CTMRGEnv) = CTMRGEnv(complex.(env.corners), complex.(env.edges))
381381

382+
cornertype(env::CTMRGEnv) = cornertype(typeof(env))
383+
cornertype(::Type{CTMRGEnv{C,E}}) where {C,E} = C
384+
edgetype(env::CTMRGEnv) = edgetype(typeof(env))
385+
edgetype(::Type{CTMRGEnv{C,E}}) where {C,E} = E
386+
387+
TensorKit.spacetype(env::CTMRGEnv) = spacetype(typeof(env))
388+
TensorKit.spacetype(::Type{E}) where {E<:CTMRGEnv} = spacetype(cornertype(E))
389+
TensorKit.sectortype(env::CTMRGEnv) = sectortype(typeof(env))
390+
TensorKit.sectortype(::Type{E}) where {E<:CTMRGEnv} = sectortype(cornertype(E))
391+
382392
# In-place update of environment
383393
function update!(env::CTMRGEnv{C,T}, env´::CTMRGEnv{C,T}) where {C,T}
384394
env.corners .= env´.corners

src/states/infinitepeps.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ end
139139

140140
## Spaces
141141

142+
TensorKit.sectortype(t::InfinitePEPS) = sectortype(typeof(t))
143+
TensorKit.sectortype(::Type{T}) where {T<:InfinitePEPS} = sectortype(eltype(T))
144+
TensorKit.spacetype(t::InfinitePEPS) = spacetype(typeof(t))
145+
TensorKit.spacetype(::Type{T}) where {T<:InfinitePEPS} = spacetype(eltype(T))
142146
virtualspace(n::InfinitePEPS, r::Int, c::Int, dir) = virtualspace(n[r, c], dir)
143147
physicalspace(n::InfinitePEPS, r::Int, c::Int) = physicalspace(n[r, c])
144148

test/ctmrg/correlation_length.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Test: @test, @testset
2+
using TensorKit
23
using TensorKit: , , SU2Irrep, Vect, permute, truncdim, truncbelow
34
using MPSKit: correlation_length, leading_boundary
45
using PEPSKit: CTMRGEnv, InfinitePEPS
@@ -8,15 +9,15 @@ using PEPSKit: CTMRGEnv, InfinitePEPS
89
vD = Vect[SU2Irrep](1//2 => 1)
910
vd = Vect[SU2Irrep](2 => 1)
1011
tAKLT_A = ones(vd vD vD vD vD)
11-
tAKLT_B = permute(adjoint(tAKLT_A), (5,), (1, 2, 3, 4))
12+
tAKLT_B = permute(adjoint(tAKLT_A), ((5,), (1, 2, 3, 4)))
1213

1314
ψ = InfinitePEPS([tAKLT_A tAKLT_B; tAKLT_B tAKLT_A])
14-
trscheme = truncdim(20) & truncbelow(1e-12)
15-
boundary_alg = (; tol=1e-10, trscheme=trscheme, maxiter=1, verbosity=0)
15+
trscheme = truncbelow(1e-12) & truncdim(48)
16+
boundary_alg = (; tol=1e-10, trscheme=trscheme, maxiter=400, verbosity=3)
1617
env0 = CTMRGEnv(randn, Float64, ψ, oneunit(vD))
1718
env, info_ctmrg = leading_boundary(env0, ψ; boundary_alg...)
1819

19-
ξ_h, ξ_v, λ_h, λ_v = correlation_length(ψ, env)
20+
ξ_h, ξ_v, λ_h, λ_v = correlation_length(ψ, env; sector=SU2Irrep(1))
2021
@test ξ_h isa Vector{Float64}
2122
@test size(ξ_h) == (2,)
2223
@test all(isfinite.(ξ_h))
@@ -26,4 +27,9 @@ using PEPSKit: CTMRGEnv, InfinitePEPS
2627
@test size(ξ_v) == (2,)
2728
@test all(isfinite.(ξ_v))
2829
@test all(ξ_v .> 0)
30+
31+
# AKLT state should have correlation length ~ 2sites
32+
# https://journals.aps.org/prb/abstract/10.1103/PhysRevB.96.121115
33+
@test all(x -> isapprox(x * size(ψ, 2), 2; atol=0.1), ξ_h)
34+
@test all(x -> isapprox(x * size(ψ, 1), 2; atol=0.1), ξ_v)
2935
end

0 commit comments

Comments
 (0)