Skip to content

Commit

Permalink
Merge branch 'spin_operators' of https://github.com/eclipse-qrisp/Qrisp
Browse files Browse the repository at this point in the history
… into spin_operators
  • Loading branch information
positr0nium committed Oct 31, 2024
2 parents 322ac28 + 0a981f1 commit af2e5ce
Show file tree
Hide file tree
Showing 26 changed files with 1,140 additions and 995 deletions.
Binary file added documentation/source/_static/BeH2_PEC_4_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/source/_static/BeH2_PEC_6_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions documentation/source/reference/Examples/GroundStateEnergyQPE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.. _GroundStateEnergyQPE:

Ground State Energy with QPE
============================

.. currentmodule:: qrisp

Example Hydrogen
================

We caluclate the ground state energy of the Hydrogen molecule with :ref:`Quantum Phase Estimation <QPE>`.

Utilizing symmetries, one can find a reduced two qubit Hamiltonian for the Hydrogen molecule. Frist, we define the Hamiltonian, and compute the
ground state energy classically.

::

from qrisp import QuantumVariable, x, QPE
from qrisp.operators.pauli.pauli import X,Y,Z
import numpy as np

# Hydrogen (reduced 2 qubit Hamiltonian)
H = -1.05237325 + 0.39793742*Z(0) -0.39793742*Z(1) -0.0112801*Z(0)*Z(1) + 0.1809312*X(0)*X(1)
E0 = H.ground_state_energy()
# Yields: -1.85727502928823

In the following, we utilize the ``trotterization`` method of the :ref:`PauliHamiltonian` to obtain a function **U** that applies **Hamiltonian Simulation**
via Trotterization. If we start in a state that is close to the ground state and apply :ref:`QPE`, we get an estimate of the ground state energy.

::

# ansatz state
qv = QuantumVariable(2)
x(qv[0])
E1 = H.get_measurement(qv)
E1
# Yields: -1.83858104676077


We calculate the ground state energy with quantum phase estimation. As the results of the phase estimation are modulo :math:`2\pi`, we subtract :math:`2\pi`.

::

U = H.trotterization()

qpe_res = QPE(qv,U,precision=10,kwargs={"steps":3},iter_spec=True)

results = qpe_res.get_measurement()
sorted_results= dict(sorted(results.items(), key=lambda item: item[1], reverse=True))
phi = list(sorted_results.items())[0][0]
E_qpe = 2*np.pi*(phi-1) # Results are modulo 2*pi, therefore subtract 2*pi
E_qpe
# Yields: -1.8591847149174
84 changes: 84 additions & 0 deletions documentation/source/reference/Examples/IsingModel.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
.. _IsingModel:

Transverse Field Ising Model
============================

.. currentmodule:: qrisp

In this example, we study Hamiltonian dynamics of the transverse field Ising model defined by the Hamiltonian

$$H = -J\\sum_{(i,j)\\in E}Z_iZ_j + B\\sum_{i\\in V}X_i$$

for a lattice graph $G=(V,E)$ and real parameters $J, B$. We investigate the total magnetization of the system as it evolves under the Hamiltonian.

Here, we consider an Ising chain.

::

import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

def generate_chain_graph(N):
coupling_list = [[k,k+1] for k in range(N-1)]
G = nx.Graph()
G.add_edges_from(coupling_list)
return G

G = generate_chain_graph(6)

We implement methods for creating the Ising Hamiltonian and the total magnetization observable for a given graph.

::

from qrisp import QuantumVariable
from qrisp.operators.pauli import X, Y, Z

def create_ising_hamiltonian(G, J, B):
H = sum(-J*Z(i)*Z(j) for (i,j) in G.edges()) + sum(B*X(i) for i in G.nodes())
return H

def create_magnetization(G):
H = (1/G.number_of_nodes())*sum(Z(i) for i in G.nodes())
return H

With all the necessary ingredients, we conduct the experiment: For varying evolution times $T$:

- Prepare the $\ket{0}^{\otimes N}$ state.

- Perform **Hamiltonian simulation** via Trotterization.

- Measure the total magnetization.

::

T_values = np.arange(0, 2.0, 0.05)
M_values = []

M = create_magnetization(G)

for T in T_values:
H = create_ising_hamiltonian(G,1.0,1.0)
U = H.trotterization()

qv = QuantumVariable(G.number_of_nodes())
U(qv,t=-T,steps=5)
M_values.append(M.get_measurement(qv,precision=0.005))

Finally, we visualize the results. As expected, the total magnetization decreases in the presence of a transverse field with increasing evolution time $T$.

::

import matplotlib.pyplot as plt
plt.scatter(T_values, M_values, color='#6929C4', marker="o", linestyle='solid', s=10, label='Magnetization')
plt.xlabel("Time", fontsize=15, color="#444444")
plt.ylabel("Magnetization", fontsize=15, color="#444444")
plt.legend(fontsize=12, labelcolor="#444444")
plt.tick_params(axis='both', labelsize=12)
plt.grid()
plt.show()

