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

How to build spin hamiltonians #1230

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions demonstrations/tutorial_how_to_spin_hamiltonian.metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"title": "How to build spin Hamiltonians",
"authors": [
{
"username": "dikshadhawan"
}
],
"dateOfPublication": "2024-10-04T00:00:00+00:00",
"dateOfLastModification": "2024-10-04T00:00:00+00:00",
"categories": [
"Getting Started",
"How-to"
],
"tags": [],
"previewImages": [
{
"type": "thumbnail",
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_how_to_use_registers.png"
},
{
"type": "large_thumbnail",
"uri": "/_static/demo_thumbnails/large_demo_thumbnails/thumbnail_large_how_to_use_registers.png"
}
],
"seoDescription": "Learn how to build spin Hamiltonians with PennyLane.",
"doi": "",
"canonicalURL": "/qml/demos/tutorial_how_to_spin_hamiltonian",
"references": [],
"basedOnPapers": [],
"referencedByPapers": [],
"relatedContent": [
{
"type": "demonstration",
"id": "tutorial_quantum_chemistry",
"weight": 1.0
},
{
"type": "demonstration",
"id": "tutorial_fermionic_operators",
"weight": 1.0
}
]
}
222 changes: 222 additions & 0 deletions demonstrations/tutorial_how_to_spin_hamiltonian.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
r"""How to build spin Hamiltonians
==================================
Spin systems provide simple but powerful models for studying problems in physics, chemistry and
quantum computing. The quantum spin models are typically described by a Hamiltonian that can be used
in a quantum algorithm to explore properties of the spin modes that are intractable with classical
computational methods. PennyLane provides a powerful set of tools that enables the users to
intuitively construct a broad range of spin Hamiltonians. Here we show you how to use these tools
for your problem of interest.
"""

######################################################################
# Hamiltonian templates
# ---------------------
#
# PennyLane has a range of functions for constructing spin model Hamiltonians with minimal input
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you mention a couple of different Hamiltonian examples?

# data needed from the user. Let’s look at the
# `Fermi-Hubbard <https://pennylane.ai/datasets/qspin/fermi-hubbard-model>`__ model as an example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused by your pointing to the dataset as I thought we were using it but they are different things

# This model can
# represent a chain of hydrogen atoms where each atom, or site, can hold one spin-up and one
# spin-down particle. The Hamiltonian describing this model has two components: the kinetic energy
# component which is parameterized by a hopping parameter and the potential energy component
# parameterized by the on-site interaction strength. The Fermi-Hubbard Hamiltonian can then be
# constructed in PennyLane by passing the hoping and interaction parameters to the fermi_hubbard
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if the link doesn't work now, I would add this

Suggested change
# constructed in PennyLane by passing the hoping and interaction parameters to the fermi_hubbard
# constructed in PennyLane by passing the hoping and interaction parameters to the :func:`fermi_hubbard <pennylane.spin.fermi_hubbard>`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same for all other functions. Another option is to put ``function name``, so that it is not seen in plain text

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# constructed in PennyLane by passing the hoping and interaction parameters to the fermi_hubbard
# constructed in PennyLane by passing the hopping and interaction parameters to the fermi_hubbard

# function. We also need to provide information about the number of sites we would like to be
# included in our Hamiltonian.
#

import pennylane as qml

n = [2]
t = 0.2
u = 0.3
Comment on lines +30 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add comments here to say which term describes what parameter or rename the parameters? This might get confusing as we don't provide the equation here.


hamiltonian = qml.spin.fermi_hubbard("chain", n, t, u)
hamiltonian

######################################################################
# The fermi_hubbard function is general enough to go beyond the simple “chain” model and construct
# the Hamiltonian for a wide range of two-dimensional and three-dimensional lattice shapes. For
# those cases, we need to provide the number of sites in each direction of the lattice. We can
# construct the Hamiltonian for a cubic lattice with 3 sites on each direction as
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# construct the Hamiltonian for a cubic lattice with 3 sites on each direction as
# construct the Hamiltonian for a cubic lattice with 3 sites in each direction as


hamiltonian = qml.spin.fermi_hubbard("cubic", [3, 3, 3], t, u)

