Skip to content

Commit 7e49c7c

Browse files
author
qyli
committed
update tutorial & clean deprecated examples
1 parent 59b7973 commit 7e49c7c

File tree

15 files changed

+139
-381
lines changed

15 files changed

+139
-381
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
33
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
44
FiniteMPS = "6b572690-f317-4dad-a5fe-5fe73a0b7d42"
55
LsqFit = "2fda8390-95c7-5789-9bda-21331edee243"
6+
NumericalIntegration = "e7bfaba1-d571-5449-8927-abc22e82249b"

docs/src/tutorial/Heisenberg.md

Lines changed: 137 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Heisenberg Chain
22

33
## Ground state
4-
In this section, we compute the ground-state, finite-T and dynamical properties of a Heisenberg chain, whose Hamiltonian reads
5-
$$
6-
H = J\sum_{i}S_{i}\cdot S_{i+1}.
7-
$$
4+
In this section, we compute the ground-state, finite-T and dynamical properties of a Heisenberg chain, whose Hamiltonian reads\
5+
$H = J\sum_{i}S_{i} S_{i+1}$.
86
Here we set $J=1$ as energy unit and use spin SU(2) symmetry.
97
```@example Heisenberg
108
using FiniteMPS
11-
using CairoMakie, Statistics, LsqFit # visualization
9+
using CairoMakie, Statistics # visualization
10+
using LsqFit: curve_fit
11+
using NumericalIntegration: integrate
1212
1313
mkpath("figs_Heisenberg") # save figures
1414
@@ -32,7 +32,7 @@ aspace = Rep[SU₂](i => 1 for i in 0:1/2:1)
3232
```
3333
Here `bspace = Rep[SU₂](0 => 1)` is the space of left boundary bond, `0` is the SU(2) quantum number of the total MPS, and `1` is the multiplicity of the trivial representation, therefore this setup indicates the total MPS is a SU(2) scalar.
3434

35-
`aspace` is the space of bulk bonds. Note the fusing of physical space and bond space leads to a constrain due to symmetry. For example, the SU(2) quantum numbers of the bonds exhibit a integer/half integer oscillation, as the physical space exactly shifts the quantum number by 1/2. Here we use a larger (with redundancy) initial bond space so that contraction of bond indices gives a non-vanished result.
35+
`aspace` is the space of bulk bonds. Note the fusion of physical space and bond space leads to a constrain due to symmetry. For example, the SU(2) quantum numbers of the bonds exhibit a integer/half integer oscillation, as the physical space exactly shifts the bond quantum number by 1/2. Here we use a larger (with redundancy) initial bond space so that contraction of bond indices gives a non-vanished result.
3636

