Skip to content

Commit 0f67079

Browse files
committed
changes to pinv and changebonds
1 parent 1f384cf commit 0f67079

7 files changed

Lines changed: 207 additions & 77 deletions

File tree

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
11
struct NoExpand <: Algorithm end
22

3-
function changebonds_left(AL, Cs, alg; kwargs...)
4-
AL, Cs = changebonds(; expand_rightspace = AL, embed_leftspace = Cs, alg, kwargs...)[[2,end]]
5-
return AL, Cs
3+
function changebonds_left(AL, C::AbstractTensorMap, alg; kwargs...)
4+
Anew, Cnew = changebonds_left(AL, (C,), alg; kwargs...)
5+
return Anew, only(Cnew)
6+
end
7+
function changebonds_left(AL, Cs::Tuple, alg; kwargs...)
8+
ALnew, Csnew = changebonds(; expand_rightspace = AL, embed_leftspace = Cs, alg, kwargs...)[[2,end]]
9+
Csnew = collect(Csnew)
10+
for i in eachindex(Csnew)[1:1]
11+
@assert ALnew * Csnew[i] AL * Cs[i] "Error in left embedding is large"
12+
end
13+
return ALnew, Csnew
14+
end
15+
16+
function changebonds_right(C::AbstractTensorMap, AR, alg; kwargs...)
17+
Cnew, ARnew = changebonds_right((C,), AR, alg; kwargs...)
18+
return only(Cnew), ARnew
619
end
720
function changebonds_right(Cs, AR, alg; kwargs...)
8-
Cs, AR = changebonds(; expand_leftspace = AR, embed_rightspace = Cs, alg, kwargs...)[[1,4]]
9-
return Cs, AR
21+
Csnew, ARnew = changebonds(; expand_leftspace = AR, embed_rightspace = Cs, alg, kwargs...)[[1,4]]
22+
Csnew = collect(Csnew)
23+
for i in eachindex(Csnew)[1:1]
24+
@assert Csnew[i] * ARnew Cs[i] * AR "Error in right embedding is $(norm(Csnew[i] * ARnew - Cs[i] * AR))"
25+
end
26+
return Csnew, ARnew
1027
end
1128
function changebonds(al,c,ar, alg; kwargs...)
12-
_, al, c, ar, _ = changebonds(; expand_rightspace = al, expand_leftspace = ar, embed_both = (c,), alg, kwargs...)
13-
return al, only(c), ar
29+
_, alnew, cnew, arnew, _ = changebonds(; expand_rightspace = al, expand_leftspace = ar, embed_both = (c,), alg, kwargs...)
30+
@assert alnew * only(cnew) * arnew al * c * ar "Error in two-site embedding is $(norm(alnew * only(cnew) * arnew - al * c * ar))"
31+
return alnew, only(cnew), arnew
1432
end
1533

