Skip to content

Commit 3f7a7ea

Browse files
committed
docs: add tutorial on VidalMPSs and TEBD
Introduce Vidal-form MPSs in the documentation, explain their basic features and the TEBD functions.
1 parent 581fcc3 commit 3f7a7ea

7 files changed

Lines changed: 372 additions & 3 deletions

File tree

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
33
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
44
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
55
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
6+
DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
67
ITensorMPS = "0d1a4710-d33b-49a5-8f18-73bdf49b47e2"
78
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
89
KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"

docs/make.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Documenter, DocumenterCitations
1+
using Documenter, DocumenterCitations, DocumenterInterLinks
22
using MPSTimeEvolution
33

44
# doctest dependencies
@@ -7,6 +7,10 @@ using CSV, DataFrames, Plots
77

88
bib = CitationBibliography(joinpath(@__DIR__, "src", "refs.bib"); style=:numeric)
99

10+
extlinks = InterLinks(
11+
"ITensorMPS" => "https://docs.itensor.org/ITensorMPS/dev/objects.inv"
12+
)
13+
1014
makedocs(;
1115
modules=[MPSTimeEvolution],
1216
sitename="MPSTimeEvolution",
@@ -18,6 +22,7 @@ makedocs(;
1822
"Reference" => [
1923
"Local operators" => "reference/localoperators.md",
2024
"Callback objects" => "reference/callback_obj.md",
25+
"Vidal-form MPSs" => "reference/vidal_mps.md",
2126
"Complete reference" => "reference/reference.md",
2227
],
2328
"Tutorial" => [
@@ -26,9 +31,10 @@ makedocs(;
2631
"examples/time_dependent_tdvp.md",
2732
"examples/tdvp1_sf.md",
2833
"examples/tdvp1_adaptive.md",
34+
"examples/tebd.md",
2935
],
3036
],
31-
plugins=[bib],
37+
plugins=[bib, extlinks],
3238
format=Documenter.HTML(;
3339
mathengine=Documenter.MathJax3(
3440
Dict(

docs/src/examples/tebd.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Time-evolving block decimation
2+
3+
The time-evolving block-decimation (TEBD) algorithm, introduced in
4+
[Vidal2003:slightly_entangled](@cite) is the ideal time-evolution scheme to
5+
simulate one-dimensional many-body systems that are characterised by at most
6+
nearest-neighbour interactions.
7+
With the quantum state encoded in a Vidal-form MPS, the TEBD algorithm can be
8+
straightforwardly parallelised due to the Suzuki–Trotter decomposition of the
9+
time-evolution operator.
10+
11+
The MPSTimeEvolution package offers two variants of TEBD that differ in the
12+
order of the Suzuki-Trotter decomposition used for the time-evolution operator.
13+
14+
Before we begin, let's introduce some objects we will need in both cases.
15+
We'll use the same initial pure state and Hamiltonian as in the [Standard
16+
TDVP1](@ref) example:
17+
18+
```math
19+
\ket{\psi_0} = \ket{\spinup} \otimes \ket{\spindown} \otimes \ket{\spinup}
20+
\otimes \ket{\spindown} \otimes \dotsb {}
21+
```
22+
23+
and
24+
25+
```math
26+
H = -\frac12 \sum_{n=1}^{N-1} \pauliz[n] \pauliz[n+1] +\sum_{n=1}^{N} \paulix[n]
27+
```
28+
29+
```jldoctest tdvp1
30+
julia> using ITensorMPS, MPSTimeEvolution
31+
32+
julia> N = 10; s = siteinds("S=1/2", N);
33+
34+
julia> ψₜ = VidalMPS(s, n -> isodd(n) ? "↑" : "↓");
35+
36+
julia> h = OpSum();
37+
38+
julia> for n in 1:N
39+
h += "σx", n
40+
end
41+
42+
julia> for n in 1:N-1
43+
h += -0.5, "σz", n, "σz", n+1
44+
end
45+
46+
```
47+
48+
We also choose the time step and the total evolution time
49+
50+
```jldoctest tdvp1
51+
julia> dt = 0.01; tmax = 10;
52+
53+
```
54+
55+
We define a callback object to track the \\(z\\)-axis magnetisation on the first
56+
three sites. By setting the last argument to `10dt`, the expectation values
57+
will be computed only every tenth time step.
58+
59+
```jldoctest tdvp1
60+
julia> cb = ExpValueCallback("Sz(1,2,3)", s, 10dt)
61+
ExpValueCallback
62+
Operators: Sz(1), Sz(2) and Sz(3)
63+
No measurements performed
64+
65+
```
66+
67+
## First-order Suzuki-Trotter decomposition
68+
69+
```@docs; canonical=false, collapsed=true
70+
tebd1!
71+
```
72+
73+
The `tebd1!` function evolves the `VidalMPS` `ψₜ` according to the specified
74+
Hamiltonian. It is enough to specfy the (full) Hamiltonian operator as an
75+
`OpSum` object: the `tebd1!` function will take care of computing the
76+
Suzuki-Trotter decomposition in odd and even terms.
77+
We also need to provide the `maxdim` and `cutoff` keyword argument in order to
78+
describe how the MPS has to be truncated after the application of the two-site
79+
time-evolution operators.
80+
81+
```jldoctest tdvp1
82+
julia> tebd1!(ψₜ, h, dt, tmax; cutoff=1e-12, maxdim=10, progress=false, callback=cb)
83+
84+
```
85+
86+
## Second-order Suzuki-Trotter decomposition
87+
88+
The interface of the TEBD function with the second-order Suzuki-Trotter
89+
algorithm is exactly the same as `tebd1!`.
90+
91+
```@docs; canonical=false, collapsed=true
92+
tebd2!
93+
```
94+
95+
In the second-order Suzuki-Trotter decomposition, the time-evolution operator
96+
over a time step \\(t\\) is
97+
98+
```math
99+
U(t) = U_{odd}(t/2) U_{even}(t) U_{odd}(t/2);
100+
```
101+
102+
if we don't need to compute the expectation values in `cb` after each time step,
103+
we can merge the \\(U\sb{odd}(t/2)\\) in the \\(U(t)\\) across time steps, i.e.
104+
105+
```math
106+
U(t)^k = U_{odd}(t/2) U_{even}(t) \bigl(U_{odd}(t) U_{even}(t)\bigr)^{k-1} U_{odd}(t/2)
107+
```
108+
109+
which avoids some tensor multiplications and unnecessary SVDs.
110+
This is automatically done by the `tebd2!` function if the measurement time step
111+
saved in the callback object is equal to \\(k>1\\) times the time step `dt`.
112+
113+
Let's run the function, after resetting the state to its initial value, and
114+
creating a new callback object:
115+
116+
```jldoctest tdvp1
117+
julia> ψₜ = VidalMPS(s, n -> isodd(n) ? "↑" : "↓");
118+
119+
julia> cb2 = ExpValueCallback("Sz(1,2,3)", s, 10dt);
120+
121+
julia> tebd2!(ψₜ, h, dt, tmax; cutoff=1e-12, maxdim=10, progress=false, callback=cb2)
122+
123+
```
124+
125+
We can see the results in the pictures below: the TEBD1 results are represented
126+
by dashed lines, and the TEDB2 results by solid lines. We find, as expected,
127+
that the two algorithm produce approximately the same results, which differ by
128+
approximately \\(10^{-5}\\) at the end of the run (which is fine, since we
129+
haven't been that careful to set up a numerical simulation with sensible
130+
parameters).
131+
132+
![Plot of Sz(1) during the evolution](tebd1_vs_tebd2.png)
133+
![Absolute difference between ](tebd1_vs_tebd2_diff.png)
25.9 KB
Loading
35.4 KB
Loading

0 commit comments

Comments
 (0)