3737
```@example Heisenberg
3838
# DMRG
@@ -113,7 +113,7 @@ $$
113113
$$
114114

115115
## Finite temperature
116-
Now we move to the finite-temperature properties via [tanTRG](https://doi.org/10.1103/PhysRevLett.130.226502), which belongs to an imaginary-time-evolution method based on MPO TDVP. Note we will use [CBE-TDVP](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.133.026401) to accelerate the computation.
116+
Now we move to the finite-temperature properties via [tanTRG](https://doi.org/10.1103/PhysRevLett.130.226502), which belongs to an imaginary-time-evolution method based on TDVP of MPO. Note we will use [CBE-TDVP](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.133.026401) to accelerate the computation.
117117

118118
```@example Heisenberg
119119
# define a beta list
@@ -150,7 +150,7 @@ Obs = convert(Dict, ObsTree)
150150
lsSM[1] = calSM(Obs)
151151
152152
```
153-
First we define a $\beta$ list, which determines the step length of imaginary-time cooling. [SETTN](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.95.161104) is adopted to initializes a high-temperature MPO, where `CBEAlg` indicates the algorithm to implement CBE. Currently only `NaiveCBE` is valid, where we directly find the optimal subspace via a svd (use random svd to accelerate), and the expanded bond dimension is set as `D + div(D, 4)`. `lsnoise` set the noise applied in the first several sweeps of variational multiplication. Next we use TDVP to cool down the system.
153+
First we define a $\beta$ list, which determines the step length of imaginary-time cooling. [SETTN](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.95.161104) is adopted to initialize a high-temperature MPO, where `CBEAlg` indicates the algorithm to implement CBE. Currently only `NaiveCBE` is valid, where we directly find the optimal subspace via a svd (use random svd to accelerate), and the expanded bond dimension is set as `D + div(D, 4)`. `lsnoise` sets the noise applied in the first several sweeps of variational multiplication. Next we use TDVP to cool down the system.
154154

155155
```@example Heisenberg
156156
# TDVP cooling
@@ -169,13 +169,12 @@ for idx in 2:length(lsβ)
169169
170170
# update data stored in ObsTree
171171
calObs!(ObsTree, ρ)
172-
Obs = convert(Dict, ObsTree)
173-
lsSM[idx] = calSM(Obs)
172+
lsSM[idx] = calSM(convert(Dict, ObsTree))
174173
end
175174
```
176-
The key function is this part is `TDVPSweep1!` that performs a single left-to-right and right-to-left 1-TDVP sweep. `GCsweep = true` indicates that a manual `GC.gc()` is called per sweep. If you suffer memory problem when using FiniteMPS.jl, the first thing to try is setting `CGsweep = true` and a stronger `GCstep = true` in the main sweeping function (e.g. `DMRGSweep1!` and `TDVPSweep1!`).
175+
The key function in this part is `TDVPSweep1!` that performs a single left-to-right and right-to-left 1-TDVP sweep. `GCsweep = true` indicates that a manual `GC.gc()` is called per sweep. If you suffer memory problem when using FiniteMPS.jl, the first thing to try is setting `CGsweep = true` and a stronger `GCstep = true` in the main sweeping function (e.g. `DMRGSweep1!` and `TDVPSweep1!`).
177176

178-
In each sweep, the normalization factor after an imaginary-time evolution is extracted to calculate the partition function `lnZ`. In order to calculate spin correlations, regenerating `ObsTree` is not needed, just use `calObs!` again to trigger the in-place update with the new MPO `rho`.
177+
In each sweep, the normalization factor after an imaginary-time evolution is extracted to calculate the partition function `lnZ`. In order to calculate spin correlations, regenerating `ObsTree` is not necessary, just use `calObs!` again to trigger the in-place update with the new MPO `ρ`.
179178

180179
Below is a simple script for visualization, where the temperature dependence of energy $e$, specific heat $c_V$ and AFM structure factor $S(\pi, \pi)$ are shown.
181180
```@example Heisenberg
@@ -184,7 +183,7 @@ Below is a simple script for visualization, where the temperature dependence of
184183
# compute C = - ∂S / ∂lnβ
185184
lsS = lsβ .* lsE .+ lslnZ
186185
lslnβ = log.(lsβ)
187-
lsCe = - diff(lsS) ./ diff(lslnβ)
186+
lsCv = - diff(lsS) ./ diff(lslnβ)
188187
lsβ_c = exp.((lslnβ[1:end-1] + lslnβ[2:end])/2)
189188
190189
fig = Figure(size = (480, 400))
@@ -204,7 +203,7 @@ end
204203
scatterlines!(ax1, 1 ./ lsβ, lsE ./ L)
205204
lines!(ax1, [0.05, 1], [Eg/L, Eg/L]; color = :red, label = "DMRG")
206205
axislegend(ax1; position = (0, 0.5))
207-
scatterlines!(ax2, 1 ./ lsβ_c, lsCe ./ L)
206+
scatterlines!(ax2, 1 ./ lsβ_c, lsCv ./ L)
208207
scatterlines!(ax3, 1 ./ lsβ, lsSM)
209208
lines!(ax3, [0.05, 1], [SM_GS, SM_GS]; color = :red)
210209
@@ -214,8 +213,131 @@ save("figs_Heisenberg/FiniteT.png", fig)
214213
From this example we see that the low-temperature limit of tanTRG does shake hands with the ground state DMRG.
215214

