Skip to content

Commit 283a62c

Browse files
authored
update left and right_virtualspace (#205)
1 parent 19fae27 commit 283a62c

17 files changed

+113
-164
lines changed

src/MPSKit.jl

-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@ export exact_diagonalization
6060
export TransferMatrix
6161
export transfer_left, transfer_right
6262

63-
@deprecate virtualspace left_virtualspace # there is a possible ambiguity when C isn't square, necessitating specifying left or right virtualspace
64-
6563
# Abstract type defs
6664
abstract type Algorithm end
6765

src/algorithms/expval.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ function expectation_value(ψ::AbstractMPS, (inds, O)::Pair)
6666
# left side
6767
T = storagetype(site_type(ψ))
6868
@plansor Vl[-1 -2; -3] := isomorphism(T,
69-
left_virtualspace(ψ, sites[1] - 1),
70-
left_virtualspace(ψ, sites[1] - 1))[-1; -3] *
69+
left_virtualspace(ψ, sites[1]),
70+
left_virtualspace(ψ, sites[1]))[-1; -3] *
7171
conj(Ut[-2])
7272

7373
# middle
@@ -104,7 +104,7 @@ function expectation_value(ψ::InfiniteMPS, H::InfiniteMPOHamiltonian,
104104
envs::AbstractMPSEnvironments=environments(ψ, H))
105105
return sum(1:length(ψ)) do i
106106
util = fill_data!(similar.AL[1], right_virtualspace(H, i)[end]), one)
107-
@plansor GR[-1 -2; -3] := r_LL(ψ, i)[-1; -3] * conj(util[-2])
107+
@plansor GR[-1 -2; -3] := r_LL(ψ, i)[-1; -3] * util[-2]
108108
return contract_mpo_expval.AL[i], leftenv(envs, i, ψ), H[i][:, 1, 1, end], GR)
109109
end
110110
end

