Skip to content

Commit f9fa21b

Browse files
committed
Include triangular-CTMRG example in the docs
1 parent d2bdb93 commit f9fa21b

File tree

11 files changed

+1258
-14
lines changed

11 files changed

+1258
-14
lines changed

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ sphinx_rtd_theme>=1.0.0
33
sphinx_autodoc_defaultargs>=0.1.2
44
sphinx_subfigure>=0.2.4
55

6-
-e .
6+
.

docs/source/examples.rst renamed to docs/source/examples/heisenberg_afm_square.rst

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
.. _examples:
2-
3-
4-
Examples
5-
========
6-
7-
We provide several examples in the `examples/ folder of the variPEPS Git repository <https://github.com/variPEPS/variPEPS_Python/tree/main/examples>`_ that demonstrate how to use the code for variational energy optimization in typical 2D many-body problems.
8-
9-
.. In this section we want to elaborately walk through the example for the Heisenberg AFM on the 2d square lattice to explain a typical usage of the library.
1+
.. _examples_heisenberg_afm_square:
102

113
Heisenberg antiferromagnet on the square lattice
124
------------------------------------------------
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
.. _examples_heisenberg_afm_triangular:
2+
3+
Heisenberg antiferromagnet on the triangular lattice
4+
----------------------------------------------------
5+
6+
.. figure:: /images/triangular_lattice.*
7+
:align: center
8+
:width: 60%
9+
:alt: Two dimensional triangular lattice with links indicating nearest neighbor
10+
interactions.
11+
12+
Two dimensional triangular lattice
13+
14+
The Hamiltonian for the Heisenberg antiferromagnet with constant exchange
15+
interaction strength :math:`J>0` is defined as:
16+
17+
.. math::
18+
19+
H = J \sum_{\langle i j \rangle} \vec{S}_i \vec{S}_j ,
20+
21+
where :math:`\langle i j \rangle` denotes the sum over all nearest neighbors in
22+
the lattice.
23+
24+
Our aim is now to find the ground state of the model using the variational iPEPS
25+
code of the variPEPS library.
26+
27+
Loading of relevant Python modules
28+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29+
30+
.. code-block:: python
31+
32+
import varipeps
33+
import jax
34+
import jax.numpy as jnp
35+
36+
First of all we have to load the relevant Python modules for our simulation. The
37+
:obj:`varipeps` module includes the full library to perform the variational
38+
optimization. Internally it is based on the :obj:`jax` framework and its
39+
:obj:`numpy`-like interface to execute the calculations. Since we will need
40+
arrays to define for example the Hamiltonian, we load this numpy interface as
41+
well.
42+
43+
variPEPS config settings
44+
^^^^^^^^^^^^^^^^^^^^^^^^
45+
46+
.. code-block:: python
47+
48+
# Config Setting
49+
50+
## Set maximal steps for the CTMRG routine
51+
varipeps.config.ctmrg_max_steps = 100
52+
## Set convergence threshold for the CTMRG routine
53+
varipeps.config.ctmrg_convergence_eps = 1e-7
54+
## Select the method used to calculate the (full) projectors in the CTMRG routine
55+
varipeps.config.ctmrg_full_projector_method = (
56+
varipeps.config.Projector_Method.FISHMAN
57+
)
58+
## Enable dynamic increase of CTMRG environment bond dimension
59+
varipeps.config.ctmrg_heuristic_increase_chi = True
60+
## Increase CTMRG enviroment bond dimension if truncation error exceeds this value
61+
varipeps.config.ctmrg_heuristic_increase_chi_threshold = 1e-4
62+
63+
## Set maximal steps for the fix point routine in the gradient calculation
64+
varipeps.config.ad_custom_max_steps = 100
65+
## Set convergence threshold for the fix point routine in the gradient calculation
66+
varipeps.config.ad_custom_convergence_eps = 5e-8
67+
68+
## Enable/Disable printing of the convergence of the single CTMRG/gradient fix point steps.
69+
## Useful to enable this during debugging, should be disabled for batch runs
70+
varipeps.config.ctmrg_print_steps = True
71+
varipeps.config.ad_custom_print_steps = False
72+
73+
## Select the method used to calculate the descent direction during optimization
74+
varipeps.config.optimizer_method = varipeps.config.Optimizing_Methods.CG
75+
## Set maximal number of steps for the optimization routine
76+
varipeps.config.optimizer_max_steps = 2000
77+
78+
The :obj:`varipeps` library allows to configure a large number of numerical
79+
parameters to fine-tune the simulation. In this example we include several
80+
options commonly used in an optimization run. For a detailed description of the
81+
configurable options we refer to the API description of the config class:
82+
:obj:`varipeps.config.VariPEPS_Config`.
83+
84+
Model parameters
85+
^^^^^^^^^^^^^^^^
86+
87+
.. code-block:: python
88+
89+
# Set constants for the simulation
90+
modelName = "HeisenbergModel"
91+
# Interaction strength
92+
J = 1
93+
# iPEPS bond dimension
94+
chiB = 2
95+
# Physical dimension
96+
p = 2
97+
# Maximal enviroment bond dimension
98+
maxChi = 64
99+
# Start value for enviroment bond dimension
100+
startChi = maxChi
101+
102+
In this block we define imporant parameters for the model we want to simulate,
103+
such as as the interaction strength, the physical dimension of our tensor
104+
network and the iPEPS bond dimension. In the last two lines the initial and the
105+
maximal enviroment bond dimension is defined. A feature of the variPEPS library
106+
is that it not only supports simulation at a fixed enviroment bond dimension,
107+
but also a heurisitic increase/decrease of the dimension up to a maximal
108+
value. The dynamic change is controlled by the truncation error in the CTMRG
109+
projector calculation (increase if the truncation error becomes too large,
110+
decrease if it becomes insignificant). For example, in the config block above
111+
the parameter ``ctmrg_heuristic_increase_chi_threshold`` is set to the threshold
112+
at which to increase the refinement parameter. The maximal bond dimension
113+
``maxChi`` ensures that the parameter does now grow unbounded, to the point
114+
where the memory and computational resources are exhausted.
115+
116+
For the triangular lattice Heisenberg AFM it is known that a quite large
117+
environment bond dimension is needed such that we directly start the simulation
118+
with the maximal allowed dimension to avoid unnecessary calculations.
119+
120+
Constructing the Hamiltonian
121+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
122+
123+
.. code-block:: python
124+
125+
# define spin-1/2 matrices
126+
Id = jnp.eye(2)
127+
Sx = jnp.array([[0, 1], [1, 0]]) / 2
128+
Sy = jnp.array([[0, -1j], [1j, 0]]) / 2
129+
Sz = jnp.array([[1, 0], [0, -1]]) / 2
130+
131+
# construct Hamiltonian terms
132+
hamiltonianGates = J * (jnp.kron(Sx, Sx) + jnp.kron(Sy, Sy) + jnp.kron(Sz, Sz))
133+
134+
# create function to compute expectation values for the square Heisenberg AFM
135+
exp_func = (
136+
varipeps.expectation.triangular_two_sites.Triangular_Two_Sites_Expectation_Value(
137+
horizontal_gates=(hamiltonianGates,),
138+
vertical_gates=(hamiltonianGates,),
139+
diagonal_gates=(hamiltonianGates,),
140+
real_d=p,
141+
is_spiral_peps=True,
142+
spiral_unitary_operator=Sy,
143+
)
144+
)
145+
146+
Here the Hamiltonian is constructed for our model. The Heisenberg AFM on the
147+
triangular lattice can be described by the sum of the spin-spin interactions on
148+
the horizontal, vertical and diagonal bonds. Since we assume a constant
149+
interaction strength for all bonds in our example, the expectation value can be
150+
calculated by the same two-site interaction gate applied in all nearest neighbor
151+
directions. The expectation function ``exp_func`` is later used in the
152+
optimization to calculate the energy expectation value, which in turn is used as
153+
cost function to obtain the ground state.
154+
155+
We use in this example the description of the model by the spiral-PEPS ansatz
156+
(`Phys. Rev. Lett. 133, 176502 (2024)
157+
<https://doi.org/10.1103/PhysRevLett.133.176502>`_). Here the model is described
158+
by a single real iPEPS tensor and a relative rotation along the :math:`S_y` axis
159+
for interactions with its neighbors. The rotation is set by a spiral vector
160+
which is supplied later in this example. This reduces the computational effort
161+
required for the optimization as only one tensor and not multiple ones have to be
162+
optimized.
163+
164+
As discussed in the following section, we use the triangular-CTMRG method for
165+
this example, therefore we use the provided expectation class for this case
166+
(:obj:`~varipeps.expectation.triangular_two_sites.Triangular_Two_Sites_Expectation_Value`).
167+
168+
Initial unit cell construction
169+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
170+
171+
.. code-block:: python
172+
173+
# Unit cell structure
174+
structure = [[0]]
175+
176+
Here we define the unit cell structure which is used to simulate our model. As
177+
noted in the section above, due to the spiral ansatz we only need a single iPEPS
178+
site.
179+
180+
.. code-block:: python
181+
182+
# Create random initialization for the iPEPS unit cell
183+
unitcell = varipeps.peps.PEPS_Unit_Cell.random(
184+
structure, # Unit cell structure
185+
p, # Physical dimension
186+
chiB, # iPEPS bond dimension
187+
startChi, # Start value for enviroment bond dimension
188+
float, # Data type for the tensors: `float` (real) or `complex` tensors
189+
max_chi=maxChi, # Maximal enviroment bond dimension
190+
peps_type=varipeps.peps.PEPS_Type.TRIANGULAR, # Select triangular PEPS
191+
)
192+
193+
Using the unit cell structure and the model parameter defined above, we can
194+
generate an initial unit cell. Here we initialize the iPEPS tensors with random
195+
numbers. Other ways to initialize the tensors are provided, for example loading results
196+
from a simple update calculation.
197+
198+
As we simulate a triangular lattice, we use the triangular-CTMRG method
199+
described in the reference `DOI 10.1103/g5gm-tzf8
200+
<https://doi.org/10.1103/g5gm-tzf8>`_. This is selected at the time of creation
201+
of the unit cell by the ``peps_type`` parameter.
202+
203+
Run the optimization
204+
^^^^^^^^^^^^^^^^^^^^
205+
206+
.. code-block:: python
207+
208+
# Run optimization
209+
result = varipeps.optimization.optimize_unitcell_fixed_spiral_vector(
210+
unitcell,
211+
jnp.array((2 / 3, 2 / 3), dtype=jnp.float64), # Spiral vector
212+
exp_func,
213+
autosave_filename=f"data/autosave_triangular_chiB_{chiB:d}_chiMax_{maxChi:d}.hdf5",
214+
)
215+
216+
This function call executes the main function of the library, the variational
217+
energy optimization to obtain a good ground state candidate. We use one of the
218+
wrapper around the main optimization function which is predefined for the case
219+
of a spiral PEPS ansatz with a fixed value for the spiral vector. There are
220+
other variants for example for the variational optimization of the full spiral
221+
vector or for the optimization of just the :math:`x`- or :math:`y`-component.
222+
The other arguments are the function for calculating the energy expectation
223+
value, and a file path for autosaving the optimization process, enabling the
224+
restoration of interrupted simulations.
225+
226+
Evaluate the results
227+
^^^^^^^^^^^^^^^^^^^^
228+
229+
In this section we show some exemplary evaluation of the result of the optimization.
230+
231+
.. code-block:: python
232+
233+
# Calculate magnetic expectation values
234+
Mag_Gates = [Sx, Sy, Sz]
235+
236+
237+
def calc_magnetic(unitcell):
238+
mag_result = []
239+
for ti, t in enumerate(unitcell.get_unique_tensors()):
240+
r = varipeps.expectation.one_site.calc_one_site_multi_gates(
241+
t.tensor, t, Mag_Gates
242+
)
243+
mag_result += r
244+
return mag_result
245+
246+
247+
magnetic_exp_values = calc_magnetic(result.unitcell)
248+
249+
We assume for our example that we are interested in the single-site spin
250+
expectation values. These could be used to analyse the :math:`z`-magnetization
251+
or the staggered magnetization of our model at/near the ground state.
252+
253+
.. code-block:: python
254+
255+
# Define some auxiliary data which should be stored along the final iPEPS unit cell
256+
auxiliary_data = {
257+
"best_energy": result.fun,
258+
"best_run": result.best_run,
259+
"magnetic_exp_values": magnetic_exp_values,
260+
}
261+
for k in sorted(result.max_trunc_error_list.keys()):
262+
auxiliary_data[f"max_trunc_error_list_{k:d}"] = result.max_trunc_error_list[k]
263+
auxiliary_data[f"step_energies_{k:d}"] = result.step_energies[k]
264+
auxiliary_data[f"step_chi_{k:d}"] = result.step_chi[k]
265+
auxiliary_data[f"step_conv_{k:d}"] = result.step_conv[k]
266+
auxiliary_data[f"step_runtime_{k:d}"] = result.step_runtime[k]
267+
268+
# save full iPEPS state
269+
result.unitcell.save_to_file(
270+
f"data/heisenberg_square_J_{J:d}_chiB_{chiB:d}_chiMax_{maxChi:d}.hdf5",
271+
auxiliary_data=auxiliary_data,
272+
)
273+
274+
Finally, we want to save the unit cell with the optimized tensors to a file for
275+
further analysis. The library allows to store the data directly into a
276+
HDF5 file along with user-supplied auxiliary data. Here, for example, we not only
277+
want to store the plain tensors but also the calculated energy, meta information
278+
from the optimization run (e.g. energy per step or the runtime per step) and the
279+
calculated magnetic expectation values. At a later examination of the results,
280+
these data can be easily loaded along with the tensors of the tensor network.

