Skip to content

Commit

Permalink
Merge pull request #90 from QuantumKitHub/pb-improve-sequential
Browse files Browse the repository at this point in the history
Make `:sequential` act column-wise
  • Loading branch information
pbrehmer authored Dec 5, 2024
2 parents 36973e7 + 9532507 commit e2545a3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 57 deletions.
8 changes: 4 additions & 4 deletions src/algorithms/contractions/ctmrg_contractions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ Apply bottom projector to southwest corner and south edge.
function renormalize_bottom_corner((row, col), envs::CTMRGEnv, projectors)
C_southwest = envs.corners[SOUTHWEST, row, _prev(col, end)]
E_south = envs.edges[SOUTH, row, col]
P_bottom = projectors[1][row, col]
P_bottom = projectors[1][row]
return @autoopt @tensor corner[χ_in; χ_out] :=
E_south[χ_in D1 D2; χ1] * C_southwest[χ1; χ2] * P_bottom[χ2 D1 D2; χ_out]
end
Expand All @@ -549,7 +549,7 @@ Apply top projector to northwest corner and north edge.
function renormalize_top_corner((row, col), envs::CTMRGEnv, projectors)
C_northwest = envs.corners[NORTHWEST, row, _prev(col, end)]
E_north = envs.edges[NORTH, row, col]
P_top = projectors[2][_next(row, end), col]
P_top = projectors[2][_next(row, end)]
return @autoopt @tensor corner[χ_in; χ_out] :=
P_top[χ_in; χ1 D1 D2] * C_northwest[χ1; χ2] * E_north[χ2 D1 D2; χ_out]
end
Expand Down Expand Up @@ -705,8 +705,8 @@ function renormalize_west_edge( # For sequential CTMRG scheme
)
return renormalize_west_edge(
envs.edges[WEST, row, _prev(col, end)],
projectors[1][row, col],
projectors[2][_next(row, end), col],
projectors[1][row],
projectors[2][_next(row, end)],
ket[row, col],
bra[row, col],
)
Expand Down
94 changes: 42 additions & 52 deletions src/algorithms/ctmrg/ctmrg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,24 @@ end
ctmrg_iter(state, envs::CTMRGEnv, alg::CTMRG) -> envs′, info
Perform one iteration of CTMRG that maps the `state` and `envs` to a new environment,
and also returns the truncation error.
and also returns the `info` `NamedTuple`.
"""
function ctmrg_iter(state, envs::CTMRGEnv, alg::SequentialCTMRG)
ϵ = zero(real(scalartype(state)))
for _ in 1:4
# left move
enlarged_envs = ctmrg_expand(state, envs, alg)
projectors, info = ctmrg_projectors(enlarged_envs, envs, alg)
envs = ctmrg_renormalize(projectors, state, envs, alg)

# rotate
for _ in 1:4 # rotate
for col in 1:size(state, 2) # left move column-wise
projectors, info = ctmrg_projectors(col, state, envs, alg)
envs = ctmrg_renormalize(col, projectors, state, envs, alg)
ϵ = max(ϵ, info.err)
end
state = rotate_north(state, EAST)
envs = rotate_north(envs, EAST)
ϵ = max(ϵ, info.err)
end

return envs, (; err=ϵ)
end
function ctmrg_iter(state, envs::CTMRGEnv, alg::SimultaneousCTMRG)
enlarged_envs = ctmrg_expand(state, envs, alg)
enlarged_envs = ctmrg_expand(eachcoordinate(state, 1:4), state, envs)
projectors, info = ctmrg_projectors(enlarged_envs, envs, alg)
envs′ = ctmrg_renormalize(enlarged_envs, projectors, state, envs, alg)
return envs′, info
Expand All @@ -177,21 +175,11 @@ ctmrg_logcancel!(log, iter, η, N) = @warnv 1 logcancel!(log, iter, η, N)
# ======================================================================================== #

"""
ctmrg_expand(state, envs, alg::CTMRG{M})
ctmrg_expand(coordinates, state, envs)
Expand the environment by absorbing a new PEPS tensor.
There are two modes of expansion: `M = :sequential` and `M = :simultaneous`.
The first mode expands the environment in one direction at a time, for convenience towards
the left. The second mode expands the environment in all four directions simultaneously.
Expand the environment by absorbing a new PEPS tensor on the given coordinates.
"""
function ctmrg_expand(state, envs::CTMRGEnv, ::SequentialCTMRG)
return ctmrg_expand([4, 1], state, envs)
end
function ctmrg_expand(state, envs::CTMRGEnv, ::SimultaneousCTMRG)
return ctmrg_expand(1:4, state, envs)
end
function ctmrg_expand(dirs, state, envs::CTMRGEnv)
coordinates = eachcoordinate(state, dirs)
function ctmrg_expand(coordinates, state, envs::CTMRGEnv)
return dtmap(idx -> TensorMap(EnlargedCorner(state, envs, idx), idx[1]), coordinates)
end

Expand All @@ -200,23 +188,26 @@ end
# ======================================================================================== #

"""
ctmrg_projectors(enlarged_envs, env, alg::CTMRG{M})
ctmrg_projectors(col::Int, enlarged_envs, env, alg::CTMRG{:sequential})
ctmrg_projectors(enlarged_envs, env, alg::CTMRG{:simultaneous})
Compute the CTMRG projectors based from enlarged environments.
In the `:simultaneous` mode, the environment SVD is run in parallel.
Compute the CTMRG projectors based on enlarged environments.
In the `:sequential` mode the projectors are computed for the column `col`, whereas
in the `:simultaneous` mode, all projectors (and corresponding SVDs) are computed in parallel.
"""
function ctmrg_projectors(
enlarged_envs, envs::CTMRGEnv{C,E}, alg::SequentialCTMRG
col::Int, state::InfinitePEPS, envs::CTMRGEnv{C,E}, alg::SequentialCTMRG
) where {C,E}
projector_alg = alg.projector_alg
ϵ = zero(real(scalartype(envs)))

coordinates = eachcoordinate(envs)
# SVD half-infinite environment
coordinates = eachcoordinate(envs)[:, col]
projectors = dtmap(coordinates) do (r, c)
# SVD half-infinite environment
r′ = _prev(r, size(envs.corners, 2))
QQ = halfinfinite_environment(enlarged_envs[1, r, c], enlarged_envs[2, r′, c])

Q1 = TensorMap(EnlargedCorner(state, envs, (SOUTHWEST, r, c)), SOUTHWEST)
Q2 = TensorMap(EnlargedCorner(state, envs, (NORTHWEST, r′, c)), NORTHWEST)
QQ = halfinfinite_environment(Q1, Q2)
trscheme = truncation_scheme(projector_alg, envs.edges[WEST, r′, c])
svd_alg = svd_algorithm(projector_alg, (WEST, r, c))
U, S, V, ϵ_local = PEPSKit.tsvd!(QQ, svd_alg; trunc=trscheme)
Expand All @@ -231,9 +222,8 @@ function ctmrg_projectors(
end

# Compute projectors
return build_projectors(U, S, V, enlarged_envs[1, r, c], enlarged_envs[2, r′, c])
return build_projectors(U, S, V, Q1, Q2)
end

return (map(first, projectors), map(last, projectors)), (; err=ϵ)
end
function ctmrg_projectors(
Expand Down Expand Up @@ -335,36 +325,36 @@ end
# ======================================================================================== #

"""
ctmrg_renormalize(enlarged_envs, projectors, state, envs, alg::CTMRG{M})
ctmrg_renormalize(col::Int, projectors, state, envs, ::CTMRG{:sequential})
ctmrg_renormalize(enlarged_envs, projectors, state, envs, ::CTMRG{:simultaneous})
Apply projectors to renormalize corners and edges.
The `:sequential` mode renormalizes the environment on the column `col`, where as the
`:simultaneous` mode renormalizes all environment tensors simultaneously.
"""
function ctmrg_renormalize(projectors, state, envs, ::SequentialCTMRG)
function ctmrg_renormalize(col::Int, projectors, state, envs, ::SequentialCTMRG)
corners = Zygote.Buffer(envs.corners)
edges = Zygote.Buffer(envs.edges)

# copy environments that do not participate
for dir in (NORTHEAST, SOUTHEAST)
for r in axes(envs.corners, 2), c in axes(envs.corners, 3)
corners[dir, r, c] = envs.corners[dir, r, c]
end
for (dir, r, c) in eachcoordinate(state, 1:4)
(c == col && dir in [SOUTHWEST, NORTHWEST]) && continue
corners[dir, r, c] = envs.corners[dir, r, c]
end
for dir in (NORTH, EAST, SOUTH)
for r in axes(envs.corners, 2), c in axes(envs.corners, 3)
edges[dir, r, c] = envs.edges[dir, r, c]
end
for (dir, r, c) in eachcoordinate(state, 1:4)
(c == col && dir == WEST) && continue
edges[dir, r, c] = envs.edges[dir, r, c]
end

# Apply projectors to renormalize corners and edges
for (r, c) in eachcoordinate(state)
C_southwest = renormalize_bottom_corner((r, c), envs, projectors)
corners[SOUTHWEST, r, c] = C_southwest / norm(C_southwest)
# Apply projectors to renormalize corners and edge
for row in axes(envs.corners, 2)
C_southwest = renormalize_bottom_corner((row, col), envs, projectors)
corners[SOUTHWEST, row, col] = C_southwest / norm(C_southwest)

C_northwest = renormalize_top_corner((r, c), envs, projectors)
corners[NORTHWEST, r, c] = C_northwest / norm(C_northwest)
C_northwest = renormalize_top_corner((row, col), envs, projectors)
corners[NORTHWEST, row, col] = C_northwest / norm(C_northwest)

E_west = renormalize_west_edge((r, c), envs, projectors, state)
edges[WEST, r, c] = E_west / norm(E_west)
E_west = renormalize_west_edge((row, col), envs, projectors, state)
edges[WEST, row, col] = E_west / norm(E_west)
end

return CTMRGEnv(copy(corners), copy(edges))
Expand Down
2 changes: 1 addition & 1 deletion test/ctmrg/ctmrgschemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ unitcells = [(1, 1), (3, 4)]
H = heisenberg_XYZ(InfiniteSquare(unitcell...))
E_sequential = costfun(psi, env_sequential, H)
E_simultaneous = costfun(psi, env_simultaneous, H)
@test E_sequential E_simultaneous rtol = 1e-4
@test E_sequential E_simultaneous rtol = 1e-3
end

# test fixedspace actually fixes space
Expand Down

0 comments on commit e2545a3

Please sign in to comment.