.. figure:: /_static/Ising_chain_N=6.png
:alt: Ising chain
:align: center

Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
.. _MolecularPotentialEnergyCurveExample:
.. _MolecularPotentialEnergyCurve:

Molecular Potential Energy Curves
=================================

.. currentmodule:: qrisp.vqe

Molecular potential energy curves and surfaces are tools in computational quantum chemistry for analysing the molecular geometries and chemical reactions.
The potential energy is defined as

$$E_{\\text{pot}}(\\{R_A\\})=E_{\\text{elec}}(\\{R_A\\})+E_{\\text{nuc}}(\\{R_A\\})$$

where $E_{\text{elec}}(\{R_A\})$ is the electronic energy and $E_{\text{nuc}}(\{R_A\})$ is the nuclear repulsion energy depending on the coordinates of the atoms $\{R_A\}$.


Example Hydrogen
================

We caluclate the Potetial Energy Curve for the Hydrogen molecule for varying interatomic distance of the atoms.
We caluclate the potential energy curve for the Hydrogen molecule for varying interatomic distance of the atoms.


We implement a function ``problem_data`` that sets up a molecule and
utilizes the `PySCF <https://pyscf.org>`_ quantum chemistry library to compute the :meth:`electronic data <qrisp.vqe.problems.electronic_structure.electronic_structure_problem>` (one- and two-electron integrals, number of orbitals, number of electroins, nuclear repulsion energy, Hartree-Fock energy)
utilizes the `PySCF <https://pyscf.org>`_ quantum chemistry library to compute the :meth:`electronic data <qrisp.vqe.problems.electronic_structure.electronic_structure_problem>` (one- and two-electron integrals, number of orbitals, number of electrons, nuclear repulsion energy, Hartree-Fock energy)
for a given molecular geometry. In this example, we vary the **atomic distance** between the two Hydrogen atoms.

::
Expand Down Expand Up @@ -56,8 +64,8 @@ Finally, we visualize the results.
::

import matplotlib.pyplot as plt
plt.scatter(x, y_hf, color='#7d7d7d',marker="o", linestyle='solid',s=10, label='HF energy')
plt.scatter(x, y_qccsd, color='#6929C4',marker="o", linestyle='solid',s=10, label='VQE (QCCSD) energy')
plt.scatter(distances, y_hf, color='#7d7d7d',marker="o", linestyle='solid',s=10, label='HF energy')
plt.scatter(distances, y_qccsd, color='#6929C4',marker="o", linestyle='solid',s=10, label='VQE (QCCSD) energy')
plt.xlabel("Atomic distance", fontsize=15, color="#444444")
plt.ylabel("Energy", fontsize=15, color="#444444")
plt.legend(fontsize=12, labelcolor="#444444")
Expand All @@ -68,17 +76,86 @@ Finally, we visualize the results.

.. figure:: /_static/H2_PEC.png
:alt: Hydrogen Potential Energy Curve
:scale: 80%
:align: center


Example Beryllium hydride
=========================

We caluclate the Potetial Energy Curve for the Beryllium hydride molecule for varying interatomic distance of the atoms.
We caluclate the potential energy curve for the Beryllium hydride molecule for varying interatomic distance of the atoms.

As in the previous example, we set up a function that computes the :meth:`electronic data <qrisp.vqe.problems.electronic_structure.electronic_structure_problem>` for
the Beryllium hydride molecule for varying **atomic distance** between the Beryllium and Hydrogen atoms.

::

from pyscf import gto
from qrisp.vqe.problems.electronic_structure import *
from qrisp import QuantumVariable

def problem_data(r):
mol = gto.M(
atom = f'''Be 0 0 0; H 0 0 {r}; H 0 0 {-r}''',
basis = 'sto-3g')
return electronic_data(mol)

We further investigate the problem size:

::
data = problem_data(2.0)
print(data['num_orb'])
print(data['num_elec'])

H = create_electronic_hamiltonian(data).to_pauli_hamiltonian()
print(H.len())

In the chosen sto-3g basis, there are 14 molecular orbitals (qubits) and 6 electrons. The problem Hamiltonian has 666 terms.
For `reducing the problem size <https://arxiv.org/abs/2009.01872>`_, an active space reduction is applied: We consider 6 **active orbitals** and 2 **active electrons**, that is,

* 4 electrons occupy the 4 lowest energy molecular orbitals

* 2 electrons are distributed among the subsequent 4 molecular orbitals (quantum optimization)

* the remaining (highest energy) 6 orbitals are not occupied

This lowers the quantum resource requirements to 4 qubits, and a reduced 4 qubit Hamiltonian is considered.

.. warning::

The following code may well take more than 10 minutes to run!

::

