Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ parts:
- file: tutorials/generating_lattices
- file: tutorials/pulser-calc-example
- file: tutorials/finite-geometries
- file: tutorials/vqe_qiskit
- caption: Use-Cases
chapters:
- file: use-cases/ssh_model
Expand Down
205 changes: 205 additions & 0 deletions docs/tutorials/vqe_qiskit.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "56fc15e4",
"metadata": {},
"source": [
"# VQE for a spin model using `qse` Operators\n",
"\n",
"This notebook builds a spin model using the `qse` `Operator` / `Operators` classes,\n",
"converts it to a Qiskit `SparsePauliOp` via `to_qiskit()` method, and runs VQE to find the ground state energy."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "116e033e",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import qse\n",
"from qse.operator.operator import Operator\n",
"from qse.operator.operators import Operators"
]
},
{
"cell_type": "markdown",
"id": "7b142901",
"metadata": {},
"source": [
"## 1. Build the spin model.\n",
"\n",
"We build a 1D **transverse-field Ising model** (TFIM) on $N=10$ qubits:\n",
"\n",
"$$H = -J \\sum_{i=0}^{N-2} Z_i Z_{i+1} - h \\sum_{i=0}^{N-1} X_i$$"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b1ec8bad",
"metadata": {},
"outputs": [],
"source": [
"N = 10\n",
"J = 1.0\n",
"h = 0.5\n",
"spacing = 1.0\n",
"\n",
"qbits = qse.lattices.chain(spacing, N)\n",
"\n",
"# ZZ interaction terms between neighbouring qubits\n",
"hamiltonian = qbits.compute_interaction_hamiltonian(\n",
" distance_func=lambda d: -J * np.isclose(d, spacing),\n",
" interaction=\"Z\",\n",
")\n",
"\n",
"# Transverse field X terms on each qubit\n",
"for i in range(N):\n",
" hamiltonian += qse.Operator(\"X\", i, N, coef=-h)"
]
},
{
"cell_type": "markdown",
"id": "be80c5c1",
"metadata": {},
"source": [
"## 2. Convert to Qiskit `SparsePauliOp`\n",
"\n",
"Once we have the Hamiltonian $H$, we can use the `to_qiskit()` method to transform it to a Qiskit Sparse Pauli Operator. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "51b961bb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SparsePauliOp(['ZZIIIIIIII', 'IZZIIIIIII', 'IIZZIIIIII', 'IIIZZIIIII', 'IIIIZZIIII', 'IIIIIZZIII', 'IIIIIIZZII', 'IIIIIIIZZI', 'IIIIIIIIZZ', 'XIIIIIIIII', 'IXIIIIIIII', 'IIXIIIIIII', 'IIIXIIIIII', 'IIIIXIIIII', 'IIIIIXIIII', 'IIIIIIXIII', 'IIIIIIIXII', 'IIIIIIIIXI', 'IIIIIIIIIX'],\n",
" coeffs=[-1. +0.j, -1. +0.j, -1. +0.j, -1. +0.j, -1. +0.j, -1. +0.j, -1. +0.j,\n",
" -1. +0.j, -1. +0.j, -0.5+0.j, -0.5+0.j, -0.5+0.j, -0.5+0.j, -0.5+0.j,\n",
" -0.5+0.j, -0.5+0.j, -0.5+0.j, -0.5+0.j, -0.5+0.j])\n"
]
}
],
"source": [
"pauli_op = hamiltonian.to_qiskit()\n",
"print(pauli_op)"
]
},
{
"cell_type": "markdown",
"id": "a006d641",
"metadata": {},
"source": [
"## 3. Set up and run VQE.\n",
"\n",
"We set up and run the VQE in qiskit. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7e8986ad",
"metadata": {},
"outputs": [],
"source": [
"from qiskit.primitives import StatevectorEstimator\n",
"from qiskit.circuit.library import efficient_su2\n",
"\n",
"import numpy as np\n",
"from scipy.optimize import minimize"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "55201685",
"metadata": {},
"outputs": [],
"source": [
"ansatz = efficient_su2(num_qubits=N, reps=2, entanglement=\"linear\")\n",
"estimator = StatevectorEstimator()\n",
"energies_list = []\n",
"\n",
"\n",
"def cost_function(params):\n",
" result = estimator.run([(ansatz, pauli_op, params)]).result()\n",
" energy = result[0].data.evs\n",
" energies_list.append(float(energy))\n",
" return float(energy)\n",
"\n",
"\n",
"# Random initial parameters\n",
"rng = np.random.default_rng(42)\n",
"x0 = rng.uniform(-np.pi, np.pi, ansatz.num_parameters)\n",
"\n",
"result = minimize(\n",
" cost_function, x0, method=\"COBYLA\", options={\"maxiter\": 2000, \"rhobeg\": 0.5}\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "94b26131",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"VQE ground state energy : -9.745759\n",
"Exact ground state energy: -9.76550395792718\n"
]
}
],
"source": [
"ground_state = np.linalg.eigh(pauli_op.to_matrix())[0][0]\n",
"print(f\"VQE ground state energy : {result.fun:.6f}\")\n",
"print(f\"Exact ground state energy: {ground_state}\")"
]
},
{
"cell_type": "markdown",
"id": "ab8e9a6d",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "87c3414d",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "env_qse",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ docs = [
"ipywidgets",
"ipympl",
"pulser", # required for creating the docs
"qiskit"
]

[tool.black]
Expand Down
Loading