@@ -35,63 +35,124 @@ $(TYPEDFIELDS)
3535 finalize:: F = Defaults. _finalize
3636end
3737
38- function find_groundstate (ψ:: InfiniteMPS , H, alg:: VUMPS , envs= environments (ψ, H))
39- # initialization
40- scheduler = Defaults. scheduler[]
41- log = IterLog (" VUMPS" )
42- ϵ:: Float64 = calc_galerkin (ψ, H, ψ, envs)
43- temp_ACs = similar .(ψ. AC)
44- alg_environments = updatetol (alg. alg_environments, 0 , ϵ)
45- recalculate! (envs, ψ, H, ψ; alg_environments. tol)
46-
47- LoggingExtras. withlevel (; alg. verbosity) do
48- @infov 2 loginit! (log, ϵ, sum (expectation_value (ψ, H, envs)))
49- for iter in 1 : (alg. maxiter)
50- alg_eigsolve = updatetol (alg. alg_eigsolve, iter, ϵ)
51- tmap! (temp_ACs, 1 : length (ψ); scheduler) do loc
52- return _vumps_localupdate (loc, ψ, H, envs, alg_eigsolve)
53- end
38+ # Internal state of the VUMPS algorithm
39+ struct VUMPSState{S,O,E}
40+ mps:: S
41+ operator:: O
42+ envs:: E
43+ iter:: Int
44+ ϵ:: Float64
45+ which:: Symbol
46+ end
5447
55- alg_gauge = updatetol (alg. alg_gauge, iter, ϵ)
56- ψ = InfiniteMPS (temp_ACs, ψ. C[end ]; alg_gauge. tol, alg_gauge. maxiter)
48+ function find_groundstate (mps:: InfiniteMPS , operator, alg:: VUMPS ,
49+ envs= environments (mps, operator))
50+ return dominant_eigsolve (operator, mps, alg, envs; which= :SR )
51+ end
5752
58- alg_environments = updatetol (alg. alg_environments, iter, ϵ)
59- recalculate! (envs, ψ, H, ψ; alg_environments. tol)
53+ function dominant_eigsolve (operator, mps, alg:: VUMPS , envs= environments (mps, operator);
54+ which)
55+ log = IterLog (" VUMPS" )
56+ iter = 0
57+ ϵ = calc_galerkin (mps, operator, mps, envs)
58+ alg_environments = updatetol (alg. alg_environments, iter, ϵ)
59+ recalculate! (envs, mps, operator, mps; alg_environments. tol)
6060
61- ψ, envs = alg. finalize (iter, ψ, H, envs):: Tuple{typeof(ψ),typeof(envs)}
61+ state = VUMPSState (mps, operator, envs, iter, ϵ, which)
62+ it = IterativeSolver (alg, state)
6263
63- ϵ = calc_galerkin (ψ, H, ψ, envs)
64+ return LoggingExtras. withlevel (; alg. verbosity) do
65+ @infov 2 loginit! (log, ϵ, sum (expectation_value (mps, operator, envs)))
6466
65- # breaking conditions
66- if ϵ <= alg. tol
67- @infov 2 logfinish! (log, iter, ϵ, expectation_value (ψ, H , envs))
68- break
67+ for (mps, envs, ϵ) in it
68+ if ϵ ≤ alg. tol
69+ @infov 2 logfinish! (log, it . iter, ϵ, expectation_value (mps, operator , envs))
70+ return mps, envs, ϵ
6971 end
70- if iter == alg. maxiter
71- @warnv 1 logcancel! (log, iter, ϵ, expectation_value (ψ, H, envs))
72- else
73- @infov 3 logiter! (log, iter, ϵ, expectation_value (ψ, H, envs))
72+ if it. iter ≥ alg. maxiter
73+ @warnv 1 logcancel! (log, it. iter, ϵ, expectation_value (mps, operator, envs))
74+ return mps, envs, ϵ
7475 end
76+ @infov 3 logiter! (log, it. iter, ϵ, expectation_value (mps, operator, envs))
7577 end
78+
79+ # this should never be reached
80+ return it. state. mps, it. state. envs, it. state. ϵ
7681 end
82+ end
7783
78- return ψ, envs, ϵ
84+ function Base. iterate (it:: IterativeSolver{<:VUMPS} , state= it. state)
85+ ACs = localupdate_step! (it, state)
86+ mps = gauge_step! (it, state, ACs)
87+ envs = envs_step! (it, state, mps)
88+
89+ # finalizer step
90+ mps, envs = it. finalize (state. iter, mps, state. operator, envs):: typeof ((mps, envs))
91+
92+ # error criterion
93+ ϵ = calc_galerkin (mps, state. operator, mps, envs)
94+
95+ # update state
96+ it. state = VUMPSState (mps, state. operator, envs, state. iter + 1 , ϵ, state. which)
97+
98+ return (mps, envs, ϵ), it. state
7999end
80100
81- function _vumps_localupdate (loc, ψ, H, envs, eigalg, factalg= QRpos ())
82- local AC′, C′
83- if Defaults. scheduler[] isa SerialScheduler
84- _, AC′ = fixedpoint (∂∂AC (loc, ψ, H, envs), ψ. AC[loc], :SR , eigalg)
85- _, C′ = fixedpoint (∂∂C (loc, ψ, H, envs), ψ. C[loc], :SR , eigalg)
86- else
87- @sync begin
88- Threads. @spawn begin
89- _, AC′ = fixedpoint (∂∂AC (loc, ψ, H, envs), ψ. AC[loc], :SR , eigalg)
90- end
91- Threads. @spawn begin
92- _, C′ = fixedpoint (∂∂C (loc, ψ, H, envs), ψ. C[loc], :SR , eigalg)
93- end
101+ function localupdate_step! (it:: IterativeSolver{<:VUMPS} , state,
102+ scheduler= Defaults. scheduler[])
103+ alg_eigsolve = updatetol (it. alg_eigsolve, state. iter, state. ϵ)
104+ alg_orth = QRpos ()
105+
106+ mps = state. mps
107+ eachsite = 1 : length (mps)
108+ src_Cs = mps isa Multiline ? eachcol (mps. C) : mps. C
109+ src_ACs = mps isa Multiline ? eachcol (mps. AC) : mps. AC
110+ ACs = similar (mps. AC)
111+ dst_ACs = mps isa Multiline ? eachcol (ACs) : ACs
112+
113+ tforeach (eachsite, src_ACs, src_Cs; scheduler) do site, AC₀, C₀
114+ dst_ACs[site] = _localupdate_vumps_step! (site, mps, state. operator, state. envs,
115+ AC₀, C₀; parallel= false , alg_orth,
116+ state. which, alg_eigsolve)
117+ return nothing
118+ end
119+
120+ return ACs
121+ end
122+
123+ function _localupdate_vumps_step! (site, mps, operator, envs, AC₀, C₀;
124+ parallel:: Bool = false , alg_orth= QRpos (),
125+ alg_eigsolve= Defaults. eigsolver, which)
126+ if ! parallel
127+ _, AC = fixedpoint (∂∂AC (site, mps, operator, envs), AC₀, which, alg_eigsolve)
128+ _, C = fixedpoint (∂∂C (site, mps, operator, envs), C₀, which, alg_eigsolve)
129+ return regauge! (AC, C; alg= alg_orth)
130+ end
131+
132+ local AC, C
133+ @sync begin
134+ @spawn begin
135+ _, AC = fixedpoint (∂∂AC (site, mps, operator, envs),
136+ AC₀, which, alg_eigsolve)
137+ end
138+ @spawn begin
139+ _, C = fixedpoint (∂∂C (site, mps, operator, envs),
140+ C₀, which, alg_eigsolve)
94141 end
95142 end
96- return regauge! (AC′, C′; alg= factalg)
143+ return regauge! (AC, C; alg= alg_orth)
144+ end
145+
146+ function gauge_step! (it:: IterativeSolver{<:VUMPS} , state, ACs:: AbstractVector )
147+ alg_gauge = updatetol (it. alg_gauge, state. iter, state. ϵ)
148+ return InfiniteMPS (ACs, state. mps. C[end ]; alg_gauge. tol, alg_gauge. maxiter)
149+ end
150+ function gauge_step! (it:: IterativeSolver{<:VUMPS} , state, ACs:: AbstractMatrix )
151+ alg_gauge = updatetol (it. alg_gauge, state. iter, state. ϵ)
152+ return MultilineMPS (ACs, @view (state. mps. C[:, end ]); alg_gauge. tol, alg_gauge. maxiter)
153+ end
154+
155+ function envs_step! (it:: IterativeSolver{<:VUMPS} , state, mps)
156+ alg_environments = updatetol (it. alg_environments, state. iter, state. ϵ)
157+ return recalculate! (state. envs, mps, state. operator, mps; alg_environments. tol)
97158end
0 commit comments