Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine pr #182

Closed
wants to merge 14 commits into from
60 changes: 59 additions & 1 deletion src/algorithms/changebonds/vumpssvd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,68 @@
return state, envs
end

function changebonds_parallel_n(state::InfiniteMPS, H, alg::VUMPSSvdCut,

Check warning on line 80 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L80

Added line #L80 was not covered by tests
envs=environments(state, H))
#prepare the loops we'll have to run over, this is different depending on wether the length of the state is odd or even !
subsets = nothing
start_locs = nothing
if iseven(length(state))
subsets = ["even", "odd"]
start_locs = Dict("even" => 1:2:length(state), "odd" => 2:2:length(state))

Check warning on line 87 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L83-L87

Added lines #L83 - L87 were not covered by tests
else
subsets = ["even", "odd", "last"]
start_locs = Dict("even" => 1:2:(length(state) - 1),

Check warning on line 90 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L89-L90

Added lines #L89 - L90 were not covered by tests
"odd" => 2:2:(length(state) - 1), "last" => length(state))
end

for subset in subsets
new_ALs = copy(state.AL)
@sync for loc in start_locs[subset]
Threads.@spawn begin
@plansor AC2[-1 -2; -3 -4] := state.AC[loc][-1 -2; 1] *

Check warning on line 98 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L94-L98

Added lines #L94 - L98 were not covered by tests
state.AR[loc + 1][1 -4; -3]

h_ac2 = ∂∂AC2(loc, state, H, envs)
(vals, vecs, _) = eigsolve(h_ac2, AC2, 1, :SR; tol=alg.tol_eigenval,

Check warning on line 102 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L101-L102

Added lines #L101 - L102 were not covered by tests
ishermitian=false)
nAC2 = vecs[1]

Check warning on line 104 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L104

Added line #L104 was not covered by tests

h_c = ∂∂C(loc + 1, state, H, envs)
(vals, vecs, _) = eigsolve(h_c, state.CR[loc + 1], 1, :SR;

Check warning on line 107 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L106-L107

Added lines #L106 - L107 were not covered by tests
tol=alg.tol_eigenval,
ishermitian=false)
nC2 = vecs[1]

Check warning on line 110 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L110

Added line #L110 was not covered by tests

#svd ac2, get new AL1 and S,V ---> AC
(AL1, S, V, eps) = tsvd(nAC2; trunc=alg.trscheme, alg=TensorKit.SVD())
@plansor AC[-1 -2; -3] := S[-1; 1] * V[1; -3 -2]

Check warning on line 114 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L113-L114

Added lines #L113 - L114 were not covered by tests

#find AL2 from AC and C as in vumps paper
QAC, _ = leftorth(AC; alg=QRpos())
QC, _ = leftorth(nC2; alg=QRpos())
dom_map = isometry(domain(QC), domain(QAC))

Check warning on line 119 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L117-L119

Added lines #L117 - L119 were not covered by tests

@plansor AL2[-1 -2; -3] := QAC[-1 -2; 1] * conj(dom_map[2; 1]) *

Check warning on line 121 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L121

Added line #L121 was not covered by tests
conj(QC[-3; 2])

#make a new state using the updated A's
new_ALs[loc] = AL1
new_ALs[loc + 1] = AL2

Check warning on line 126 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L125-L126

Added lines #L125 - L126 were not covered by tests
end
end
state = InfiniteMPS(new_ALs; tol=alg.tol_gauge)
end
return state, envs

Check warning on line 131 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L128-L131

Added lines #L128 - L131 were not covered by tests
end

function changebonds(state::InfiniteMPS, H, alg::VUMPSSvdCut, envs=environments(state, H))
if (length(state) == 1)
return changebonds_1(state, H, alg, envs)
else
return changebonds_n(state, H, alg, envs)
@static if Defaults.parallelize_sites

Check warning on line 138 in src/algorithms/changebonds/vumpssvd.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/changebonds/vumpssvd.jl#L138