1634
function changebonds(;
@@ -21,8 +39,8 @@ function changebonds(;
2139
embed_both = missing,
2240
alg,
2341
ac2 = missing,
24-
expansion_leftspace = ismissing(ac2) ? missing : sup_inf_space(ac2),
25-
expansion_rightspace = ismissing(expansion_leftspace) ? (ismissing(ac2) ? missing : sup_inf_space(ac2)) : expansion_leftspace,
42+
expansion_leftspace =missing, # = ismissing(ac2) ? missing : sup_inf_space(ac2),
43+
expansion_rightspace = missing #ismissing(expansion_leftspace) ? (ismissing(ac2) ? missing : sup_inf_space(ac2)) : expansion_leftspace,
2644
)
2745
return changebonds(
2846
embed_rightspace, expand_rightspace,embed_both, expand_leftspace, embed_leftspace, alg;
@@ -36,24 +54,28 @@ function changebonds(
3654
)
3755
if !ismissing(expand_rightspace)
3856
expand_rightspace_new = _expand_leftisometry(expand_rightspace, alg, expansion_leftspace)
39-
if space(expand_rightspace) != space(expand_rightspace_new) || true
57+
if space(expand_rightspace) != space(expand_rightspace_new)
58+
println("happened1")
4059
if !ismissing(embed_leftspace)
41-
embed_leftspace = (_embed_left_space(expand_rightspace_new, A, alg) for A in embed_leftspace)
60+
embed_leftspace = collect(_embed_left_space(expand_rightspace_new, expand_rightspace,A) for A in embed_leftspace)
4261
end
4362
if !ismissing(embed_both)
44-
embed_both = (_embed_left_space(expand_rightspace_new, A, alg) for A in embed_both)
63+
embed_both = collect(_embed_left_space(expand_rightspace_new, expand_rightspace, A) for A in embed_both)
4564
end
65+
else
66+
@assert expand_rightspace expand_rightspace_new "Error: expand_rightspace is not approximately equal to expand_rightspace_new, but their spaces are the same. This should not happen."
4667
end
4768
expand_rightspace = expand_rightspace_new
4869
end
4970
if !ismissing(expand_leftspace)
5071
expand_leftspace_new = _expand_rightisometry(expand_leftspace, alg, expansion_rightspace)
51-
if space(expand_leftspace) != space(expand_leftspace_new) || true
72+
if space(expand_leftspace) != space(expand_leftspace_new)
73+
println("happened2")
5274
if !ismissing(embed_rightspace)
53-
embed_rightspace = (_embed_right_space(A, expand_leftspace_new, alg) for A in embed_rightspace)
75+
embed_rightspace = collect(_embed_right_space(A,expand_leftspace, expand_leftspace_new) for A in embed_rightspace)
5476
end
5577
if !ismissing(embed_both)
56-
embed_both = (_embed_right_space(A, expand_leftspace_new, alg) for A in embed_both)
78+
embed_both = collect(_embed_right_space(A, expand_leftspace, expand_leftspace_new) for A in embed_both)
5779
end
5880
end
5981
expand_leftspace = expand_leftspace_new
@@ -68,6 +90,9 @@ end
6890
function sup_inf_space(ac2)
6991
VL = fuse(space(ac2, 1) space(ac2, 2))
7092
VR = fuse(space(ac2, 3) space(ac2, 4))
93+
@show VL, VR
94+
@show supremum(VL, VR), infimum(VL, VR)
95+
@show supremum(VL, VR) infimum(VL, VR)
7196
return supremum(VL, VR) infimum(VL, VR)
7297
end
7398
function _sample_space(space, sup, trscheme)
@@ -77,51 +102,94 @@ end
77102
function _expand_leftisometry(A::MPSTensor, alg, expansion_leftspace)
78103
VL = left_null(A)
79104
V = _sample_space(right_virtualspace(VL), expansion_leftspace, alg.trscheme)
105+
# @show right_virtualspace(VL), expansion_leftspace, V
106+
dim(V) == 0 && return A
80107
XL = randisometry(scalartype(VL), right_virtualspace(VL) V)
81-
return catdomain(A, VL * XL)
108+
x = catdomain(A, VL * XL)
109+
@tensor I1[right'; right] := x[phys,left,right] * conj(x[phys,left,right'])
110+
@assert I1 one(I1) "I1 is $I1"
111+
return x
82112
end
83113

84114
function _expand_rightisometry(A::MPSTensor, alg, expansion_rightspace)
85115
return _transpose_front(_expand_rightisometry(_transpose_tail(A; copy = true), alg, expansion_rightspace))
86116
end
87117
function _expand_rightisometry(AR_tail::AbstractTensorMap, alg, expansion_rightspace)
88118
VR = right_null(AR_tail)
119+
@tensor overlap[left'; left] := AR_tail[left,phys,right] * conj(VR[left',phys,right])
120+
@assert abs(norm(overlap))<1e-10 "Error in overlap is $(norm(overlap))"
121+
89122
V = _sample_space(space(VR, 1), expansion_rightspace, alg.trscheme)
123+
dim(V) == 0 && return AR_tail
90124
XR = randisometry(scalartype(VR), space(VR, 1) V)
91-
return catcodomain(AR_tail, XR' * VR)
125+
b = XR' * VR
126+
@tensor I1[left; left'] := b[left,phys,right] * conj(b[left',phys,right])
127+
@assert I1 one(I1) "Error in b is $(norm(I1 - one(I1))) $(norm(I1)), $(norm(one(I1)))"
128+
129+
x = catcodomain(AR_tail, b)
130+
x = _transpose_front(x)
131+
@tensor I1[left'; left] := x[left,phys,right] * conj(x[left',phys,right])
132+
@assert I1 one(I1) "Error is $(norm(I1 - one(I1))) $(norm(I1)), $(norm(one(I1)))"
133+
return _transpose_tail(x)
92134
end
93135

94-
function _embed_left_space(A::MPSTensor, C::MPSBondTensor, alg)
136+
function _embed_left_space(A::MPSTensor, C::MPSBondTensor, alg::Algorithm)
95137
C′ = similar(C, right_virtualspace(A) right_virtualspace(C))
96138
scale!(randn!(C′), alg.noisefactor)
97139
C′ = TensorKit.absorb!(C′, C)
98140
return C′
99141
end
100-
function _embed_left_space(A::MPSTensor, Anext::MPSTensor, alg)
142+
function _embed_left_space(A::MPSTensor, Anext::MPSTensor, alg::Algorithm)
101143
Anext′ = similar(Anext, right_virtualspace(A) physicalspace(Anext) right_virtualspace(Anext))
102144
scale!(randn!(Anext′), alg.noisefactor)
103145
Anext′ = TensorKit.absorb!(Anext′, Anext)
104146
return Anext′
105147
end
106148

