Skip to content

Commit b8775be

Browse files
borisdevoslkdvos
andauthored
Compatibility with multifusion categories (#297)
* add_util_leg spinoff for MPOHamiltonian * apply add_util_mpoleg to correlator * use add_util_mpoleg in FiniteMPO * use add_util_mpoleg in test on correlator * avoid `oneunit(S)` in one constructor of `InfiniteMPOHamiltonian` * avoid `oneunit(S)` in one constructor of `FiniteMPOHamiltonian` * remove type `LocalOperator` in `_oneunit` * remove braidings in `left/right_excitation_transfer_system` of `InfiniteMPOHamiltonian` * typo in `right_excitation_transfer_system` * rewrite `(In)FiniteMPOHamiltonian` and the way `oneunit` was avoided * avoid `oneunit(spacetype(H))` evaluation * super important typo * remove comments * get `return_type` in `excitations` to evaluate the `sector` kwarg * typo * manipulate `oneunit`s in addition of `MPOHamiltonian`s * format * simplify expression * add comments * get `infinite_temperature_density_matrix` working * generalise identifying space in `infinite_temperature_density_matrix` * make util spaces generic in `left/right_excitation_transfer_system` * remove braiding in `InfiniteQP` environments + rename variables for consistency * Revert "remove braiding in `InfiniteQP` environments + rename variables for consistency" This reverts commit 2114cdc. * add multifusion tests * actually use my variable everywhere * add Z2 Ising model * compare to Z2 Ising model + add injectivity check * remove defaulting to `Z2Irrep` for new operators * fix kitaev model term (even if it's not used) * format * actually run the multifusion test * import TestSetup module, remove unused deps + add variance tests * specify allowed spin for Z2 `S_zz` + don't use deprecated call * add variance tests for `FiniteMPS` + allow it to be negative (?) + add `FiniteExcited` test * Revert "Merge branch 'master' of https://github.com/QuantumKitHub/MPSKit.jl into boris-MTK-compat" This reverts commit 2c96ab1, reversing changes made to a17874a. * Revert "Revert "Merge branch 'master' of https://github.com/QuantumKitHub/MPSKit.jl into boris-MTK-compat"" This reverts commit fdd95c7. * Revert "Merge branch 'master' of https://github.com/QuantumKitHub/MPSKit.jl into boris-MTK-compat" This reverts commit 2c96ab1, reversing changes made to 8cf041f. * Revert "Revert "Merge branch 'master' of https://github.com/QuantumKitHub/MPSKit.jl into boris-MTK-compat"" This reverts commit 2f1108e. * fix the messed up merges hopefully * format * actually format everything * typo * deal with float dimension * `left/rightunit` for MPS and MPO * using `left/rightunit(space)` * test updates * some `unitspace`s * some `rightunitspace`s * docstring to ED * remove ED error test * more `rightunitspace`s in tests * even more `rightunitspace`s * some `unit`s, `leftunit`s and `isunit`s * some code suggestions and fixes * update `add_util_leg` and delete `add_util_mpoleg` * format * relax only to first * check if hamiltonians are diagonal * `leftunitspace` where it feels spatially correct and allowed * Update src/algorithms/correlators.jl Co-authored-by: Lukas Devos <ldevos98@gmail.com> * deal with `unitspace` within `MPOHamiltonian` constructors * get `left/right_canicalize!` working * address some comments * unit space insertions and removals * bring back the wrapper --------- Co-authored-by: Lukas Devos <ldevos98@gmail.com>
1 parent a4639ff commit b8775be

25 files changed

+330
-114
lines changed

.github/workflows/Tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
- states
3030
- operators
3131
- algorithms
32+
- multifusion
3233
- other
3334
os:
3435
- ubuntu-latest

src/algorithms/ED.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
exact_diagonalization(H::FiniteMPOHamiltonian;
3-
sector=first(sectors(oneunit(physicalspace(H, 1)))),
3+
sector=rightunit(H),
44
len::Int=length(H), num::Int=1, which::Symbol=:SR,
55
alg=Defaults.alg_eigsolve(; dynamic_tols=false))
66
-> vals, state_vecs, convhist
@@ -13,7 +13,7 @@ equivalent to dense eigenvectors.
1313
- `H::FiniteMPOHamiltonian`: the Hamiltonian to diagonalize.
1414
1515
### Keyword arguments
16-
- `sector=first(sectors(oneunit(physicalspace(H, 1))))`: the total charge of the
16+
- `sector=rightunit(H)`: the total charge of the
1717
eigenvectors, which is chosen trivial by default.
1818
- `len::Int=length(H)`: the length of the system.
1919
- `num::Int=1`: the number of eigenvectors to find.
@@ -32,7 +32,7 @@ equivalent to dense eigenvectors.
3232
"""
3333
function exact_diagonalization(
3434
H::FiniteMPOHamiltonian;
35-
sector = one(sectortype(H)), num::Int = 1, which::Symbol = :SR,
35+
sector = rightunit(H), num::Int = 1, which::Symbol = :SR,
3636
alg = Defaults.alg_eigsolve(; dynamic_tols = false)
3737
)
3838
L = length(H)
@@ -44,7 +44,7 @@ function exact_diagonalization(
4444

4545
# fuse from left to right
4646
ALs = Vector{Union{Missing, TA}}(missing, L)
47-
left = oneunit(spacetype(H))
47+
left = spacetype(H)(rightunit(sector) => 1)
4848
for i in 1:(middle_site - 1)
4949
P = physicalspace(H, i)
5050
ALs[i] = isomorphism(T, left P fuse(left P))

src/algorithms/correlators.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function correlator(
1616
)
1717
first(js) > i || @error "i should be smaller than j ($i, $(first(js)))"
1818
S₁ = _firstspace(O₁)
19-
S₁ == oneunit(S₁) || throw(ArgumentError("O₁ should start with a trivial leg."))
19+
isunitspace(S₁) || throw(ArgumentError("O₁ should start with a trivial leg."))
2020
S₂ = _lastspace(O₂)
2121
S₂ == S₁' || throw(ArgumentError("O₂ should end with a trivial leg."))
2222

src/algorithms/excitation/chepigaansatz.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ end
3535

3636
function excitations(
3737
H, alg::ChepigaAnsatz, ψ::FiniteMPS, envs = environments(ψ, H);
38-
sector = one(sectortype(ψ)), num::Int = 1, pos::Int = length(ψ) ÷ 2
38+
sector = leftunit(ψ), num::Int = 1, pos::Int = length(ψ) ÷ 2
3939
)
4040
1 pos length(ψ) || throw(ArgumentError("invalid position $pos"))
41-
sector == one(sector) || error("not yet implemented for charged excitations")
41+
isunit(sector) || error("not yet implemented for charged excitations")
4242

4343
# add random offset to kickstart Krylov process:
4444
AC = ψ.AC[pos]
@@ -100,10 +100,10 @@ end
100100

101101
function excitations(
102102
H, alg::ChepigaAnsatz2, ψ::FiniteMPS, envs = environments(ψ, H);
103-
sector = one(sectortype(ψ)), num::Int = 1, pos::Int = length(ψ) ÷ 2
103+
sector = leftunit(ψ), num::Int = 1, pos::Int = length(ψ) ÷ 2
104104
)
105105
1 pos length(ψ) - 1 || throw(ArgumentError("invalid position $pos"))
106-
sector == one(sector) || error("not yet implemented for charged excitations")
106+
isunit(sector) || error("not yet implemented for charged excitations")
107107

108108
# add random offset to kickstart Krylov process:
109109
@plansor AC2[-1 -2; -3 -4] := ψ.AC[pos][-1 -2; 1] * ψ.AR[pos + 1][1 -4; -3]

src/algorithms/excitation/quasiparticleexcitation.jl

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ end
4646
function excitations(H, alg::QuasiparticleAnsatz, ϕ₀::InfiniteQP, lenvs, renvs; num::Int = 1)
4747
E = effective_excitation_renormalization_energy(H, ϕ₀, lenvs, renvs)
4848
H_eff = EffectiveExcitationHamiltonian(H, lenvs, renvs, E)
49-
5049
Es, ϕs, convhist = eigsolve(ϕ₀, num, :SR, alg.alg) do ϕ
5150
return H_eff(ϕ; alg.alg_environments...)
5251
end
@@ -86,14 +85,14 @@ Create and optimize infinite quasiparticle states.
8685
# Keywords
8786
- `num::Int`: number of excited states to compute
8887
- `solver`: algorithm for the linear solver of the quasiparticle environments
89-
- `sector=one(sectortype(left_ψ))`: charge of the quasiparticle state
88+
- `sector=leftunit(left_ψ)`: charge of the quasiparticle state
9089
- `parallel=true`: enable multi-threading over different momenta
9190
"""
9291
function excitations(
9392
H, alg::QuasiparticleAnsatz, momentum::Number, lmps::InfiniteMPS,
9493
lenvs = environments(lmps, H), rmps::InfiniteMPS = lmps,
9594
renvs = lmps === rmps ? lenvs : environments(rmps, H);
96-
sector = one(sectortype(lmps)), kwargs...
95+
sector = leftunit(lmps), kwargs...
9796
)
9897
ϕ₀ = LeftGaugedQP(rand, lmps, rmps; sector, momentum)
9998
return excitations(H, alg, ϕ₀, lenvs, renvs; kwargs...)
@@ -103,15 +102,23 @@ function excitations(
103102
lenvs = environments(lmps, H), rmps = lmps,
104103
renvs = lmps === rmps ? lenvs : environments(rmps, H);
105104
verbosity = Defaults.verbosity, num = 1,
106-
sector = one(sectortype(lmps)), parallel = true, kwargs...
107-
)
108-
Toutput = Core.Compiler.return_type(
109-
excitations,
110-
Tuple{
111-
typeof(H), typeof(alg), eltype(momenta), typeof(lmps),
112-
typeof(lenvs), typeof(rmps), typeof(renvs),
113-
}
105+
sector = leftunit(lmps), parallel = true, kwargs...
114106
)
107+
# wrapper to evaluate sector as positional argument
108+
Toutput = let
109+
function wrapper(H, alg, p, lmps, lenvs, rmps, renvs, sector; kwargs...)
110+
return excitations(
111+
H, alg, p, lmps, lenvs, rmps, renvs; sector, kwargs...
112+
)
113+
end
114+
Core.Compiler.return_type(
115+
wrapper, Tuple{
116+
typeof(H), typeof(alg), eltype(momenta), typeof(lmps),
117+
typeof(lenvs), typeof(rmps), typeof(renvs), typeof(sector),
118+
}
119+
)
120+
end
121+
115122
results = similar(momenta, Toutput)
116123
scheduler = parallel ? :greedy : :serial
117124
tmap!(results, momenta; scheduler) do momentum
@@ -167,13 +174,13 @@ Create and optimize finite quasiparticle states.
167174
168175
# Keywords
169176
- `num::Int`: number of excited states to compute
170-
- `sector=one(sectortype(left_ψ))`: charge of the quasiparticle state
177+
- `sector=leftunit(lmps)`: charge of the quasiparticle state
171178
"""
172179
function excitations(
173180
H, alg::QuasiparticleAnsatz, lmps::FiniteMPS,
174181
lenvs = environments(lmps, H), rmps::FiniteMPS = lmps,
175182
renvs = lmps === rmps ? lenvs : environments(rmps, H);
176-
sector = one(sectortype(lmps)), num = 1
183+
sector = leftunit(lmps), num = 1
177184
)
178185
ϕ₀ = LeftGaugedQP(rand, lmps, rmps; sector)
179186
return excitations(H, alg, ϕ₀, lenvs, renvs; num)
@@ -262,7 +269,7 @@ function excitations(
262269
H::MultilineMPO, alg::QuasiparticleAnsatz, momentum::Real, lmps::MultilineMPS,
263270
lenvs = environments(lmps, H), rmps = lmps,
264271
renvs = lmps === rmps ? lenvs : environments(rmps, H);
265-
sector = one(sectortype(lmps)), kwargs...
272+
sector = leftunit(lmps), kwargs...
266273
)
267274
ϕ₀ = LeftGaugedQP(randn, lmps, rmps; sector, momentum)
268275
return excitations(H, alg, ϕ₀, lenvs, renvs; kwargs...)

src/algorithms/fixedpoint.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
fixedpoint(A, x₀, which::Symbol; kwargs...) -> val, vec
55
fixedpoint(A, x₀, which::Symbol, alg) -> val, vec
66
7-
Compute the fixedpoint of a linear operator `A` using the specified eigensolver `alg`. The
7+
Compute the fixed point of a linear operator `A` using the specified eigensolver `alg`. The
88
fixedpoint is assumed to be unique.
99
"""
1010
function fixedpoint(A, x₀, which::Symbol, alg::Lanczos)
1111
vals, vecs, info = eigsolve(A, x₀, 1, which, alg)
1212

1313
if info.converged == 0
14-
@warnv 1 "fixedpoint not converged after $(info.numiter) iterations: normres = $(info.normres[1])"
14+
@warnv 1 "fixed point not converged after $(info.numiter) iterations: normres = $(info.normres[1])"
1515
end
1616

1717
return vals[1], vecs[1]
@@ -21,10 +21,10 @@ function fixedpoint(A, x₀, which::Symbol, alg::Arnoldi)
2121
TT, vecs, vals, info = schursolve(A, x₀, 1, which, alg)
2222

2323
if info.converged == 0
24-
@warnv 1 "fixedpoint not converged after $(info.numiter) iterations: normres = $(info.normres[1])"
24+
@warnv 1 "fixed point not converged after $(info.numiter) iterations: normres = $(info.normres[1])"
2525
end
2626
if size(TT, 2) > 1 && TT[2, 1] != 0
27-
@warnv 1 "non-unique fixedpoint detected"
27+
@warnv 1 "non-unique fixed point detected"
2828
end
2929

3030
return vals[1], vecs[1]

src/algorithms/groundstate/gradient_grassmann.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function find_groundstate(
5959
ψ::S, H, alg::GradientGrassmann, envs::P = environments(ψ, H)
6060
)::Tuple{S, P, Float64} where {S, P}
6161
!isa(ψ, FiniteMPS) || dim(ψ.C[end]) == 1 ||
62-
@warn "This is not fully supported - split the mps up in a sum of mps's and optimize seperately"
62+
@warn "This is not fully supported - split the mps up in a sum of mps's and optimize separately"
6363
normalize!(ψ)
6464

6565
fg(x) = GrassmannMPS.fg(x, H, envs)

src/algorithms/timestep/taylorcluster.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,14 @@ function make_time_mpo(
186186
H′ = copy(parent(H))
187187

188188
V_left = left_virtualspace(H[1])
189-
V_left′ = (V_left, oneunit(V_left), oneunit(V_left))
189+
V_left′ = (V_left, leftunitspace(V_left), leftunitspace(V_left))
190190
H′[1] = similar(H[1], V_left′ space(H[1], 2) domain(H[1]))
191191
for (I, v) in nonzero_pairs(H[1])
192192
H′[1][I] = v
193193
end
194194

195195
V_right = right_virtualspace(H[end])
196-
V_right′ = (oneunit(V_right), oneunit(V_right), V_right)
196+
V_right′ = (rightunitspace(V_right), rightunitspace(V_right), V_right)
197197
H′[end] = similar(H[end], codomain(H[end]) space(H[end], 3)' V_right′)
198198
for (I, v) in nonzero_pairs(H[end])
199199
H′[end][I[1], 1, 1, end] = v

src/algorithms/timestep/wii.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,14 @@ function make_time_mpo(
9494
H′ = copy(parent(H))
9595

9696
V_left = left_virtualspace(H[1])
97-
V_left′ = (V_left, oneunit(V_left), oneunit(V_left))
97+
V_left′ = (V_left, leftunitspace(V_left), leftunitspace(V_left))
9898
H′[1] = similar(H[1], V_left′ space(H[1], 2) domain(H[1]))
9999
for (I, v) in nonzero_pairs(H[1])
100100
H′[1][I] = v
101101
end
102102

103103
V_right = right_virtualspace(H[end])
104-
V_right′ = (oneunit(V_right), oneunit(V_right), V_right)
104+
V_right′ = (rightunitspace(V_right), rightunitspace(V_right), V_right)
105105
H′[end] = similar(H[end], codomain(H[end]) space(H[end], 3)' V_right′)
106106
for (I, v) in nonzero_pairs(H[end])
107107
H′[end][I[1], 1, 1, end] = v

src/algorithms/toolbox.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Return the density matrix of the infinite temperature state for a given Hamilton
2828
This is the identity matrix in the physical space, and the identity in the auxiliary space.
2929
"""
3030
function infinite_temperature_density_matrix(H::MPOHamiltonian)
31-
V = oneunit(spacetype(H))
31+
V = first(left_virtualspace(H[1]))
3232
W = map(1:length(H)) do site
3333
return BraidingTensor{scalartype(H)}(physicalspace(H, site), V)
3434
end
@@ -78,7 +78,7 @@ end
7878

7979
"""
8080
transfer_spectrum(above::InfiniteMPS; below=above, tol=Defaults.tol, num_vals=20,
81-
sector=first(sectors(oneunit(left_virtualspace(above, 1)))))
81+
sector=leftunit(above))
8282
8383
Calculate the partial spectrum of the left mixed transfer matrix corresponding to the
8484
overlap of a given `above` state and a `below` state. The `sector` keyword argument can be
@@ -89,7 +89,7 @@ domain of each eigenvector. The `tol` and `num_vals` keyword arguments are passe
8989
"""
9090
function transfer_spectrum(
9191
above::InfiniteMPS; below = above, tol = Defaults.tol, num_vals = 20,
92-
sector = first(sectors(oneunit(left_virtualspace(above, 1))))
92+
sector = leftunit(above)
9393
)
9494
init = randomize!(
9595
similar(
@@ -276,13 +276,14 @@ function periodic_boundary_conditions(mpo::InfiniteMPO{O}, L = length(mpo)) wher
276276
V_wrap = left_virtualspace(mpo, 1)
277277
ST = storagetype(O)
278278

279-
util = isometry(storagetype(O), oneunit(V_wrap) one(V_wrap))
279+
util = isometry(storagetype(O), rightunitspace(V_wrap) one(V_wrap))
280280
@plansor cup[-1; -2 -3] := id(ST, V_wrap)[-2; -3] * util[-1]
281281

282282
local F_right
283283
for i in 1:L
284-
V_left = i == 1 ? oneunit(V_wrap) : fuse(V_wrap left_virtualspace(mpo, i))
285-
V_right = i == L ? oneunit(V_wrap) : fuse(V_wrap right_virtualspace(mpo, i))
284+
# kept as rightunitspace, but might need to change if we consider off-diagonal MPOs
285+
V_left = i == 1 ? rightunitspace(V_wrap) : fuse(V_wrap left_virtualspace(mpo, i))
286+
V_right = i == L ? rightunitspace(V_wrap) : fuse(V_wrap right_virtualspace(mpo, i))
286287
output[i] = similar(
287288
mpo[i], V_left * physicalspace(mpo, i) physicalspace(mpo, i) * V_right
288289
)
@@ -337,7 +338,7 @@ function periodic_boundary_conditions(H::InfiniteMPOHamiltonian, L = length(H))
337338
output = Vector{O}(undef, L)
338339
for site in 1:L
339340
V_left = if site == 1
340-
oneunit(V_wrap)
341+
leftunitspace(V_wrap)
341342
else
342343
vs = Vector{S}(undef, chi_)
343344
for (k, v) in indmap
@@ -346,7 +347,7 @@ function periodic_boundary_conditions(H::InfiniteMPOHamiltonian, L = length(H))
346347
SumSpace(vs)
347348
end
348349
V_right = if site == L
349-
oneunit(V_wrap)
350+
rightunitspace(V_wrap)
350351
else
351352
vs = Vector{S}(undef, chi_)
352353
for (k, v) in indmap

0 commit comments

Comments
 (0)