Added line #L138 was not covered by tests
return changebonds_parallel_n(state, H, alg, envs)
else
return changebonds_n(state, H, alg, envs)
end
end
end
74 changes: 59 additions & 15 deletions src/algorithms/grassmann.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
module GrassmannMPS

using ..MPSKit
using ..Defaults
using TensorKit
import TensorKitManifolds.Grassmann

Expand Down Expand Up @@ -69,22 +70,38 @@

function ManifoldPoint(state::Union{InfiniteMPS,FiniteMPS}, envs)
al_d = similar(state.AL)
for i in 1:length(state)
al_d[i] = MPSKit.∂∂AC(i, state, envs.opp, envs) * state.AC[i]
@static if Defaults.parallelize_sites

Check warning on line 73 in src/algorithms/grassmann.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/grassmann.jl#L73

Added line #L73 was not covered by tests
@sync for i in 1:length(state)
Threads.@spawn begin
al_d[i] = MPSKit.∂∂AC(i, state, envs.opp, envs) * state.AC[i]
end
end
else
for i in 1:length(state)
al_d[i] = MPSKit.∂∂AC(i, state, envs.opp, envs) * state.AC[i]
end
end

g = Grassmann.project.(al_d, state.AL)

Rhoreg = Vector{eltype(state.CR)}(undef, length(state))
δmin = sqrt(eps(real(scalartype(state))))
for i in 1:length(state)
Rhoreg[i] = regularize(state.CR[i], max(norm(g[i]) / 10, δmin))
@static if Defaults.parallelize_sites

Check warning on line 88 in src/algorithms/grassmann.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/grassmann.jl#L88

Added line #L88 was not covered by tests
@sync for i in 1:length(state)
Threads.@spawn begin
Rhoreg[i] = regularize(state.CR[i], max(norm(g[i]) / 10, δmin))
end
end
else
for i in 1:length(state)
Rhoreg[i] = regularize(state.CR[i], max(norm(g[i]) / 10, δmin))
end
end

return ManifoldPoint(state, envs, g, Rhoreg)
end

function ManifoldPoint(state::MPSMultiline, envs)
#TODO : support parralelize_sites
# FIXME: add support for unitcells
@assert length(state.AL) == 1 "GradientGrassmann only supports MPSMultiline without unitcells for now"

Expand Down Expand Up @@ -115,9 +132,16 @@
function fg(x::ManifoldPoint{T}) where {T<:Union{InfiniteMPS,FiniteMPS}}
# the gradient I want to return is the preconditioned gradient!
g_prec = Vector{PrecGrad{eltype(x.g),eltype(x.Rhoreg)}}(undef, length(x.g))