216215
## Spin dynamics
217-
TODO
216+
In this section we will compute the ground-state dynamical spin structure factor (DSF)
217+
$S(k,\omega) = \sum_{i = 1}^L e^{-ik(r_i-r_j)} \int_{-\infty}^\infty dt e^{i\omega t}\langle S_i^z(t)S_j^z\rangle$,
218+
where $j$ is chosen as a reference site. More specifically, we will use TDVP to compute $\langle S_i^z(t)S_j^z\rangle = e^{iE_gt}\langle \Psi| S_i^z |\Phi(t)\rangle$ where $|\Phi(t)\rangle = e^{-iHt}S_j^z|\Psi\rangle$.
219+
```@example Heisenberg
220+
lst = 0:1.0:10 # time list
221+
matSijt = zeros(ComplexF64, L, length(lst)) # S_{i,j_ref}(t)
222+
223+
# obtain |Φ(0)⟩ = S_j|Ψ⟩
224+
j_ref = div(L, 2)
225+
226+
# fuse the additional bonds due to non-abelian symmetry
227+
aspace_S = codomain(SU2Spin.SS[2])[1]
228+
aspace_Ψ = codomain(Ψ[1])[1]
229+
aspace_Φ = fuse(aspace_S, aspace_Ψ)
230+
231+
# wrap the operator S_j to a MPO
232+
Tree = InteractionTree(L)
233+
addIntr!(Tree, SU2Spin.SS[2], j_ref, 1.0; name = :S)
234+
S_MPO = AutomataMPO(Tree)
235+
236+
# note Φ should be a complex MPS
237+
Φ = randMPS(ComplexF64, fill(SU2Spin.pspace, L), vcat(aspace_Φ, fill(aspace, L - 1)))
238+
239+
# variationally find |Φ⟩ = S_j|Ψ⟩
240+
mul!(Φ, S_MPO, Ψ;
241+
CBEAlg = NaiveCBE(D + div(D, 4), 1e-8; rsvd = true),
242+
trunc = truncdim(D), GCsweep = true,
243+
lsnoise = [0.1, 0.01, 0.001], tol = 1e-12,
244+
)
245+
```
246+
Note we cannot directly compute $\langle S_i^z(t)S_j^z\rangle$, as the operator $S^z$ breaks the SU(2) symmetry. Therefore, what we actually compute is $\langle S_i(t) \cdot S_j\rangle / 3$, where $S_j$ operator is a SU(2) spinor with an additional index that labels the representation space. After preparing the initial `Φ` with correct symmetry index, we call `mul!` function to perform variational multiplication.
247+
248+
```@example Heisenberg
249+
# define a new ObsTree to calculate each inner product ⟨Ψ|S_i|Φ⟩
250+
ObsTree = ObservableTree(L)
251+
for i in 1:L
252+
addObs!(ObsTree, SU2Spin.SS[1], i; name = :S)
253+
end
254+
255+
iso = isometry(aspace_Φ, aspace_S ⊗ aspace_Ψ)
256+
El = permute(iso', ((2, 1), (3,)))
257+
calObs!(ObsTree, Ψ, Φ; El = El)
258+
matSijt[:, 1] = [ObsTree.Refs["S"][(i,)][] / 3 for i in 1:L]
259+
```
260+
Emphasize that the isometry to fuse the space of $S_j$ and $|\Psi\rangle$ must be considered carefully. We exactly insert a pair of isometries without changing the contraction result. One is implicitly applied in `mul!` to fuse the two additonal indices to the new one of `Φ`, and the other becomes the left boundary environment tensor `El` sent to `calObs!`.
261+
262+
```@example Heisenberg
263+
# time evolution
264+
265+
# construct the trilayer environment for TDVP
266+
Env = Environment(Φ', H, Φ)
267+
# time evolution
268+
for idx in 2:length(lst)
269+
dt = lst[idx] - lst[idx-1]
270+
271+
TDVPSweep1!(Env, -im * dt;
272+
CBEAlg = NaiveCBE(D + div(D, 4), 1e-8; rsvd = true),
273+
GCsweep = true, trunc = truncdim(D)
274+
)
275+
276+
calObs!(ObsTree, Ψ, Φ; El = El)
277+
# e^{iEgt}⟨Ψ|S_i^+|Φ⟩
278+
matSijt[:, idx] = exp(im * Eg * lst[idx]) * map(1:L) do i
279+
ObsTree.Refs["S"][(i,)][] / 3
280+
end
281+
end
282+
```
283+
In this part we use CBE-TDVP to perform real-time evolution of `Φ` and calculate the time-dependent spin correlations as some inner products.
284+
285+
```@example Heisenberg
286+
# spatial FT
287+
lsk = 0:2/L:2 # unit = π
288+
matcoef = map([(k, i) for k in lsk, i in 1:L]) do (k, i)
289+
exp(-im * k * (i - j_ref) * π)
290+
end
291+
matSkt = matcoef * matSijt
292+
293+
# time FT
294+
lsω = 0:0.1:4 # frequency list
295+
296+
# use a Parzen window to suppress the non-physical oscillation
297+
function ParzenWindow(x::Float64)
298+
if abs(x) < 1 / 2
299+
return 1 - 6 * x^2 + 6 * abs(x)^3
300+
elseif abs(x) < 1
301+
return 2 * (1 - abs(x))^3
302+
else
303+
return 0.0
304+
end
305+
end
306+
lsWt = ParzenWindow.(lst ./ maximum(lst))
307+
308+
matSkω = zeros(length(lsk), length(lsω))
309+
for iω in 1:length(lsω)
310+
lscoef = exp.(im * lsω[iω] .* lst) .* lsWt
311+
for ik in 1:length(lsk)
312+
matSkω[ik, iω] = 2 * integrate(lst, real.(matSkt[ik, :] .* lscoef))
313+
end
314+
end
315+
```
316+
After collecting all real-space time-dependent spin correlations, we perform FT to obtain the DSF. Note time-reversal symmetry is used in the numerical integration so that only $t>0$ data is required.
317+
Moreover, we multiply a parzen window function to the time domain to suppress the non-physical oscillation in frequency domain.
218318

