Hamiltonian in QuAIRKit

QuAIRKit uses the Hamiltonian class to represent Hamiltonian. In this tutorial, users will learn how to construct Hamiltonian in QuAIRKit.

Table of Contents

[1]:
import torch

import quairkit as qkit
from quairkit.core.hamiltonian import *
from quairkit.database.hamiltonian import *
from quairkit.database.random import *
from quairkit.loss import *

Introduction to Hamiltonian

In physics, Hamiltonian is often represented by the symbol \(\hat{H}\), Hamiltonian \(\hat{H}\) is a mathematical representation of the total energy of a system. In quantum mechanics, Hamiltonian refers to the sum of the kinetic energy operator \(\hat{T}\) and potential energy operator \(\hat{V}\) of the system [1-2],

\[\hat{H} = \hat{T} + \hat{V}. \tag{1}\]

Its spectrum, namely, the system’s energy spectrum, or its set of energy eigenvalues \(\{\lambda_k\}^{d-1}_{k=0}\), results in possible outcomes obtainable from a measurement of the system’s total energy. Matrix representation of a Hamiltonian operator \(\hat{H}\) is \(H\). \(H\) satisfies the following conditions: \(H = H^\dagger\), namely, Hamiltonian is a hermitian matrix.

When the dimension of the Hilbert space is \(d=2\), a set of Pauli matrices [1-3] defined as follows :

\[\begin{split}I = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix}, \quad X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}, \quad Y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}, \quad Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}. \tag{2}\end{split}\]

For single-qubit system, the Hamiltonian can be expressed via Pauli matrices [3] as:

\[H = p_0 I + p_1 X + p_2 Y + p_3 Z, \tag{3}\]

where \(p_0\), \(p_1\), \(p_2\), and \(p_3\) are the real coefficients of the Pauli matrices. For \(n\)-qubit systems, the Hamiltonian might be expressed as a sum of tensor products of Pauli strings \(P\):

\[H = \sum_{i=0} p_i \left (\bigotimes_{j = 0}^n P_j \right), \tag{4}\]

where \(p_i\) is the real coefficients of the Pauli matrices, and \(P_j, \; P_j \in \{ \sigma_0, \sigma_1, \sigma_2, \sigma_3 \}\), is a Pauli matrix on the \(j\)-th qubit.

Construction of Hamiltonian

There are four examples: Ising model, XY chain, Random Hamiltonian, and Heisenberg model.

  • Ising model describes Hamiltonian with two-site interaction and external field:

    \[\sum_{i<j} J_{ij}Z_i Z_j + \sum_{k} h_k X_k \tag{1}\]

    where \(J_{ij}\) is the coupling strength between sites \(i\) and \(j\), and \(h_k\) is the magnetic field strength at vertex \(k\). In QuAirKit, Ising model can be constructed via ising_hamiltonian.

  • XY chain refers to the Hamiltonian:

    \[\sum_{ i<j}(J^x_{ij}X_i X_j + J^y_{ij}Y_i Y_j) \tag{2}\]

    where \(J^x_{ij}\) and \(J^y_{ij}\) are the coupling strengths between sites \(i\) and \(j\). XY model is able to be implemented from xy_hamiltonian.

  • Heisenberg model serves as a good candidate to study the ferromagnetic phase transition:

    \[\sum_{i<j}(J^x_{ij}X_i X_j + J^y_{ij}Y_i Y_j + J^z_{ij}Z_i Z_j) \tag{3}\]

    where \(J^x_{ij}\), \(J^y_{ij}\), and \(J^z_{ij}\) are the coupling strengths between sites \(i\) and \(j\). Heisenberg model can be implemented by heisenberg_hamiltonian.

QuAIRKit also supports random Hamiltonian, with given seed and number of qubits.

[2]:
num_qubits = 3  # initial setting with 3 qubits
split_line = '\n' + '-' * 100 + '\n'  # a line of '-' for better readability

gamma = torch.ones(num_qubits, num_qubits) * 0.5
beta = torch.ones(num_qubits) * 0.3
H = ising_hamiltonian(gamma, beta)
print("The Pauli decomposition of the Hamiltonian for the Ising model is:\n", H, end=split_line)

gamma = torch.ones(2, num_qubits, num_qubits) * 0.5
H = xy_hamiltonian(gamma)
print("The Pauli decomposition of the Hamiltonian for the XY chain is:\n", H, end=split_line)

gamma = torch.ones(3, num_qubits, num_qubits) * 0.5
H = heisenberg_hamiltonian(gamma)
print("The Pauli decomposition of the Hamiltonian for the Heisenberg model is:\n", H, end=split_line)

H = random_hamiltonian_generator(num_qubits)
print("The Pauli decomposition of the random Hamiltonian is:\n", H, end=split_line)
The Pauli decomposition of the Hamiltonian for the Ising model is:
 0.5 Z0, Z1
