1404 lines (1403 with data), 132.7 kB
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "e-qZmPKaLbJ7"
},
"outputs": [],
"source": [
"# This cell is added by sphinx-gallery\n",
"# It can be customized to whatever you like\n",
"%matplotlib inline\n",
"# !pip install pennylane"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZPrrGxMTLbJ7"
},
"source": [
"The Quantum Graph Recurrent Neural Network\n",
"==========================================\n",
"\n",
"::: {.meta}\n",
":property=\\\"og:description\\\": Using a quantum graph recurrent neural\n",
"network to learn quantum dynamics. :property=\\\"og:image\\\":\n",
"<https://pennylane.ai/qml/_images/qgrnn_thumbnail.png>\n",
":::\n",
"\n",
"*Author: Jack Ceroni --- Posted: 27 July 2020. Last updated: 25 March\n",
"2021.*\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CU3x_5JALbJ8"
},
"source": [
"This demonstration investigates quantum graph recurrent neural networks\n",
"(QGRNN), which are the quantum analogue of a classical graph recurrent\n",
"neural network, and a subclass of the more general quantum graph neural\n",
"network ansatz. Both the QGNN and QGRNN were introduced in [this paper\n",
"(2019)](https://arxiv.org/abs/1909.12264).\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3M64CbeaLbJ8"
},
"source": [
"The Idea\n",
"========\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "H3vGd3-BLbJ8"
},
"source": [
"A graph is defined as a set of *nodes* along with a set of **edges**,\n",
"which represent connections between nodes. Information can be encoded\n",
"into graphs by assigning numbers to nodes and edges, which we call\n",
"**weights**. It is usually convenient to think of a graph visually:\n",
"\n",
"{.align-center width=\"70.0%\"}\n",
"\n",
"In recent years, the concept of a [graph neural\n",
"network](https://arxiv.org/abs/1812.08434) (GNN) has been receiving a\n",
"lot of attention from the machine learning community. A GNN seeks to\n",
"learn a representation (a mapping of data into a low-dimensional vector\n",
"space) of a given graph with feature vectors assigned to nodes and\n",
"edges. Each of the vectors in the learned representation preserves not\n",
"only the features, but also the overall topology of the graph, i.e.,\n",
"which nodes are connected by edges. The quantum graph neural network\n",
"attempts to do something similar, but for features that are\n",
"quantum-mechanical; for instance, a collection of quantum states.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "T3MTH5BWLbJ8"
},
"source": [
"Consider the class of qubit Hamiltonians that are *quadratic*, meaning\n",
"that the terms of the Hamiltonian represent either interactions between\n",
"two qubits, or the energy of individual qubits. This class of\n",
"Hamiltonians is naturally described by graphs, with second-order terms\n",
"between qubits corresponding to weighted edges between nodes, and\n",
"first-order terms corresponding to node weights.\n",
"\n",
"A well known example of a quadratic Hamiltonian is the transverse-field\n",
"Ising model, which is defined as\n",
"\n",
"$$\\hat{H}_{\\text{Ising}}(\\boldsymbol\\theta) \\ = \\ \\displaystyle\\sum_{(i, j) \\in E}\n",
"\\theta_{ij}^{(1)} Z_{i} Z_{j} \\ + \\ \\displaystyle\\sum_{i} \\theta_{i}^{(2)} Z_{i} \\ + \\\n",
"\\displaystyle\\sum_{i} X_{i},$$\n",
"\n",
"where $\\boldsymbol\\theta \\ = \\ \\{\\theta^{(1)}, \\ \\theta^{(2)}\\}$. In\n",
"this Hamiltonian, the set $E$ that determines which pairs of qubits have\n",
"$ZZ$ interactions can be represented by the set of edges for some graph.\n",
"With the qubits as nodes, this graph is called the *interaction graph*.\n",
"The $\\theta^{(1)}$ parameters correspond to the edge weights and the\n",
"$\\theta^{(2)}$ parameters correspond to weights on the nodes.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4fIzrPwnLbJ9"
},
"source": [
"This result implies that we can think about *quantum circuits* with\n",
"graph-theoretic properties. Recall that the time-evolution operator with\n",
"respect to some Hamiltonian $H$ is defined as:\n",
"\n",
"$$U \\ = \\ e^{-it H}.$$\n",
"\n",
"Thus, we have a clean way of taking quadratic Hamiltonians and turning\n",
"them into unitaries (quantum circuits) that preserve the same\n",
"correspondance to a graph. In the case of the Ising Hamiltonian, we\n",
"have:\n",
"\n",
"$$U_{\\text{Ising}} \\ = \\ e^{-it \\hat{H}_{\\text{Ising}} (\\boldsymbol\\theta)} \\ = \\ \\exp \\Big[ -it\n",
"\\Big( \\displaystyle\\sum_{(i, j) \\in E} \\theta_{ij}^{(1)} Z_{i} Z_{j} \\ + \\\n",
"\\displaystyle\\sum_{i} \\theta_{i}^{(2)} Z_{i} \\ + \\ \\displaystyle\\sum_{i} X_{i} \\Big) \\Big]$$\n",
"\n",
"In general, this kind of unitary is very difficult to implement on a\n",
"quantum computer. However, we can approximate it using the\n",
"[Trotter-Suzuki\n",
"decomposition](https://en.wikipedia.org/wiki/Time-evolving_block_decimation#The_Suzuki-Trotter_expansion):\n",
"\n",
"$$\\exp \\Big[ -it \\Big( \\displaystyle\\sum_{(i, j) \\in E} \\theta_{ij}^{(1)} Z_{i} Z_{j} \\ + \\\n",
"\\displaystyle\\sum_{i} \\theta_{i}^{(2)} Z_{i} \\ + \\ \\displaystyle\\sum_{i} X_{i} \\Big) \\Big]\n",
"\\ \\approx \\ \\displaystyle\\prod_{k \\ = \\ 1}^{t / \\Delta} \\Bigg[ \\displaystyle\\prod_{j \\ = \\\n",
"1}^{Q} e^{-i \\Delta \\hat{H}_{\\text{Ising}}^{j}(\\boldsymbol\\theta)} \\Bigg]$$\n",
"\n",
"where $\\hat{H}_{\\text{Ising}}^{j}(\\boldsymbol\\theta)$ is the $j$-th term\n",
"of the Ising Hamiltonian and $\\Delta$ is some small number.\n",
"\n",
"This circuit is a specific instance of the **Quantum Graph Recurrent\n",
"Neural Network**, which in general is defined as a variational ansatz of\n",
"the form\n",
"\n",
"$$U_{H}(\\boldsymbol\\mu, \\ \\boldsymbol\\gamma) \\ = \\ \\displaystyle\\prod_{i \\ = \\ 1}^{P} \\Bigg[\n",
"\\displaystyle\\prod_{j \\ = \\ 1}^{Q} e^{-i \\gamma_j H^{j}(\\boldsymbol\\mu)} \\Bigg],$$\n",
"\n",
"for some parametrized quadratic Hamiltonian, $H(\\boldsymbol\\mu)$.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uKXgaaF1LbJ9"
},
"source": [
"Using the QGRNN\n",
"===============\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GDA7lU2tLbJ9"
},
"source": [
"Since the QGRNN ansatz is equivalent to the approximate time evolution\n",
"of some quadratic Hamiltonian, we can use it to learn the dynamics of a\n",
"quantum system.\n",
"\n",
"Continuing with the Ising model example, let\\'s imagine we have some\n",
"system governed by $\\hat{H}_{\\text{Ising}}(\\boldsymbol\\alpha)$ for an\n",
"unknown set of target parameters, $\\boldsymbol\\alpha$ and an unknown\n",
"interaction graph $G$. Let\\'s also suppose we have access to copies of\n",
"some low-energy, non-ground state of the target Hamiltonian,\n",
"$|\\psi_0\\rangle$. In addition, we have access to a collection of\n",
"time-evolved states,\n",
"$\\{ |\\psi(t_1)\\rangle, \\ |\\psi(t_2)\\rangle, \\ ..., \\ |\\psi(t_N)\\rangle \\}$,\n",
"defined by:\n",
"\n",
"$$|\\psi(t_k)\\rangle \\ = \\ e^{-i t_k \\hat{H}_{\\text{Ising}}(\\boldsymbol\\alpha)} |\\psi_0\\rangle.$$\n",
"\n",
"We call the low-energy states and the collection of time-evolved states\n",
"*quantum data*. From here, we randomly pick a number of time-evolved\n",
"states from our collection. For any state that we choose, which is\n",
"evolved to some time $t_k$, we compare it to\n",
"\n",
"$$U_{\\hat{H}_{\\text{Ising}}}(\\boldsymbol\\mu, \\ \\Delta) |\\psi_0\\rangle \\ \\approx \\ e^{-i t_k\n",
"\\hat{H}_{\\text{Ising}}(\\boldsymbol\\mu)} |\\psi_0\\rangle.$$\n",
"\n",
"This is done by feeding one of the copies of $|\\psi_0\\rangle$ into a\n",
"quantum circuit with the QGRNN ansatz, with some guessed set of\n",
"parameters $\\boldsymbol\\mu$ and a guessed interaction graph, $G'$. We\n",
"then use a classical optimizer to maximize the average \\\"similarity\\\"\n",
"between the time-evolved states and the states prepared with the QGRNN.\n",
"\n",
"As the QGRNN states becomes more similar to each time-evolved state for\n",
"each sampled time, it follows that\n",
"$\\boldsymbol\\mu \\ \\rightarrow \\ \\boldsymbol\\alpha$ and we are able to\n",
"learn the unknown parameters of the Hamiltonian.\n",
"\n",
"{.align-center\n",
"width=\"90.0%\"}\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hYWy2SBeLbJ9"
},
"source": [
"Learning an Ising Model with the QGRNN\n",
"======================================\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HlWNWZZULbJ9"
},
"source": [
"We now attempt to use the QGRNN to learn the parameters corresponding to\n",
"an arbitrary transverse-field Ising model Hamiltonian.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GpdeYnFwLbJ-"
},
"source": [
"Getting Started\n",
"===============\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-5FbshFpLbJ-"
},
"source": [
"We begin by importing the necessary dependencies:\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "WoSjhgrvLbJ_"
},
"outputs": [],
"source": [
"import pennylane as qml\n",
"from matplotlib import pyplot as plt\n",
"from pennylane import numpy as np\n",
"import scipy\n",
"import networkx as nx\n",
"import copy"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SgJGdX-wLbJ_"
},
"source": [
"We also define some fixed values that are used throughout the\n",
"simulation.\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "FCZr2sEhLbJ_"
},
"outputs": [],
"source": [
"qubit_number = 4\n",
"qubits = range(qubit_number)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LLRw3rbhLbJ_"
},
"source": [
"In this simulation, we don\\'t have quantum data readily available to\n",
"pass into the QGRNN, so we have to generate it ourselves. To do this, we\n",
"must have knowledge of the target interaction graph and the target\n",
"Hamiltonian.\n",
"\n",
"Let us use the following cyclic graph as the target interaction graph of\n",
"the Ising Hamiltonian:\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 534
},
"id": "BBidusUTLbJ_",
"outputId": "0c46fd84-ae0e-4151-fa1c-e895585b1e2a"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Edges: [(0, 1), (0, 3), (1, 2), (2, 3)]\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"source": [
"ising_graph = nx.cycle_graph(qubit_number)\n",
"\n",
"print(f\"Edges: {ising_graph.edges}\")\n",
"nx.draw(ising_graph)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "U1Dum11GLbJ_"
},
"source": [
"We can then initialize the \"unknown\" target parameters that describe the\n",
"target Hamiltonian,\n",
"$\\boldsymbol\\alpha \\ = \\ \\{\\alpha^{(1)}, \\ \\alpha^{(2)}\\}$. Recall from\n",
"the introduction that we have defined our parametrized Ising Hamiltonian\n",
"to be of the form:\n",
"\n",
"$$\\hat{H}_{\\text{Ising}}(\\boldsymbol\\theta) \\ = \\ \\displaystyle\\sum_{(i, j) \\in E}\n",
"\\theta_{ij}^{(1)} Z_{i} Z_{j} \\ + \\ \\displaystyle\\sum_{i} \\theta_{i}^{(2)} Z_{i} \\ + \\\n",
"\\displaystyle\\sum_{i} X_{i},$$\n",
"\n",
"where $E$ is the set of edges in the interaction graph, and $X_i$ and\n",
"$Z_i$ are the Pauli-X and Pauli-Z on the $i$-th qubit.\n",
"\n",
"For this tutorial, we choose the target parameters by sampling from a\n",
"uniform probability distribution ranging from $-2$ to $2$, with\n",
"two-decimal precision.\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "dguKYJmcLbJ_"
},
"outputs": [],
"source": [
"target_weights = [0.56, 1.24, 1.67, -0.79]\n",
"target_bias = [-1.44, -1.43, 1.18, -0.93]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AiyO6svHLbJ_"
},
"source": [
"In theory, these parameters can be any value we want, provided they are\n",
"reasonably small enough that the QGRNN can reach them in a tractable\n",
"number of optimization steps. In `matrix_params`, the first list\n",
"represents the $ZZ$ interaction parameters and the second list\n",
"represents the single-qubit $Z$ parameters.\n",
"\n",
"Finally, we use this information to generate the matrix form of the\n",
"Ising model Hamiltonian in the computational basis:\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 437
},
"id": "xDSq-w2_LbJ_",
"outputId": "b1fd5ee7-6895-4566-ee8a-309d7242394a"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 480x480 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAaMAAAGkCAYAAACckEpMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAdLElEQVR4nO3df2xV9f3H8deltZeuaa+2jpY7W+kMEQXEH4VG8bvB10bSIEoWdRrEBjedWxFqDYNuK/7Eim6u/iBFzHfC9hXFfCPoSNSwiqARCm2tk2zjR+ywSkpnor1SxoW05/vHd959K4W2cD5991yej+TE3HMP7/PK8d6+cu49PQ15nucJAABDI6wDAABAGQEAzFFGAABzlBEAwBxlBAAwRxkBAMxRRgAAc5QRAMAcZQQAMEcZAQDMBbqMVqxYoTFjxmjkyJEqLi7Wjh07rCP1q6amRpMnT1ZmZqZGjRql2bNna/fu3daxBu2xxx5TKBRSRUWFdZQB+eyzz3TbbbcpJydH6enpmjhxohobG61j9au7u1vV1dUqLCxUenq6LrjgAj388MMabnfx2rp1q2bNmqVoNKpQKKQNGzb0et7zPC1dulSjR49Wenq6SkpKtHfvXpuw33Cy7MeOHdPixYs1ceJEZWRkKBqN6vbbb9eBAwfsAv9Lf8f8/7v77rsVCoVUW1s7ZPkGK7BltG7dOlVWVur+++9Xc3OzJk2apBkzZqijo8M62klt2bJF5eXl2r59uzZt2qRjx47p2muvVVdXl3W0Adu5c6eee+45XXLJJdZRBuSLL77Q1KlTddZZZ+mNN97QX/7yF/3mN7/ROeecYx2tX8uXL1ddXZ2effZZ/fWvf9Xy5cv1+OOP65lnnrGO1ktXV5cmTZqkFStW9Pn8448/rqefflorV65UQ0ODMjIyNGPGDB05cmSIkx7vZNkPHz6s5uZmVVdXq7m5Wa+++qp2796t66+/3iBpb/0d86+tX79e27dvVzQaHaJkp8gLqClTpnjl5eWJx93d3V40GvVqamoMUw1eR0eHJ8nbsmWLdZQB+eqrr7yxY8d6mzZt8r7//e97CxcutI7Ur8WLF3tXX321dYxTMnPmTO+OO+7ote4HP/iBN2fOHKNE/ZPkrV+/PvG4p6fHy8vL85544onEui+//NILh8PeSy+9ZJDwxL6ZvS87duzwJHn79+8fmlADcKLcn376qfed73zH27Vrl3f++ed7v/3tb4c820AF8szo6NGjampqUklJSWLdiBEjVFJSom3bthkmG7zOzk5JUnZ2tnGSgSkvL9fMmTN7Hfvh7vXXX1dRUZFuuukmjRo1Spdddpmef/5561gDctVVV6m+vl579uyRJH344Yd67733VFpaapxs4FpbW9Xe3t7rNROJRFRcXBy496v0f+/ZUCiks88+2zrKSfX09Gju3LlatGiRxo8fbx2nX6nWAU7F559/ru7ubuXm5vZan5ubq7/97W9GqQavp6dHFRUVmjp1qiZMmGAdp18vv/yympubtXPnTusog/Lxxx+rrq5OlZWV+sUvfqGdO3dqwYIFSktLU1lZmXW8k1qyZIlisZjGjRunlJQUdXd3a9myZZozZ451tAFrb2+XpD7fr18/FxRHjhzR4sWLdeuttyorK8s6zkktX75cqampWrBggXWUAQlkGSWL8vJy7dq1S++99551lH61tbVp4cKF2rRpk0aOHGkdZ1B6enpUVFSkRx99VJJ02WWXadeuXVq5cuWwL6NXXnlFL774otauXavx48erpaVFFRUVikajwz57sjl27JhuvvlmeZ6nuro66zgn1dTUpKeeekrNzc0KhULWcQYkkB/TnXvuuUpJSdHBgwd7rT948KDy8vKMUg3O/PnztXHjRm3evFnnnXeedZx+NTU1qaOjQ5dffrlSU1OVmpqqLVu26Omnn1Zqaqq6u7utI57Q6NGjdfHFF/dad9FFF+mTTz4xSjRwixYt0pIlS3TLLbdo4sSJmjt3ru69917V1NRYRxuwr9+TQX6/fl1E+/fv16ZNm4b9WdG7776rjo4OFRQUJN6v+/fv13333acxY8ZYx+tTIMsoLS1NV1xxherr6xPrenp6VF9fryuvvNIwWf88z9P8+fO1fv16vf322yosLLSONCDXXHONPvroI7W0tCSWoqIizZkzRy0tLUpJSbGOeEJTp0497vL5PXv26PzzzzdKNHCHDx/WiBG936YpKSnq6ekxSjR4hYWFysvL6/V+jcViamhoGPbvV+nfRbR371796U9/Uk5OjnWkfs2dO1d//vOfe71fo9GoFi1apLfeess6Xp8C+zFdZWWlysrKVFRUpClTpqi2tlZdXV2aN2+edbSTKi8v19q1a/Xaa68pMzMz8Zl5JBJRenq6cboTy8zM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\n"
},
"metadata": {}
}
],
"source": [
"def create_hamiltonian_matrix(n_qubits, graph, weights, bias):\n",
"\n",
" full_matrix = np.zeros((2 ** n_qubits, 2 ** n_qubits))\n",
"\n",
" # Creates the interaction component of the Hamiltonian\n",
" for i, edge in enumerate(graph.edges):\n",
" interaction_term = 1\n",
" for qubit in range(0, n_qubits):\n",
" if qubit in edge:\n",
" interaction_term = np.kron(interaction_term, qml.matrix(qml.PauliZ)(0))\n",
" else:\n",
" interaction_term = np.kron(interaction_term, np.identity(2))\n",
" full_matrix += weights[i] * interaction_term\n",
"\n",
" # Creates the bias components of the matrix\n",
" for i in range(0, n_qubits):\n",
" z_term = x_term = 1\n",
" for j in range(0, n_qubits):\n",
" if j == i:\n",
" z_term = np.kron(z_term, qml.matrix(qml.PauliZ)(0))\n",
" x_term = np.kron(x_term, qml.matrix(qml.PauliX)(0))\n",
" else:\n",
" z_term = np.kron(z_term, np.identity(2))\n",
" x_term = np.kron(x_term, np.identity(2))\n",
" full_matrix += bias[i] * z_term + x_term\n",
"\n",
" return full_matrix\n",
"\n",
"\n",
"# Prints a visual representation of the Hamiltonian matrix\n",
"ham_matrix = create_hamiltonian_matrix(qubit_number, ising_graph, target_weights, target_bias)\n",
"plt.matshow(ham_matrix, cmap=\"hot\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EZSqkuz8LbJ_"
},
"source": [
"Preparing Quantum Data\n",
"======================\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "PmSFvIn5LbJ_"
},
"source": [
"The collection of quantum data needed to run the QGRNN has two\n",
"components: (i) copies of a low-energy state, and (ii) a collection of\n",
"time-evolved states, each of which are simply the low-energy state\n",
"evolved to different times. The following is a low-energy state of the\n",
"target Hamiltonian:\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "TvhFkhYOLbJ_"
},
"outputs": [],
"source": [
"low_energy_state = [\n",
" (-0.054661080280306085 + 0.016713907320174026j),\n",
" (0.12290003656489545 - 0.03758500591109822j),\n",
" (0.3649337966440005 - 0.11158863596657455j),\n",
" (-0.8205175732627094 + 0.25093231967092877j),\n",
" (0.010369790825776609 - 0.0031706387262686003j),\n",
" (-0.02331544978544721 + 0.007129899300113728j),\n",
" (-0.06923183949694546 + 0.0211684344103713j),\n",
" (0.15566094863283836 - 0.04760201916285508j),\n",
" (0.014520590919500158 - 0.004441887836078486j),\n",
" (-0.032648113364535575 + 0.009988590222879195j),\n",
" (-0.09694382811137187 + 0.02965579457620536j),\n",
" (0.21796861485652747 - 0.06668776658411019j),\n",
" (-0.0027547112135013247 + 0.0008426289322652901j),\n",
" (0.006193695872468649 - 0.0018948418969390599j),\n",
" (0.018391279795405405 - 0.005625722994009138j),\n",
" (-0.041350974715649635 + 0.012650711602265649j),\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nZ5F5vM7LbJ_"
},
"source": [
"This state can be obtained by using a decoupled version of the\n",
"`Variational Quantum Eigensolver </demos/tutorial_vqe>`{.interpreted-text\n",
"role=\"doc\"} algorithm (VQE). Essentially, we choose a VQE ansatz such\n",
"that the circuit cannot learn the exact ground state, but it can get\n",
"fairly close. Another way to arrive at the same result is to perform VQE\n",
"with a reasonable ansatz, but to terminate the algorithm before it\n",
"converges to the ground state. If we used the exact ground state\n",
"$|\\psi_0\\rangle$, the time-dependence would be trivial and the data\n",
"would not provide enough information about the Hamiltonian parameters.\n",
"\n",
"We can verify that this is a low-energy state by numerically finding the\n",
"lowest eigenvalue of the Hamiltonian and comparing it to the energy\n",
"expectation of this low-energy state:\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "ZBpXVqTtLbJ_",
"outputId": "4d94ef57-a6d0-4476-c92d-b08195c47129"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Energy Expectation: -7.244508985189116\n",
"Ground State Energy: -7.330689661291244\n"
]
}
],
"source": [
"res = np.vdot(low_energy_state, (ham_matrix @ low_energy_state))\n",
"energy_exp = np.real_if_close(res)\n",
"print(f\"Energy Expectation: {energy_exp}\")\n",
"\n",
"\n",
"ground_state_energy = np.real_if_close(min(np.linalg.eig(ham_matrix)[0]))\n",
"print(f\"Ground State Energy: {ground_state_energy}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dQRr5pFSLbKA"
},
"source": [
"We have in fact found a low-energy, non-ground state, as the energy\n",
"expectation is slightly greater than the energy of the true ground\n",
"state. This, however, is only half of the information we need. We also\n",
"require a collection of time-evolved, low-energy states. Evolving the\n",
"low-energy state forward in time is fairly straightforward: all we have\n",
"to do is multiply the initial state by a time-evolution unitary. This\n",
"operation can be defined as a custom gate in PennyLane:\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "zxIkTaPiLbKA"
},
"outputs": [],
"source": [
"def state_evolve(hamiltonian, qubits, time):\n",
"\n",
" U = scipy.linalg.expm(-1j * hamiltonian * time)\n",
" qml.QubitUnitary(U, wires=qubits)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "auVMu4Q4LbKA"
},
"source": [
"We don\\'t actually generate time-evolved quantum data quite yet, but we\n",
"now have all the pieces required for its preparation.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XUMWybNQLbKA"
},
"source": [
"Learning the Hamiltonian\n",
"========================\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TrYpMK0NLbKA"
},
"source": [
"With the quantum data defined, we are able to construct the QGRNN and\n",
"learn the target Hamiltonian. Each of the exponentiated Hamiltonians in\n",
"the QGRNN ansatz, $\\hat{H}^{j}_{\\text{Ising}}(\\boldsymbol\\mu)$, are the\n",
"$ZZ$, $Z$, and $X$ terms from the Ising Hamiltonian. This gives:\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "RewvANn3LbKA"
},
"outputs": [],
"source": [
"def qgrnn_layer(weights, bias, qubits, graph, trotter_step):\n",
"\n",
" # Applies a layer of RZZ gates (based on a graph)\n",
" for i, edge in enumerate(graph.edges):\n",
" qml.MultiRZ(2 * weights[i] * trotter_step, wires=(edge[0], edge[1]))\n",
"\n",
" # Applies a layer of RZ gates\n",
" for i, qubit in enumerate(qubits):\n",
" qml.RZ(2 * bias[i] * trotter_step, wires=qubit)\n",
"\n",
" # Applies a layer of RX gates\n",
" for qubit in qubits:\n",
" qml.RX(2 * trotter_step, wires=qubit)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZcYEXhauLbKA"
},
"source": [
"As was mentioned in the first section, the QGRNN has two registers. In\n",
"one register, some piece of quantum data $|\\psi(t)\\rangle$ is prepared\n",
"and in the other we have\n",
"$U_{H}(\\boldsymbol\\mu, \\ \\Delta) |\\psi_0\\rangle$. We need a way to\n",
"measure the similarity between these states. This can be done by using\n",
"the fidelity, which is simply the modulus squared of the inner product\n",
"between the states,\n",
"$| \\langle \\psi(t) | U_{H}(\\Delta, \\ \\boldsymbol\\mu) |\\psi_0\\rangle |^2$.\n",
"To calculate this value, we use a [SWAP\n",
"test](https://en.wikipedia.org/wiki/Swap_test) between the registers:\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "-5RqUqBKLbKA"
},
"outputs": [],
"source": [
"def swap_test(control, register1, register2):\n",
"\n",
" qml.Hadamard(wires=control)\n",
" for reg1_qubit, reg2_qubit in zip(register1, register2):\n",
" qml.CSWAP(wires=(control, reg1_qubit, reg2_qubit))\n",
" qml.Hadamard(wires=control)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "To4GLL8VLbKA"
},
"source": [
"After performing this procedure, the value returned from a measurement\n",
"of the circuit is $\\langle Z \\rangle$, with respect to the `control`\n",
"qubit. The probability of measuring the $|0\\rangle$ state in this\n",
"control qubit is related to both the fidelity between registers and\n",
"$\\langle Z \\rangle$. Thus, with a bit of algebra, we find that\n",
"$\\langle Z \\rangle$ is equal to the fidelity.\n",
"\n",
"Before creating the full QGRNN and the cost function, we define a few\n",
"more fixed values. Among these is a \\\"guessed\\\" interaction graph, which\n",
"we set to be a [complete\n",
"graph](https://en.wikipedia.org/wiki/Complete_graph). This choice is\n",
"motivated by the fact that any target interaction graph will be a\n",
"subgraph of this initial guess. Part of the idea behind the QGRNN is\n",
"that we don't know the interaction graph, and it has to be learned. In\n",
"this case, the graph is learned *automatically* as the target parameters\n",
"are optimized. The $\\boldsymbol\\mu$ parameters that correspond to edges\n",
"that don\\'t exist in the target graph will simply approach $0$.\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 534
},
"id": "C5JNAOMSLbKA",
"outputId": "7d2ccda3-2603-4d20-a849-074bb12547ee"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Edges: [(4, 5), (4, 6), (4, 7), (5, 6), (5, 7), (6, 7)]\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "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EZFRMdtjg5JvZSPm4h2dX7dELSHm4h1czMiGa41nn7NYUlKCy5cvl9oYc+HCBTx8+BAAUKFCBcjlcjRu3BjBwcGa4livXj1YWVnpPD8RERGRrpltoVwTl/b8o4FekbWVDKtj0/BFD28AQFFRES5dulRqY0xiYiIKCgoAAJUqVYK3tzeaN2+OwYMHa4qjk5OTUe0QJyIiInpZZvvIu8OPUUjNytPb9SsgH/LLG3D+/HkkJSWhqKgIAFC1atV/PaZ+9L9r1arF4khERERmySxXKHMKipGmxzIJAA8ke9y8cxcdOnTAmDFjNOWxevXqLI5ERERkUcyyUKZm5kLfy64ymQzzV22Ed51Ker4TERERkXEzy10fhTo6JshY7kNERERkzMyyUNrZGObTMtR9iIiIiIyZWTaiBo4O0PdbjLL/uw8RERGRpTPLQulgbwNnPUyyeZyzYzk42JvlK6hEREREL8UsCyUA+HvUgLWVftYpra1k8HevoZdrExEREZkasy2UA3yc9XKoOfC/aTkDfZ31cm0iIiIiU2O2hdKtZgW0c62m81VKaysZ2rlWe+7YRSIiIiJLYbaFEgCm924MGx0XShsrGab3bqzTaxIRERGZMrMulPWqlsOX/zdvW1e+6uGNenre8ENERERkSsy6UAJAcAtnTOzsrpNrTersgf4t+O4kERER0eNkkiTpe0qhUVh/Ig3Ttp9HsVp6qc061lYy2FjJ8FUPb5ZJIiIioiewmEIJAOlZeZi85RxiLt6BtZXsmcXy0e+3c62G6b0b8zE3ERER0VNYVKF8JPlWNtbEpSEqKQNpmXl4/D+ADP87tNzfvQYG+jpzNzcRERHRc1hkoXxcbkExUjJzUVishp2NFRo4OnACDhEREdFLsPhCSURERETaMftd3kRERESkXyyURERERKQVFkoiIiIi0goLJRERERFphYWSiIiIiLTCQklEREREWmGhJCIiIiKtsFASERERkVZYKImIiIhIKyyURERERKQVFkoiIiIi0goLJRERERFphYWSiIiIiLTCQklEREREWmGhJCIiIiKtsFASERERkVZYKImIiIhIKyyURERERKQVFkoiIiIi0goLJRERERFphYWSiIiIiLTCQklEREREWmGhJCIiIiKtsFASERERkVZYKImIiIhIKyyURERERKQVFkoiIiIi0goLJRERERFphYWSiIiIiLTCQklEREREWmGhJCIiIiKtsFASERERkVZYKImIiIhIKyyURERERKQVFkoiIiIi0goLJRERERFphYWSiIiIiLTy/wAo7YwQ07NpugAAAABJRU5ErkJggg==\n"
},
"metadata": {}
}
],
"source": [
"# Defines some fixed values\n",
"\n",
"reg1 = tuple(range(qubit_number)) # First qubit register\n",
"reg2 = tuple(range(qubit_number, 2 * qubit_number)) # Second qubit register\n",
"\n",
"control = 2 * qubit_number # Index of control qubit\n",
"trotter_step = 0.01 # Trotter step size\n",
"\n",
"# Defines the interaction graph for the new qubit system\n",
"\n",
"new_ising_graph = nx.complete_graph(reg2)\n",
"\n",
"print(f\"Edges: {new_ising_graph.edges}\")\n",
"nx.draw(new_ising_graph)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4fc6XyLdLbKA"
},
"source": [
"With this done, we implement the QGRNN circuit for some given time\n",
"value:\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"id": "iu4hcd2oLbKA"
},
"outputs": [],
"source": [
"def qgrnn(weights, bias, time=None):\n",
"\n",
" # Prepares the low energy state in the two registers\n",
" qml.QubitStateVector(np.kron(low_energy_state, low_energy_state), wires=reg1 + reg2)\n",
"\n",
" # Evolves the first qubit register with the time-evolution circuit to\n",
" # prepare a piece of quantum data\n",
" state_evolve(ham_matrix, reg1, time)\n",
"\n",
" # Applies the QGRNN layers to the second qubit register\n",
" depth = time / trotter_step # P = t/Delta\n",
" for _ in range(0, int(depth)):\n",
" qgrnn_layer(weights, bias, reg2, new_ising_graph, trotter_step)\n",
"\n",
" # Applies the SWAP test between the registers\n",
" swap_test(control, reg1, reg2)\n",
"\n",
" # Returns the results of the SWAP test\n",
" return qml.expval(qml.PauliZ(control))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zUGsNfnsLbKA"
},
"source": [
"We have the full QGRNN circuit, but we still need to define a cost\n",
"function. We know that\n",
"$| \\langle \\psi(t) | U_{H}(\\boldsymbol\\mu, \\ \\Delta) |\\psi_0\\rangle |^2$\n",
"approaches $1$ as the states become more similar and approaches $0$ as\n",
"the states become orthogonal. Thus, we choose to minimize the quantity\n",
"$-| \\langle \\psi(t) | U_{H}(\\boldsymbol\\mu, \\ \\Delta) |\\psi_0\\rangle |^2$.\n",
"Since we are interested in calculating this value for many different\n",
"pieces of quantum data, the final cost function is the average negative\n",
"fidelity\\* between registers:\n",
"\n",
"$$\\mathcal{L}(\\boldsymbol\\mu, \\ \\Delta) \\ = \\ - \\frac{1}{N} \\displaystyle\\sum_{i \\ = \\ 1}^{N} |\n",
"\\langle \\psi(t_i) | \\ U_{H}(\\boldsymbol\\mu, \\ \\Delta) \\ |\\psi_0\\rangle |^2,$$\n",
"\n",
"where we use $N$ pieces of quantum data.\n",
"\n",
"Before creating the cost function, we must define a few more fixed\n",
"variables:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"id": "R7jK3kMqLbKB"
},
"outputs": [],
"source": [
"N = 15 # The number of pieces of quantum data that are used for each step\n",
"max_time = 0.1 # The maximum value of time that can be used for quantum data"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "X_e9a1jVLbKB"
},
"source": [
"We then define the negative fidelity cost function:\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"id": "qizc8MsqLbKB"
},
"outputs": [],
"source": [
"rng = np.random.default_rng(seed=42)\n",
"\n",
"def cost_function(weight_params, bias_params):\n",
"\n",
" # Randomly samples times at which the QGRNN runs\n",
" times_sampled = rng.random(size=N) * max_time\n",
"\n",
" # Cycles through each of the sampled times and calculates the cost\n",
" total_cost = 0\n",
" for dt in times_sampled:\n",
" result = qgrnn_qnode(weight_params, bias_params, time=dt)\n",
" total_cost += -1 * result\n",
"\n",
" return total_cost / N"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "m5WwkvDHLbKB"
},
"source": [
"Next we set up for optimization.\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"id": "3bzbEsNJLbKB"
},
"outputs": [],
"source": [
"# Defines the new device\n",
"qgrnn_dev = qml.device(\"default.qubit\", wires=2 * qubit_number + 1)\n",
"\n",
"# Defines the new QNode\n",
"qgrnn_qnode = qml.QNode(qgrnn, qgrnn_dev, interface=\"autograd\")\n",
"\n",
"steps = 300\n",
"\n",
"optimizer = qml.AdamOptimizer(stepsize=0.3)\n",
"\n",
"weights = rng.random(size=len(new_ising_graph.edges), requires_grad=True) - 0.5\n",
"bias = rng.random(size=qubit_number, requires_grad=True) - 0.5\n",
"\n",
"initial_weights = copy.copy(weights)\n",
"initial_bias = copy.copy(bias)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Hik8L3erLbKB"
},
"source": [
"All that remains is executing the optimization loop.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "gPvXgB7MLbKB",
"outputId": "fedfd42d-6a1c-42aa-de6d-a0786615a80f"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Cost at Step 0: -0.9803638573791906\n",
"Weights at Step 0: [-0.02603926 0.23887338 0.65859458 0.4973626 -0.10582631 0.17562606]\n",
"Bias at Step 0: [-0.03885261 -0.01392638 -0.07189834 0.25038114]\n",
"---------------------------------------------\n",
"Cost at Step 5: -0.996941435016429\n",
"Weights at Step 5: [-0.81324145 1.07476846 1.1061694 1.58556358 0.32683696 -0.30451739]\n",
"Bias at Step 5: [-0.69258221 -1.04745285 1.06920295 0.4729811 ]\n",
"---------------------------------------------\n",
"Cost at Step 10: -0.998631791121192\n",
"Weights at Step 10: [-0.42326896 0.79838566 0.61651522 1.83801512 -0.18661762 0.09585344]\n",
"Bias at Step 10: [-0.14865635 -1.13290709 1.50067486 -0.17013801]\n",
"---------------------------------------------\n",
"Cost at Step 15: -0.9989288704590784\n",
"Weights at Step 15: [-0.01780188 0.51935145 0.84042409 1.67694816 -0.08570868 -0.17039931]\n",
"Bias at Step 15: [ 0.14049396 -0.85137402 1.46620821 0.01876606]\n",
"---------------------------------------------\n",
"Cost at Step 20: -0.9989877966855808\n",
"Weights at Step 20: [-0.04606544 0.61564422 1.20996012 1.53724787 0.03102305 -0.38463701]\n",
"Bias at Step 20: [-0.15660669 -0.72249342 1.28027729 0.17742167]\n",
"---------------------------------------------\n",
"Cost at Step 25: -0.9996824290201453\n",
"Weights at Step 25: [-0.15679743 0.6818271 1.14305623 1.52203978 -0.28441025 -0.08613302]\n",
"Bias at Step 25: [-0.44370877 -0.83552897 1.05067071 -0.21716541]\n",
"---------------------------------------------\n",
"Cost at Step 30: -0.9997260854147976\n",
"Weights at Step 30: [-0.10965584 0.55377334 1.23770269 1.66310423 -0.22452586 -0.16214067]\n",
"Bias at Step 30: [-0.42105765 -1.09901301 0.97692017 -0.25131789]\n",
"---------------------------------------------\n",
"Cost at Step 35: -0.999720785496688\n",
"Weights at Step 35: [ 0.05371611 0.40094669 1.34935989 1.75342972 -0.10426342 -0.3430209 ]\n",
"Bias at Step 35: [-0.31829145 -1.20422776 1.00699464 -0.19185141]\n",
"---------------------------------------------\n",
"Cost at Step 40: -0.9998268061103935\n",
"Weights at Step 40: [ 0.14696981 0.42062742 1.30031302 1.74223276 -0.23815364 -0.30014355]\n",
"Bias at Step 40: [-0.42731939 -1.12652083 1.05747061 -0.37945587]\n",
"---------------------------------------------\n",
"Cost at Step 45: -0.999854979792434\n",
"Weights at Step 45: [ 0.13980781 0.52546791 1.3589372 1.7401287 -0.24171811 -0.37131231]\n",
"Bias at Step 45: [-0.66159346 -1.08685666 1.08351978 -0.44685154]\n",
"---------------------------------------------\n",
"Cost at Step 50: -0.9999300663096155\n",
"Weights at Step 50: [ 0.24206772 0.42578458 1.38259253 1.73759016 -0.17042668 -0.47614044]\n",
"Bias at Step 50: [-0.67166662 -1.11916085 1.01155301 -0.45307945]\n",
"---------------------------------------------\n",
"Cost at Step 55: -0.9999158295165241\n",
"Weights at Step 55: [ 0.3107698 0.32643162 1.30955235 1.7661931 -0.18233325 -0.47326321]\n",
"Bias at Step 55: [-0.67871142 -1.20848815 0.93740127 -0.56458235]\n",
"---------------------------------------------\n",
"Cost at Step 60: -0.9999308699951126\n",
"Weights at Step 60: [ 0.28372115 0.36451651 1.33221677 1.80954685 -0.13589698 -0.54109403]\n",
"Bias at Step 60: [-0.83208754 -1.2754807 0.93311571 -0.60834148]\n",
"---------------------------------------------\n",
"Cost at Step 65: -0.999959884466806\n",
"Weights at Step 65: [ 0.36974336 0.3193621 1.31162222 1.76724553 -0.13338673 -0.583552 ]\n",
"Bias at Step 65: [-0.88515714 -1.21379111 0.91018067 -0.66955516]\n",
"---------------------------------------------\n",
"Cost at Step 70: -0.9999592904739002\n",
"Weights at Step 70: [ 0.41857481 0.28942942 1.30436789 1.7750691 -0.10866857 -0.63517285]\n",
"Bias at Step 70: [-0.94301792 -1.21574698 0.92016109 -0.71763258]\n",
"---------------------------------------------\n",
"Cost at Step 75: -0.9999713292245083\n",
"Weights at Step 75: [ 0.42211115 0.27516391 1.30028462 1.8124991 -0.08626634 -0.66806052]\n",
"Bias at Step 75: [-1.02418273 -1.27352011 0.92542777 -0.77781084]\n",
"---------------------------------------------\n",
"Cost at Step 80: -0.9999807570513847\n",
"Weights at Step 80: [ 0.46823298 0.22196986 1.29819846 1.79885961 -0.07375557 -0.69509066]\n",
"Bias at Step 80: [-1.06297822 -1.27152207 0.89615772 -0.8267624 ]\n",
"---------------------------------------------\n",
"Cost at Step 85: -0.9999834576872019\n",
"Weights at Step 85: [ 0.48867472 0.20430434 1.31813101 1.79817224 -0.05572355 -0.73012137]\n",
"Bias at Step 85: [-1.12351456 -1.26935382 0.8986494 -0.85965751]\n",
"---------------------------------------------\n",
"Cost at Step 90: -0.9999848348340454\n",
"Weights at Step 90: [ 0.50938179 0.1815515 1.31872181 1.81333952 -0.057935 -0.74241479]\n",
"Bias at Step 90: [-1.1648444 -1.28126866 0.91927043 -0.91218166]\n",
"---------------------------------------------\n",
"Cost at Step 95: -0.9999858404580841\n",
"Weights at Step 95: [ 0.53198063 0.14682073 1.32951939 1.81872826 -0.03723321 -0.7724539 ]\n",
"Bias at Step 95: [-1.19340463 -1.29189249 0.92624482 -0.93540509]\n",
"---------------------------------------------\n",
"Cost at Step 100: -0.999985474261986\n",
"Weights at Step 100: [ 0.54088845 0.12642269 1.32832267 1.81359343 -0.03539024 -0.78147771]\n",
"Bias at Step 100: [-1.23731699 -1.29310153 0.92559765 -0.97196362]\n",
"---------------------------------------------\n",
"Cost at Step 105: -0.9999849674159557\n",
"Weights at Step 105: [ 0.5519262 0.1056115 1.33563262 1.81489961 -0.02321254 -0.80109894]\n",
"Bias at Step 105: [-1.26753973 -1.29708393 0.93540955 -0.99148978]\n",
"---------------------------------------------\n",
"Cost at Step 110: -0.9999893366309286\n",
"Weights at Step 110: [ 0.56454314 0.08311651 1.3315906 1.81716268 -0.01884894 -0.81132014]\n",
"Bias at Step 110: [-1.28690663 -1.30170285 0.9490766 -1.01449621]\n",
"---------------------------------------------\n",
"Cost at Step 115: -0.9999910021365572\n",
"Weights at Step 115: [ 0.56547562 0.07231051 1.33386244 1.81426223 -0.010147 -0.82398566]\n",
"Bias at Step 115: [-1.31862939 -1.30416747 0.95796895 -1.02789104]\n",
"---------------------------------------------\n",
"Cost at Step 120: -0.9999892236888762\n",
"Weights at Step 120: [ 0.57542644 0.05174682 1.33008488 1.80845608 -0.00677923 -0.83031403]\n",
"Bias at Step 120: [-1.33280139 -1.30462293 0.96278424 -1.04167386]\n",
"---------------------------------------------\n",
"Cost at Step 125: -0.9999921564251922\n",
"Weights at Step 125: [ 5.74855656e-01 4.41140455e-02 1.33148721e+00 1.81141630e+00\n",
" -1.45922147e-03 -8.37792448e-01]\n",
"Bias at Step 125: [-1.35272154 -1.31313306 0.9769263 -1.05024412]\n",
"---------------------------------------------\n",
"Cost at Step 130: -0.9999896546781485\n",
"Weights at Step 130: [ 5.81148179e-01 3.12881718e-02 1.32648858e+00 1.80476572e+00\n",
" -1.34382543e-04 -8.40486390e-01]\n",
"Bias at Step 130: [-1.36266437 -1.3122935 0.98373353 -1.05698837]\n",
"---------------------------------------------\n",
"Cost at Step 135: -0.999989389789069\n",
"Weights at Step 135: [ 0.58113254 0.02553698 1.32817847 1.8011998 0.00461508 -0.84568556]\n",
"Bias at Step 135: [-1.37617879 -1.31580751 0.99147423 -1.05740398]\n",
"---------------------------------------------\n",
"Cost at Step 140: -0.9999909647373425\n",
"Weights at Step 140: [ 5.84031155e-01 1.80486810e-02 1.32738886e+00 1.80061135e+00\n",
" 1.65406266e-03 -8.43424714e-01]\n",
"Bias at Step 140: [-1.38227067 -1.32143299 0.9995722 -1.06391802]\n",
"---------------------------------------------\n",
"Cost at Step 145: -0.9999882409907013\n",
"Weights at Step 145: [ 0.58696427 0.01254767 1.33270229 1.79866053 0.00341283 -0.84622868]\n",
"Bias at Step 145: [-1.38755681 -1.3249532 1.00609436 -1.06294709]\n",
"---------------------------------------------\n",
"Cost at Step 150: -0.9999882142877635\n",
"Weights at Step 150: [ 5.88782557e-01 9.26749787e-03 1.33607830e+00 1.79737635e+00\n",
" 8.61705971e-04 -8.44657239e-01]\n",
"Bias at Step 150: [-1.39299146 -1.32891592 1.01108686 -1.06590915]\n",
"---------------------------------------------\n",
"Cost at Step 155: -0.9999874507805563\n",
"Weights at Step 155: [ 5.92771490e-01 4.43280303e-03 1.34076089e+00 1.79756493e+00\n",
" -5.09973154e-04 -8.44577799e-01]\n",
"Bias at Step 155: [-1.39410552 -1.33352314 1.01473829 -1.06769553]\n",
"---------------------------------------------\n",
"Cost at Step 160: -0.9999873005360721\n",
"Weights at Step 160: [ 0.59576847 0.00268011 1.34849234 1.79906537 -0.00323521 -0.84434153]\n",
"Bias at Step 160: [-1.3972048 -1.33712094 1.01690619 -1.07141221]\n",
"---------------------------------------------\n",
"Cost at Step 165: -0.9999874561658166\n",
"Weights at Step 165: [ 5.98598863e-01 2.45970557e-04 1.34798706e+00 1.79893319e+00\n",
" -3.96831663e-03 -8.44402361e-01]\n",
"Bias at Step 165: [-1.39840678 -1.3400862 1.01678644 -1.07427356]\n",
"---------------------------------------------\n",
"Cost at Step 170: -0.999988664299768\n",
"Weights at Step 170: [ 0.59556051 0.00301936 1.33720573 1.79440069 0.00246633 -0.84842527]\n",
"Bias at Step 170: [-1.40433835 -1.34054744 1.01793737 -1.06932111]\n",
"---------------------------------------------\n",
"Cost at Step 175: -0.9999876765392001\n",
"Weights at Step 175: [ 0.59507328 0.00398439 1.32779833 1.78879332 0.0043839 -0.84887631]\n",
"Bias at Step 175: [-1.40733842 -1.33831837 1.01934095 -1.06713091]\n",
"---------------------------------------------\n",
"Cost at Step 180: -0.999991473708912\n",
"Weights at Step 180: [ 0.59530716 0.0028657 1.32842831 1.78856307 0.00360646 -0.8477063 ]\n",
"Bias at Step 180: [-1.40721243 -1.34142579 1.02195458 -1.06673697]\n",
"---------------------------------------------\n",
"Cost at Step 185: -0.9999877064247253\n",
"Weights at Step 185: [ 5.97140521e-01 1.29792043e-03 1.33864708e+00 1.78999566e+00\n",
" 1.00191981e-03 -8.46805223e-01]\n",
"Bias at Step 185: [-1.40651854 -1.34399438 1.0238182 -1.06735418]\n",
"---------------------------------------------\n",
"Cost at Step 190: -0.9999945812804165\n",
"Weights at Step 190: [ 6.00719014e-01 -1.62402633e-03 1.34764455e+00 1.79338122e+00\n",
" -4.62571494e-03 -8.43587564e-01]\n",
"Bias at Step 190: [-1.40364571 -1.34711672 1.02503773 -1.07251647]\n",
"---------------------------------------------\n",
"Cost at Step 195: -0.999989989786025\n",
"Weights at Step 195: [ 6.00908732e-01 -1.62012049e-03 1.35014363e+00 1.79380038e+00\n",
" -2.98349731e-03 -8.45624230e-01]\n",
"Bias at Step 195: [-1.40422823 -1.34839724 1.024814 -1.07151688]\n",
"---------------------------------------------\n",
"Cost at Step 200: -0.9999881542248072\n",
"Weights at Step 200: [ 5.99981319e-01 -1.88775908e-04 1.34385950e+00 1.79176993e+00\n",
" -1.80551029e-03 -8.46142226e-01]\n",
"Bias at Step 200: [-1.40629448 -1.34706972 1.02376301 -1.07210325]\n",
"---------------------------------------------\n",
"Cost at Step 205: -0.9999881740456698\n",
"Weights at Step 205: [ 5.99261166e-01 2.51688730e-04 1.33482422e+00 1.78924276e+00\n",
" 2.54997378e-04 -8.46778052e-01]\n",
"Bias at Step 205: [-1.40688336 -1.34566627 1.02294251 -1.07166319]\n",
"---------------------------------------------\n",
"Cost at Step 210: -0.9999849643591882\n",
"Weights at Step 210: [ 0.59556376 0.00290579 1.32712069 1.78534996 0.00520243 -0.8492702 ]\n",
"Bias at Step 210: [-1.4100142 -1.34414691 1.02376047 -1.06630716]\n",
"---------------------------------------------\n",
"Cost at Step 215: -0.9999886489345433\n",
"Weights at Step 215: [ 0.59355916 0.00370791 1.32450808 1.78322703 0.00640902 -0.84894837]\n",
"Bias at Step 215: [-1.41048592 -1.34401778 1.02684022 -1.06268802]\n",
"---------------------------------------------\n",
"Cost at Step 220: -0.9999878707967713\n",
"Weights at Step 220: [ 5.94865214e-01 1.31396790e-03 1.32851226e+00 1.78368971e+00\n",
" 1.99943131e-03 -8.44829812e-01]\n",
"Bias at Step 220: [-1.40762506 -1.34564162 1.02914859 -1.06395825]\n",
"---------------------------------------------\n",
"Cost at Step 225: -0.9999894983980553\n",
"Weights at Step 225: [ 5.96129030e-01 -2.70446381e-04 1.33726404e+00 1.78530720e+00\n",
" -9.14375384e-04 -8.43087376e-01]\n",
"Bias at Step 225: [-1.40591305 -1.34783606 1.03097914 -1.06389792]\n",
"---------------------------------------------\n",
"Cost at Step 230: -0.9999922381489225\n",
"Weights at Step 230: [ 5.95698562e-01 2.12153829e-05 1.34097628e+00 1.78640344e+00\n",
" -2.66939871e-04 -8.43866656e-01]\n",
"Bias at Step 230: [-1.40598424 -1.35013 1.03301139 -1.06176633]\n",
"---------------------------------------------\n",
"Cost at Step 235: -0.9999915503513058\n",
"Weights at Step 235: [ 5.94412462e-01 1.26937987e-03 1.33568147e+00 1.78429986e+00\n",
" 1.10164011e-03 -8.44057595e-01]\n",
"Bias at Step 235: [-1.40759178 -1.35003317 1.03306412 -1.06029115]\n",
"---------------------------------------------\n",
"Cost at Step 240: -0.9999899139875156\n",
"Weights at Step 240: [ 0.59325925 0.00212116 1.32698164 1.78079875 0.00265113 -0.84377279]\n",
"Bias at Step 240: [-1.40862419 -1.34902462 1.03344422 -1.05847877]\n",
"---------------------------------------------\n",
"Cost at Step 245: -0.9999889983186859\n",
"Weights at Step 245: [ 5.95248184e-01 1.16515643e-03 1.32888367e+00 1.77990336e+00\n",
" 3.18940688e-04 -8.42352373e-01]\n",
"Bias at Step 245: [-1.40780015 -1.34809049 1.03368968 -1.05975704]\n",
"---------------------------------------------\n",
"Cost at Step 250: -0.9999881214395573\n",
"Weights at Step 250: [ 5.94746365e-01 3.52226215e-04 1.33273458e+00 1.78271878e+00\n",
" 2.35450291e-04 -8.42131285e-01]\n",
"Bias at Step 250: [-1.40703427 -1.35285926 1.03469553 -1.05970064]\n",
"---------------------------------------------\n",
"Cost at Step 255: -0.9999893074495982\n",
"Weights at Step 255: [ 5.95128451e-01 1.41833640e-03 1.33495243e+00 1.78118103e+00\n",
" -1.66495422e-04 -8.42564017e-01]\n",
"Bias at Step 255: [-1.40849133 -1.35075613 1.03571014 -1.05899157]\n",
"---------------------------------------------\n",
"Cost at Step 260: -0.9999911831425025\n",
"Weights at Step 260: [ 5.93954624e-01 3.65997215e-04 1.32747775e+00 1.78014389e+00\n",
" 1.86270231e-03 -8.42368868e-01]\n",
"Bias at Step 260: [-1.40745686 -1.35292854 1.03598998 -1.05730236]\n",
"---------------------------------------------\n",
"Cost at Step 265: -0.9999898569345608\n",
"Weights at Step 265: [ 5.94054550e-01 2.22631406e-03 1.32948594e+00 1.77704330e+00\n",
" 1.19766250e-03 -8.42715291e-01]\n",
"Bias at Step 265: [-1.41030685 -1.34876472 1.03609132 -1.05643617]\n",
"---------------------------------------------\n",
"Cost at Step 270: -0.9999877705287914\n",
"Weights at Step 270: [ 5.94781072e-01 -1.11477042e-04 1.33392437e+00 1.78305723e+00\n",
" 3.76174702e-04 -8.42183574e-01]\n",
"Bias at Step 270: [-1.40704689 -1.35586199 1.03817742 -1.058197 ]\n",
"---------------------------------------------\n",
"Cost at Step 275: -0.9999913225494264\n",
"Weights at Step 275: [ 5.94417898e-01 1.55898287e-03 1.33236765e+00 1.77833787e+00\n",
" 8.61473931e-04 -8.42756926e-01]\n",
"Bias at Step 275: [-1.4102245 -1.35092356 1.03638933 -1.05664399]\n",
"---------------------------------------------\n",
"Cost at Step 280: -0.999991247464759\n",
"Weights at Step 280: [ 5.96133973e-01 -6.81094713e-04 1.33226199e+00 1.78221990e+00\n",
" -1.23665053e-03 -8.41018922e-01]\n",
"Bias at Step 280: [-1.40689524 -1.35460515 1.03788072 -1.06013602]\n",
"---------------------------------------------\n",
"Cost at Step 285: -0.9999871732223706\n",
"Weights at Step 285: [ 5.97358644e-01 -9.15319018e-04 1.33478275e+00 1.78040181e+00\n",
" -2.90160465e-03 -8.40389367e-01]\n",
"Bias at Step 285: [-1.40803754 -1.35171341 1.03412961 -1.06239103]\n",
"---------------------------------------------\n",
"Cost at Step 290: -0.9999918619409637\n",
"Weights at Step 290: [ 5.94771896e-01 8.18512334e-04 1.32655817e+00 1.77910435e+00\n",
" 2.12609569e-03 -8.43221244e-01]\n",
"Bias at Step 290: [-1.40897233 -1.35158162 1.03631282 -1.05834328]\n",
"---------------------------------------------\n",
"Cost at Step 295: -0.9999908671570564\n",
"Weights at Step 295: [ 5.95660428e-01 9.09973737e-04 1.33134943e+00 1.77946500e+00\n",
" -2.53296584e-04 -8.42278191e-01]\n",
"Bias at Step 295: [-1.40945183 -1.35032335 1.03559811 -1.06039016]\n",
"---------------------------------------------\n"
]
}
],
"source": [
"for i in range(0, steps):\n",
" (weights, bias), cost = optimizer.step_and_cost(cost_function, weights, bias)\n",
"\n",
" # Prints the value of the cost function\n",
" if i % 5 == 0:\n",
" print(f\"Cost at Step {i}: {cost}\")\n",
" print(f\"Weights at Step {i}: {weights}\")\n",
" print(f\"Bias at Step {i}: {bias}\")\n",
" print(\"---------------------------------------------\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TLYEfeyjLbKB"
},
"source": [
"With the learned parameters, we construct a visual representation of the\n",
"Hamiltonian to which they correspond and compare it to the target\n",
"Hamiltonian, and the initial guessed Hamiltonian:\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 210
},
"id": "QnPHQC1PLbKB",
"outputId": "4418f7de-b924-4c2d-ae0b-6ad626551982"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 600x600 with 3 Axes>"
],
"image/png": "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\n"
},
"metadata": {}
}
],
"source": [
"new_ham_matrix = create_hamiltonian_matrix(\n",
" qubit_number, nx.complete_graph(qubit_number), weights, bias\n",
")\n",
"\n",
"init_ham = create_hamiltonian_matrix(\n",
" qubit_number, nx.complete_graph(qubit_number), initial_weights, initial_bias\n",
")\n",
"\n",
"fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(6, 6))\n",
"\n",
"axes[0].matshow(ham_matrix, vmin=-7, vmax=7, cmap=\"hot\")\n",
"axes[0].set_title(\"Target\", y=1.13)\n",
"\n",
"axes[1].matshow(init_ham, vmin=-7, vmax=7, cmap=\"hot\")\n",
"axes[1].set_title(\"Initial\", y=1.13)\n",
"\n",
"axes[2].matshow(new_ham_matrix, vmin=-7, vmax=7, cmap=\"hot\")\n",
"axes[2].set_title(\"Learned\", y=1.13)\n",
"\n",
"plt.subplots_adjust(wspace=0.3, hspace=0.3)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zspKar5SLbKB"
},
"source": [
"These images look very similar, indicating that the QGRNN has done a\n",
"good job learning the target Hamiltonian.\n",
"\n",
"We can also look at the exact values of the target and learned\n",
"parameters. Recall how the target interaction graph has $4$ edges while\n",
"the complete graph has $6$. Thus, as the QGRNN converges to the optimal\n",
"solution, the weights corresponding to edges $(1, 3)$ and $(2, 0)$ in\n",
"the complete graph should go to $0$, as this indicates that they have no\n",
"effect, and effectively do not exist in the learned Hamiltonian.\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"id": "-ql-50F_LbKB"
},
"outputs": [],
"source": [
"# We first pick out the weights of edges (1, 3) and (2, 0)\n",
"# and then remove them from the list of target parameters\n",
"\n",
"weights_noedge = []\n",
"weights_edge = []\n",
"for ii, edge in enumerate(new_ising_graph.edges):\n",
" if (edge[0] - qubit_number, edge[1] - qubit_number) in ising_graph.edges:\n",
" weights_edge.append(weights[ii])\n",
" else:\n",
" weights_noedge.append(weights[ii])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WL7HVML3LbKB"
},
"source": [
"Then, we print all of the weights:\n"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 0
},
"id": "rlB_pAzGLbKB",
"outputId": "ae59834f-dead-437f-ac7c-d030cd9da2f1"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Target parameters Learned parameters\n",
"Weights\n",
"-----------------------------------------\n",
"0.56 | 0.5974609311535144\n",
"1.24 | 1.3411495568824126\n",
"1.67 | 1.784741915545322\n",
"-0.79 | -0.8434429713923873\n",
"\n",
"Bias\n",
"-----------------------------------------\n",
"-1.44 | -1.4067252706628723\n",
"-1.43 | -1.3546960101894798\n",
"1.18 | 1.0354062517348281\n",
"-0.93 | -1.0615531663839644\n",
"\n",
"Non-Existing Edge Parameters: [-0.0013558219901317857, -0.0007373999961358714]\n"
]
}
],
"source": [
"print(\"Target parameters Learned parameters\")\n",
"print(\"Weights\")\n",
"print(\"-\" * 41)\n",
"for ii_target, ii_learned in zip(target_weights, weights_edge):\n",
" print(f\"{ii_target : <20}|{ii_learned : >20}\")\n",
"\n",
"print(\"\\nBias\")\n",
"print(\"-\"*41)\n",
"for ii_target, ii_learned in zip(target_bias, bias):\n",
" print(f\"{ii_target : <20}|{ii_learned : >20}\")\n",
"\n",
"print(f\"\\nNon-Existing Edge Parameters: {[val.unwrap() for val in weights_noedge]}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "K4jKWHsELbKB"
},
"source": [
"The weights of edges $(1, 3)$ and $(2, 0)$ are very close to $0$,\n",
"indicating we have learned the cycle graph from the complete graph. In\n",
"addition, the remaining learned weights are fairly close to those of the\n",
"target Hamiltonian. Thus, the QGRNN is functioning properly, and has\n",
"learned the target Ising Hamiltonian to a high degree of accuracy!\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0BWaZBY7LbKB"
},
"source": [
"References\n",
"==========\n",
"\n",
"1. Verdon, G., McCourt, T., Luzhnica, E., Singh, V., Leichenauer, S., &\n",
" Hidary, J. (2019). Quantum Graph Neural Networks. arXiv preprint\n",
" [arXiv:1909.12264](https://arxiv.org/abs/1909.12264).\n",
"\n",
"About the author\n",
"================\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.9.17"
},
"colab": {
"provenance": []
}
},
"nbformat": 4,
"nbformat_minor": 0
}