Skip to content

Commit 0e29ff1

Browse files
authored
Fix subspace expansion for 1-site unit cell (#44)
1 parent cb9ffcc commit 0e29ff1

File tree

3 files changed

+96
-44
lines changed

3 files changed

+96
-44
lines changed

src/models/models.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ end
2424

2525
function InfiniteITensorSum(model::Model, s::CelledVector; kwargs...)
2626
N = length(s)
27-
H = InfiniteITensorSum(N)
2827
tensors = [ITensor(model, s, n; kwargs...) for n in 1:N] #slightly improved version. Note: the current implementation does not really allow for staggered potentials for example
2928
return InfiniteITensorSum(tensors)
3029
end

src/subspace_expansion.jl

Lines changed: 89 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -113,61 +113,98 @@ function subspace_expansion(
113113
NL *= dag(U)
114114
NR *= dag(V)
115115

116-
ALⁿ¹, l = ITensors.directsum(
116+
ALⁿ¹, newl = ITensors.directsum(
117117
ψ.AL[n1], dag(NL), uniqueinds.AL[n1], NL), uniqueinds(NL, ψ.AL[n1]); tags=("Left",)
118118
)
119-
ARⁿ², r = ITensors.directsum(
119+
ARⁿ², newr = ITensors.directsum(
120120
ψ.AR[n2], dag(NR), uniqueinds.AR[n2], NR), uniqueinds(NR, ψ.AR[n2]); tags=("Right",)
121121
)
122122

123-
C = ITensor(dag(l)..., dag(r)...)
123+
C = ITensor(dag(newl)..., dag(newr)...)
124124
ψCⁿ¹ = permute.C[n1], lⁿ¹..., rⁿ¹...)
125125
for I in eachindex.C[n1])
126126
v = ψCⁿ¹[I]
127127
if !iszero(v)
128128
C[I] = ψCⁿ¹[I]
129129
end
130130
end
131+
if nsites(ψ) == 1
132+
ALⁿ² = ITensor(commoninds(C, ARⁿ²), uniqueinds(ALⁿ¹, ψ.AL[n1 - 1])...)
133+
il = only(uniqueinds(ALⁿ¹, ALⁿ²))
134+
ĩl = only(uniqueinds(ALⁿ², ALⁿ¹))
135+
for IV in eachindval(inds(ALⁿ¹))
136+
ĨV = replaceind_indval(IV, il => ĩl)
137+
v = ALⁿ¹[IV...]
138+
if !iszero(v)
139+
ALⁿ²[ĨV...] = v
140+
end
141+
end
142+
ARⁿ¹ = ITensor(commoninds(C, ALⁿ¹), uniqueinds(ARⁿ², ψ.AR[n2 + 1])...)
143+
ir = only(uniqueinds(ARⁿ², ARⁿ¹))
144+
ĩr = only(uniqueinds(ARⁿ¹, ARⁿ²))
145+
for IV in eachindval(inds(ARⁿ²))
146+
ĨV = replaceind_indval(IV, ir => ĩr)
147+
v = ARⁿ²[IV...]
148+
if !iszero(v)
149+
ARⁿ¹[ĨV...] = v
150+
end
151+
end
131152

132-
# Also expand the dimension of the neighboring MPS tensors
133-
ALⁿ² = ITensor(dag(l)..., uniqueinds.AL[n2], ψ.AL[n1])...)
134-
135-
il = only(uniqueinds.AL[n2], ALⁿ²))
136-
ĩl = only(uniqueinds(ALⁿ², ψ.AL[n2]))
137-
for IV in eachindval(inds.AL[n2]))
138-
ĨV = replaceind_indval(IV, il => ĩl)
139-
v = ψ.AL[n2][IV...]
140-
if !iszero(v)
141-
ALⁿ²[ĨV...] = v
153+
CL = combiner(newl; tags=tags(only(lⁿ¹)))
154+
newind = uniqueinds(CL, newl)
155+
newind = replacetags(newind, tags(only(newind)), tags(r[n1 - 1]))
156+
temp = δ(dag(newind), newr)
157+
ALⁿ² *= CL
158+
ALⁿ² *= temp
159+
CR = combiner(newr; tags=tags(only(rⁿ¹)))
160+
newind = uniqueinds(CR, newr)
161+
newind = replacetags(newind, tags(only(newind)), tags(l[n2]))
162+
temp = δ(dag(newind), newl)
163+
ARⁿ¹ *= CR
164+
ARⁿ¹ *= temp
165+
C = (C * dag(CL)) * dag(CR)
166+
return (ALⁿ¹, ALⁿ²), C, (ARⁿ¹, ARⁿ²)
167+
else
168+
# Also expand the dimension of the neighboring MPS tensors
169+
ALⁿ² = ITensor(dag(newl)..., uniqueinds.AL[n2], ψ.AL[n1])...)
170+
171+
il = only(uniqueinds.AL[n2], ALⁿ²))
172+
ĩl = only(uniqueinds(ALⁿ², ψ.AL[n2]))
173+
for IV in eachindval(inds.AL[n2]))
174+
ĨV = replaceind_indval(IV, il => ĩl)
175+
v = ψ.AL[n2][IV...]
176+
if !iszero(v)
177+
ALⁿ²[ĨV...] = v
178+
end
142179
end
143-
end
144180

145-
ARⁿ¹ = ITensor(dag(r)..., uniqueinds.AR[n1], ψ.AR[n2])...)
181+
ARⁿ¹ = ITensor(dag(newr)..., uniqueinds.AR[n1], ψ.AR[n2])...)
146182