0.5 Z0, Z2
0.5 Z1, Z2
0.30000001192092896 X0
0.30000001192092896 X1
0.30000001192092896 X2
----------------------------------------------------------------------------------------------------
The Pauli decomposition of the Hamiltonian for the XY chain is:
 0.5 X0, X1
0.5 Y0, Y1
0.5 X0, X2
0.5 Y0, Y2
0.5 X1, X2
0.5 Y1, Y2
----------------------------------------------------------------------------------------------------
The Pauli decomposition of the Hamiltonian for the Heisenberg model is:
 0.5 X0, X1
0.5 Y0, Y1
0.5 Z0, Z1
0.5 X0, X2
0.5 Y0, Y2
0.5 Z0, Z2
0.5 X1, X2
0.5 Y1, Y2
0.5 Z1, Z2
----------------------------------------------------------------------------------------------------
The Pauli decomposition of the random Hamiltonian is:
 0.30402787550624577 Z1, Z2
-0.44363024944835594 X0, Y1, X2
0.6638237762231716 Y0, Z1, X2
----------------------------------------------------------------------------------------------------

Users can customize a Hamiltonian matrix with given coefficients and the corresponding Pauli matrices.

[3]:
h_list = [[0.1, "X0,Z1"], [0.3, "Z1"], [0.5, "Z2"]]

print(
    "For given Hamiltonian coefficients, "
    "the coresponding Hamiltonian class is:\n",
    Hamiltonian(h_list),
)
For given Hamiltonian coefficients, the coresponding Hamiltonian class is:
 0.1 X0, Z1
0.3 Z1
0.5 Z2

Expection value of the Hamiltonian

The expectation value of \(H\) [1-3] with respect to state \(\vert \psi\rangle\) is defined as:

\[\langle H \rangle := \langle \psi \vert H \vert \psi \rangle, \tag{4}\]

which is also known as the energy of the system. A more general form of expectation value of \(H\) considers mixed state \(\rho\):

\[\langle H \rangle = \operatorname{tr}(H\rho). \tag{5}\]

In QuAIRKit, ExpecVal or State.expec_val calculates the expectation value of \(H\).

[4]:
rho = random_state(num_qubits)
print('Expection value of the Hamiltonian:', rho.expec_val(H), end=split_line)

exp_H = ExpecVal(H)
print('Expection value of the Hamiltonian:', exp_H(rho))
Expection value of the Hamiltonian: tensor(-0.0484)
----------------------------------------------------------------------------------------------------
Expection value of the Hamiltonian: tensor(-0.0484)

Moreover, for batch state, batch calculation of the expection value of a Hamiltonian is also provided.

[5]:
rho = random_state(num_qubits, size=10)  # 1000 random 3-qubit states

print(
    "For 1000 random 3-qubit states, "
    "a set of Expection value of a given Hamiltonian:\n",
    rho.expec_val(H),
    end=split_line,
)
# this is equivalent to below code
# list_exp_H = []
# for i in range(len(rho)):
#     list_exp_H.append(rho[i].expec_val(H))
# list_exp_H = torch.stack(list_exp_H)

exp_H = ExpecVal(H)
print(
    "For 1000 random 3-qubit states, "
    "a set of Expection value of a given Hamiltonian:\n",
    exp_H(rho),
)
# this is equivalent to below code
# exp_H = ExpecVal(H)
# list_exp_H = []
# for i in range(len(rho)):
#     list_exp_H.append(exp_H(rho[i]))
# list_exp_H = torch.stack(list_exp_H)
For 1000 random 3-qubit states, a set of Expection value of a given Hamiltonian:
 tensor([-0.0007, -0.0193, -0.0598, -0.0859, -0.1097, -0.1909,  0.0444,  0.0678,
        -0.1136,  0.0709])
----------------------------------------------------------------------------------------------------
For 1000 random 3-qubit states, a set of Expection value of a given Hamiltonian:
 tensor([-0.0007, -0.0193, -0.0598, -0.0859, -0.1097, -0.1909,  0.0444,  0.0678,
        -0.1136,  0.0709])

The Hamiltonian class

There are some important properties involving Hamiltonian class.

  • n_terms: Number of terms.

  • pauli_str: The Pauli string corresponding to the Hamiltonian.

  • coefficients: The coefficients of the terms in the Hamiltonian.

  • matrix: The matrix form of the Hamiltonian.

  • pauli_words: The Pauli word of each term, i.e. [‘ZIZ’, ‘IIX’].

  • n_qubits: Number of qubits in the Hamiltonian.

[6]:
H = random_hamiltonian_generator(num_qubits)
print("The Pauli decomposition of the random Hamiltonian is:\n", H, end=split_line)

print('Number of terms:', H.n_terms, end=split_line)

