Skip to content

Commit a4de5ff

Browse files
committed
Streamline convergence checks
1 parent e8f07eb commit a4de5ff

1 file changed

Lines changed: 39 additions & 71 deletions

File tree

src/algorithms/time_evolution/ntupdate.jl

Lines changed: 39 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -155,34 +155,56 @@ function MPSKit.timestep(
155155
end
156156

157157
"""
158-
time_evolve(
159-
it::TimeEvolver{<:NeighbourUpdate},
160-
[H::LocalOperator, env::CTMRGEnv, ctm_alg::CTMRGAlgorithm];
161-
tol::Float64 = 1.0e-7, check_interval::Int = 10
162-
) -> (psi, info)
158+
$(SIGNATURES)
163159
164-
Perform time evolution to the end of `NeighbourUpdate` TimeEvolver `it`,
165-
or until convergence of energy set by a positive `tol`.
160+
Perform time evolution to the end of `NeighbourUpdate` TimeEvolver `it`.
161+
`check_interval` sets the number of iterations between outputs of information.
162+
"""
163+
function MPSKit.time_evolve(it::TimeEvolver{<:NeighbourUpdate}; check_interval::Int = 50)
164+
time_start = time0 = time()
165+
@info "--- Time evolution (neighbourhood tensor update), dt = $(it.dt) ---"
166+
info0 = nothing
167+
for (psi, info) in it
168+
iter = it.state.iter
169+
stop = (iter == it.nstep)
170+
showinfo = (iter == 1) || (iter % check_interval == 0) || stop
171+
time1 = time()
172+
if showinfo
173+
Δλ = (info0 === nothing) ? NaN : compare_weights(info.wts, info0.wts)
174+
@info @sprintf(
175+
"NTU iter %d: t = %.2e, |Δλ| = %.3e. Time: %.2f s",
176+
it.state.iter, it.state.t, Δλ, time1 - time0
177+
)
178+
end
179+
if stop
180+
time_end = time()
181+
@info @sprintf("Time evolution finished in %.2f s", time_end - time_start)
182+
return psi, info
183+
end
184+
info0, time0 = info, time()
185+
end
186+
return
187+
end
166188

167-
To enable convergence check (for imaginary time evolution of InfinitePEPS only),
168-
provide the Hamiltonian `H`, CTMRG environment `env`, CTMRG algorithm `ctm_alg`
169-
and setting `tol > 0`.
189+
"""
190+
$(SIGNATURES)
170191
171-
`check_interval` sets the number of iterations between energy checks
172-
(for ground state search) and outputs of information.
192+
Perform time evolution until convergence of `TimeEvolver` iterator `it`.
193+
For `NeighbourUpdate`, convergence is determined by the change of energy
194+
between two checks being smaller than `tol`.
173195
"""
174196
function MPSKit.time_evolve(
175-
it::TimeEvolver{<:NeighbourUpdate},
197+
it::TimeEvolver{<:NeighbourUpdate, G, S},
176198
H::LocalOperator, env::CTMRGEnv, ctm_alg::CTMRGAlgorithm;
177199
tol::Float64 = 1.0e-7, check_interval::Int = 10
178-
)
200+
) where {G, S <: NTUState{<:InfinitePEPS}}
179201
@info "--- Time evolution (neighbourhood tensor update), dt = $(it.dt) ---"
180202
time_start = time0 = time()
181203
psi0 = copy(it.state.psi)
182-
@assert (psi0 isa InfinitePEPS) && it.alg.imaginary_time "Only imaginary time evolution of InfinitePEPS allows convergence checking."
204+
@assert it.alg.imaginary_time "Only imaginary time evolution of InfinitePEPS allows convergence checking."
183205
# initial energy
184206
env, = leading_boundary(env, psi0, ctm_alg)
185-
energy = expectation_value(psi0, H, env) / prod(size(psi0))
207+
energy = real(expectation_value(psi0, H, env)) / prod(size(psi0))
186208
@info @sprintf("NTU iter 0: E = %.4e", energy)
187209
info0 = (; energy, env)
188210
# start evolving
@@ -201,7 +223,7 @@ function MPSKit.time_evolve(
201223
end
202224
env, = leading_boundary(env, psi, ctm_alg)
203225
# measure energy
204-
energy = expectation_value(psi, H, env) / prod(size(psi))
226+
energy = real(expectation_value(psi, H, env)) / prod(size(psi))
205227
ΔE = energy - energy0
206228
info = @insert info.energy = energy
207229
info = @insert info.env = env
@@ -239,57 +261,3 @@ function MPSKit.time_evolve(
239261
end
240262
return
241263
end
242-
243-
function MPSKit.time_evolve(it::TimeEvolver{<:NeighbourUpdate}; check_interval::Int = 50)
244-
time_start = time0 = time()
245-
@info "--- Time evolution (neighbourhood tensor update), dt = $(it.dt) ---"
246-
info0 = nothing
247-
for (psi, info) in it
248-
iter = it.state.iter
249-
stop = (iter == it.nstep)
250-
showinfo = (iter == 1) || (iter % check_interval == 0) || stop
251-
time1 = time()
252-
if showinfo
253-
Δλ = (info0 === nothing) ? NaN : compare_weights(info.wts, info0.wts)
254-
@info @sprintf(
255-
"NTU iter %d: t = %.2e, |Δλ| = %.3e. Time: %.2f s",
256-
it.state.iter, it.state.t, Δλ, time1 - time0
257-
)
258-
end
259-
if stop
260-
time_end = time()
261-
@info @sprintf("Time evolution finished in %.2f s", time_end - time_start)
262-
return psi, info
263-
end
264-
info0, time0 = info, time()
265-
end
266-
return
267-
end
268-
269-
"""
270-
time_evolve(
271-
psi0::Union{InfinitePEPS, InfinitePEPO}, H::LocalOperator,
272-
dt::Number, nstep::Int, alg::NeighbourUpdate;
273-
t0::Number = 0.0, symmetrize_gates::Bool = false,
274-
check_interval::Int = 10
275-
) -> (psi, info)
276-
277-
Perform time evolution on the initial state `psi0` with Hamiltonian `H`,
278-
using `NeighbourUpdate` algorithm `alg`, time step `dt` for
279-
`nstep` number of steps.
280-
281-
- Set `symmetrize_gates = true` for second-order Trotter decomposition.
282-
- Use `t0` to specify the initial time of `psi0`.
283-
- `check_interval` sets the interval to output information (and check convergence).
284-
Output during the evolution can be turned off by setting `check_interval <= 0`.
285-
- `info` is a NamedTuple containing information of the evolution,
286-
including the time `info.t` evolved since `psi0`.
287-
"""
288-
function MPSKit.time_evolve(
289-
psi0::InfiniteState, H::LocalOperator, dt::Number, nstep::Int,
290-
alg::NeighbourUpdate; symmetrize_gates::Bool = false,
291-
t0::Number = 0.0, check_interval::Int = 10
292-
)
293-
it = TimeEvolver(psi0, H, dt, nstep, alg; t0, symmetrize_gates)
294-
return time_evolve(it; check_interval)
295-
end

0 commit comments

Comments
 (0)