|
1 | 1 | using MPSKit: InfiniteEnvironments |
2 | 2 |
|
3 | | -## Actual overloads: purely due to product structure in virtual spaces of 'effective' MPO |
4 | | -## tensors |
| 3 | +# overloads required purely because of the fact that left and right virtual spaces are now |
| 4 | +# ProductSpace instances |
5 | 5 |
|
6 | 6 | function MPSKit.issamespace( |
7 | 7 | envs::InfiniteEnvironments, |
@@ -42,237 +42,3 @@ function MPSKit.allocate_GR( |
42 | 42 | TT = TensorMap{T} |
43 | 43 | return TT(undef, V) |
44 | 44 | end |
45 | | - |
46 | | -## All the rest: purely relaxation of type restriction of AbstractMPO{O<:MPOTensor} |
47 | | - |
48 | | -function MPSKit.environment_alg( |
49 | | - ::Union{InfiniteMPS,MultilineMPS}, |
50 | | - ::Union{InfiniteTransferMatrix,MultilineTransferMatrix}, |
51 | | - ::Union{InfiniteMPS,MultilineMPS}; |
52 | | - tol=MPSKit.Defaults.tol, |
53 | | - maxiter=MPSKit.Defaults.maxiter, |
54 | | - krylovdim=MPSKit.Defaults.krylovdim, |
55 | | - verbosity=MPSKit.Defaults.VERBOSE_NONE, |
56 | | - eager=true, |
57 | | -) |
58 | | - return Arnoldi(; tol, maxiter, krylovdim, verbosity, eager) |
59 | | -end |
60 | | - |
61 | | -function MPSKit.environments( |
62 | | - above::InfiniteMPS, |
63 | | - operator::InfiniteTransferMatrix, |
64 | | - below::InfiniteMPS=above; |
65 | | - kwargs..., |
66 | | -) |
67 | | - GLs, GRs = MPSKit.initialize_environments(above, operator, below) |
68 | | - envs = InfiniteEnvironments(GLs, GRs) |
69 | | - return MPSKit.recalculate!(envs, above, operator, below; kwargs...) |
70 | | -end |
71 | | - |
72 | | -function MPSKit.environments( |
73 | | - above::MultilineMPS, |
74 | | - operator::MultilineTransferMatrix, |
75 | | - below::MultilineMPS=above; |
76 | | - kwargs..., |
77 | | -) |
78 | | - (rows = size(above, 1)) == size(operator, 1) == size(below, 1) || |
79 | | - throw(ArgumentError("Incompatible sizes")) |
80 | | - envs = map(1:rows) do row |
81 | | - return environments(above[row], operator[row], below[row + 1]; kwargs...) |
82 | | - end |
83 | | - return Multiline(PeriodicVector(envs)) |
84 | | -end |
85 | | - |
86 | | -function MPSKit.recalculate!( |
87 | | - envs::InfiniteEnvironments, |
88 | | - above::InfiniteMPS, |
89 | | - operator::InfiniteTransferMatrix, |
90 | | - below::InfiniteMPS=above; |
91 | | - kwargs..., |
92 | | -) |
93 | | - if !MPSKit.issamespace(envs, above, operator, below) |
94 | | - # TODO: in-place initialization? |
95 | | - GLs, GRs = MPSKit.initialize_environments(above, operator, below) |
96 | | - copy!(envs.GLs, GLs) |
97 | | - copy!(envs.GRs, GRs) |
98 | | - end |
99 | | - |
100 | | - alg = MPSKit.environment_alg(above, operator, below; kwargs...) |
101 | | - |
102 | | - @sync begin |
103 | | - @spawn MPSKit.compute_leftenvs!(envs, above, operator, below, alg) |
104 | | - @spawn MPSKit.compute_rightenvs!(envs, above, operator, below, alg) |
105 | | - end |
106 | | - MPSKit.normalize!(envs, above, operator, below) |
107 | | - |
108 | | - return envs |
109 | | -end |
110 | | - |
111 | | -function MPSKit.recalculate!( |
112 | | - envs::MultilineEnvironments, |
113 | | - above::MultilineMPS, |
114 | | - operator::MultilineTransferMatrix, |
115 | | - below::MultilineMPS=above; |
116 | | - kwargs..., |
117 | | -) |
118 | | - (rows = size(above, 1)) == size(operator, 1) == size(below, 1) || |
119 | | - throw(ArgumentError("Incompatible sizes")) |
120 | | - @threads for row in 1:rows |
121 | | - MPSKit.recalculate!(envs[row], above[row], operator[row], below[row + 1]; kwargs...) |
122 | | - end |
123 | | - return envs |
124 | | -end |
125 | | - |
126 | | -function MPSKit.initialize_environments( |
127 | | - above::InfiniteMPS, operator::InfiniteTransferMatrix, below::InfiniteMPS=above |
128 | | -) |
129 | | - L = MPSKit.check_length(above, operator, below) |
130 | | - GLs = PeriodicVector([ |
131 | | - MPSKit.randomize!(MPSKit.allocate_GL(below, operator, above, i)) for i in 1:L |
132 | | - ]) |
133 | | - GRs = PeriodicVector([ |
134 | | - MPSKit.randomize!(MPSKit.allocate_GR(below, operator, above, i)) for i in 1:L |
135 | | - ]) |
136 | | - return GLs, GRs |
137 | | -end |
138 | | - |
139 | | -function MPSKit.compute_leftenvs!( |
140 | | - envs::InfiniteEnvironments, |
141 | | - above::InfiniteMPS, |
142 | | - operator::InfiniteTransferMatrix, |
143 | | - below::InfiniteMPS, |
144 | | - alg, |
145 | | -) |
146 | | - # compute eigenvector |
147 | | - T = MPSKit.TransferMatrix(above.AL, operator, below.AL) |
148 | | - λ, envs.GLs[1] = MPSKit.fixedpoint(flip(T), envs.GLs[1], :LM, alg) |
149 | | - # push through unitcell |
150 | | - for i in 2:length(operator) |
151 | | - envs.GLs[i] = |
152 | | - envs.GLs[i - 1] * |
153 | | - MPSKit.TransferMatrix(above.AL[i - 1], operator[i - 1], below.AL[i - 1]) |
154 | | - end |
155 | | - return λ, envs |
156 | | -end |
157 | | - |
158 | | -function MPSKit.compute_rightenvs!( |
159 | | - envs::InfiniteEnvironments, |
160 | | - above::InfiniteMPS, |
161 | | - operator::InfiniteTransferMatrix, |
162 | | - below::InfiniteMPS, |
163 | | - alg, |
164 | | -) |
165 | | - # compute eigenvector |
166 | | - T = MPSKit.TransferMatrix(above.AR, operator, below.AR) |
167 | | - λ, envs.GRs[end] = MPSKit.fixedpoint(T, envs.GRs[end], :LM, alg) |
168 | | - # push through unitcell |
169 | | - for i in reverse(1:(length(operator) - 1)) |
170 | | - envs.GRs[i] = |
171 | | - MPSKit.TransferMatrix(above.AR[i + 1], operator[i + 1], below.AR[i + 1]) * |
172 | | - envs.GRs[i + 1] |
173 | | - end |
174 | | - return λ, envs |
175 | | -end |
176 | | - |
177 | | -function TensorKit.normalize!( |
178 | | - envs::InfiniteEnvironments, |
179 | | - above::InfiniteMPS, |
180 | | - operator::InfiniteTransferMatrix, |
181 | | - below::InfiniteMPS, |
182 | | -) |
183 | | - for i in 1:length(operator) |
184 | | - λ = dot(below.C[i], MPSKit.∂C(above.C[i], envs.GLs[i + 1], envs.GRs[i])) |
185 | | - scale!(envs.GLs[i + 1], inv(λ)) |
186 | | - end |
187 | | - return envs |
188 | | -end |
189 | | - |
190 | | -# TODO: move these to MPSKit? |
191 | | -function MPSKit.leftenv(envs::MultilineEnvironments, r::Int, c::Int, state) |
192 | | - return leftenv(envs[r], c, parent(state)) |
193 | | -end |
194 | | -function MPSKit.rightenv(envs::MultilineEnvironments, r::Int, c::Int, state) |
195 | | - return rightenv(envs[r], c, parent(state)) |
196 | | -end |
197 | | - |
198 | | -function MPSKit.expectation_value( |
199 | | - ψ::MultilineMPS, |
200 | | - O::MultilineTransferMatrix, |
201 | | - envs::MultilineEnvironments=environments(ψ, O), |
202 | | -) |
203 | | - return prod(product(1:size(ψ, 1), 1:size(ψ, 2))) do (i, j) |
204 | | - GL = leftenv(envs, i, j, ψ) |
205 | | - GR = rightenv(envs, i, j, ψ) |
206 | | - return MPSKit.contract_mpo_expval(ψ.AC[i, j], GL, O[i, j], GR, ψ.AC[i + 1, j]) |
207 | | - end |
208 | | -end |
209 | | -function MPSKit.expectation_value(st::InfiniteMPS, transfer::InfiniteTransferMatrix) |
210 | | - return expectation_value(Multiline([st]), Multiline([transfer])) |
211 | | -end |
212 | | - |
213 | | -function MPSKit.calc_galerkin( |
214 | | - pos::CartesianIndex{2}, |
215 | | - above::MultilineMPS, |
216 | | - operator::MultilineTransferMatrix, |
217 | | - below::MultilineMPS, |
218 | | - envs::MultilineEnvironments, |
219 | | -) |
220 | | - row, col = pos.I |
221 | | - return MPSKit.calc_galerkin(col, above[row], operator[row], below[row + 1], envs[row]) |
222 | | -end |
223 | | -function MPSKit.calc_galerkin( |
224 | | - above::MultilineMPS, |
225 | | - operator::MultilineTransferMatrix, |
226 | | - below::MultilineMPS, |
227 | | - envs::MultilineEnvironments, |
228 | | -) |
229 | | - return maximum( |
230 | | - pos -> MPSKit.calc_galerkin(pos, above, operator, below, envs), |
231 | | - CartesianIndices(size(above)), |
232 | | - ) |
233 | | -end |
234 | | - |
235 | | -function MPSKit.leading_boundary( |
236 | | - state::InfiniteMPS, |
237 | | - operator::InfiniteTransferMatrix, |
238 | | - alg, |
239 | | - envs=environments(state, operator), |
240 | | -) |
241 | | - state_multi = convert(MultilineMPS, state) |
242 | | - operator_multi = Multiline([operator]) |
243 | | - envs_multi = Multiline([envs]) |
244 | | - state_multi′, envs_multi′, err = leading_boundary( |
245 | | - state_multi, operator_multi, alg, envs_multi |
246 | | - ) |
247 | | - state′ = convert(InfiniteMPS, state_multi′) |
248 | | - envs´ = convert(InfiniteEnvironments, envs_multi′) |
249 | | - return state′, envs´, err |
250 | | -end |
251 | | - |
252 | | -# TODO: remove this once it's in MPSKit |
253 | | -Base.convert(::Type{InfiniteEnvironments}, envs::MultilineEnvironments) = only(envs) |
254 | | - |
255 | | -# this is a total pain... |
256 | | -function MPSKit._vumps_localupdate( |
257 | | - col, ψ::MultilineMPS, O::MultilineTransferMatrix, envs, eigalg, factalg=QRpos() |
258 | | -) |
259 | | - local AC′, C′ |
260 | | - if Defaults.scheduler[] isa Defaults.SerialScheduler |
261 | | - _, AC′ = MPSKit.fixedpoint(MPSKit.∂∂AC(col, ψ, O, envs), ψ.AC[:, col], :LM, eigalg) |
262 | | - _, C′ = MPSKit.fixedpoint(MPSKit.∂∂C(col, ψ, O, envs), ψ.C[:, col], :LM, eigalg) |
263 | | - else |
264 | | - @sync begin |
265 | | - Threads.@spawn begin |
266 | | - _, AC′ = MPSKit.fixedpoint( |
267 | | - MPSKit.∂∂AC(col, ψ, O, envs), ψ.AC[:, col], :LM, eigalg |
268 | | - ) |
269 | | - end |
270 | | - Threads.@spawn begin |
271 | | - _, C′ = MPSKit.fixedpoint( |
272 | | - MPSKit.∂∂C(col, ψ, O, envs), ψ.C[:, col], :LM, eigalg |
273 | | - ) |
274 | | - end |
275 | | - end |
276 | | - end |
277 | | - return MPSKit.regauge!.(AC′, C′; alg=factalg)[:] |
278 | | -end |
0 commit comments