147-
ir = only(uniqueinds.AR[n1], ARⁿ¹))
148-
ĩr = only(uniqueinds(ARⁿ¹, ψ.AR[n1]))
149-
for IV in eachindval(inds.AR[n1]))
150-
ĨV = replaceind_indval(IV, ir => ĩr)
151-
v = ψ.AR[n1][IV...]
152-
if !iszero(v)
153-
ARⁿ¹[ĨV...] = v
183+
ir = only(uniqueinds.AR[n1], ARⁿ¹))
184+
ĩr = only(uniqueinds(ARⁿ¹, ψ.AR[n1]))
185+
for IV in eachindval(inds.AR[n1]))
186+
ĨV = replaceind_indval(IV, ir => ĩr)
187+
v = ψ.AR[n1][IV...]
188+
if !iszero(v)
189+
ARⁿ¹[ĨV...] = v
190+
end
154191
end
155-
end
156192

157-
CL = combiner(l; tags=tags(only(lⁿ¹)))
158-
CR = combiner(r; tags=tags(only(rⁿ¹)))
159-
ALⁿ¹ *= CL
160-
ALⁿ² *= dag(CL)
161-
ARⁿ² *= CR
162-
ARⁿ¹ *= dag(CR)
163-
C = (C * dag(CL)) * dag(CR)
193+
CL = combiner(newl; tags=tags(only(lⁿ¹)))
194+
CR = combiner(newr; tags=tags(only(rⁿ¹)))
195+
ALⁿ¹ *= CL
196+
ALⁿ² *= dag(CL)
197+
ARⁿ² *= CR
198+
ARⁿ¹ *= dag(CR)
199+
C = (C * dag(CL)) * dag(CR)
200+
return (ALⁿ¹, ALⁿ²), C, (ARⁿ¹, ARⁿ²)
201+
end
164202

165203
# TODO: delete or only print when verbose
166204
## ψ₂ = ψ.AL[n1] * ψ.C[n1] * ψ.AR[n2]
167205
## ψ̃₂ = ALⁿ¹ * C * ARⁿ²
168206
## local_energy(ψ, H) = (noprime(ψ * H) * dag(ψ))[]
169207

170-
return (ALⁿ¹, ALⁿ²), C, (ARⁿ¹, ARⁿ²)
171208
end
172209

173210
function subspace_expansion(ψ, H; kwargs...)
@@ -181,12 +218,28 @@ function subspace_expansion(ψ, H; kwargs...)
181218
ALⁿ¹², Cⁿ¹, ARⁿ¹² = subspace_expansion(ψ, H, (n1, n2); kwargs...)
182219
ALⁿ¹, ALⁿ² = ALⁿ¹²
183220
ARⁿ¹, ARⁿ² = ARⁿ¹²
184-
AL[n1] = ALⁿ¹
185-
AL[n2] = ALⁿ²
186-
C[n1] = Cⁿ¹
187-
AR[n1] = ARⁿ¹
188-
AR[n2] = ARⁿ²
221+
if N == 1
222+
AL[n1] = ALⁿ²
223+
C[n1] = Cⁿ¹
224+
AR[n2] = ARⁿ¹
225+
else
226+
AL[n1] = ALⁿ¹
227+
AL[n2] = ALⁿ²
228+
C[n1] = Cⁿ¹
229+
AR[n1] = ARⁿ¹
230+
AR[n2] = ARⁿ²
231+
end
189232
ψ = InfiniteCanonicalMPS(AL, C, AR)
190233
end
191234
return ψ
192235
end
236+
#
237+
#
238+
# tt = ψ1.AL[1] * ψ1.C[1]; e = (tt * dag(tt))[]
239+
# @show norm( ψ1.AL[1] * ψ1.C[1] - ψ1.C[0] * ψ1.AR[1] )
240+
# l = linkinds(only, ψ1.AL)
241+
# r = linkinds(only, ψ1.AR)
242+
# tt = δ(l[0], prime(dag(l[0]))) * ψ1.AL[1] * dag(prime(ψ1)).AL[1] * dag(δ(s[1], dag(prime(s[1]))));
243+
# tt == denseblocks(δ(l[1], prime(dag(l[1]))))
244+
# tt = δ(dag(r[1]), prime(r[1])) * ψ1.AR[1] * dag(prime(ψ1)).AR[1] * dag(δ(s[1], dag(prime(s[1]))));
245+
# tt == denseblocks(δ(dag(r[0]), prime(r[0])))

test/test_vumps.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ using Random
3838

3939
for multisite_update_alg in ["sequential", "parallel"],
4040
conserve_qns in [true, false],
41-
nsites in [2, 3, 4],
41+
nsites in [1, 2, 3, 4],
4242
time_step in [-Inf, -0.5]
4343

44-
if conserve_qns
45-
# Flux density is inconsistent for odd unit cells
46-
isodd(nsites) && continue
47-
end
44+
#if conserve_qns
45+
# Flux density is inconsistent for odd unit cells
46+
# isodd(nsites) && continue
47+
#end
4848

49-
space_ = fill(space_shifted(model, 0; conserve_qns=conserve_qns), nsites)
49+
space_ = fill(space_shifted(model, 1; conserve_qns=conserve_qns), nsites)
5050
s = infsiteinds("S=1/2", nsites; space=space_)
5151
ψ = InfMPS(s, initstate)
5252

@@ -123,7 +123,7 @@ end
123123
## space = (("SzParity", 1, 2) => χ ÷ 2) ⊕ (("SzParity", 0, 2) => χ ÷ 2)
124124
## ψ = InfiniteMPS(ComplexF64, s; space=space)
125125
## randn!.(ψ)
126-
##
126+
##
127127
## ψ = orthogonalize(ψ, :)
128128
## @test prod(ψ.AL[1:N]) * ψ.C[N] ≈ ψ.C[0] * prod(ψ.AR[1:N])
129129
## end

0 commit comments

Comments
 (0)