Skip to content

Commit a142e4e

Browse files
authored
Refactor boundary MPS contractions to directly use MPSKit.InfiniteMPO (#125)
* Update for relaxed MPO eltype restrictions * Add height type parameter * Bump MPSKit compat * Format
1 parent f583b38 commit a142e4e

6 files changed

Lines changed: 68 additions & 352 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ FiniteDifferences = "0.12"
3131
KrylovKit = "0.8, 0.9"
3232
LinearAlgebra = "1"
3333
LoggingExtras = "1"
34-
MPSKit = "0.12"
34+
MPSKit = "0.12.4"
3535
MPSKitModels = "0.4"
3636
OhMyThreads = "0.7"
3737
OptimKit = "0.3, 0.4"

src/PEPSKit.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ include("states/infinitepartitionfunction.jl")
3131

3232
include("operators/infinitepepo.jl")
3333
include("operators/transfermatrix.jl")
34-
include("operators/derivatives.jl")
3534
include("operators/localoperator.jl")
3635
include("operators/lattices/squarelattice.jl")
3736
include("operators/models.jl")

src/algorithms/contractions/vumps_contractions.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
using MPSKit: GenericMPSTensor, MPSBondTensor
22

3-
const PEPSSandwich{T<:PEPSTensor} = Tuple{T,T}
4-
ket(p::PEPSSandwich) = p[1]
5-
bra(p::PEPSSandwich) = p[2]
6-
7-
const PEPOSandwich{N,T<:PEPSTensor,P<:PEPOTensor} = Tuple{T,T,Tuple{Vararg{P,N}}}
8-
ket(p::PEPOSandwich) = p[1]
9-
bra(p::PEPOSandwich) = p[2]
10-
pepo(p::PEPOSandwich) = p[3]
11-
pepo(p::PEPOSandwich, i::Int) = p[3][i]
12-
133
#
144
# Environment transfer functions
155
#
Lines changed: 2 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using MPSKit: InfiniteEnvironments
22

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
55

66
function MPSKit.issamespace(
77
envs::InfiniteEnvironments,
@@ -42,237 +42,3 @@ function MPSKit.allocate_GR(
4242
TT = TensorMap{T}
4343
return TT(undef, V)
4444
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

src/operators/derivatives.jl

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)