319+
```@example Heisenberg
320+
# visualization
321+
fig = Figure(size = (480, 240))
322+
ax = Axis(fig[1, 1];
323+
xlabel = L"k / \pi",
324+
ylabel = L"\omega",
325+
limits = ((0, 2), extrema(lsω))
326+
)
327+
328+
hm = heatmap!(ax, lsk, lsω, matSkω)
329+
Colorbar(fig[1, 2], hm; label = L"S(k, \omega)")
330+
331+
# upper and lower boundaries
332+
lsω_upper = π .* sin.(lsk .* (π/2))
333+
lsω_lower = (π/2) .* abs.(sin.(lsk .* π))
334+
lines!(ax, lsk, lsω_upper; color = :white, linestyle = :dash)
335+
lines!(ax, lsk, lsω_lower; color = :white, linestyle = :dash)
336+
337+
save("figs_Heisenberg/Skomega.png", fig)
338+
```
339+
![](./figs_Heisenberg/Skomega.png)
340+
The exact (thermodynamical limit) upper and lower boundaries are also shown. Our numerial results align well with them, up to the frequency resolution (FWHM $\approx 8 / t_\textrm{max}$) due to the finite evolution time $t_\textrm{max} = 10$.
219341

220342

221343

docs/src/tutorial/Observable.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ Here `Tree` is an `ObservableTree` object that contains all observables to be ca
3434
```@example Observable
3535
Obs["SzSz"][(1, 2)]
3636
```
37-
is the correlation `\langle S_1^z S_2^z\rangle`. One can perform a simple quantum mechanics calculation to check this result.
37+
is the correlation $\langle S_1^z S_2^z\rangle$. One can perform a simple quantum mechanics calculation to check this result.
3838

3939
Here is just a simple example to show the basic usage, more complex examples that contain fermion correlations and multi-site correlations (e.g. pairing correlations) can be found in the concrete example for [Hubbard model](@ref Hubbard).

example/FreeFermion_tanTRG/Project.toml

Lines changed: 0 additions & 3 deletions
This file was deleted.

example/FreeFermion_tanTRG/addPkg.jl

Lines changed: 0 additions & 8 deletions
This file was deleted.

example/FreeFermion_tanTRG/main.jl

Lines changed: 0 additions & 62 deletions
This file was deleted.

example/FreeFermion_tanTRG/model.jl

Lines changed: 0 additions & 64 deletions
This file was deleted.

example/Hubbard_DMRG/Project.toml

Lines changed: 0 additions & 3 deletions
This file was deleted.

example/Hubbard_DMRG/addPkg.jl

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)