Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Struqture

Struqture is a library that is used to describe quantum mechanical operators and systems. It can be used as an input to HQS Quantum Solver for defining spin systems.

For this chapter, we use the system of antiferromagnetically coupled spins defined by the Hamiltonian , where

as an example.

Imports & Parameters

Throughout this chapter, we will use the following imports.

import numpy as np
import matplotlib.pyplot as plt
from scipy.sparse.linalg import eigsh

from struqture_py import PauliHamiltonian, PauliProduct

from hqs_quantum_solver.spins import (
    VectorSpace, Operator, magnetic_field_z, struqture_term
)

Furthermore, we will make use of the following parameters.

M = 7    # number of sites/spins
U = 1.0  # interaction strength
B = 3.0  # magnetic field strength (will be introduced later)

Building Operators

Hamiltonians for spin systems can be described in Struqture using the PauliHamiltonian class. (Other options for describing spin systems are the PauliOperator and PlusMinusOperator classes.) The class describes a sum of products of operators. Each operator acts on a specific site of the system, and each product has at most one operator per site. More precisely, the operators have the form Inhere, , , and . The previously defined Hamiltonian can be written in this form: we have that which has the desired shape.

To define the Hamiltonian using Struqture, we first create an object of type PauliHamiltonian and then add the individual products using the .add_operator_product method. Each product is given by a string, describing the operator product, and the corresponding coefficient. The string consecutively lists the terms of the product, where each factor is represented by a number followed by a character. The number defines the site the operator is acting on, and the character defines the type of the operator, e.g. "2X3X" describes the product . In the following code, we use Python format strings to build the required strings.

interaction = PauliHamiltonian()

for j in range(M - 1):
    interaction.add_operator_product(f"{j}X{j+1}X", 0.25 * U)
    interaction.add_operator_product(f"{j}Y{j+1}Y", 0.25 * U)
    interaction.add_operator_product(f"{j}Z{j+1}Z", 0.25 * U)

print(interaction)

Running the code above creates the desired operator and prints the following output, which shows how Struqture stores the operator, where each line gives one summand from the formula for the Hamiltonian.

PauliHamiltonian{
0X1X: 5e-1,
0Y1Y: 5e-1,
0Z1Z: 5e-1,
1X2X: 5e-1,
1Y2Y: 5e-1,
1Z2Z: 5e-1,
2X3X: 5e-1,
2Y3Y: 5e-1,
2Z3Z: 5e-1,
3X4X: 5e-1,
3Y4Y: 5e-1,
3Z4Z: 5e-1,
4X5X: 5e-1,
4Y5Y: 5e-1,
4Z5Z: 5e-1,
5X6X: 5e-1,
5Y6Y: 5e-1,
5Z6Z: 5e-1,
}

Having a description of the Hamiltonian, we can create an actual operator that we can use in computations. The first thing to do is to convert the Struqture object into a Quantum Solver expression, using the struqture_term function. Then, as we have seen earlier, we create a VectorSpace object and finally an Operator object, by passing in the expression describing the operator and the vector space. Note that we can use the .current_number_spins method to set the number of sites in the vector space.

v = VectorSpace(sites=interaction.current_number_spins(), total_spin_z="all")
hamiltonian = Operator(struqture_term(interaction), domain=v)

With the operator, we can now compute and plot the energy levels, in the same way as we did previously.

eigvals, eigvecs = eigsh(hamiltonian, k=16, which="SA")

plt.figure("energy")
plt.title("Energy Levels")
plt.xlabel("Level Number")
plt.ylabel("Energy")
plt.plot(eigvals, "x")

The resulting figure is shown below.

The energy levels.

Combining Expressions

Next, we want to consider a slightly more complicated example. Assume that the spin system that we have defined at the beginning of this chapter is exposed to a magnetic field in direction of the -axis. More precisely, we want to consider the Hamiltonian that is given by

If we wanted, we could build the entire Hamiltonian using Struqture. There is, however, an easier way. Quantum Solver has already a definition of the magnetic-field term, namely the magnetic_field_z function. Furthermore, Quantum Solver allows building of arbitrary linear combination of Quantum Solver expressions. Hence, we can combine the Struqture definition of the spin interaction with the magnetic_field_z function, which is shown below.

hamiltonian2 = Operator(
    magnetic_field_z(coef=B * np.ones(v.sites)) + struqture_term(interaction),
    domain=v
)

Then, again, we can compute the energy levels and plot them.

eigvals2, eigvecs2 = eigsh(hamiltonian2, k=16, which="SA")

plt.figure("energy-with-field")
plt.title("Energy Levels with Magnetic Field")
plt.xlabel("Level Number")
plt.ylabel("Energy")
plt.plot(eigvals2, "x")

Finally, running the code produces the figure below.

The energy levels with a magnetic field.

Complete Code

# Title    : Using Struqture with HQS Quantum Solver
# Filename : struqture.py

# ===== Imports and Parameters =====

import numpy as np
import matplotlib.pyplot as plt
from scipy.sparse.linalg import eigsh

from struqture_py import PauliHamiltonian, PauliProduct

from hqs_quantum_solver.spins import (
    VectorSpace, Operator, magnetic_field_z, struqture_term
)

M = 7    # number of sites/spins
U = 1.0  # interaction strength
B = 3.0  # magnetic field strength (will be introduced later)

# ===== Struqture Definition of the System =====

interaction = PauliHamiltonian()

for j in range(M - 1):
    interaction.add_operator_product(f"{j}X{j+1}X", 0.25 * U)
    interaction.add_operator_product(f"{j}Y{j+1}Y", 0.25 * U)
    interaction.add_operator_product(f"{j}Z{j+1}Z", 0.25 * U)

print(interaction)

# ===== Creating the Operator =====

v = VectorSpace(sites=interaction.current_number_spins(), total_spin_z="all")
hamiltonian = Operator(struqture_term(interaction), domain=v)

eigvals, eigvecs = eigsh(hamiltonian, k=16, which="SA")

plt.figure("energy")
plt.title("Energy Levels")
plt.xlabel("Level Number")
plt.ylabel("Energy")
plt.plot(eigvals, "x")

# ===== Combining Expressions =====

hamiltonian2 = Operator(
    magnetic_field_z(coef=B * np.ones(v.sites)) + struqture_term(interaction),
    domain=v
)

eigvals2, eigvecs2 = eigsh(hamiltonian2, k=16, which="SA")

plt.figure("energy-with-field")
plt.title("Energy Levels with Magnetic Field")
plt.xlabel("Level Number")
plt.ylabel("Energy")
plt.plot(eigvals2, "x")