107-
function _embed_right_space(C::MPSBondTensor, A::AbstractTensorMap, alg)
149+
function _embed_right_space(C::MPSBondTensor, A::AbstractTensorMap, alg::Algorithm)
108150
C′ = similar(C, left_virtualspace(C) space(A, 1))
109151
scale!(randn!(C′), alg.noisefactor)
110152
C′ = TensorKit.absorb!(C′, C)
111153
return C′
112154
end
113-
function _embed_right_space(Anext::MPSTensor, A::AbstractTensorMap, alg)
155+
function _embed_right_space(Anext::MPSTensor, A::AbstractTensorMap, alg::Algorithm)
114156
Anext′ = similar(Anext, left_virtualspace(Anext) physicalspace(Anext) space(A, 1))
115157
scale!(randn!(Anext′), alg.noisefactor)
116158
Anext′ = TensorKit.absorb!(Anext′, Anext)
117159
return Anext′
118160
end
119161

162+
function _embed_left_space(A::MPSTensor, Aold::MPSTensor, C::MPSBondTensor)
163+
@tensor C_new[-1; -2] := conj(A[1,2;-1])*Aold[1,2;3] *C[3; -2]
164+
return add_noise(C_new)
165+
end
166+
function _embed_left_space(A::MPSTensor, Aold::MPSTensor, C::MPSTensor)
167+
@tensor C_new[-1,-2; -3] := conj(A[1,2;-1])*Aold[1,2;3]*C[3,-2; -3]
168+
return add_noise(C_new)
169+
end
170+
function _embed_right_space(C::MPSBondTensor, Aold::AbstractTensorMap, A::AbstractTensorMap)
171+
@tensor C_new[-1; -2] := C[-1; 1]*Aold[1,2;3]*conj(A[-2,2; 3])
172+
return add_noise(C_new)
173+
end
174+
function _embed_right_space(C::MPSTensor, Aold::AbstractTensorMap, A::AbstractTensorMap)
175+
@tensor C_new[-1,-2; -3] := C[-1,-2; 1]*Aold[1,2;3]*conj(A[-3,2; 3])
176+
return add_noise(C_new)
177+
end
178+
179+
function add_noise(A::AbstractTensorMap, noisefactor=eps()^(3/4))
180+
A′ = similar(A)
181+
scale!(randn!(A′), noisefactor)
182+
return A + A′
183+
end
184+
185+
186+
187+
120188

121189
extract_sector_types(::Type{GradedSpace{S,D}}) where {S<:Sector,D} = (S,)
122190
extract_sector_types(::Type{GradedSpace{ProductSector{T},D}}) where {T<:Tuple,D} = Tuple(T.parameters)
123191
extract_sector_types(sp::GradedSpace) = extract_sector_types(typeof(sp))
124-
function generate_sampling_space(psi::MPSKit.AbstractMPS; cutoff::Integer=100, minsize::Integer=1)
192+
function generate_sampling_space(psi::MPSKit.AbstractMPS; cutoff::Integer=50, minsize::Integer=1)
125193
sp = physicalspace(psi.AL[1])
126194
I = sectortype(sp)
127195
types = extract_sector_types(sp)
@@ -138,29 +206,41 @@ end
138206

139207
function constrained_product(iters, cutoff)
140208
N = length(iters)
141-
142-
# 1. Materialize the necessary prefixes (0 to cutoff -> cutoff + 1 elements)
209+
210+
# Materialize prefixes up to cutoff (0..cutoff -> cutoff + 1 elements)
143211
prefixes = [collect(Iterators.take(it, cutoff + 1)) for it in iters]
212+
cutoff_sq = cutoff^2
144213