distances = np.arange(0.2, 4.0, 0.1)
y_hf = []
y_qccsd = []

for r in distances:
data = problem_data(r)
y_hf.append(data['energy_hf'])
vqe = electronic_structure_problem(data,active_orb=4,active_elec=2)
results = []
for i in range(5):
res = vqe.run(QuantumVariable(6),depth=2,max_iter=100,optimizer='COBYLA',mes_kwargs={'precision':0.005})
results.append(res+data['energy_nuc'])
y_qccsd.append(min(results))

Finally, we visualize the results.

::

import matplotlib.pyplot as plt
plt.scatter(distances[5:], y_hf[5:], color='#7d7d7d',marker="o", linestyle='solid',s=10, label='HF energy')
plt.scatter(distances[5:], y_qccsd[5:], color='#6929C4',marker="o", linestyle='solid',s=10, label='VQE (QCCSD) energy')
plt.xlabel("Atomic distance", fontsize=15, color="#444444")
plt.ylabel("Energy", fontsize=15, color="#444444")
plt.legend(fontsize=12, labelcolor="#444444")
plt.tick_params(axis='both', labelsize=12)
plt.grid()
plt.show()


.. figure:: /_static/BeH2_PEC_4_2.png
:alt: Beryllium Hydrate Potential Energy Curve
:align: center
12 changes: 9 additions & 3 deletions documentation/source/reference/Examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ In this section, we provide a glimpse into the diverse range of applications tha
- Provides implementations for solving optimization problems using the Quantum Approximate Optimization Algorithm. For a detailed tutorial on how to use QAOA, please refer to the :ref:`in depth QAOA tutorial <QAOA101>`.
* - :ref:`ShorExample`
- Showcases the cryptographic implications of implementating Shor's algorithm and provides insight in how to easily use a custom adder.
* - :ref:`MolecularPotentialEnergyCurveExample`
- Molecular Potetial Energy Curve

* - :ref:`MolecularPotentialEnergyCurve`
- Calculating molecular potential energy curves with :ref:`VQE`.
* - :ref:`GroundStateEnergyQPE`
- Calculating ground state energies with quantum phase estimation.
* - :ref:`IsingModel`
- Hamiltonian simulation of a transverse field Ising model.


.. toctree::
:hidden:
Expand All @@ -57,3 +61,5 @@ In this section, we provide a glimpse into the diverse range of applications tha
QAOA
Shor
MolecularPotentialEnergyCurve
GroundStateEnergyQPE
IsingModel
30 changes: 23 additions & 7 deletions documentation/source/reference/Hamiltonians/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Hamiltonians

This Hamiltonians submodule of Qrisp provides a unified framework to describe, optimize and simulate quantum Hamiltonians.
It provides a collection of different types of Hamiltonians that can be used to model and solve a variety of problems in physics, chemistry, or optimization.
(Up to now, Pauli Hamiltonians have been implemented, but stay tuned for future updates!)
(Up to now, Pauli Hamiltonians and Fermionic Hamiltonians have been implemented, but stay tuned for future updates!)
Each type of Hamiltonian comes with comprehensive documentation and brief examples to help you understand its implementation and usage:

.. list-table::
Expand All @@ -16,12 +16,8 @@ Each type of Hamiltonian comes with comprehensive documentation and brief exampl

* - Hamiltonian
- USED FOR
* - :ref:`Hamiltonian <Hamiltonian>`
- unified framework for quantum Hamiltonians
* - :ref:`PauliHamiltonian <PauliHamiltonian>`
- describe Hamiltonians in terms of Pauli operators
* - :ref:`BoundPauliHamiltonian <BoundPauliHamiltonian>`
- describe Hamiltonians in terms of Pauli operators, bound to specific QuantumVariables
* - :ref:`FermionicHamiltonian <FermionicHamiltonian>`
- describe Hamiltonians in terms of fermionic ladder operators

Expand All @@ -32,7 +28,27 @@ We encourage you to explore these Hamiltonians, delve into their documentation,
.. toctree::
:hidden:

Hamiltonian
PauliHamiltonian
BoundPauliHamiltonian
FermionicHamiltonian


Examples
========

.. list-table::
:widths: 25 25
:header-rows: 1

* - Title
- Description
* - :ref:`VQEHeisenberg`
- Investigating the antiferromagnetic Heisenberg model with :ref:`VQE <VQE>`.
* - :ref:`VQEElectronicStructure`
- Solving the electronic structure problem with :ref:`VQE <VQE>`.
* - :ref:`MolecularPotentialEnergyCurve`
- Calculating molecular potential energy curves with :ref:`VQE <VQE>`.
* - :ref:`GroundStateEnergyQPE`
- Calculating ground state energies with :ref:`quantum phase estimation <QPE>`.
* - :ref:`IsingModel`
- Hamiltonian simulation of the transverse field Ising model.

Loading

0 comments on commit af2e5ce

Please sign in to comment.