for i in 1:length(x.state)
g_prec[i] = PrecGrad(rmul!(copy(x.g[i]), x.state.CR[i]'), x.Rhoreg[i])
@static if Defaults.parallelize_sites

Check warning on line 135 in src/algorithms/grassmann.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/grassmann.jl#L135

Added line #L135 was not covered by tests
@sync for i in 1:length(x.state)
Threads.@spawn begin
g_prec[i] = PrecGrad(rmul!(copy(x.g[i]), x.state.CR[i]'), x.Rhoreg[i])
end
end
else
for i in 1:length(x.state)
g_prec[i] = PrecGrad(rmul!(copy(x.g[i]), x.state.CR[i]'), x.Rhoreg[i])
end
end

# TODO: the operator really should not be part of the environments, and this should
Expand All @@ -128,6 +152,7 @@
return real(f), g_prec
end
function fg(x::ManifoldPoint{<:MPSMultiline})
#TODO : support parralelize_sites
@assert length(x.state) == 1 "GradientGrassmann only supports MPSMultiline without unitcells for now"
# the gradient I want to return is the preconditioned gradient!
g_prec = map(enumerate(x.g)) do (i, cg)
Expand All @@ -147,6 +172,7 @@
Retract a left-canonical MPSMultiline along Grassmann tangent `g` by distance `alpha`.
"""
function retract(x::ManifoldPoint{<:MPSMultiline}, tg, alpha)
#TODO : support parralelize_sites
g = reshape(tg, size(x.state))

nal = similar(x.state.AL)
Expand All @@ -170,11 +196,19 @@
envs = x.envs
nal = similar(state.AL)
h = similar(g) # The tangent at the end-point
for i in 1:length(g)
nal[i], th = Grassmann.retract(state.AL[i], g[i].Pg, alpha)
h[i] = PrecGrad(th)
@static if Defaults.parallelize_sites

Check warning on line 199 in src/algorithms/grassmann.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/grassmann.jl#L199

Added line #L199 was not covered by tests
@sync for i in 1:length(g)
Threads.@spawn begin
nal[i], th = Grassmann.retract(state.AL[i], g[i].Pg, alpha)
h[i] = PrecGrad(th)
end
end
else
for i in 1:length(g)
nal[i], th = Grassmann.retract(state.AL[i], g[i].Pg, alpha)
h[i] = PrecGrad(th)
end
end

nstate = InfiniteMPS(nal, state.CR[end])

newpoint = ManifoldPoint(nstate, envs)
Expand All @@ -186,6 +220,7 @@
Retract a left-canonical finite MPS along Grassmann tangent `g` by distance `alpha`.
"""
function retract(x::ManifoldPoint{<:FiniteMPS}, g, alpha)
#TODO : support parralelize_sites.
state = x.state
envs = x.envs

Expand All @@ -208,9 +243,18 @@
`alpha`. `xp` is the end-point of the retraction.
"""
function transport!(h, x, g, alpha, xp)
for i in 1:length(h)
h[i] = PrecGrad(Grassmann.transport!(h[i].Pg, x.state.AL[i], g[i].Pg, alpha,
xp.state.AL[i]))
@static if Defaults.parallelize_sites

Check warning on line 246 in src/algorithms/grassmann.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/grassmann.jl#L246

Added line #L246 was not covered by tests
@sync for i in 1:length(h)
Threads.@spawn begin
h[i] = PrecGrad(Grassmann.transport!(h[i].Pg, x.state.AL[i], g[i].Pg, alpha,
xp.state.AL[i]))
end
end
else
for i in 1:length(h)
h[i] = PrecGrad(Grassmann.transport!(h[i].Pg, x.state.AL[i], g[i].Pg, alpha,
xp.state.AL[i]))
end
end
return h
end
Expand Down
123 changes: 111 additions & 12 deletions test/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,98 @@ end
end
end

@testset "InfiniteMPS 3-site groundstates" verbose = true begin
tol = 1e-8
g = 4.0
D = 6
H = repeat(force_planar(transverse_field_ising(; g)), 3)

@testset "VUMPS" begin
ψ₀ = repeat(InfiniteMPS(ℙ^2, ℙ^D), 3)
v₀ = variance(ψ₀, H)

# test logging
ψ, envs, δ = find_groundstate(ψ₀, H, VUMPS(; tol, verbosity=5, maxiter=2))

ψ, envs, δ = find_groundstate(ψ, H, VUMPS(; tol, verbosity=1))
v = variance(ψ, H, envs)

# test using low variance
@test sum(δ) ≈ 0 atol = 1e-3
@test v < v₀
@test v < 1e-2
end

@testset "IDMRG1" begin
ψ₀ = repeat(InfiniteMPS(ℙ^2, ℙ^D), 3)
v₀ = variance(ψ₀, H)

# test logging
ψ, envs, δ = find_groundstate(ψ₀, H, IDMRG1(; tol, verbosity=5, maxiter=2))

ψ, envs, δ = find_groundstate(ψ, H, IDMRG1(; tol, verbosity=1))
v = variance(ψ, H, envs)

# test using low variance
@test sum(δ) ≈ 0 atol = 1e-3
@test v < v₀
@test v < 1e-2
end

@testset "IDMRG2" begin
ψ₀ = repeat(InfiniteMPS(ℙ^2, ℙ^D), 3)
v₀ = variance(ψ₀, H)
trscheme = truncbelow(1e-8)

# test logging
ψ, envs, δ = find_groundstate(ψ₀, H,
IDMRG2(; tol, verbosity=5, maxiter=2,
trscheme))

ψ, envs, δ = find_groundstate(ψ, H,
IDMRG2(; tol, verbosity=1, trscheme))
v = variance(ψ, H, envs)

# test using low variance
@test sum(δ) ≈ 0 atol = 1e-3
@test v < v₀
@test v < 1e-2
end

@testset "GradientGrassmann" begin
ψ₀ = repeat(InfiniteMPS(ℙ^2, ℙ^D), 3)
v₀ = variance(ψ₀, H)

# test logging
ψ, envs, δ = find_groundstate(ψ₀, H,
GradientGrassmann(; tol, verbosity=5, maxiter=2))

ψ, envs, δ = find_groundstate(ψ, H, GradientGrassmann(; tol, verbosity=1))
v = variance(ψ, H, envs)

# test using low variance
@test sum(δ) ≈ 0 atol = 1e-3
@test v < v₀
@test v < 1e-2
end

@testset "Combination" begin
ψ₀ = repeat(InfiniteMPS(ℙ^2, ℙ^D), 3)
v₀ = variance(ψ₀, H)

alg = VUMPS(; tol=100 * tol, verbosity=1, maxiter=10) &
GradientGrassmann(; tol, verbosity=1, maxiter=50)
ψ, envs, δ = find_groundstate(ψ₀, H, alg)

v = variance(ψ, H, envs)

# test using low variance
@test sum(δ) ≈ 0 atol = 1e-3
@test v < v₀
@test v < 1e-2
end
end

@testset "LazySum FiniteMPS groundstate" verbose = true begin
tol = 1e-8
D = 15
Expand Down Expand Up @@ -471,25 +563,32 @@ end
nn = TensorMap(rand, ComplexF64, pspace * pspace, pspace * pspace)
nn += nn'

state = InfiniteMPS([pspace, pspace], [Dspace, Dspace])
state1 = InfiniteMPS(pspace, Dspace)
state2 = InfiniteMPS([pspace, pspace], [Dspace, Dspace])
state3 = InfiniteMPS([pspace, pspace, pspace], [Dspace, Dspace, Dspace])

state_re = changebonds(state,
state_re = changebonds(state2,
RandExpand(; trscheme=truncdim(dim(Dspace) * dim(Dspace))))
@test dot(state, state_re) ≈ 1 atol = 1e-8
@test dot(state2, state_re) ≈ 1 atol = 1e-8

state_oe, _ = changebonds(state,
state_oe, _ = changebonds(state2,
repeat(MPOHamiltonian(nn), 2),
OptimalExpand(;
trscheme=truncdim(dim(Dspace) *
dim(Dspace))))
@test dot(state, state_oe) ≈ 1 atol = 1e-8

state_vs, _ = changebonds(state, repeat(MPOHamiltonian(nn), 2),
VUMPSSvdCut(; trscheme=notrunc()))
@test dim(left_virtualspace(state, 1)) < dim(left_virtualspace(state_vs, 1))

state_vs_tr = changebonds(state_vs, SvdCut(; trscheme=truncdim(dim(Dspace))))
@test dim(right_virtualspace(state_vs_tr, 1)) < dim(right_virtualspace(state_vs, 1))
@test dot(state2, state_oe) ≈ 1 atol = 1e-8

#test vumpssvd with different unit cells
for state in [state1, state2, state3]
@show length(state)
state_vs, _ = changebonds(state, repeat(MPOHamiltonian(nn), length(state)),
VUMPSSvdCut(; trscheme=notrunc()))
@test dim(left_virtualspace(state, 1)) < dim(left_virtualspace(state_vs, 1))

state_vs_tr = changebonds(state_vs, SvdCut(; trscheme=truncdim(dim(Dspace))))
@test dim(right_virtualspace(state_vs_tr, 1)) <
dim(right_virtualspace(state_vs, 1))
end
end

@testset "finite mps" begin
Expand Down
Loading