145-
# 2. Lazy generation via Channel
214+
# Generate tuples whose index-vector lies inside an L2 ball (sphere)
215+
# i.e. sum(i.^2) <= cutoff^2. We prune by limiting each coordinate
216+
# to floor(sqrt(remaining_budget_sq)) and to the available prefix length.
146217
return Channel() do channel
147-
function recurse(dim, current_sum, current_tuple)
218+
function recurse(dim, current_sqsum, current_tuple)
219+
# available maximum index for this dimension from collected prefix
220+
max_avail = length(prefixes[dim]) - 1
221+
if max_avail < 0
222+
return
223+
end
224+
148225
if dim == N
149-
# Remaining budget for the last dimension
150-
remaining = cutoff - current_sum
151-
for i in 0:remaining
152-
# i+1 because Julia is 1-indexed for array access
153-
put!(channel, (current_tuple..., prefixes[dim][i+1]))
226+
rem_sq = cutoff_sq - current_sqsum
227+
max_i = min(max_avail, floor(Int, sqrt(max(0, rem_sq))))
228+
if max_i >= 0
229+
for i in 0:max_i
230+
put!(channel, (current_tuple..., prefixes[dim][i+1]))
231+
end
154232
end
155233
else
156-
# Each index can be anything from 0 up to the remaining budget
157-
upper_bound = cutoff - current_sum
158-
for i in 0:upper_bound
159-
recurse(dim + 1, current_sum + i, (current_tuple..., prefixes[dim][i+1]))
234+
rem_sq = cutoff_sq - current_sqsum
235+
max_i = min(max_avail, cutoff, floor(Int, sqrt(max(0, rem_sq))))
236+
if max_i >= 0
237+
for i in 0:max_i
238+
recurse(dim + 1, current_sqsum + i*i, (current_tuple..., prefixes[dim][i+1]))
239+
end
160240
end
161241
end
162242
end
163-
243+
164244
recurse(1, 0, ())
165245
end
166246
end

src/algorithms/groundstate/dmrg.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ function find_groundstate!(::FiniteChainStyle, ψ, H, alg::DMRG2, envs = environ
137137
ϵ = maximum(ϵs)
138138
log = IterLog("DMRG2")
139139

140+
E = 0.0
141+
140142
LoggingExtras.withlevel(; alg.verbosity) do
141143
for iter in 1:(alg.maxiter)
142144
alg_eigsolve = updatetol(alg.alg_eigsolve, iter, ϵ)
@@ -151,14 +153,15 @@ function find_groundstate!(::FiniteChainStyle, ψ, H, alg::DMRG2, envs = environ
151153
_, newA2center = fixedpoint(Hac2, ac2, :SR, alg_eigsolve)
152154

153155
al, c, ar = svd_trunc!(newA2center; trunc = trscheme, alg = alg.alg_svd)
154-
al, (c,) = changebonds_left(al, (c, ), expscheme; ac2 = ac2)
156+
al, c = changebonds_left(al, c, expscheme; ac2 = ac2)
155157
normalize!(c)
156158
v = @plansor ac2[1 2; 3 4] * conj(al[1 2; 5]) * conj(c[5; 6]) * conj(ar[6; 3 4])
157159
ϵs[pos] = max(ϵs[pos], abs(1 - abs(v)))
158160

159161
ψ.AC[pos] = (al, complex(c))
160162
ψ.AC[pos + 1] = (complex(c), _transpose_front(ar))
161163
end
164+
println(ϵs)
162165

163166
# right to left sweep
164167
for pos in (length(ψ) - 2):-1:1
@@ -167,7 +170,7 @@ function find_groundstate!(::FiniteChainStyle, ψ, H, alg::DMRG2, envs = environ
167170
_, newA2center = fixedpoint(Hac2, ac2, :SR, alg_eigsolve)
168171

169172
al, c, ar = svd_trunc!(newA2center; trunc = trscheme, alg = alg.alg_svd)
170-
(c,), ar = changebonds_right((c,), ar, expscheme; ac2 = ac2)
173+
c, ar = changebonds_right(c, ar, expscheme; ac2 = ac2)
171174
normalize!(c)
172175
v = @plansor ac2[1 2; 3 4] * conj(al[1 2; 5]) * conj(c[5; 6]) * conj(ar[6; 3 4])
173176
ϵs[pos] = max(ϵs[pos], abs(1 - abs(v)))
@@ -179,16 +182,17 @@ function find_groundstate!(::FiniteChainStyle, ψ, H, alg::DMRG2, envs = environ
179182
ϵ = maximum(ϵs)
180183
ψ, envs = alg.finalize(iter, ψ, H, envs)::Tuple{typeof(ψ), typeof(envs)}
181184

185+
E = expectation_value(ψ, H, envs)
182186
if ϵ <= alg.tol && iter > alg.miniter
183-
@infov 2 logfinish!(log, iter, ϵ, expectation_value(ψ, H, envs))
187+
@infov 2 logfinish!(log, iter, ϵ, E)
184188
break
185189
end
186190
if iter == alg.maxiter
187-
@warnv 1 logcancel!(log, iter, ϵ, expectation_value(ψ, H, envs))
191+
@warnv 1 logcancel!(log, iter, ϵ, E)
188192
else
189-
@infov 3 logiter!(log, iter, ϵ, expectation_value(ψ, H, envs))
193+
@infov 3 logiter!(log, iter, ϵ, E)
190194
end
191195
end
192196
end
193-
return ψ, envs, ϵ
197+
return ψ, envs, ϵ, E
194198
end

0 commit comments

Comments
 (0)