######################################################################
# Similarity, a broad range of other well-investigated spin model Hamiltonians can be constructed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Similarity, a broad range of other well-investigated spin model Hamiltonians can be constructed
# Similarly, a broad range of other well-investigated spin model Hamiltonians can be constructed

# with the dedicated functions available in the spin module, by just providing the lattice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we can link it now but it would be good to add a link here to the spin module

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can't link it, we can maybe provide a list of spin-Hamiltonians we can construct.

# information and the Hamiltonian parameters.
#
# Building Hamiltonians manually
# ------------------------------
#
# The Hamiltonian template functions are great and simple tools for someone who just wants to build
# a Hamiltonian quickly. However, PennyLane offers intuitive tools that can be used to construct
# spin Hamiltonians manually which are very handy for building customized Hamiltonians. Let’s learn
# how to use this tools by constructing the Hamiltonian for the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# how to use this tools by constructing the Hamiltonian for the
# how to use these tools by constructing the Hamiltonian for the

# `transverse field Ising <https://pennylane.ai/datasets/qspin/transverse-field-ising-model>`__
# model on a two-dimension lattice.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# model on a two-dimension lattice.
# model on a two-dimensional lattice.

#
# The Hamiltonian is represented as:
#
# .. math::
#
# \hat{H} = -J \sum_{<i,j>} \sigma_i^{z} \sigma_j^{z} - h\sum_{i} \sigma_{i}^{x},
#
# where :math:`J` is the coupling defined for the Hamiltonian, :math:`h` is the strength of
# transverse magnetic field and :math:`i,j` represent the indices for neighbouring spins.
#
# Our approach for doing this is to construct a lattice that represents the spin sites and
# their connectivity. This is done by using the Lattice class that can be constructed either by
# calling the helper function generate_lattice or by manually constructing the object. Let's see
# examples of both methods. First we use generate_lattice to construct a square lattice containing 9
# sites which are all connected to their nearest neighbor.

lattice = qml.spin.lattice._generate_lattice('square', [3, 3])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious about why this is a private function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will become public in a WIP PR.


######################################################################
# Let's visualize this lattice to see how it looks. We create a simple function for plotting the
# lattice.

import numpy as np
import matplotlib.pyplot as plt

def plot(lattice, figsize=None):

if figsize:
plt.figure(figsize=figsize)
else:
plt.figure(figsize=lattice.n_cells[::-1])

nodes = lattice.lattice_points

for edge in lattice.edges:
start_index, end_index, color = edge
start_pos, end_pos = nodes[start_index], nodes[end_index]

x_axis = [start_pos[0], end_pos[0]]
y_axis = [start_pos[1], end_pos[1]]
plt.plot(x_axis, y_axis, color='gold')

plt.scatter(nodes[:,0], nodes[:,1], color='dodgerblue', s=100)
for index, pos in enumerate(nodes):
plt.text(pos[0]-0.2, pos[1]+0.1, str(index), color='gray')

plt.axis("off")
plt.show()

plot(lattice)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!


######################################################################
# Now, we construct the same lattice manually by explicitly defining the positions of the sites in a
# unit cell, the translation vectors defining the lattice and the number of cells in each direction.

from pennylane.spin import Lattice

nodes = [[0, 0]] # coordinates of nodes inside the unit cell
vectors = [[1, 0], [0, 1]] # unit cell translation vectors
n_cells = [3, 3] # number of unit cells in each direction

lattice = Lattice(n_cells, vectors, nodes)

######################################################################
# This gives us the same lattice as we created with generate_lattice but constructing the lattice
# manually is more flexible while generate_lattice only works for some predefined lattice shapes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can link the generate_lattice function here, so that a reader can see which pre-defined shapes are available.

#
# Now that we have the lattice, we can use its attributes, e.g., edges and vertices, to construct
# our transverse field Ising model Hamiltonian. We just need to define the coupling and onsite
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might remember the reader that these are J and h

# parameters

from pennylane import X, Y, Z

coupling, onsite = 1.0, 1.0

hamiltonian = 0.0
# add the one-site terms
for vertex in range(lattice.n_sites):
hamiltonian += -onsite * X(vertex)
# add the coupling terms
for edge in lattice.edges_indices:
i, j = edge[0], edge[1]
hamiltonian += - coupling * (Z(i) @ Z(j))