src/algorithms/fidelity_susceptibility.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function fidelity_susceptibility(state::Union{FiniteMPS,InfiniteMPS}, H₀::T,
1111
Tos = LeftGaugedQP(rand, state)
1212
for (i, ac) in enumerate(state.AC)
1313
temp = ∂∂AC(i, state, V, venvs) * ac
14-
help = fill_data!(similar(ac, utilleg(Tos)), one)
14+
help = fill_data!(similar(ac, auxiliaryspace(Tos)), one)
1515
@plansor Tos[i][-1 -2; -3 -4] := temp[-1 -2; -4] * help[-3]
1616
end
1717

src/algorithms/timestep/timeevmpo.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ function make_time_mpo(H::InfiniteMPOHamiltonian{T}, dt, alg::WII) where {T}
327327
Vᵣ = right_virtualspace(H, i)[1:(end - 1)]
328328
P = physicalspace(H, i)
329329

330-
h′ = similar(H[i], Vₗ P P Vᵣ')
330+
h′ = similar(H[i], Vₗ P P Vᵣ)
331331
h′[2:end, 1, 1, 2:end] = WA[i]
332332
h′[2:end, 1, 1, 1] = WB[i]
333333
h′[1, 1, 1, 2:end] = WC[i]

src/algorithms/toolbox.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ domain of each eigenvector. The `tol` and `num_vals` keyword arguments are passe
6363
"""
6464
function transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,
6565
sector=first(sectors(oneunit(left_virtualspace(above, 1)))))
66-
init = randomize!(similar(above.AL[1], left_virtualspace(below, 0),
67-
ℂ[typeof(sector)](sector => 1)' * left_virtualspace(above, 0)))
66+
init = randomize!(similar(above.AL[1], left_virtualspace(below, 1),
67+
ℂ[typeof(sector)](sector => 1)' * left_virtualspace(above, 1)))
6868

69-
transferspace = fuse(left_virtualspace(above, 0) * left_virtualspace(below, 0)')
69+
transferspace = fuse(left_virtualspace(above, 1) * left_virtualspace(below, 1)')
7070
num_vals = min(dim(transferspace, sector), num_vals) # we can ask at most this many values
7171
eigenvals, eigenvecs, convhist = eigsolve(flip(TransferMatrix(above.AL, below.AL)),
7272
init, num_vals, :LM; tol=tol)
@@ -239,26 +239,26 @@ function periodic_boundary_conditions(mpo::InfiniteMPO{O},
239239

240240
# allocate output
241241
output = Vector{O}(undef, L)
242-
V_wrap = left_virtualspace(mpo, 1)'
242+
V_wrap = left_virtualspace(mpo, 1)
243243
ST = storagetype(O)
244244

245245
util = fill!(similar(mpo[1], oneunit(V_wrap)), one(scalartype(O)))
246-
@plansor cup[-1; -2 -3] := id(ST, V_wrap)[-3; -2] * util[-1]
246+
@plansor cup[-1; -2 -3] := id(ST, V_wrap)[-2; -3] * util[-1]
247247

248248
local F_right
249249
for i in 1:L
250250
V_left = i == 1 ? oneunit(V_wrap) : fuse(V_wrap left_virtualspace(mpo, i))
251-
V_right = i == L ? oneunit(V_wrap) : fuse(V_wrap' right_virtualspace(mpo, i)')
251+
V_right = i == L ? oneunit(V_wrap) : fuse(V_wrap right_virtualspace(mpo, i))
252252
output[i] = similar(mpo[i],
253253
V_left * physicalspace(mpo, i)
254254
physicalspace(mpo, i) * V_right)
255255
F_left = i == 1 ? cup : F_right
256256
F_right = i == L ? cup :
257-
isomorphism(ST, V_right V_wrap * right_virtualspace(mpo, i)')
258-
@plansor output[i][-1 -2; -3 -4] = F_left[-1; 1 2] *
259-
τ[-3 1; 4 3] *
260-
mpo[i][2 -2; 3 5] *
261-
conj(F_right[-4; 4 5])
257+
isomorphism(ST, V_right V_wrap' * right_virtualspace(mpo, i))
258+
@plansor contractcheck = true output[i][-1 -2; -3 -4] = F_left[-1; 1 2] *
259+
τ[-3 1; 4 3] *
260+
mpo[i][2 -2; 3 5] *
261+
conj(F_right[-4; 4 5])
262262
end
263263

264264
mpo isa SparseMPO && dropzeros!.(output) # the above process fills sparse mpos with zeros.

src/environments/abstract_envs.jl

+7-9
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ Base.unlock(envs::AbstractMPSEnvironments) = unlock(envs.lock);
1414
# Allocating tensors
1515
# ------------------
1616

17-
# TODO: fix the fucking left/right virtualspace bullshit
18-
# TODO: storagetype stuff
1917
function allocate_GL(bra::AbstractMPS, mpo::AbstractMPO, ket::AbstractMPS, i::Int)
2018
T = Base.promote_type(scalartype(bra), scalartype(mpo), scalartype(ket))
21-
V = left_virtualspace(bra, i - 1) left_virtualspace(mpo, i)'
22-
left_virtualspace(ket, i - 1)
19+
V = left_virtualspace(bra, i) left_virtualspace(mpo, i)'
20+
left_virtualspace(ket, i)
2321
if V isa BlockTensorKit.TensorMapSumSpace
2422
TT = blocktensormaptype(spacetype(bra), numout(V), numin(V), T)
2523
else
@@ -30,7 +28,7 @@ end
3028

3129
function allocate_GR(bra::AbstractMPS, mpo::AbstractMPO, ket::AbstractMPS, i::Int)
3230
T = Base.promote_type(scalartype(bra), scalartype(mpo), scalartype(ket))
33-
V = right_virtualspace(ket, i) right_virtualspace(mpo, i)'
31+
V = right_virtualspace(ket, i) right_virtualspace(mpo, i)
3432
right_virtualspace(bra, i)
3533
if V isa BlockTensorKit.TensorMapSumSpace
3634
TT = blocktensormaptype(spacetype(bra), numout(V), numin(V), T)
@@ -42,8 +40,8 @@ end
4240

4341
function allocate_GBL(bra::QP, mpo::AbstractMPO, ket::QP, i::Int)
4442
T = Base.promote_type(scalartype(bra), scalartype(mpo), scalartype(ket))
45-
V = left_virtualspace(bra.left_gs, i - 1) left_virtualspace(mpo, i)'
46-
auxiliaryspace(ket)' left_virtualspace(ket.left_gs, i - 1)
43+
V = left_virtualspace(bra, i) left_virtualspace(mpo, i)'
44+
auxiliaryspace(ket)' left_virtualspace(ket, i)
4745
if V isa BlockTensorKit.TensorMapSumSpace
4846
TT = blocktensormaptype(spacetype(bra), numout(V), numin(V), T)
4947
else
@@ -54,8 +52,8 @@ end
5452

5553
function allocate_GBR(bra::QP, mpo::AbstractMPO, ket::QP, i::Int)
5654
T = Base.promote_type(scalartype(bra), scalartype(mpo), scalartype(ket))
57-
V = right_virtualspace(ket.right_gs, i) right_virtualspace(mpo, i)'
58-
auxiliaryspace(ket)' right_virtualspace(bra.right_gs, i)
55+
V = right_virtualspace(ket, i) right_virtualspace(mpo, i)
56+
auxiliaryspace(ket)' right_virtualspace(bra, i)
5957
if V isa BlockTensorKit.TensorMapSumSpace
6058
TT = blocktensormaptype(spacetype(bra), numout(V), numin(V), T)
6159
else

src/environments/finite_envs.jl

+3-15
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,18 @@ function environments(below, operator, above, leftstart, rightstart)
3434
rightenvs)
3535
end
3636

37-
function environments(below::FiniteMPS{S}, O::DenseMPO, above=nothing) where {S}
38-
N = length(below)
39-
leftstart = isomorphism(storagetype(S),
40-
left_virtualspace(below, 0) space(O[1], 1)'
41-
left_virtualspace(something(above, below), 0))
42-
rightstart = isomorphism(storagetype(S),
43-
right_virtualspace(something(above, below), N)
44-
space(O[N], 4)'
45-
right_virtualspace(below, length(below)))
46-
return environments(below, O, above, leftstart, rightstart)
47-
end
48-
4937
function environments(below::FiniteMPS{S}, O::Union{FiniteMPO,FiniteMPOHamiltonian},
5038
above=nothing) where {S}
51-
Vl_bot = left_virtualspace(below, 0)
39+
Vl_bot = left_virtualspace(below, 1)
5240
Vl_mid = left_virtualspace(O, 1)
53-
Vl_top = isnothing(above) ? left_virtualspace(below, 0) : left_virtualspace(above, 0)
41+
Vl_top = isnothing(above) ? left_virtualspace(below, 1) : left_virtualspace(above, 1)
5442
leftstart = isomorphism(storagetype(S), Vl_bot Vl_mid' Vl_top)
5543

5644
N = length(below)
5745
Vr_bot = right_virtualspace(below, N)
5846
Vr_mid = right_virtualspace(O, N)
5947
Vr_top = isnothing(above) ? right_virtualspace(below, N) : right_virtualspace(above, N)
60-
rightstart = isomorphism(storagetype(S), Vr_top Vr_mid' Vr_bot)
48+
rightstart = isomorphism(storagetype(S), Vr_top Vr_mid Vr_bot)
6149

6250
return environments(below, O, above, leftstart, rightstart)
6351
end

src/operators/abstractmpo.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ Compute the mpo tensor that arises from multiplying MPOs.
156156
function fuse_mul_mpo(O1::MPOTensor, O2::MPOTensor)
157157
T = promote_type(scalartype(O1), scalartype(O2))
158158
F_left = fuser(T, left_virtualspace(O2), left_virtualspace(O1))
159-
F_right = fuser(T, right_virtualspace(O2)', right_virtualspace(O1)')
159+
F_right = fuser(T, right_virtualspace(O2), right_virtualspace(O1))
160160
@plansor O[-1 -2; -3 -4] := F_left[-1; 1 2] *
161161
O2[1 5; -3 3] *
162162
O1[2 -2; 5 4] *
@@ -203,7 +203,7 @@ function add_physical_charge(O::BraidingTensor, charge::Sector)
203203
sectortype(O) === typeof(charge) || throw(SectorMismatch())
204204
auxspace = Vect[typeof(charge)](charge => 1)
205205
V = left_virtualspace(O) fuse(physicalspace(O), auxspace)
206-
fuse(physicalspace(O), auxspace) right_virtualspace(O)'
206+
fuse(physicalspace(O), auxspace) right_virtualspace(O)
207207
return BraidingTensor{scalartype(O)}(V)
208208
end
209209
function add_physical_charge(O::AbstractBlockTensorMap{<:Any,<:Any,2,2}, charge::Sector)
@@ -213,7 +213,7 @@ function add_physical_charge(O::AbstractBlockTensorMap{<:Any,<:Any,2,2}, charge:
213213

214214
Odst = similar(O,
215215
left_virtualspace(O) fuse(physicalspace(O), auxspace)
216-
fuse(physicalspace(O), auxspace) right_virtualspace(O)')
216+
fuse(physicalspace(O), auxspace) right_virtualspace(O))
217217
for (I, v) in nonzero_pairs(O)
218218
Odst[I] = add_physical_charge(v, charge)
219219
end

src/operators/mpo.jl

+23-32
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const FiniteMPO{O<:MPOTensor} = MPO{O,Vector{O}}
1919

2020
function FiniteMPO(Os::AbstractVector{O}) where {O<:MPOTensor}
2121
for i in eachindex(Os)[1:(end - 1)]
22-
dual(right_virtualspace(Os[i])) == left_virtualspace(Os[i + 1]) ||
22+
right_virtualspace(Os[i]) == left_virtualspace(Os[i + 1]) ||
2323
throw(SpaceMismatch("unmatching virtual spaces at site $i"))
2424
end
2525
return FiniteMPO{O}(Os)
@@ -38,7 +38,7 @@ const InfiniteMPO{O<:MPOTensor} = MPO{O,PeriodicVector{O}}
3838

3939
function InfiniteMPO(Os::AbstractVector{O}) where {O<:MPOTensor}
4040
for i in eachindex(Os)
41-
dual(right_virtualspace(Os[i])) == left_virtualspace(Os[mod1(i + 1, end)]) ||
41+
right_virtualspace(Os[i]) == left_virtualspace(Os[mod1(i + 1, end)]) ||
4242
throw(SpaceMismatch("umatching virtual spaces at site $i"))
4343
end
4444
return InfiniteMPO{O}(Os)
@@ -139,8 +139,8 @@ function Base.convert(::Type{TensorMap}, mpo::FiniteMPO)
139139
U_left = ones(scalartype(mpo), V_left)'
140140

141141
V_right = right_virtualspace(mpo, length(mpo))
142-
@assert V_right == oneunit(V_right)'
143-
U_right = ones(scalartype(mpo), V_right')
142+
@assert V_right == oneunit(V_right)
143+
U_right = ones(scalartype(mpo), V_right)
144144

145145
tensors = vcat(U_left, parent(mpo), U_right)
146146
indices = [[i, -i, -(2N - i + 1), i + 1] for i in 1:length(mpo)]
@@ -166,10 +166,10 @@ function Base.:+(mpo1::FiniteMPO{TO}, mpo2::FiniteMPO{TO}) where {TO}
166166
A = storagetype(TO)
167167

168168
# left half
169-
F₁ = isometry(A, (right_virtualspace(mpo1, 1) right_virtualspace(mpo2, 1))',
170-
right_virtualspace(mpo1, 1)')
169+
F₁ = isometry(A, (right_virtualspace(mpo1, 1) right_virtualspace(mpo2, 1)),
170+
right_virtualspace(mpo1, 1))
171171
F₂ = leftnull(F₁)
172-
@assert _lastspace(F₂) == right_virtualspace(mpo2, 1)
172+
@assert _lastspace(F₂) == right_virtualspace(mpo2, 1)'
173173

174174
@plansor O[-3 -1 -2; -4] := mpo1[1][-1 -2; -3 1] * conj(F₁[-4; 1]) +
175175
mpo2[1][-1 -2; -3 1] * conj(F₂[-4; 1])
@@ -184,10 +184,10 @@ function Base.:+(mpo1::FiniteMPO{TO}, mpo2::FiniteMPO{TO}) where {TO}
184184
@plansor O₂[-1 -2; -3 -4] := R[-1; 1] * F₂[1; 2] * mpo2[i][2 -2; -3 -4]
185185

186186
# incorporate fusers from right side
187-
F₁ = isometry(A, (right_virtualspace(mpo1, i) right_virtualspace(mpo2, i))',
188-
right_virtualspace(mpo1, i)')
187+
F₁ = isometry(A, (right_virtualspace(mpo1, i) right_virtualspace(mpo2, i)),
188+
right_virtualspace(mpo1, i))
189189
F₂ = leftnull(F₁)
190-
@assert _lastspace(F₂) == right_virtualspace(mpo2, i)
190+
@assert _lastspace(F₂) == right_virtualspace(mpo2, i)'
191191
@plansor O[-3 -1 -2; -4] := O₁[-1 -2; -3 1] * conj(F₁[-4; 1]) +
192192
O₂[-1 -2; -3 1] * conj(F₂[-4; 1])
193193

@@ -248,8 +248,8 @@ function Base.:*(mpo1::FiniteMPO{TO}, mpo2::FiniteMPO{TO}) where {TO}
248248
S = spacetype(TO)
249249
if (left_virtualspace(mpo1, 1) != oneunit(S) ||
250250
left_virtualspace(mpo2, 1) != oneunit(S)) ||
251-
(right_virtualspace(mpo1, N)' != oneunit(S) ||
252-
right_virtualspace(mpo2, N)' != oneunit(S))
251+
(right_virtualspace(mpo1, N) != oneunit(S) ||
252+
right_virtualspace(mpo2, N) != oneunit(S))
253253
@warn "left/right virtual space is not trivial, fusion may not be unique"
254254
# this is a warning because technically any isomorphism that fuses the left/right
255255
# would work and for now I dont feel like figuring out if this is important
@@ -261,13 +261,8 @@ function Base.:*(mpo1::FiniteMPO{TO}, mpo2::FiniteMPO{TO}) where {TO}
261261
# note order of mpos: mpo1 * mpo2 * state -> mpo2 on top of mpo1
262262
local Fᵣ # trick to make Fᵣ defined in the loop
263263
for i in 1:N
264-
Fₗ = i != 1 ? Fᵣ :
265-
isomorphism(A, fuse(left_virtualspace(mpo2, i), left_virtualspace(mpo1, i)),
266-
left_virtualspace(mpo2, i) * left_virtualspace(mpo1, i))
267-
Fᵣ = isomorphism(A,
268-
fuse(right_virtualspace(mpo2, i)', right_virtualspace(mpo1, i)'),
269-
right_virtualspace(mpo2, i)' * right_virtualspace(mpo1, i)')
270-
264+
Fₗ = i != 1 ? Fᵣ : fuser(A, left_virtualspace(mpo2, i), left_virtualspace(mpo1, i))
265+
Fᵣ = fuser(A, right_virtualspace(mpo2, i), right_virtualspace(mpo1, i))
271266
@plansor O[i][-1 -2; -3 -4] := Fₗ[-1; 1 4] * mpo2[i][1 2; -3 3] *
272267
mpo1[i][4 -2; 2 5] *
273268
conj(Fᵣ[-4; 3 5])
@@ -284,11 +279,8 @@ function Base.:*(mpo::FiniteMPO, mps::FiniteMPS)
284279

285280
local Fᵣ # trick to make Fᵣ defined in the loop
286281
for i in 1:length(mps)
287-
Fₗ = i != 1 ? Fᵣ :
288-
isomorphism(TT, fuse(left_virtualspace(A[i]), left_virtualspace(mpo, i)),
289-
left_virtualspace(A[i]) * left_virtualspace(mpo, i))
290-
Fᵣ = isomorphism(TT, fuse(right_virtualspace(A[i])', right_virtualspace(mpo, i)'),
291-
right_virtualspace(A[i])' * right_virtualspace(mpo, i)')
282+
Fₗ = i != 1 ? Fᵣ : fuser(TT, left_virtualspace(mps, i), left_virtualspace(mpo, i))
283+
Fᵣ = fuser(TT, right_virtualspace(mps, i), right_virtualspace(mpo, i))
292284
A[i] = _fuse_mpo_mps(mpo[i], A[i], Fₗ, Fᵣ)
293285
end
294286

@@ -298,12 +290,11 @@ function Base.:*(mpo::FiniteMPO, mps::FiniteMPS)
298290
end
299291

300292
function Base.:*(mpo::InfiniteMPO, mps::InfiniteMPS)
301-
check_length(mpo, mps)
293+
L = check_length(mpo, mps)
302294
T = promote_type(scalartype(mpo), scalartype(mps))
303-
fusers = PeriodicArray(map(mps.AL, mpo) do al, mp
304-
return fuser(T, _firstspace(al), _firstspace(mp))
305-
end)
306-
As = map(1:length(mps)) do i
295+
fusers = PeriodicArray(fuser.(T, left_virtualspace.(Ref(mps), 1:L),
296+
left_virtualspace.(Ref(mpo), 1:L)))
297+
As = map(1:L) do i
307298
return _fuse_mpo_mps(mpo[i], mps.AL[i], fusers[i], fusers[i + 1])
308299
end
309300
return changebonds(InfiniteMPS(As), SvdCut(; trscheme=notrunc()))
@@ -346,14 +337,14 @@ function TensorKit.dot(bra::FiniteMPS{T}, mpo::FiniteMPO, ket::FiniteMPS{T}) whe
346337
Nhalf = N ÷ 2
347338
# left half
348339
ρ_left = isomorphism(storagetype(T),
349-
left_virtualspace(bra, 0) left_virtualspace(mpo, 1)',
350-
left_virtualspace(ket, 0))
340+
left_virtualspace(bra, 1) left_virtualspace(mpo, 1)',
341+
left_virtualspace(ket, 1))
351342
T_left = TransferMatrix(ket.AL[1:Nhalf], mpo[1:Nhalf], bra.AL[1:Nhalf])
352343
ρ_left = ρ_left * T_left
353344

354345
# right half
355346
ρ_right = isomorphism(storagetype(T),
356-
right_virtualspace(ket, N) right_virtualspace(mpo, N)',
347+
right_virtualspace(ket, N) right_virtualspace(mpo, N),
357348
right_virtualspace(ket, length(ket)))
358349
T_right = TransferMatrix(ket.AR[(Nhalf + 1):end], mpo[(Nhalf + 1):end],
359350
bra.AR[(Nhalf + 1):end])

0 commit comments

Comments
 (0)