Tutorial: Easy Quantum System Setup with ChatGPT#

Welcome to our ChatGPT-powered tutorial on setting up Hamiltonians for quantum systems! Get ready to dive into the quantum world effortlessly. Let’s spice things up with some visual flair!

What You Can Do with ChatGPT#

With ChatGPT, you’re in control! Here’s what you can tweak:

Customize Your System#

  • Electrons: Adjust the number of electrons buzzing around.

  • Orbitals: Play with the spatial arrangement by setting the orbital count.

  • Symmetry: Fine-tune the electron integrals’ symmetry.

  • Connectivity: Choose between periodic or open boundaries, and explore 1D chains or 2D lattices.

Tailor Your Hamiltonian#

  • Occupation-based: Set energies for each orbital, tweak interactions between neighboring orbitals, and manage Coulomb repulsion between electrons.

  • Spin-based: Adjust couplings between electrons on the same or adjacent orbitals, and control the strength of the magnetic field.

Note: Giving full control to ChatGPT can lead to some unexpected results. But don’t worry, we’ve got you covered with a few presets to get you started. Let’s dive in!

Before you start#

Before you start, make sure you have installed the gpt version of the ModelHamiltonian package. You can find detailed instructions here. Once intalled, you need to provide your OpenAI API key to use the model. You can find instructions on how to get your API key at the official OpenAI tutorial.

Please, make sure to put your API key in the file called config.toml that is located in the folder ~/moha/gpt. Don’t forget to put quotes around your API key.

Example 1: Simple 1D Huckel model#

In this example we will see how to generate a simple 1D Huckel model. We will set the number of electrons to 4, the number of orbitals to 4, and the hopping parameter to 1. We will save ouput to fcidump file that will be called huckel_1d.fcidump.

Step 1: Set up the system#

ChatGPT has generated 1D Huckel model with open boundary conditions. The hamiltonian is saved in the file huckel_1d.fcidump.

from moha.gpt import generate_ham

ham = generate_ham("Generate a simple 1d Huckel model with open boundary condition and t=-1. Set energy of orbitals alpha equal to 0. System has 4 sites and 4 orbitals. Return ouput in the spatial basis. \
                    Save it to the fcidump file called huckel_1d")
The given system represents a 1D chain of 4 sites with 4 orbitals. It is described by the Huckel model, which characterizes pi-electron systems. The energy of each orbital is set to zero. The hopping parameter between adjacent orbitals is -1, indicating a delocalized electron system. The system has no charge at each site.
System is: 1d

Step 2: Accessing results#

Once generated, electron integrals are stored as scipy.sparse.csr_matrix. We will convert one-electron integral to dense matrix and print it using the to_dense method.

one_body = ham.one_body
one_body_dense = ham.to_dense(one_body)
print(one_body_dense)
[[ 0. -1.  0.  0.]
 [-1.  0. -1.  0.]
 [ 0. -1.  0. -1.]
 [ 0.  0. -1.  0.]]

Great! One-electron integrals are generated correctly. Let’s move on to the next example.

Example 2: 1D Hubbard model#

In this example we will see how to generate a 1D Hubbard model with periodic boundary condtions. We will set the number of electrons to 2, the number of orbitals to 4, the hopping parameter to -1, and the Coulomb repulsion on each site to 0.5. The energy of orbital we set to 0. We can save ouput as .npz file that will be called hubbard_1d.

import numpy as np

hub = generate_ham("Generate a simple  Hubbard model with periodic boundary condition and t=-1, U=0.5.\
                    Put energy of orbital equal to 0. System has 2 electrons and 4 orbitals. Return ouput in the spatial basis. \
                    Save it to the npz file and call it hubbard_1d.")

one_body = hub.one_body
one_body_dense = hub.to_dense(one_body)
print(one_body_dense)


two_body = hub.two_body
# to convert two_body to dense form we need to specify the dimension of the returned tensor
# in this case, the dimension is 4
two_body_dense = hub.to_dense(two_body, dim=4)
# get non-zero elements
indices = np.where(two_body_dense != 0)
# print non-zero elements
for ind in zip(*indices):
    print(f"Element {ind} has value {two_body_dense[ind]}")
