Skip to content

Commit 4991a6c

Browse files
pbrehmerlkdvos
andauthored
Clean up and simplify optimization interface (#127)
- Return truncation error and condition number of projectors in `ctmrg_iter` and `leading_boundary` - Track truncation errors, condition numbers, unit-cell-wise gradient norms and optimization step times during `fixedpoint` optimization - Rename `costfun` to `cost_function` - Add `symmetrization::SymmetrizationStyle` field to `PEPSOptimize` - Fix naming convention for `CTMRGEnv` to `env` - Break up `peps_opt.jl` file --------- Co-authored-by: Lukas Devos <ldevos98@gmail.com>
1 parent f0382f4 commit 4991a6c

31 files changed

+610
-560
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ opt_alg = PEPSOptimize(;
5454

5555
# ground state search
5656
state = InfinitePEPS(2, D)
57-
ctm = leading_boundary(CTMRGEnv(state, ComplexSpace(chi)), state, ctm_alg)
58-
result = fixedpoint(state, H, opt_alg, ctm)
57+
ctm, = leading_boundary(CTMRGEnv(state, ComplexSpace(chi)), state, ctm_alg)
58+
peps, env, E, = fixedpoint(H, state, ctm, opt_alg)
5959

60-
@show result.E # -0.6625...
60+
@show E # -0.6625...
6161
```
6262

docs/src/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ opt_alg = PEPSOptimize(;
3636

3737
# ground state search
3838
state = InfinitePEPS(2, D)
39-
ctm = leading_boundary(CTMRGEnv(state, ComplexSpace(chi)), state, ctm_alg)
40-
result = fixedpoint(state, H, opt_alg, ctm)
39+
ctm, = leading_boundary(CTMRGEnv(state, ComplexSpace(chi)), state, ctm_alg)
40+
peps, env, E, = fixedpoint(H, state, ctm, opt_alg)
4141

42-
@show result.E # -0.6625...
42+
@show E # -0.6625...
4343
```

examples/boundary_mps.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ T = InfiniteTransferPEPS(peps, 1, 1)
2626
mps = PEPSKit.initializeMPS(T, [ComplexSpace(20)])
2727

2828
# We then find the leading boundary MPS fixed point using the VUMPS algorithm
29-
mps, envs, ϵ = leading_boundary(mps, T, VUMPS())
29+
mps, env, ϵ = leading_boundary(mps, T, VUMPS())
3030

3131
# The norm of the state per unit cell is then given by the expectation value <mps|T|mps>
3232
N = abs(prod(expectation_value(mps, T)))
3333

3434
# This can be compared to the result obtained using the CTMRG algorithm
35-
ctm = leading_boundary(
35+
ctm, = leading_boundary(
3636
peps, SimultaneousCTMRG(; verbosity=1), CTMRGEnv(peps, ComplexSpace(20))
3737
)
3838
= abs(norm(peps, ctm))
@@ -52,10 +52,10 @@ peps2 = InfinitePEPS(ComplexSpace(2), ComplexSpace(2); unitcell=(2, 2))
5252
T2 = PEPSKit.MultilineTransferPEPS(peps2, 1)
5353

5454
mps2 = PEPSKit.initializeMPS(T2, fill(ComplexSpace(20), 2, 2))
55-
mps2, envs2, ϵ = leading_boundary(mps2, T2, VUMPS())
55+
mps2, env2, ϵ = leading_boundary(mps2, T2, VUMPS())
5656
N2 = abs(prod(expectation_value(mps2, T2)))
5757

58-
ctm2 = leading_boundary(
58+
ctm2, = leading_boundary(
5959
peps2, SimultaneousCTMRG(; verbosity=1), CTMRGEnv(peps2, ComplexSpace(20))
6060
)
6161
N2´ = abs(norm(peps2, ctm2))
@@ -77,7 +77,7 @@ pepo = ising_pepo(1)
7777
T3 = InfiniteTransferPEPO(peps, pepo, 1, 1)
7878

7979
mps3 = PEPSKit.initializeMPS(T3, [ComplexSpace(20)])
80-
mps3, envs3, ϵ = leading_boundary(mps3, T3, VUMPS())
80+
mps3, env3, ϵ = leading_boundary(mps3, T3, VUMPS())
8181
@show N3 = abs(prod(expectation_value(mps3, T3)))
8282

8383
# These objects and routines can be used to optimize PEPS fixed points of 3D partition

examples/heisenberg.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ opt_alg = PEPSOptimize(;
2626
# E/N = −0.6694421, which is a QMC estimate from https://arxiv.org/abs/1101.3281.
2727
# Of course there is a noticable bias for small χbond and χenv.
2828
ψ₀ = InfinitePEPS(2, χbond)
29-
env₀ = leading_boundary(CTMRGEnv(ψ₀, ℂ^χenv), ψ₀, ctm_alg)
30-
result = fixedpoint(ψ₀, H, opt_alg, env₀)
31-
@show result.E
29+
env₀, = leading_boundary(CTMRGEnv(ψ₀, ℂ^χenv), ψ₀, ctm_alg)
30+
peps, env, E, = fixedpoint(H, ψ, env₀, opt_alg₀)
31+
@show E

examples/heisenberg_evol/heis_tools.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ using PEPSKit
1616
"""
1717
Measure magnetization on each site
1818
"""
19-
function cal_mags(peps::InfinitePEPS, envs::CTMRGEnv)
19+
function cal_mags(peps::InfinitePEPS, env::CTMRGEnv)
2020
N1, N2 = size(peps)
2121
lattice = collect(space(t, 1) for t in peps.A)
2222
# detect symmetry on physical axis
@@ -32,7 +32,7 @@ function cal_mags(peps::InfinitePEPS, envs::CTMRGEnv)
3232
return [
3333
collect(
3434
expectation_value(
35-
peps, LocalOperator(lattice, (CartesianIndex(r, c),) => Sa), envs
35+
peps, LocalOperator(lattice, (CartesianIndex(r, c),) => Sa), env
3636
) for (r, c) in Iterators.product(1:N1, 1:N2)
3737
) for Sa in Sas
3838
]
@@ -41,11 +41,11 @@ end
4141
"""
4242
Measure physical quantities for Heisenberg model
4343
"""
44-
function measure_heis(peps::InfinitePEPS, H::LocalOperator, envs::CTMRGEnv)
44+
function measure_heis(peps::InfinitePEPS, H::LocalOperator, env::CTMRGEnv)
4545
results = Dict{String,Any}()
4646
N1, N2 = size(peps)
47-
results["e_site"] = costfun(peps, envs, H) / (N1 * N2)
48-
results["mag"] = cal_mags(peps, envs)
47+
results["e_site"] = costfun(peps, env, H) / (N1 * N2)
48+
results["mag"] = cal_mags(peps, env)
4949
results["mag_norm"] = collect(
5050
norm([mags[r, c] for mags in results["mag"]]) for
5151
(r, c) in Iterators.product(1:N1, 1:N2)

examples/heisenberg_evol/simpleupdate.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ include("heis_tools.jl")
33
# benchmark data is from Phys. Rev. B 94, 035133 (2016)
44
Dbond, χenv, symm = 4, 16, Trivial
55
trscheme_peps = truncerr(1e-10) & truncdim(Dbond)
6-
trscheme_envs = truncerr(1e-10) & truncdim(χenv)
6+
trscheme_env = truncerr(1e-10) & truncdim(χenv)
77
N1, N2 = 2, 2
88
# Heisenberg model Hamiltonian
99
# (already only includes nearest neighbor terms)
@@ -41,10 +41,10 @@ for (dt, tol) in zip(dts, tols)
4141
end
4242
# measure physical quantities with CTMRG
4343
peps_ = InfinitePEPS(peps)
44-
envs = CTMRGEnv(rand, Float64, peps_, Espace)
45-
ctm_alg = SequentialCTMRG(; tol=1e-10, verbosity=2, trscheme=trscheme_envs)
46-
envs = leading_boundary(envs, peps_, ctm_alg)
47-
meas = measure_heis(peps_, ham, envs)
44+
env₀ = CTMRGEnv(rand, Float64, peps_, Espace)
45+
ctm_alg = SequentialCTMRG(; tol=1e-10, verbosity=2, trscheme=trscheme_env)
46+
env = leading_boundary(env₀, peps_, ctm_alg)
47+
meas = measure_heis(peps_, ham, env)
4848
display(meas)
4949
@info @sprintf("Energy = %.8f\n", meas["e_site"])
5050
@info @sprintf("Staggered magnetization = %.8f\n", mean(meas["mag_norm"]))

examples/hubbard_su.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ peps = InfinitePEPS(peps)
4040
# CTMRG
4141
χenv0, χenv = 6, 20
4242
Espace = Vect[fℤ₂](0 => χenv0 / 2, 1 => χenv0 / 2)
43-
envs = CTMRGEnv(randn, Float64, peps, Espace)
43+
env = CTMRGEnv(randn, Float64, peps, Espace)
4444
for χ in [χenv0, χenv]
4545
ctm_alg = SequentialCTMRG(; maxiter=300, tol=1e-7)
46-
envs = leading_boundary(envs, peps, ctm_alg)
46+
env, = leading_boundary(env, peps, ctm_alg)
4747
end
4848

4949
# Benchmark values of the ground state energy from
@@ -53,7 +53,7 @@ Es_exact = Dict(0 => -1.62, 2 => -0.176, 4 => 0.8603, 6 => -0.6567, 8 => -0.5243
5353
E_exact = Es_exact[U] - U / 2
5454

5555
# measure energy
56-
E = costfun(peps, envs, ham) / (N1 * N2)
56+
E = cost_function(peps, env, ham) / (N1 * N2)
5757
@info "Energy = $E"
5858
@info "Benchmark energy = $E_exact"
5959
@test isapprox(E, E_exact; atol=5e-2)

src/PEPSKit.jl

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -54,56 +54,65 @@ include("algorithms/time_evolution/simpleupdate.jl")
5454

5555
include("algorithms/toolbox.jl")
5656

57-
include("algorithms/peps_opt.jl")
58-
5957
include("utility/symmetrization.jl")
6058

59+
include("algorithms/optimization/fixed_point_differentiation.jl")
60+
include("algorithms/optimization/peps_optimization.jl")
61+
6162
"""
6263
module Defaults
63-
const ctmrg_maxiter = 100
64-
const ctmrg_miniter = 4
65-
const ctmrg_tol = 1e-8
66-
const fpgrad_maxiter = 30
67-
const fpgrad_tol = 1e-6
68-
const reuse_env = true
69-
const trscheme = FixedSpaceTruncation()
70-
const fwd_alg = TensorKit.SDD()
71-
const rrule_alg = Arnoldi(; tol=1e-2fpgrad_tol, krylovdim=48, verbosity=-1)
72-
const svd_alg = SVDAdjoint(; fwd_alg, rrule_alg)
73-
const projector_alg_type = HalfInfiniteProjector
74-
const projector_alg = projector_alg_type(svd_alg, trscheme, 2)
75-
const ctmrg_alg = SimultaneousCTMRG(
76-
ctmrg_tol, ctmrg_maxiter, ctmrg_miniter, 2, projector_alg
77-
)
78-
const optimizer = LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=3)
79-
const gradient_linsolver = KrylovKit.BiCGStab(;
80-
maxiter=Defaults.fpgrad_maxiter, tol=Defaults.fpgrad_tol
81-
)
82-
const iterscheme = :fixed
83-
const gradient_alg = LinSolver(; solver=gradient_linsolver, iterscheme)
84-
const scheduler = Ref{Scheduler}(Threads.nthreads() == 1 ? SerialScheduler() : DynamicScheduler())
85-
end
8664
87-
Module containing default values that represent typical algorithm parameters.
65+
Module containing default algorithm parameter values and arguments.
8866
89-
- `ctmrg_maxiter`: Maximal number of CTMRG iterations per run
90-
- `ctmrg_miniter`: Minimal number of CTMRG carried out
91-
- `ctmrg_tol`: Tolerance checking singular value and norm convergence
92-
- `fpgrad_maxiter`: Maximal number of iterations for computing the CTMRG fixed-point gradient
93-
- `fpgrad_tol`: Convergence tolerance for the fixed-point gradient iteration
94-
- `reuse_env`: If `true`, the current optimization step is initialized on the previous environment
95-
- `trscheme`: Truncation scheme for SVDs and other decompositions
96-
- `fwd_alg`: SVD algorithm that is used in the forward pass
67+
# CTMRG
68+
- `ctmrg_tol=1e-8`: Tolerance checking singular value and norm convergence
69+
- `ctmrg_maxiter=100`: Maximal number of CTMRG iterations per run
70+
- `ctmrg_miniter=4`: Minimal number of CTMRG carried out
71+
- `trscheme=FixedSpaceTruncation()`: Truncation scheme for SVDs and other decompositions
72+
- `fwd_alg=TensorKit.SDD()`: SVD algorithm that is used in the forward pass
9773
- `rrule_alg`: Reverse-rule for differentiating that SVD
98-
- `svd_alg`: Combination of `fwd_alg` and `rrule_alg`
99-
- `projector_alg_type`: Default type of projector algorithm
74+
75+
```
76+
rrule_alg = Arnoldi(; tol=ctmrg_tol, krylovdim=48, verbosity=-1)
77+
```
78+
79+
- `svd_alg=SVDAdjoint(; fwd_alg, rrule_alg)`: Combination of `fwd_alg` and `rrule_alg`
80+
- `projector_alg_type=HalfInfiniteProjector`: Default type of projector algorithm
10081
- `projector_alg`: Algorithm to compute CTMRG projectors
82+
83+
```
84+
projector_alg = projector_alg_type(; svd_alg, trscheme, verbosity=0)
85+
```
86+
10187
- `ctmrg_alg`: Algorithm for performing CTMRG runs
102-
- `optimizer`: Optimization algorithm for PEPS ground-state optimization
88+
89+
```
90+
ctmrg_alg = SimultaneousCTMRG(
91+
ctmrg_tol, ctmrg_maxiter, ctmrg_miniter, 2, projector_alg
92+
)
93+
```
94+
95+
# Optimization
96+
- `fpgrad_maxiter=30`: Maximal number of iterations for computing the CTMRG fixed-point gradient
97+
- `fpgrad_tol=1e-6`: Convergence tolerance for the fixed-point gradient iteration
98+
- `iterscheme=:fixed`: Scheme for differentiating one CTMRG iteration
10399
- `gradient_linsolver`: Default linear solver for the `LinSolver` gradient algorithm
104-
- `iterscheme`: Scheme for differentiating one CTMRG iteration
100+
101+
```
102+
gradient_linsolver=KrylovKit.BiCGStab(; maxiter=fpgrad_maxiter, tol=fpgrad_tol)
103+
```
104+
105105
- `gradient_alg`: Algorithm to compute the gradient fixed-point
106-
- `scheduler`: Multi-threading scheduler which can be accessed via `set_scheduler!`
106+
107+
```
108+
gradient_alg = LinSolver(; solver=gradient_linsolver, iterscheme)
109+
```
110+
111+
- `reuse_env=true`: If `true`, the current optimization step is initialized on the previous environment
112+
- `optimizer=LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=3)`: Default `OptimKit.OptimizerAlgorithm` for PEPS optimization
113+
114+
# OhMyThreads scheduler
115+
- `scheduler=Ref{Scheduler}(...)`: Multi-threading scheduler which can be accessed via `set_scheduler!`
107116
"""
108117
module Defaults
109118
using TensorKit, KrylovKit, OptimKit, OhMyThreads
@@ -113,28 +122,30 @@ module Defaults
113122
SVDAdjoint,
114123
HalfInfiniteProjector,
115124
SimultaneousCTMRG
125+
126+
# CTMRG
116127
const ctmrg_tol = 1e-8
117128
const ctmrg_maxiter = 100
118129
const ctmrg_miniter = 4
119-
const fpgrad_maxiter = 30
120-
const fpgrad_tol = 1e-6
121130
const sparse = false
122-
const reuse_env = true
123131
const trscheme = FixedSpaceTruncation()
124132
const fwd_alg = TensorKit.SDD()
125-
const rrule_alg = Arnoldi(; tol=1e-2fpgrad_tol, krylovdim=48, verbosity=-1)
133+
const rrule_alg = Arnoldi(; tol=ctmrg_tol, krylovdim=48, verbosity=-1)
126134
const svd_alg = SVDAdjoint(; fwd_alg, rrule_alg)
127135
const projector_alg_type = HalfInfiniteProjector
128-
const projector_alg = projector_alg_type(svd_alg, trscheme, 2)
136+
const projector_alg = projector_alg_type(; svd_alg, trscheme, verbosity=0)
129137
const ctmrg_alg = SimultaneousCTMRG(
130138
ctmrg_tol, ctmrg_maxiter, ctmrg_miniter, 2, projector_alg
131139
)
132-
const optimizer = LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=3)
133-
const gradient_linsolver = KrylovKit.BiCGStab(;
134-
maxiter=Defaults.fpgrad_maxiter, tol=Defaults.fpgrad_tol
135-
)
140+
141+
# Optimization
142+
const fpgrad_maxiter = 30
143+
const fpgrad_tol = 1e-6
144+
const gradient_linsolver = KrylovKit.BiCGStab(; maxiter=fpgrad_maxiter, tol=fpgrad_tol)
136145
const iterscheme = :fixed
137146
const gradient_alg = LinSolver(; solver=gradient_linsolver, iterscheme)
147+
const reuse_env = true
148+
const optimizer = LBFGS(32; maxiter=100, gradtol=1e-4, verbosity=3)
138149

139150
# OhMyThreads scheduler defaults
140151
const scheduler = Ref{Scheduler}()
@@ -187,7 +198,7 @@ export SVDAdjoint, IterSVD
187198
export CTMRGEnv, SequentialCTMRG, SimultaneousCTMRG
188199
export FixedSpaceTruncation, HalfInfiniteProjector, FullInfiniteProjector
189200
export LocalOperator
190-
export expectation_value, costfun, product_peps, correlation_length
201+
export expectation_value, cost_function, product_peps, correlation_length
191202
export leading_boundary
192203
export PEPSOptimize, GeomSum, ManualIter, LinSolver
193204
export fixedpoint

0 commit comments

Comments
 (0)