hamiltonian

######################################################################
# In this example we just used the in-built attributes of the lattice we created without further
# customising them. The lattice can be constructed in a very flexible way that allows constructing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# customising them. The lattice can be constructed in a very flexible way that allows constructing
# customising them. The lattice can be constructed in a more flexible way that allows constructing

# customized Hamiltonians. Let's look at an example.
#
# Building customized Hamiltonians
# --------------------------------
# Now we work on a more complicated Hamiltonian to see how our existing tools allow building it
# intuitively. We chose the anisotropic `Kitaev <https://arxiv.org/abs/cond-mat/0506438>`__
# honeycomb model where the coupling
# parameters depend on the orientation of the bonds. We can build the Hamiltonian by building the
# lattice manually and adding custom edges between the nodes. For instance, to define a custom
# ``XX`` edge with coupling constant 0.5 between nodes 0 and 1, we use:

custom_edge = [(0, 1), ('XX', 0.5)]

######################################################################
# Let's now build our Hamiltonian. We first define the unit cell by specifying the positions of the
# nodes and the unit cell translation vector and then define the number of unit cells in each
# direction.

nodes = [[0.5, 0.5 / 3 ** 0.5], [1, 1 / 3 ** 0.5]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand what the nodes are here

vectors = [[1, 0], [0.5, np.sqrt(3) / 2]]
n_cells = [3, 3]

######################################################################
# Let's plot the lattice to see how it looks like.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Let's plot the lattice to see how it looks like.
# Let's plot the lattice to see how it looks.


plot(Lattice(n_cells, vectors, nodes), figsize=(5, 3))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮


######################################################################
# Now we add custom edges to the lattice. We have three different edge orientations that we define
# as

custom_edges = [[(0, 1), ('XX', 0.5)],
[(1, 2), ('YY', 0.6)],
[(1, 6), ('ZZ', 0.7)]]

lattice = Lattice(n_cells, vectors, nodes, custom_edges=custom_edges)

######################################################################
# Then we pass the lattice to the spin_hamiltonian function, which is a helper
# function that constructs a Hamiltonian from a lattice.

hamiltonian = qml.spin.spin_hamiltonian(lattice=lattice)

######################################################################
# The spin_hamiltonian function has a simple logic and loops over the custom edges and nodes
# to build the Hamiltonian. In our example, we can also manually do that with a simple code.


opmap = {'X': X, 'Y': Y, 'Z': Z}

hamiltonian = 0.0
for edge in lattice.edges:
i, j = edge[0], edge[1]
k, l = edge[2][0][0], edge[2][0][1]
hamiltonian += opmap[k](i) @ opmap[l](j) * edge[2][1]

hamiltonian

######################################################################
# See how we can easily and intuitively construct the Kitaev model Hamiltonian with the tools in
# these tools. You can compare the constructed Hamiltonian with the template we already have for
# the Kitaev model and verify that the Hamiltonians are the same.
Comment on lines +207 to +209
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# See how we can easily and intuitively construct the Kitaev model Hamiltonian with the tools in
# these tools. You can compare the constructed Hamiltonian with the template we already have for
# the Kitaev model and verify that the Hamiltonians are the same.
# See how we can easily and intuitively construct the Kitaev model Hamiltonian with the tools available in the
# spin module. You can compare the constructed Hamiltonian with the template we already have for
# the Kitaev model and verify that the Hamiltonians are the same.

#
# Conclusion
# ----------
# The spin module in PennyLane provides a set of powerful tools for constructing spin model
# Hamiltonians. Here we learned how to use these tools to construct pre-defined Hamiltonian
# templates, such as the Fermi-Hubbard model Hamiltonian, and use the Lattice object to construct
# more advanced and customised models such as the Kitaev honeycomb Hamiltonian. The versatility of
# the new spin functions and classes allows constructing any new spin model Hamiltonian intuitively.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# the new spin functions and classes allows constructing any new spin model Hamiltonian intuitively.
# the new spin functions and classes allows construction of any new spin model Hamiltonian intuitively.

#
# About the author
# ----------------
#
# .. include:: ../_static/authors/diksha_dhawan.txt
Loading