The Hubbard model is a simplified model for studying electron behavior in a solid material. It describes the behavior of electrons on a lattice and includes parameters for the energy of each orbital, the hopping parameter between adjacent orbitals, and the Coulomb interaction between electrons on the same site. In this case, the energy of the orbital is set to 0, the hopping parameter is -1, and the on-site Coulomb interaction is 0.5. The system has 4 orbitals and 2 electrons. The boundary conditions are periodic, which means that the system forms a ring-like structure.
System is: 1d
[[ 0. -1.  0. -1.]
 [-1.  0. -1.  0.]
 [ 0. -1.  0. -1.]
 [-1.  0. -1.  0.]]
Element (0, 0, 0, 0) has value 0.5
Element (1, 1, 1, 1) has value 0.5
Element (2, 2, 2, 2) has value 0.5
Element (3, 3, 3, 3) has value 0.5

Example 2 is ready! Let’s move on to the spin-based Hamiltonian.

Example 3: Spin-based Hamiltonian#

In this example we will see how to generate a Heisenber XXX model. We will set the number of electrons to 4, the number of orbitals to 4. The coupling terms between electrons are \(J_{eq} = J_{ax} = 0.5\). This time we will not save the output to a file.

heisenberg = generate_ham("Generate a 1d Heisenberg model with periodic boundary condition. Both coupling terms are equal to 0.5.\
                           System has 4 sites and 4 orbitals. Return ouput in the spinorbital basis and don't save the result.")

# checking if parameters are set correctly
print(f"J_ax is: \n {heisenberg.J_ax}\n J_eq is:\n {heisenberg.J_eq}")
print(f"External field = {heisenberg.mu}")

one_body = heisenberg.one_body
one_body_dense = heisenberg.to_dense(one_body)

two_body = heisenberg.two_body
two_body_dense = heisenberg.to_dense(two_body)
1D Heisenberg model with periodic boundary condition. The coupling terms along x and y axes, J_eq and J_ax, respectively, are both equal to 0.5.
System is: 1d
J_ax is: 
 [[0.  0.5 0.  0.5]
 [0.5 0.  0.5 0. ]
 [0.  0.5 0.  0.5]
 [0.5 0.  0.5 0. ]]
 J_eq is:
 [[0.  0.5 0.  0.5]
 [0.5 0.  0.5 0. ]
 [0.  0.5 0.  0.5]
 [0.5 0.  0.5 0. ]]
External field = 0.0

Great job! It seems like you’re getting the hang of it. Let’s move on to the next, final example.

Example 4: Richardson model#

In this example we will see the real power of ChatGPT. We will generate a Richardson model with 6 electrons and 3x2 orbitals. We will set a 2 dimensional lattice 3x2 lattice with periodic boundary conditions. The coupling term is set to 0.5. Keep in mind, that in this case chatgpt will need to realize that in richardson model \(J_{ax}\) term does not exist.

rg = generate_ham("Generate a 2d Richardson-Gaudin model that has 6 electrons. It should have a 3x2 size with periodic boundary condition. Coupling J is 0.5.\
                   Return ouput in the spatial basis. Assume 4-fold symmetry. Don't save the result.")
A 2D Richardson-Gaudin model with 6 electrons. The system has periodic boundary conditions and a 3x2 size. The coupling parameter J is 0.5. The model assumes 4-fold symmetry.
System is: 2d

Impressive! You’ve successfully set up a Richardson model. Let’s print the adjacency matrix and \(J_{eq}, J_{aq}\) terms to see if everything is correct.

print(f"Adjacency matrix is:\n \n {rg.connectivity} \n")
print(f"J_ax is:\n {rg.J_ax} \n")
print(f"J_eq is:\n {rg.J_eq}") 
Adjacency matrix is:
 
 [[0. 1. 1. 1. 0. 0.]
 [1. 0. 1. 0. 1. 0.]
 [1. 1. 0. 0. 0. 1.]
 [1. 0. 0. 0. 1. 1.]
 [0. 1. 0. 1. 0. 1.]
 [0. 0. 1. 1. 1. 0.]] 

J_ax is:
 [[0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]] 

J_eq is:
 [[0.  0.5 0.5 0.5 0.  0. ]
 [0.5 0.  0.5 0.  0.5 0. ]
 [0.5 0.5 0.  0.  0.  0.5]
 [0.5 0.  0.  0.  0.5 0.5]
 [0.  0.5 0.  0.5 0.  0.5]
 [0.  0.  0.5 0.5 0.5 0. ]]