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

Implement full-infinite projector algorithm #99

Merged
merged 21 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
13827ec
Add HalfInfiniteProjector and FullInfiniteProjector, add beginnings o…
pbrehmer Nov 28, 2024
ccb366f
Add half-infinite contractions methods and diagrams, refactor names s…
pbrehmer Dec 3, 2024
582e3ae
Add FullInfiniteEnviroment sparse struct
pbrehmer Dec 3, 2024
1016c6b
Update full-inf docstrings
pbrehmer Dec 3, 2024
8c8eec1
Add actual full-infinite contractions
pbrehmer Dec 4, 2024
4d0db6e
Add FullInfiniteProjector projector computation and remove redundant …
pbrehmer Dec 4, 2024
05dda44
Merge branch 'master' into pb-full-inf-proj
pbrehmer Dec 5, 2024
3ea633e
Split up CTMRG file and refactor simultaneous and sequential modes, i…
pbrehmer Dec 5, 2024
d9d0b05
Fix typos, make runnable, replace pullback with rrule_via_ad
pbrehmer Dec 6, 2024
85c2cf8
Make FullInfiniteProjector runnable
pbrehmer Dec 6, 2024
1d75b48
Add docstrings
pbrehmer Dec 6, 2024
16a9ee1
Fix FullInfiniteProjector for :sequential, add tests, remove old grad…
pbrehmer Dec 6, 2024
231cf92
Apply suggestions, update gaugefix test
pbrehmer Dec 9, 2024
48e41c3
Fix FixedSpaceTruncation
pbrehmer Dec 9, 2024
ea998b1
Format, fix gauge test, further steps towards FullInf differentiability
pbrehmer Dec 9, 2024
2082302
Fix differentiability and gradients test
pbrehmer Dec 10, 2024
663bf84
Restore gradients test
pbrehmer Dec 10, 2024
45456f0
Update gaugefix test again
pbrehmer Dec 10, 2024
528da01
Fix unitcell test
pbrehmer Dec 10, 2024
2052899
Merge branch 'master' of github.com:quantumghent/PEPSKit.jl into pb-f…
pbrehmer Dec 12, 2024
1c4800c
Fix formatting
pbrehmer Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ H = heisenberg_XYZ(InfiniteSquare(); Jx=-1, Jy=1, Jz=-1) # sublattice rotation t
# configuring the parameters
D = 2
chi = 20
ctm_alg = CTMRG(; tol=1e-10, miniter=4, maxiter=100, verbosity=1, trscheme=truncdim(chi))
ctm_alg = SimultaneousCTMRG(; tol=1e-10, trscheme=truncdim(chi))
opt_alg = PEPSOptimize(;
boundary_alg=ctm_alg,
optimizer=LBFGS(4; maxiter=100, gradtol=1e-4, verbosity=2),
Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ H = heisenberg_XYZ(InfiniteSquare(); Jx=-1, Jy=1, Jz=-1) # sublattice rotation t
# configuring the parameters
D = 2
chi = 20
ctm_alg = CTMRG(; tol=1e-10, miniter=4, maxiter=100, verbosity=1, trscheme=truncdim(chi))
ctm_alg = SimultaneousCTMRG(; tol=1e-10, trscheme=truncdim(chi))
opt_alg = PEPSOptimize(;
boundary_alg=ctm_alg,
optimizer=LBFGS(4; maxiter=100, gradtol=1e-4, verbosity=2),
Expand Down
8 changes: 6 additions & 2 deletions examples/boundary_mps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ mps, envs, ϵ = leading_boundary(mps, T, VUMPS())
N = abs(prod(expectation_value(mps, T)))

# This can be compared to the result obtained using the CTMRG algorithm
ctm = leading_boundary(peps, CTMRG(; verbosity=1), CTMRGEnv(peps, ComplexSpace(20)))
ctm = leading_boundary(
peps, SimultaneousCTMRG(; verbosity=1), CTMRGEnv(peps, ComplexSpace(20))
)
N´ = abs(norm(peps, ctm))

@show abs(N - N´) / N
Expand All @@ -53,7 +55,9 @@ mps2 = PEPSKit.initializeMPS(T2, fill(ComplexSpace(20), 2, 2))
mps2, envs2, ϵ = leading_boundary(mps2, T2, VUMPS())
N2 = abs(prod(expectation_value(mps2, T2)))

ctm2 = leading_boundary(peps2, CTMRG(; verbosity=1), CTMRGEnv(peps2, ComplexSpace(20)))
ctm2 = leading_boundary(
peps2, SimultaneousCTMRG(; verbosity=1), CTMRGEnv(peps2, ComplexSpace(20))
)
N2´ = abs(norm(peps2, ctm2))

@show abs(N2 - N2´) / N2
Expand Down
2 changes: 1 addition & 1 deletion examples/heisenberg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ H = heisenberg_XYZ(InfiniteSquare(); Jx=-1, Jy=1, Jz=-1)
# Parameters
χbond = 2
χenv = 20
ctm_alg = CTMRG(; tol=1e-10, miniter=4, maxiter=100, verbosity=2)
ctm_alg = SimultaneousCTMRG(; tol=1e-10, verbosity=2)
opt_alg = PEPSOptimize(;
boundary_alg=ctm_alg,
optimizer=LBFGS(4; maxiter=100, gradtol=1e-4, verbosity=2),
Expand Down
39 changes: 18 additions & 21 deletions examples/hubbard_su.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Test
using Printf
using Random
using PEPSKit
using TensorKit
Expand All @@ -14,15 +13,16 @@ if symm == Trivial
else
error("Not implemented")
end

peps = InfiniteWeightPEPS(rand, Float64, Pspace, Vspace; unitcell=(N1, N2))

# normalize vertex tensors
for ind in CartesianIndices(peps.vertices)
peps.vertices[ind] /= norm(peps.vertices[ind], Inf)
end

# Hubbard model Hamiltonian at half-filling
t, U = 1.0, 6.0
ham = hubbard_model(Float64, Trivial, Trivial, InfiniteSquare(N1, N2); t=t, U=U, mu=U / 2)
t, U = 1, 6
ham = hubbard_model(Float64, Trivial, Trivial, InfiniteSquare(N1, N2); t, U, mu=U / 2)

# simple update
dts = [1e-2, 1e-3, 4e-4, 1e-4]
Expand All @@ -31,32 +31,29 @@ maxiter = 10000
for (n, (dt, tol)) in enumerate(zip(dts, tols))
trscheme = truncerr(1e-10) & truncdim(Dcut)
alg = SimpleUpdate(dt, tol, maxiter, trscheme)
result = simpleupdate(peps, ham, alg; bipartite=false)
global peps = result[1]
peps, = simpleupdate(peps, ham, alg; bipartite=false)
end

# absort weight into site tensors
# absorb weight into site tensors
peps = InfinitePEPS(peps)

# CTMRG
χenv0, χenv = 6, 20
Espace = Vect[fℤ₂](0 => χenv0 / 2, 1 => χenv0 / 2)
envs = CTMRGEnv(randn, Float64, peps, Espace)
for χ in [χenv0, χenv]
trscheme = truncerr(1e-9) & truncdim(χ)
ctm_alg = CTMRG(;
maxiter=40, tol=1e-10, verbosity=3, trscheme=trscheme, ctmrgscheme=:sequential
)
global envs = leading_boundary(envs, peps, ctm_alg)
ctm_alg = SequentialCTMRG(; maxiter=300, tol=1e-7)
envs = leading_boundary(envs, peps, ctm_alg)
end

"""
Benchmark values of the ground state energy from
Qin, M., Shi, H., & Zhang, S. (2016). Benchmark study of the two-dimensional Hubbard model with auxiliary-field quantum Monte Carlo method. Physical Review B, 94(8), 085103.
"""
# measure physical quantities
E = costfun(peps, envs, ham) / (N1 * N2)
# Benchmark values of the ground state energy from
# Qin, M., Shi, H., & Zhang, S. (2016). Benchmark study of the two-dimensional Hubbard
# model with auxiliary-field quantum Monte Carlo method. Physical Review B, 94(8), 085103.
Es_exact = Dict(0 => -1.62, 2 => -0.176, 4 => 0.8603, 6 => -0.6567, 8 => -0.5243)
E_exact = Es_exact[U] - U / 2
@info @sprintf("Energy = %.8f\n", E)
@info @sprintf("Benchmark energy = %.8f\n", E_exact)
@test isapprox(E, E_exact; atol=1e-2)

# measure energy
E = costfun(peps, envs, ham) / (N1 * N2)
@info "Energy = $E"
@info "Benchmark energy = $E_exact"
@test isapprox(E, E_exact; atol=5e-2)
35 changes: 27 additions & 8 deletions src/PEPSKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module PEPSKit
using LinearAlgebra, Statistics, Base.Threads, Base.Iterators, Printf
using Base: @kwdef
using Compat
using Accessors
using Accessors: @set
using VectorInterface
using TensorKit, KrylovKit, MPSKit, OptimKit, TensorOperations
using ChainRulesCore, Zygote
Expand Down Expand Up @@ -43,6 +43,9 @@ include("algorithms/contractions/ctmrg_contractions.jl")

include("algorithms/ctmrg/sparse_environments.jl")
include("algorithms/ctmrg/ctmrg.jl")
include("algorithms/ctmrg/projectors.jl")
include("algorithms/ctmrg/simultaneous.jl")
include("algorithms/ctmrg/sequential.jl")
include("algorithms/ctmrg/gaugefix.jl")

include("algorithms/time_evolution/gatetools.jl")
Expand All @@ -61,12 +64,16 @@ include("utility/symmetrization.jl")
const ctmrg_tol = 1e-8
const fpgrad_maxiter = 30
const fpgrad_tol = 1e-6
const ctmrgscheme = :simultaneous
const reuse_env = true
const trscheme = FixedSpaceTruncation()
const fwd_alg = TensorKit.SDD()
const rrule_alg = Arnoldi(; tol=1e-2fpgrad_tol, krylovdim=48, verbosity=-1)
const svd_alg = SVDAdjoint(; fwd_alg, rrule_alg)
const projector_alg_type = HalfInfiniteProjector
const projector_alg = projector_alg_type(svd_alg, trscheme, 2)
const ctmrg_alg = SimultaneousCTMRG(
ctmrg_tol, ctmrg_maxiter, ctmrg_miniter, 2, projector_alg
)
const optimizer = LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=2)
const gradient_linsolver = KrylovKit.BiCGStab(;
maxiter=Defaults.fpgrad_maxiter, tol=Defaults.fpgrad_tol
Expand All @@ -83,12 +90,14 @@ Module containing default values that represent typical algorithm parameters.
- `ctmrg_tol`: Tolerance checking singular value and norm convergence
- `fpgrad_maxiter`: Maximal number of iterations for computing the CTMRG fixed-point gradient
- `fpgrad_tol`: Convergence tolerance for the fixed-point gradient iteration
- `ctmrgscheme`: Scheme for growing, projecting and renormalizing CTMRG environments
- `reuse_env`: If `true`, the current optimization step is initialized on the previous environment
- `trscheme`: Truncation scheme for SVDs and other decompositions
- `fwd_alg`: SVD algorithm that is used in the forward pass
- `rrule_alg`: Reverse-rule for differentiating that SVD
- `svd_alg`: Combination of `fwd_alg` and `rrule_alg`
- `projector_alg_type`: Default type of projector algorithm
- `projector_alg`: Algorithm to compute CTMRG projectors
- `ctmrg_alg`: Algorithm for performing CTMRG runs
- `optimizer`: Optimization algorithm for PEPS ground-state optimization
- `gradient_linsolver`: Default linear solver for the `LinSolver` gradient algorithm
- `iterscheme`: Scheme for differentiating one CTMRG iteration
Expand All @@ -97,19 +106,28 @@ Module containing default values that represent typical algorithm parameters.
"""
module Defaults
using TensorKit, KrylovKit, OptimKit, OhMyThreads
using PEPSKit: LinSolver, FixedSpaceTruncation, SVDAdjoint
using PEPSKit:
LinSolver,
FixedSpaceTruncation,
SVDAdjoint,
HalfInfiniteProjector,
SimultaneousCTMRG
const ctmrg_tol = 1e-8
const ctmrg_maxiter = 100
const ctmrg_miniter = 4
const ctmrg_tol = 1e-8
const fpgrad_maxiter = 30
const fpgrad_tol = 1e-6
const ctmrgscheme = :simultaneous
const sparse = false
const reuse_env = true
const trscheme = FixedSpaceTruncation()
const fwd_alg = TensorKit.SDD()
const rrule_alg = Arnoldi(; tol=1e-2fpgrad_tol, krylovdim=48, verbosity=-1)
const svd_alg = SVDAdjoint(; fwd_alg, rrule_alg)
const projector_alg_type = HalfInfiniteProjector
const projector_alg = projector_alg_type(svd_alg, trscheme, 2)
const ctmrg_alg = SimultaneousCTMRG(
ctmrg_tol, ctmrg_maxiter, ctmrg_miniter, 2, projector_alg
)
const optimizer = LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=2)
const gradient_linsolver = KrylovKit.BiCGStab(;
maxiter=Defaults.fpgrad_maxiter, tol=Defaults.fpgrad_tol
Expand Down Expand Up @@ -165,9 +183,10 @@ end
using .Defaults: set_scheduler!
export set_scheduler!
export SVDAdjoint, IterSVD, NonTruncSVDAdjoint
export FixedSpaceTruncation, ProjectorAlg, CTMRG, CTMRGEnv, correlation_length
export CTMRGEnv, SequentialCTMRG, SimultaneousCTMRG
export FixedSpaceTruncation, HalfInfiniteProjector, FullInfiniteProjector
export LocalOperator
export expectation_value, costfun, product_peps
export expectation_value, costfun, product_peps, correlation_length
export leading_boundary
export PEPSOptimize, GeomSum, ManualIter, LinSolver
export fixedpoint
Expand Down
54 changes: 40 additions & 14 deletions src/algorithms/contractions/ctmrg_contractions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,40 @@
end

"""
halfinfinite_environment(quadrant1::AbstractTensorMap{S,3,3}, quadrant2::AbstractTensorMap{S,3,3})
halfinfinite_environment(C_1, C_2, E_1, E_2, E_3, E_4,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}
halfinfinite_environment(C_1, C_2, E_1, E_2, E_3, E_4, x,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}
halfinfinite_environment(x, C_1, C_2, E_1, E_2, E_3, E_4,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}
contract_projectors(U, S, V, Q, Q_next)

Compute projectors based on a SVD of `Q * Q_next`, where the inverse square root
`isqS` of the singular values is computed.

Left projector:
```
-- |~~~~~~| -- |~~|
|Q_next| |V'| -- isqS --
== |~~~~~~| == |~~|
```

Right projector:
```
|~~| -- |~~~| --
-- isqS -- |U'| | Q |
|~~| == |~~~| ==
```
"""
function contract_projectors(U, S, V, Q, Q_next)
isqS = sdiag_pow(S, -0.5)
P_left = Q_next * V' * isqS # use * to respect fermionic case
P_right = isqS * U' * Q
return P_left, P_right
end

"""
half_infinite_environment(quadrant1::AbstractTensorMap{S,3,3}, quadrant2::AbstractTensorMap{S,3,3})
half_infinite_environment(C_1, C_2, E_1, E_2, E_3, E_4,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}
half_infinite_environment(C_1, C_2, E_1, E_2, E_3, E_4, x,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}
half_infinite_environment(x, C_1, C_2, E_1, E_2, E_3, E_4,
ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2) where {P<:PEPSTensor}

Contract two quadrants (enlarged corners) to form a half-infinite environment.

Expand All @@ -236,27 +263,26 @@
| || || |
```

Alternatively, contract environment with a vector `x` acting on it
Alternatively, contract the environment with a vector `x` acting on it

```
C_1 -- E_2 -- E_3 -- C_2
| || || |
E_1 == ket_bra_1 == ket_bra_2 == E_4
| || || |
[~~~~~~x~~~~~~]
|| |
```

or contract the adjoint environment with `x`, e.g. as needed for iterative solvers.
"""
function halfinfinite_environment(
function half_infinite_environment(
quadrant1::AbstractTensorMap{S,3,3}, quadrant2::AbstractTensorMap{S,3,3}
) where {S}
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
quadrant1[χ_in D_inabove D_inbelow; χ D1 D2] *
quadrant2[χ D1 D2; χ_out D_outabove D_outbelow]
end
function halfinfinite_environment(
function half_infinite_environment(

Check warning on line 285 in src/algorithms/contractions/ctmrg_contractions.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/contractions/ctmrg_contractions.jl#L285

Added line #L285 was not covered by tests
C_1, C_2, E_1, E_2, E_3, E_4, ket_1::P, ket_2::P, bra_1::P=ket_1, bra_2::P=ket_2
) where {P<:PEPSTensor}
return @autoopt @tensor env[χ_in D_inabove D_inbelow; χ_out D_outabove D_outbelow] :=
Expand All @@ -271,7 +297,7 @@
C_2[χ4; χ5] *
E_4[χ5 D7 D8; χ_out]
end
function halfinfinite_environment(
function half_infinite_environment(

Check warning on line 300 in src/algorithms/contractions/ctmrg_contractions.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/contractions/ctmrg_contractions.jl#L300

Added line #L300 was not covered by tests
C_1,
C_2,
E_1,
Expand All @@ -297,7 +323,7 @@
E_4[χ5 D7 D8; χ6] *
x[χ6 D11 D12]
end
function halfinfinite_environment(
function half_infinite_environment(

Check warning on line 326 in src/algorithms/contractions/ctmrg_contractions.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/contractions/ctmrg_contractions.jl#L326

Added line #L326 was not covered by tests
x::AbstractTensor{S,3},
C_1,
C_2,
Expand All @@ -310,7 +336,7 @@
bra_1::P=ket_1,
bra_2::P=ket_2,
) where {S,P<:PEPSTensor}
return @autoopt @tensor env_x[χ_in D_inabove D_inbelow] :=
return @autoopt @tensor x_env[χ_in D_inabove D_inbelow] :=

Check warning on line 339 in src/algorithms/contractions/ctmrg_contractions.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/contractions/ctmrg_contractions.jl#L339

Added line #L339 was not covered by tests
x[χ1 D1 D2] *
conj(E_1[χ1 D3 D4; χ2]) *
conj(C_1[χ2; χ3]) *
Expand Down
Loading
Loading