print('The Pauli string corresponding to the Hamiltonian:\n', H.pauli_str, end=split_line)

print('The coefficients of the terms in the Hamiltonian:\n', H.coefficients, end=split_line)

print('The matrix form of the Hamiltonian:\n', H.matrix, end=split_line)

print('The Pauli word of each term:', H.pauli_words, end=split_line)

print('Number of qubits in the Hamiltonian:', H.n_qubits, end=split_line)
The Pauli decomposition of the random Hamiltonian is:
 0.6087798181466624 Y1, X2
-0.8219269134530314 Z0, Z1, Z2
-0.7649579970411409 Y0, Y1, Y2
----------------------------------------------------------------------------------------------------
Number of terms: 3
----------------------------------------------------------------------------------------------------
The Pauli string corresponding to the Hamiltonian:
 [[0.6087798181466624, 'Y1,X2'], [-0.8219269134530314, 'Z0,Z1,Z2'], [-0.7649579970411409, 'Y0,Y1,Y2']]
----------------------------------------------------------------------------------------------------
The coefficients of the terms in the Hamiltonian:
 [0.6087798181466624, -0.8219269134530314, -0.7649579970411409]
----------------------------------------------------------------------------------------------------
The matrix form of the Hamiltonian:
 tensor([[-0.8219+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000-0.6088j,
          0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000-0.7650j],
        [ 0.0000+0.0000j,  0.8219+0.0000j,  0.0000-0.6088j,  0.0000+0.0000j,
          0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.7650j,  0.0000+0.0000j],
        [ 0.0000+0.0000j,  0.0000+0.6088j,  0.8219+0.0000j,  0.0000+0.0000j,
          0.0000+0.0000j,  0.0000+0.7650j,  0.0000+0.0000j,  0.0000+0.0000j],
        [ 0.0000+0.6088j,  0.0000+0.0000j,  0.0000+0.0000j, -0.8219+0.0000j,
          0.0000-0.7650j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j],
        [ 0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.7650j,
          0.8219+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000-0.6088j],
        [ 0.0000+0.0000j,  0.0000+0.0000j,  0.0000-0.7650j,  0.0000+0.0000j,
          0.0000+0.0000j, -0.8219+0.0000j,  0.0000-0.6088j,  0.0000+0.0000j],
        [ 0.0000+0.0000j,  0.0000-0.7650j,  0.0000+0.0000j,  0.0000+0.0000j,
          0.0000+0.0000j,  0.0000+0.6088j, -0.8219+0.0000j,  0.0000+0.0000j],
        [ 0.0000+0.7650j,  0.0000+0.0000j,  0.0000+0.0000j,  0.0000+0.0000j,
          0.0000+0.6088j,  0.0000+0.0000j,  0.0000+0.0000j,  0.8219+0.0000j]])
----------------------------------------------------------------------------------------------------
The Pauli word of each term: ['IYX', 'ZZZ', 'YYY']
----------------------------------------------------------------------------------------------------
Number of qubits in the Hamiltonian: 3
----------------------------------------------------------------------------------------------------

References

[1] Sakurai, J. J., and Jim Napolitano. Modern Quantum Mechanics. 3rd ed. Cambridge: Cambridge University Press, 2020. Print.

[2] Griffiths, David J., and Darrell F. Schroeter. Introduction to Quantum Mechanics. 3rd ed. Cambridge: Cambridge University Press, 2018. Print.

[3] Nielsen, Michael A., and Isaac L. Chuang. Quantum computation and quantum information. Vol. 2. Cambridge: Cambridge university press, 2001.

Table: A reference of notation conventions in this tutorial.

Symbol

Variant

Description

\(\hat{H}\)

the Hamiltonian operator

\(\hat{T}\)

the kinetic energy operator

\(\hat{V}\)

the potential energy operator

\(\operatorname{tr}\)

trace of a matrix

\(H\)

the matrix representation of the Hamiltonian

\(\lambda\)

\(\lambda_k\)

the eigenvalue of the Hamiltonian

\(d\)

the dimension of the Hilbert space

\(\vert \psi \rangle\)

quantum pure state

\(\rho\)

quantum state

\(I\)

\(\sigma_0\)

Identity matrix

\(X\), \(Y\), \(Z\)

\(\sigma_1\), \(\sigma_2\), \(\sigma_3\)

Pauli matrices

[7]:
qkit.print_info()

---------VERSION---------
quairkit: 0.2.0
torch: 2.4.1+cpu
numpy: 1.26.0
scipy: 1.14.1
matplotlib: 3.9.2
---------SYSTEM---------
Python version: 3.10.15
OS: Windows
OS version: 10.0.26100
---------DEVICE---------
CPU: ARMv8 (64-bit) Family 8 Model 1 Revision 201, Qualcomm Technologies Inc