docs/source/examples/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.. _examples:
2+
3+
4+
Examples
5+
========
6+
7+
We provide several examples in the `examples/ folder of the variPEPS Git repository <https://github.com/variPEPS/variPEPS_Python/tree/main/examples>`_ that demonstrate how to use the code for variational energy optimization in typical 2D many-body problems.
8+
9+
.. toctree::
10+
:maxdepth: 1
11+
12+
heisenberg_afm_square
13+
heisenberg_afm_triangular

docs/source/general.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Usage
2828

2929
The :obj:`varipeps` module is organized in several submodules corresponding to
3030
the different features. For a variational optimization the most important parts
31-
are (a full overview can be found in the :ref:`_api`):
31+
are (a full overview can be found in the :ref:`api`):
3232

3333
* :obj:`varipeps.peps`: To define iPEPS unit cell and the tensors on each site,
3434
the library provides in this submodule the abstractions to define such a unit
@@ -46,7 +46,7 @@ are (a full overview can be found in the :ref:`_api`):
4646
with this part by the main function
4747
:obj:`varipeps.optimization.optimize_peps_network`.
4848

49-
All these different modules can be seen in action in the :ref:`_examples`
49+
All these different modules can be seen in action in the :ref:`examples`
5050
section of the documentation where exemplary code is discussed in detail.
5151

5252
Citation
9.86 KB
Binary file not shown.

0 commit comments

Comments
 (0)