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],
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 :
For single-qubit system, the Hamiltonian can be expressed via Pauli matrices [3] as:
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\):
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:
which is also known as the energy of the system. A more general form of expectation value of \(H\) considers mixed state \(\rho\):
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