diff --git a/examples/qubit_rotation/README.md b/examples/qubit_rotation/README.md new file mode 100644 index 00000000..1b553fd0 --- /dev/null +++ b/examples/qubit_rotation/README.md @@ -0,0 +1,10 @@ +# Qubit Rotation Tutorial + +Tutorial based off of Pennylane's [Basic Tutorial: qubit rotation](https://pennylane.ai/qml/demos/tutorial_qubit_rotation) + +``` +python3 qubit_rotation.py +``` + +Expected to reach a loss of -1 by epoch 160 + diff --git a/examples/qubit_rotation/TQ_Qubit_Rotation_Tutorial.ipynb b/examples/qubit_rotation/TQ_Qubit_Rotation_Tutorial.ipynb new file mode 100644 index 00000000..64f8ef7a --- /dev/null +++ b/examples/qubit_rotation/TQ_Qubit_Rotation_Tutorial.ipynb @@ -0,0 +1,988 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# TorchQuantum Qubit Rotation Tutorial\n", + "\n", + "> Note: This tutorial was adapted from Pennylane's [Basic tutorial: qubit rotation](https://pennylane.ai/qml/demos/tutorial_qubit_rotation) by Josh Izaac.\n", + "\n", + "To see how TorchQuantum allows the easy construction and optimization of quantum functions, let's consider the simple case of qubit rotation.\n", + "\n", + "The task at hand is to optimize two rotation gates in order to flip a single qubit from state |0⟩ to state |1⟩.\n", + "\n" + ], + "metadata": { + "id": "Y6HrDR9HLIgG" + } + }, + { + "cell_type": "markdown", + "source": [ + "## The quantum circuit" + ], + "metadata": { + "id": "Y7jxsrq-TcqC" + } + }, + { + "cell_type": "markdown", + "source": [ + "In the qubit rotation example, we wish to implement the following quantum circuit:\n", + "\n", + "![image.png](data:image/png;base64,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)\n", + "\n", + "Breaking this down step-by-step, we first start with a qubit in the ground state $|0⟩ = [1\\ 0]^T$, and rotate it around the x-axis by applying the gate\n", + "\n", + "$\\begin{split}R_x(\\phi_1) = e^{-i \\phi_1 \\sigma_x /2} =\n", + "\\begin{bmatrix}\n", + "\\cos \\frac{\\phi_1}{2} & -i \\sin \\frac{\\phi_1}{2}\n", + "\\\\\n", + "-i \\sin \\frac{\\phi_1}{2} & \\cos \\frac{\\phi_1}{2}\n", + "\\end{bmatrix},\n", + "\\end{split}$\n", + "\n", + "and then around the y-axis via the gate\n", + "\n", + "$\\begin{split}R_y(\\phi_2) = e^{-i \\phi_2 \\sigma_y/2} =\n", + "\\begin{bmatrix} \\cos \\frac{\\phi_2}{2} & - \\sin \\frac{\\phi_2}{2}\n", + "\\\\\n", + "\\sin \\frac{\\phi_2}{2} & \\cos \\frac{\\phi_2}{2}\n", + "\\end{bmatrix}.\\end{split}$\n", + "\n", + "After these operations the qubit is now in the state\n", + "\n", + "$| \\psi \\rangle = R_y(\\phi_2) R_x(\\phi_1) | 0 \\rangle.$\n", + "\n", + "Finally, we measure the expectation value $⟨ψ∣σ_z∣ψ⟩$ of the Pauli-Z operator\n", + "\n", + "Using the above to calculate the exact expectation value, we find that\n", + "\n", + "$\\begin{split}\\sigma_z =\n", + "\\begin{bmatrix} 1 & 0\n", + "\\\\\n", + "0 & -1\n", + "\\end{bmatrix}.\\end{split}$\n", + "\n", + "Depending on the circuit parameters $ϕ_1$ and $ϕ_2$, the output expectation lies between 1 (if $|ψ⟩ = |0⟩) and -1 (if |ψ⟩ = |1⟩).\n", + "\n", + "$\\langle \\psi \\mid \\sigma_z \\mid \\psi \\rangle\n", + " = \\langle 0 \\mid R_x(\\phi_1)^\\dagger R_y(\\phi_2)^\\dagger \\sigma_z R_y(\\phi_2) R_x(\\phi_1) \\mid 0 \\rangle\n", + " = \\cos(\\phi_1)\\cos(\\phi_2).$\n", + "\n", + "Let's see how we can easily implement and optimize this circuit using TorchQuantum.\n", + "\n" + ], + "metadata": { + "id": "oFuPFpXhTFAR" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Importing TorchQuantum" + ], + "metadata": { + "id": "5sge9dfJTer6" + } + }, + { + "cell_type": "markdown", + "source": [ + "The first thing we need to do is install and import TorchQuantum. To utilize all of TorchQuantum's features, install it from source." + ], + "metadata": { + "id": "4qF2oH1MTmHb" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "omF7GkuHKaPp", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "2c200ab7-f939-4193-d872-01c0f98b3ee6" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Cloning into 'torchquantum'...\n", + "remote: Enumerating objects: 13551, done.\u001b[K\n", + "remote: Counting objects: 100% (1822/1822), done.\u001b[K\n", + "remote: Compressing objects: 100% (758/758), done.\u001b[K\n", + "remote: Total 13551 (delta 1085), reused 1640 (delta 980), pack-reused 11729\u001b[K\n", + "Receiving objects: 100% (13551/13551), 104.07 MiB | 21.17 MiB/s, done.\n", + "Resolving deltas: 100% (7442/7442), done.\n", + "Obtaining file:///content/torchquantum\n", + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "Requirement already satisfied: numpy>=1.19.2 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (1.22.4)\n", + "Requirement already satisfied: torchvision>=0.9.0.dev20210130 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (0.15.2+cu118)\n", + "Requirement already satisfied: tqdm>=4.56.0 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (4.65.0)\n", + "Requirement already satisfied: setuptools>=52.0.0 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (67.7.2)\n", + "Requirement already satisfied: torch>=1.8.0 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (2.0.1+cu118)\n", + "Collecting torchdiffeq>=0.2.3 (from torchquantum==0.1.7)\n", + " Downloading torchdiffeq-0.2.3-py3-none-any.whl (31 kB)\n", + "Collecting torchpack>=0.3.0 (from torchquantum==0.1.7)\n", + " Downloading torchpack-0.3.1-py3-none-any.whl (34 kB)\n", + "Collecting qiskit==0.38.0 (from torchquantum==0.1.7)\n", + " Downloading qiskit-0.38.0.tar.gz (13 kB)\n", + " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "Requirement already satisfied: matplotlib>=3.3.2 in /usr/local/lib/python3.10/dist-packages (from torchquantum==0.1.7) (3.7.1)\n", + "Collecting pathos>=0.2.7 (from torchquantum==0.1.7)\n", + " Downloading pathos-0.3.0-py3-none-any.whl (79 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m79.8/79.8 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting pylatexenc>=2.10 (from torchquantum==0.1.7)\n", + " Downloading pylatexenc-2.10.tar.gz (162 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m162.6/162.6 kB\u001b[0m \u001b[31m9.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + "Collecting dill==0.3.4 (from torchquantum==0.1.7)\n", + " Downloading dill-0.3.4-py2.py3-none-any.whl (86 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.9/86.9 kB\u001b[0m \u001b[31m8.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting qiskit-terra==0.21.2 (from qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading qiskit_terra-0.21.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.7 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.7/6.7 MB\u001b[0m \u001b[31m13.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting qiskit-aer==0.11.0 (from qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading qiskit_aer-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (19.2 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m19.2/19.2 MB\u001b[0m \u001b[31m64.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting qiskit-ibmq-provider==0.19.2 (from qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading qiskit_ibmq_provider-0.19.2-py3-none-any.whl (240 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m240.4/240.4 kB\u001b[0m \u001b[31m23.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.10/dist-packages (from qiskit-aer==0.11.0->qiskit==0.38.0->torchquantum==0.1.7) (1.10.1)\n", + "Requirement already satisfied: requests>=2.19 in /usr/local/lib/python3.10/dist-packages (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (2.27.1)\n", + "Collecting requests-ntlm>=1.1.0 (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading requests_ntlm-1.2.0-py3-none-any.whl (6.0 kB)\n", + "Requirement already satisfied: urllib3>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (1.26.16)\n", + "Requirement already satisfied: python-dateutil>=2.8.0 in /usr/local/lib/python3.10/dist-packages (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (2.8.2)\n", + "Requirement already satisfied: websocket-client>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (1.6.1)\n", + "Collecting websockets>=10.0 (from qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (129 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m129.9/129.9 kB\u001b[0m \u001b[31m13.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting retworkx>=0.11.0 (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading retworkx-0.13.0-py3-none-any.whl (10 kB)\n", + "Collecting ply>=3.10 (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading ply-3.11-py2.py3-none-any.whl (49 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.6/49.6 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: psutil>=5 in /usr/local/lib/python3.10/dist-packages (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7) (5.9.5)\n", + "Requirement already satisfied: sympy>=1.3 in /usr/local/lib/python3.10/dist-packages (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7) (1.11.1)\n", + "Collecting stevedore>=3.0.0 (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading stevedore-5.1.0-py3-none-any.whl (49 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.6/49.6 kB\u001b[0m \u001b[31m5.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting tweedledum<2.0,>=1.1 (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading tweedledum-1.1.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (929 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m929.7/929.7 kB\u001b[0m \u001b[31m55.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting symengine>=0.9 (from qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading symengine-0.10.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (37.4 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m37.4/37.4 MB\u001b[0m \u001b[31m14.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (1.1.0)\n", + "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (0.11.0)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (4.40.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (1.4.4)\n", + "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (23.1)\n", + "Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (8.4.0)\n", + "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3.2->torchquantum==0.1.7) (3.1.0)\n", + "Collecting ppft>=1.7.6.6 (from pathos>=0.2.7->torchquantum==0.1.7)\n", + " Downloading ppft-1.7.6.6-py3-none-any.whl (52 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.8/52.8 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hINFO: pip is looking at multiple versions of pathos to determine which version is compatible with other requirements. This could take a while.\n", + "Collecting pathos>=0.2.7 (from torchquantum==0.1.7)\n", + " Downloading pathos-0.2.9-py3-none-any.whl (76 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.9/76.9 kB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading pathos-0.2.8-py2.py3-none-any.whl (81 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m81.7/81.7 kB\u001b[0m \u001b[31m8.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting multiprocess>=0.70.12 (from pathos>=0.2.7->torchquantum==0.1.7)\n", + " Downloading multiprocess-0.70.14-py310-none-any.whl (134 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m134.3/134.3 kB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting pox>=0.3.0 (from pathos>=0.2.7->torchquantum==0.1.7)\n", + " Downloading pox-0.3.2-py3-none-any.whl (29 kB)\n", + "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->torchquantum==0.1.7) (3.12.2)\n", + "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->torchquantum==0.1.7) (4.7.1)\n", + "Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->torchquantum==0.1.7) (3.1)\n", + "Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->torchquantum==0.1.7) (3.1.2)\n", + "Requirement already satisfied: triton==2.0.0 in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->torchquantum==0.1.7) (2.0.0)\n", + "Requirement already satisfied: cmake in /usr/local/lib/python3.10/dist-packages (from triton==2.0.0->torch>=1.8.0->torchquantum==0.1.7) (3.25.2)\n", + "Requirement already satisfied: lit in /usr/local/lib/python3.10/dist-packages (from triton==2.0.0->torch>=1.8.0->torchquantum==0.1.7) (16.0.6)\n", + "Requirement already satisfied: h5py in /usr/local/lib/python3.10/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.7) (3.8.0)\n", + "Collecting loguru (from torchpack>=0.3.0->torchquantum==0.1.7)\n", + " Downloading loguru-0.7.0-py3-none-any.whl (59 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m60.0/60.0 kB\u001b[0m \u001b[31m7.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting multimethod (from torchpack>=0.3.0->torchquantum==0.1.7)\n", + " Downloading multimethod-1.9.1-py3-none-any.whl (10 kB)\n", + "Requirement already satisfied: pyyaml in /usr/local/lib/python3.10/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.7) (6.0)\n", + "Requirement already satisfied: tensorboard in /usr/local/lib/python3.10/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.7) (2.12.3)\n", + "Collecting tensorpack (from torchpack>=0.3.0->torchquantum==0.1.7)\n", + " Downloading tensorpack-0.11-py2.py3-none-any.whl (296 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m296.3/296.3 kB\u001b[0m \u001b[31m27.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: toml in /usr/local/lib/python3.10/dist-packages (from torchpack>=0.3.0->torchquantum==0.1.7) (0.10.2)\n", + "INFO: pip is looking at multiple versions of multiprocess to determine which version is compatible with other requirements. This could take a while.\n", + "Collecting multiprocess>=0.70.12 (from pathos>=0.2.7->torchquantum==0.1.7)\n", + " Downloading multiprocess-0.70.13-py310-none-any.whl (133 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m133.1/133.1 kB\u001b[0m \u001b[31m10.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h Downloading multiprocess-0.70.12.2-py39-none-any.whl (128 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m128.7/128.7 kB\u001b[0m \u001b[31m15.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.0->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (1.16.0)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (2023.5.7)\n", + "Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (2.0.12)\n", + "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.19->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (3.4)\n", + "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.10/dist-packages (from sympy>=1.3->qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7) (1.3.0)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch>=1.8.0->torchquantum==0.1.7) (2.1.3)\n", + "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (1.4.0)\n", + "Requirement already satisfied: grpcio>=1.48.2 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (1.56.0)\n", + "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (2.17.3)\n", + "Requirement already satisfied: google-auth-oauthlib<1.1,>=0.5 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (1.0.0)\n", + "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (3.4.3)\n", + "Requirement already satisfied: protobuf>=3.19.6 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (3.20.3)\n", + "Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (0.7.1)\n", + "Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (2.3.6)\n", + "Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.10/dist-packages (from tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (0.40.0)\n", + "Requirement already satisfied: termcolor>=1.1 in /usr/local/lib/python3.10/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.7) (2.3.0)\n", + "Requirement already satisfied: tabulate>=0.7.7 in /usr/local/lib/python3.10/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.7) (0.8.10)\n", + "Requirement already satisfied: msgpack>=0.5.2 in /usr/local/lib/python3.10/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.7) (1.0.5)\n", + "Collecting msgpack-numpy>=0.4.4.2 (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.7)\n", + " Downloading msgpack_numpy-0.4.8-py2.py3-none-any.whl (6.9 kB)\n", + "Requirement already satisfied: pyzmq>=16 in /usr/local/lib/python3.10/dist-packages (from tensorpack->torchpack>=0.3.0->torchquantum==0.1.7) (23.2.1)\n", + "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (5.3.1)\n", + "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (0.3.0)\n", + "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (4.9)\n", + "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from google-auth-oauthlib<1.1,>=0.5->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (1.3.1)\n", + "Collecting cryptography>=1.3 (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading cryptography-41.0.2-cp37-abi3-manylinux_2_28_x86_64.whl (4.3 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.3/4.3 MB\u001b[0m \u001b[31m79.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting pyspnego>=0.1.6 (from requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading pyspnego-0.9.1-py3-none-any.whl (132 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m132.9/132.9 kB\u001b[0m \u001b[31m12.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting rustworkx==0.13.0 (from retworkx>=0.11.0->qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading rustworkx-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m62.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hCollecting pbr!=2.1.0,>=2.0.0 (from stevedore>=3.0.0->qiskit-terra==0.21.2->qiskit==0.38.0->torchquantum==0.1.7)\n", + " Downloading pbr-5.11.1-py2.py3-none-any.whl (112 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m112.7/112.7 kB\u001b[0m \u001b[31m8.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.10/dist-packages (from cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (1.15.1)\n", + "Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in /usr/local/lib/python3.10/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (0.5.0)\n", + "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.10/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<1.1,>=0.5->tensorboard->torchpack>=0.3.0->torchquantum==0.1.7) (3.2.2)\n", + "Requirement already satisfied: pycparser in /usr/local/lib/python3.10/dist-packages (from cffi>=1.12->cryptography>=1.3->requests-ntlm>=1.1.0->qiskit-ibmq-provider==0.19.2->qiskit==0.38.0->torchquantum==0.1.7) (2.21)\n", + "Building wheels for collected packages: qiskit, pylatexenc\n", + " Building wheel for qiskit (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for qiskit: filename=qiskit-0.38.0-py3-none-any.whl size=12128 sha256=7a54933fa9c2e1b1caffdc6129aa17723a1f8a19655b68eb148d3b916a542664\n", + " Stored in directory: /root/.cache/pip/wheels/9c/b0/59/d6281e20610c76a5f88c9b931c6b338410f70b4ba6561453bc\n", + " Building wheel for pylatexenc (setup.py) ... \u001b[?25l\u001b[?25hdone\n", + " Created wheel for pylatexenc: filename=pylatexenc-2.10-py3-none-any.whl size=136820 sha256=087f5465344ad90f93c062a3e9d3224bf3afdb393350b74383207ecbe6a0509b\n", + " Stored in directory: /root/.cache/pip/wheels/d3/31/8b/e09b0386afd80cfc556c00408c9aeea5c35c4d484a9c762fd5\n", + "Successfully built qiskit pylatexenc\n", + "Installing collected packages: pylatexenc, ply, websockets, tweedledum, symengine, rustworkx, ppft, pox, pbr, multimethod, msgpack-numpy, loguru, dill, tensorpack, stevedore, retworkx, multiprocess, cryptography, qiskit-terra, pyspnego, pathos, requests-ntlm, qiskit-aer, qiskit-ibmq-provider, qiskit, torchpack, torchdiffeq, torchquantum\n", + " Running setup.py develop for torchquantum\n", + "Successfully installed cryptography-41.0.2 dill-0.3.4 loguru-0.7.0 msgpack-numpy-0.4.8 multimethod-1.9.1 multiprocess-0.70.12.2 pathos-0.2.8 pbr-5.11.1 ply-3.11 pox-0.3.2 ppft-1.7.6.6 pylatexenc-2.10 pyspnego-0.9.1 qiskit-0.38.0 qiskit-aer-0.11.0 qiskit-ibmq-provider-0.19.2 qiskit-terra-0.21.2 requests-ntlm-1.2.0 retworkx-0.13.0 rustworkx-0.13.0 stevedore-5.1.0 symengine-0.10.0 tensorpack-0.11 torchdiffeq-0.2.3 torchpack-0.3.1 torchquantum-0.1.7 tweedledum-1.1.1 websockets-11.0.3\n" + ] + } + ], + "source": [ + "!git clone https://github.com/mit-han-lab/torchquantum.git\n", + "!cd torchquantum && pip install --editable ." + ] + }, + { + "cell_type": "markdown", + "source": [ + "> **Note: To be able to install TorchQuantum on Colab, you must restart your runtime before continuing!**\n", + "\n", + "After installing from source (and restarting if using Colab!), you can import TorchQuantum." + ], + "metadata": { + "id": "Ckw9S9C0TzuH" + } + }, + { + "cell_type": "code", + "source": [ + "import torchquantum as tq" + ], + "metadata": { + "id": "vhmIuM9Wc70Z" + }, + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Creating a device" + ], + "metadata": { + "id": "PxW4zls2Y3QM" + } + }, + { + "cell_type": "markdown", + "source": [ + "Before we can construct our quantum node, we need to initialize a device.\n", + "\n", + "> **Definition**\n", + ">\n", + "> Any computational object that can apply quantum operations and return a measurement value is called a quantum **device**.\n", + "\n", + "> *Devices are loaded in PennyLane via the class [QuantumDevice()](https://github.com/mit-han-lab/torchquantum/blob/main/torchquantum/devices.py#L13)*\n" + ], + "metadata": { + "id": "Y08Q6dMKY6HC" + } + }, + { + "cell_type": "markdown", + "source": [ + "For this tutorial, we are using the qubit model, so let's initialize the 'default' device provided by TorchQuantum." + ], + "metadata": { + "id": "0bgRmzQLeOtt" + } + }, + { + "cell_type": "code", + "source": [ + "qdev = tq.QuantumDevice(n_wires=1, device_name=\"default\", bsz=1, device=\"cuda\", record_op=True)" + ], + "metadata": { + "id": "NUrCxUQvc_3i" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "For all devices, [QuantumDevice()](https://github.com/mit-han-lab/torchquantum/blob/main/torchquantum/devices.py#L13) accepts the following arguments:\n", + "\n", + "* n_wires: number of qubits to initialize the device with\n", + "* device_name: name of the quantum device to be loaded\n", + "* bsz: batch size of the quantum state\n", + "* device: which classical computing device to use, 'cpu' or 'cuda' (similar to the device option in PyTorch)\n", + "* record_op: whether to record the operations on the quantum device and then they can be used to construct a static computation graph\n", + "\n", + "Here, as we only require a single qubit for this example, we set wires=1." + ], + "metadata": { + "id": "uJOZRR--dQ0n" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Constructing the Circuit" + ], + "metadata": { + "id": "n2bS-rw1em0a" + } + }, + { + "cell_type": "markdown", + "source": [ + "Now that we have initialized our device, we can begin to construct the circuit. In TorchQuantum, there are multiple ways to construct a circuit, and we can explore a few of them." + ], + "metadata": { + "id": "9W-rBf2CfCQd" + } + }, + { + "cell_type": "code", + "source": [ + "# specify parameters\n", + "params = [0.54, 0.12]\n", + "\n", + "# create circuit\n", + "qdev.rx(params=params[0], wires=0)\n", + "qdev.ry(params=params[1], wires=0)" + ], + "metadata": { + "id": "qcmWA-o4hBqa" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "This method calls the gates directly from the QuantumDevice. For the rotations, we can specify which wire it belongs to (zero-indexed) and a parameter theta for the amount of rotation. However, the rotation gates also have other parameters.\n", + "\n", + "* wires: which qibits the gate is applied to\n", + "* theta: the amount of rotation\n", + "* n_wires: number of qubits the gate is applied to\n", + "* static: whether use static mode computation\n", + "* parent_graph: Parent QuantumGraph of current operation\n", + "* inverse: whether inverse the gate\n", + "* comp_method: option to use 'bmm' or 'einsum' method to perform matrix vector multiplication" + ], + "metadata": { + "id": "RQhCOnNAhm7q" + } + }, + { + "cell_type": "markdown", + "source": [ + "To get the following expected value, we can use two different functions from torchquantum's measurement module." + ], + "metadata": { + "id": "zY5lSe3Nl-78" + } + }, + { + "cell_type": "code", + "source": [ + "from torchquantum.measurement import expval_joint_analytical, expval_joint_sampling" + ], + "metadata": { + "id": "3IHmc_ILirVI" + }, + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "* `expval_joint_analytical` will compute the expectation value of a joint observable in analytical way, assuming the statevector is available. This can only be run on a classical simulator, not real quantum hardware.\n", + "\n", + "* `expval_joint_analytical` will compute the expectation value of a joint observable from sampling the measurement bistring. This can be run on both a classical simualtion and real quantum hardware. Since this is sampling the measurements, it requires a parameters for the number of shots, `n_shots`.\n", + "\n" + ], + "metadata": { + "id": "h_05PJxAjIMk" + } + }, + { + "cell_type": "code", + "source": [ + "exp_a = expval_joint_analytical(qdev, 'Z')\n", + "exp_s = expval_joint_sampling(qdev, 'Z', n_shots=1024)\n", + "\n", + "print(exp_a, exp_s)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3TIwrhn1kD-a", + "outputId": "0af08a9b-5c1c-475b-9845-3aa2331ed59e" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "tensor([0.8515]) tensor([0.8184])\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "The two numbers are about the same, and if we increase the number of shots for the joint sampling, its expected value should approach the same value as the analytical." + ], + "metadata": { + "id": "9rUMiTshkuYk" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Calculating quantum gradients" + ], + "metadata": { + "id": "WyHxuz4_l0lB" + } + }, + { + "cell_type": "markdown", + "source": [ + "From the expected values output, notice that the analytical expected value has an automatically-calculated gradient which can be used when constructing quantum machine learning models. This is because TorchQuantum automatically calculates the gradients. Let's find the gradient of each individual gate.\n", + "\n", + "To do so, we can create the circuit slightly differently, saving each operation as a variable then adding it to the circuit. We can then once again get the expected value with `expval_joint_analytical`." + ], + "metadata": { + "id": "GNlFHcRDnqVl" + } + }, + { + "cell_type": "code", + "source": [ + "qdev = tq.QuantumDevice(n_wires=1)\n", + "\n", + "op1 = tq.RX(has_params=True, trainable=True, init_params=0.54)\n", + "op1(qdev, wires=0)\n", + "\n", + "op2 = tq.RY(has_params=True, trainable=True, init_params=0.12)\n", + "op2(qdev, wires=0)\n", + "\n", + "\n", + "expval = expval_joint_analytical(qdev, 'Z')" + ], + "metadata": { + "id": "m_n2ROPNoFzn" + }, + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "We can then call `.backward()` on the expected value, just like in PyTorch. Afterwards, we can see the gradient of each operation under the `params` option." + ], + "metadata": { + "id": "znstxaD3pFdK" + } + }, + { + "cell_type": "code", + "source": [ + "expval[0].backward()\n", + "\n", + "# calculate the gradients for each operation!\n", + "print(op1.params.grad, op2.params.grad)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "d6ehHkuSo5Oq", + "outputId": "d3610b9a-48b2-4797-c3c9-818db8ce0687" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "tensor([[-0.5104]]) tensor([[-0.1027]])\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Optimization" + ], + "metadata": { + "id": "R8PqqWa5pbzU" + } + }, + { + "cell_type": "markdown", + "source": [ + "Next, let's make use of PyTorch's optimizers to optimize the two circuit parameters $\\phi_1$ and $\\phi_2$ such that the qubit, originally in state |0⟩, is rotated to be in state |1⟩. This is equivalent to measuring a Pauli-Z expectation value of -1, since the state |1⟩ is an eigenvector of the Pauli-Z matrix with eigenvalue λ=−1." + ], + "metadata": { + "id": "q4I7DC2Uphzs" + } + }, + { + "cell_type": "markdown", + "source": [ + "To construct this circuit, we can use a class similar to a PyTorch module! We can begin by importing torch." + ], + "metadata": { + "id": "G3h9LjzJqf0k" + } + }, + { + "cell_type": "code", + "source": [ + "import torch" + ], + "metadata": { + "id": "X3LeotDeqoIh" + }, + "execution_count": 38, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "We can next create the class extending the PyTorch module and add our gates in a similar fashion as the previous steps." + ], + "metadata": { + "id": "LbN7Fo67qpGI" + } + }, + { + "cell_type": "code", + "source": [ + "import torchquantum as tq\n", + "import torchquantum.functional as tqf\n", + "\n", + "class OptimizationModel(torch.nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.rx0 = tq.RX(has_params=True, trainable=True, init_params=0.011)\n", + " self.ry0 = tq.RY(has_params=True, trainable=True, init_params=0.012)\n", + "\n", + " def forward(self):\n", + " # create a quantum device to run the gates\n", + " qdev = tq.QuantumDevice(n_wires=1)\n", + "\n", + " # add some trainable gates (need to instantiate ahead of time)\n", + " self.rx0(qdev, wires=0)\n", + " self.ry0(qdev, wires=0)\n", + "\n", + " return expval_joint_analytical(qdev, 'Z')" + ], + "metadata": { + "id": "gxve5-2SpdDA" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "To optimize the rotation, we need to define a cost function. By minimizing the cost function, the optimizer will determine the values of the circuit parameters that produce the desired outcome.\n", + "\n", + "In this case, our desired outcome is a Pauli-Z expectation value of −1. Since we know that the Pauli-Z expectation is bound between [−1, 1], we can define our cost directly as the output of the circuit.\n", + "\n", + "Similar to PyTorch, we can create a train function to compute the gradients of the loss function and have the optimizer perform an optimization step." + ], + "metadata": { + "id": "Ifi5cH_eq_zW" + } + }, + { + "cell_type": "code", + "source": [ + "def train(model, device, optimizer):\n", + " targets = 0\n", + "\n", + " outputs = model()\n", + " loss = outputs\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " return loss.item()" + ], + "metadata": { + "id": "H5xxXrWUrAO3" + }, + "execution_count": 53, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Finally, we can run the model. We can import PyTorch's gradient descent module and use it to optimize our model." + ], + "metadata": { + "id": "dn0131aKrjQ8" + } + }, + { + "cell_type": "code", + "source": [ + "def main():\n", + " seed = 0\n", + " torch.manual_seed(seed)\n", + "\n", + " use_cuda = torch.cuda.is_available()\n", + " device = torch.device(\"cuda\" if use_cuda else \"cpu\")\n", + "\n", + " model = OptimizationModel()\n", + " n_epochs = 200\n", + " optimizer = torch.optim.SGD(model.parameters(), lr=0.1)\n", + "\n", + " for epoch in range(1, n_epochs + 1):\n", + " # train\n", + " loss = train(model, device, optimizer)\n", + " output = (model.rx0.params[0].item(), model.ry0.params[0].item())\n", + " print(f\"Epoch {epoch}: {output}\")\n", + "\n", + " if epoch % 10 == 0:\n", + " print(f\"Loss after step {epoch}: {loss}\")" + ], + "metadata": { + "id": "4WJ7yL5SrjkA" + }, + "execution_count": 54, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Finally, we can call the main function and run the entire sequence!" + ], + "metadata": { + "id": "eY5PvCqhr1ZF" + } + }, + { + "cell_type": "code", + "source": [ + "main()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "_hCBPtMvr4wB", + "outputId": "2091f42b-7263-4e5d-d2f7-eab8b07bbe7f" + }, + "execution_count": 55, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1: (0.012099898420274258, 0.013199898414313793)\n", + "Epoch 2: (0.013309753499925137, 0.014519752934575081)\n", + "Epoch 3: (0.014640549197793007, 0.015971548855304718)\n", + "Epoch 4: (0.01610436476767063, 0.017568465322256088)\n", + "Epoch 5: (0.01771448366343975, 0.01932499371469021)\n", + "Epoch 6: (0.019485509023070335, 0.02125706896185875)\n", + "Epoch 7: (0.021433496847748756, 0.023382212966680527)\n", + "Epoch 8: (0.023576095700263977, 0.02571968361735344)\n", + "Epoch 9: (0.025932706892490387, 0.028290653601288795)\n", + "Epoch 10: (0.028524650260806084, 0.03111839108169079)\n", + "Loss after step 10: 0.9992638230323792\n", + "Epoch 11: (0.031375348567962646, 0.03422846272587776)\n", + "Epoch 12: (0.0345105305314064, 0.03764895722270012)\n", + "Epoch 13: (0.037958454340696335, 0.041410721838474274)\n", + "Epoch 14: (0.04175013676285744, 0.04554762691259384)\n", + "Epoch 15: (0.04591960832476616, 0.050096847116947174)\n", + "Epoch 16: (0.05050419643521309, 0.055099159479141235)\n", + "Epoch 17: (0.05554480850696564, 0.06059926748275757)\n", + "Epoch 18: (0.06108624115586281, 0.06664614379405975)\n", + "Epoch 19: (0.06717751175165176, 0.07329340279102325)\n", + "Epoch 20: (0.07387219369411469, 0.08059966564178467)\n", + "Loss after step 20: 0.9950657486915588\n", + "Epoch 21: (0.08122873306274414, 0.08862894773483276)\n", + "Epoch 22: (0.08931083232164383, 0.09745106101036072)\n", + "Epoch 23: (0.09818772971630096, 0.10714197158813477)\n", + "Epoch 24: (0.10793451964855194, 0.11778417229652405)\n", + "Epoch 25: (0.11863239109516144, 0.12946699559688568)\n", + "Epoch 26: (0.13036876916885376, 0.14228680729866028)\n", + "Epoch 27: (0.14323736727237701, 0.15634718537330627)\n", + "Epoch 28: (0.15733805298805237, 0.17175881564617157)\n", + "Epoch 29: (0.172776460647583, 0.18863925337791443)\n", + "Epoch 30: (0.18966329097747803, 0.20711229741573334)\n", + "Loss after step 30: 0.9676356315612793\n", + "Epoch 31: (0.20811320841312408, 0.2273070216178894)\n", + "Epoch 32: (0.2282431572675705, 0.2493562251329422)\n", + "Epoch 33: (0.2501700222492218, 0.27339422702789307)\n", + "Epoch 34: (0.2740074098110199, 0.29955384135246277)\n", + "Epoch 35: (0.2998615801334381, 0.32796236872673035)\n", + "Epoch 36: (0.32782599329948425, 0.35873648524284363)\n", + "Epoch 37: (0.3579748272895813, 0.39197587966918945)\n", + "Epoch 38: (0.3903552293777466, 0.427755743265152)\n", + "Epoch 39: (0.42497843503952026, 0.46611812710762024)\n", + "Epoch 40: (0.4618101119995117, 0.5070626139640808)\n", + "Loss after step 40: 0.8138567805290222\n", + "Epoch 41: (0.5007606744766235, 0.5505368709564209)\n", + "Epoch 42: (0.5416762828826904, 0.5964280366897583)\n", + "Epoch 43: (0.5843320488929749, 0.6445562839508057)\n", + "Epoch 44: (0.6284285187721252, 0.6946715116500854)\n", + "Epoch 45: (0.6735928058624268, 0.7464552521705627)\n", + "Epoch 46: (0.7193858623504639, 0.7995281219482422)\n", + "Epoch 47: (0.7653157711029053, 0.8534636497497559)\n", + "Epoch 48: (0.8108565211296082, 0.9078077673912048)\n", + "Epoch 49: (0.8554709553718567, 0.9621021151542664)\n", + "Epoch 50: (0.8986347317695618, 1.0159088373184204)\n", + "Loss after step 50: 0.3750203549861908\n", + "Epoch 51: (0.9398593902587891, 1.0688340663909912)\n", + "Epoch 52: (0.9787107706069946, 1.1205471754074097)\n", + "Epoch 53: (1.0148218870162964, 1.1707944869995117)\n", + "Epoch 54: (1.0478986501693726, 1.2194054126739502)\n", + "Epoch 55: (1.0777196884155273, 1.2662931680679321)\n", + "Epoch 56: (1.1041301488876343, 1.311449408531189)\n", + "Epoch 57: (1.127032995223999, 1.354935884475708)\n", + "Epoch 58: (1.1463772058486938, 1.3968735933303833)\n", + "Epoch 59: (1.1621465682983398, 1.4374314546585083)\n", + "Epoch 60: (1.1743487119674683, 1.4768157005310059)\n", + "Loss after step 60: 0.052838265895843506\n", + "Epoch 61: (1.1830050945281982, 1.5152597427368164)\n", + "Epoch 62: (1.1881437301635742, 1.553015947341919)\n", + "Epoch 63: (1.1897931098937988, 1.590348243713379)\n", + "Epoch 64: (1.1879782676696777, 1.6275262832641602)\n", + "Epoch 65: (1.1827187538146973, 1.6648198366165161)\n", + "Epoch 66: (1.1740283966064453, 1.702493667602539)\n", + "Epoch 67: (1.1619168519973755, 1.7408030033111572)\n", + "Epoch 68: (1.146392583847046, 1.7799879312515259)\n", + "Epoch 69: (1.1274679899215698, 1.820267915725708)\n", + "Epoch 70: (1.1051654815673828, 1.8618348836898804)\n", + "Loss after step 70: -0.10590392351150513\n", + "Epoch 71: (1.0795255899429321, 1.9048453569412231)\n", + "Epoch 72: (1.0506160259246826, 1.9494123458862305)\n", + "Epoch 73: (1.018541693687439, 1.9955958127975464)\n", + "Epoch 74: (0.9834545850753784, 2.043394088745117)\n", + "Epoch 75: (0.9455628991127014, 2.0927350521087646)\n", + "Epoch 76: (0.9051381945610046, 2.1434707641601562)\n", + "Epoch 77: (0.8625186085700989, 2.1953752040863037)\n", + "Epoch 78: (0.8181073665618896, 2.2481465339660645)\n", + "Epoch 79: (0.7723652124404907, 2.30141544342041)\n", + "Epoch 80: (0.7257967591285706, 2.354759931564331)\n", + "Loss after step 80: -0.4779837727546692\n", + "Epoch 81: (0.6789312362670898, 2.4077253341674805)\n", + "Epoch 82: (0.6322994232177734, 2.459847927093506)\n", + "Epoch 83: (0.5864096879959106, 2.5106801986694336)\n", + "Epoch 84: (0.5417252779006958, 2.5598134994506836)\n", + "Epoch 85: (0.4986463487148285, 2.6068966388702393)\n", + "Epoch 86: (0.4574976861476898, 2.6516494750976562)\n", + "Epoch 87: (0.4185234606266022, 2.6938676834106445)\n", + "Epoch 88: (0.38188809156417847, 2.7334227561950684)\n", + "Epoch 89: (0.34768232703208923, 2.770256519317627)\n", + "Epoch 90: (0.31593260169029236, 2.8043713569641113)\n", + "Loss after step 90: -0.876086413860321\n", + "Epoch 91: (0.28661224246025085, 2.835820436477661)\n", + "Epoch 92: (0.25965315103530884, 2.8646953105926514)\n", + "Epoch 93: (0.23495660722255707, 2.891116142272949)\n", + "Epoch 94: (0.21240299940109253, 2.915221691131592)\n", + "Epoch 95: (0.1918598860502243, 2.937161445617676)\n", + "Epoch 96: (0.1731884628534317, 2.957089900970459)\n", + "Epoch 97: (0.156248539686203, 2.97516131401062)\n", + "Epoch 98: (0.14090220630168915, 2.991525888442993)\n", + "Epoch 99: (0.12701639533042908, 3.0063281059265137)\n", + "Epoch 100: (0.11446458846330643, 3.019704818725586)\n", + "Loss after step 100: -0.9828835129737854\n", + "Epoch 101: (0.1031278446316719, 3.0317838191986084)\n", + "Epoch 102: (0.09289533644914627, 3.042684316635132)\n", + "Epoch 103: (0.08366449177265167, 3.052516460418701)\n", + "Epoch 104: (0.07534093409776688, 3.0613811016082764)\n", + "Epoch 105: (0.0678381696343422, 3.069370985031128)\n", + "Epoch 106: (0.06107722595334053, 3.0765702724456787)\n", + "Epoch 107: (0.054986197501420975, 3.0830557346343994)\n", + "Epoch 108: (0.0494997613132, 3.088897228240967)\n", + "Epoch 109: (0.04455867409706116, 3.0941579341888428)\n", + "Epoch 110: (0.040109291672706604, 3.0988948345184326)\n", + "Loss after step 110: -0.997883677482605\n", + "Epoch 111: (0.03610309213399887, 3.1031599044799805)\n", + "Epoch 112: (0.03249623253941536, 3.106999635696411)\n", + "Epoch 113: (0.029249126091599464, 3.1104564666748047)\n", + "Epoch 114: (0.026326047256588936, 3.1135683059692383)\n", + "Epoch 115: (0.023694779723882675, 3.1163694858551025)\n", + "Epoch 116: (0.021326277405023575, 3.1188907623291016)\n", + "Epoch 117: (0.019194360822439194, 3.1211602687835693)\n", + "Epoch 118: (0.01727544330060482, 3.1232030391693115)\n", + "Epoch 119: (0.015548276714980602, 3.1250417232513428)\n", + "Epoch 120: (0.013993724249303341, 3.1266965866088867)\n", + "Loss after step 120: -0.9997422099113464\n", + "Epoch 121: (0.012594552710652351, 3.128185987472534)\n", + "Epoch 122: (0.011335243470966816, 3.1295266151428223)\n", + "Epoch 123: (0.010201825760304928, 3.130733013153076)\n", + "Epoch 124: (0.00918172113597393, 3.131819009780884)\n", + "Epoch 125: (0.008263605646789074, 3.132796287536621)\n", + "Epoch 126: (0.0074372864328324795, 3.1336758136749268)\n", + "Epoch 127: (0.006693588104099035, 3.134467363357544)\n", + "Epoch 128: (0.006024251226335764, 3.1351797580718994)\n", + "Epoch 129: (0.005421841982752085, 3.1358211040496826)\n", + "Epoch 130: (0.004879669286310673, 3.1363983154296875)\n", + "Loss after step 130: -0.9999685883522034\n", + "Epoch 131: (0.004391710739582777, 3.13691782951355)\n", + "Epoch 132: (0.0039525460451841354, 3.137385368347168)\n", + "Epoch 133: (0.0035572960041463375, 3.1378061771392822)\n", + "Epoch 134: (0.003201569663360715, 3.1381847858428955)\n", + "Epoch 135: (0.0028814151883125305, 3.1385254859924316)\n", + "Epoch 136: (0.0025932753924280405, 3.1388320922851562)\n", + "Epoch 137: (0.002333949087187648, 3.139108180999756)\n", + "Epoch 138: (0.002100554993376136, 3.1393566131591797)\n", + "Epoch 139: (0.0018905001925304532, 3.139580249786377)\n", + "Epoch 140: (0.0017014506738632917, 3.1397814750671387)\n", + "Loss after step 140: -0.9999963045120239\n", + "Epoch 141: (0.001531305955722928, 3.139962673187256)\n", + "Epoch 142: (0.0013781756861135364, 3.1401257514953613)\n", + "Epoch 143: (0.0012403583386912942, 3.140272378921509)\n", + "Epoch 144: (0.0011163227027282119, 3.140404462814331)\n", + "Epoch 145: (0.0010046905372291803, 3.1405231952667236)\n", + "Epoch 146: (0.0009042215533554554, 3.1406302452087402)\n", + "Epoch 147: (0.0008137994445860386, 3.1407265663146973)\n", + "Epoch 148: (0.0007324195466935635, 3.140813112258911)\n", + "Epoch 149: (0.0006591776036657393, 3.1408910751342773)\n", + "Epoch 150: (0.0005932598724029958, 3.140961170196533)\n", + "Loss after step 150: -0.9999995231628418\n", + "Epoch 151: (0.0005339339259080589, 3.141024351119995)\n", + "Epoch 152: (0.00048054056242108345, 3.1410810947418213)\n", + "Epoch 153: (0.000432486500358209, 3.141132354736328)\n", + "Epoch 154: (0.00038923785905353725, 3.1411783695220947)\n", + "Epoch 155: (0.00035031407605856657, 3.1412198543548584)\n", + "Epoch 156: (0.0003152826684527099, 3.1412570476531982)\n", + "Epoch 157: (0.0002837544016074389, 3.1412906646728516)\n", + "Epoch 158: (0.0002553789527155459, 3.1413209438323975)\n", + "Epoch 159: (0.00022984105453360826, 3.141348123550415)\n", + "Epoch 160: (0.00020685694471467286, 3.1413726806640625)\n", + "Loss after step 160: -1.0\n", + "Epoch 161: (0.0001861712516983971, 3.14139461517334)\n", + "Epoch 162: (0.0001675541279837489, 3.1414144039154053)\n", + "Epoch 163: (0.00015079871809575707, 3.141432285308838)\n", + "Epoch 164: (0.00013571884483098984, 3.1414482593536377)\n", + "Epoch 165: (0.0001221469574375078, 3.141462802886963)\n", + "Epoch 166: (0.00010993226169375703, 3.1414756774902344)\n", + "Epoch 167: (9.893903188640252e-05, 3.1414873600006104)\n", + "Epoch 168: (8.904512651497498e-05, 3.141497850418091)\n", + "Epoch 169: (8.014061313588172e-05, 3.141507387161255)\n", + "Epoch 170: (7.212655327748507e-05, 3.1415159702301025)\n", + "Loss after step 170: -1.0\n", + "Epoch 171: (6.491389649454504e-05, 3.141523599624634)\n", + "Epoch 172: (5.8422505389899015e-05, 3.1415305137634277)\n", + "Epoch 173: (5.258025339571759e-05, 3.1415367126464844)\n", + "Epoch 174: (4.732222805614583e-05, 3.1415421962738037)\n", + "Epoch 175: (4.2590003431541845e-05, 3.141547203063965)\n", + "Epoch 176: (3.833100345218554e-05, 3.1415517330169678)\n", + "Epoch 177: (3.4497901651775464e-05, 3.1415557861328125)\n", + "Epoch 178: (3.10481118503958e-05, 3.141559362411499)\n", + "Epoch 179: (2.794330066535622e-05, 3.1415627002716064)\n", + "Epoch 180: (2.5148970962618478e-05, 3.1415657997131348)\n", + "Loss after step 180: -1.0\n", + "Epoch 181: (2.263407441205345e-05, 3.141568422317505)\n", + "Epoch 182: (2.0370667698443867e-05, 3.141570806503296)\n", + "Epoch 183: (1.83336014742963e-05, 3.141572952270508)\n", + "Epoch 184: (1.6500242054462433e-05, 3.1415748596191406)\n", + "Epoch 185: (1.485021766711725e-05, 3.1415765285491943)\n", + "Epoch 186: (1.3365195627557114e-05, 3.141578197479248)\n", + "Epoch 187: (1.2028675882902462e-05, 3.1415796279907227)\n", + "Epoch 188: (1.0825808203662746e-05, 3.141580820083618)\n", + "Epoch 189: (9.743227565195411e-06, 3.1415820121765137)\n", + "Epoch 190: (8.76890499057481e-06, 3.14158296585083)\n", + "Loss after step 190: -1.0\n", + "Epoch 191: (7.89201476436574e-06, 3.1415839195251465)\n", + "Epoch 192: (7.1028134698281065e-06, 3.141584873199463)\n", + "Epoch 193: (6.392532213794766e-06, 3.1415855884552)\n", + "Epoch 194: (5.753278855991084e-06, 3.1415863037109375)\n", + "Epoch 195: (5.177951152290916e-06, 3.141587018966675)\n", + "Epoch 196: (4.660155809688149e-06, 3.141587495803833)\n", + "Epoch 197: (4.194140274194069e-06, 3.141587972640991)\n", + "Epoch 198: (3.7747263377241325e-06, 3.1415884494781494)\n", + "Epoch 199: (3.3972537494264543e-06, 3.1415889263153076)\n", + "Epoch 200: (3.057528374483809e-06, 3.141589403152466)\n", + "Loss after step 200: -1.0\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "We can see that the optimization converges after approximately 160 steps.\n", + "\n", + "Substituting this into the theoretical result $⟨ψ∣σ_z∣ψ⟩ = \\cos ϕ_1 \\cos ϕ_2$, we can verify that this is indeed one possible value of the circuit parameters that produces $⟨ψ∣σ_z∣ψ⟩ = −1$, resulting in the qubit being rotated to the state |1⟩.\n", + "\n" + ], + "metadata": { + "id": "GpzzV6kyr_Z1" + } + } + ] +} \ No newline at end of file diff --git a/examples/qubit_rotation/qubit_rotation.py b/examples/qubit_rotation/qubit_rotation.py new file mode 100644 index 00000000..3e0d17d6 --- /dev/null +++ b/examples/qubit_rotation/qubit_rotation.py @@ -0,0 +1,66 @@ +''' +Qubit Rotation Optimization, adapted from https://pennylane.ai/qml/demos/tutorial_qubit_rotation +''' + +# import dependencies +import torchquantum as tq +import torch +from torchquantum.measurement import expval_joint_analytical + +class OptimizationModel(torch.nn.Module): + ''' + Circuit with rx and ry gate + ''' + def __init__(self): + super().__init__() + self.rx0 = tq.RX(has_params=True, trainable=True, init_params=0.011) + self.ry0 = tq.RY(has_params=True, trainable=True, init_params=0.012) + + def forward(self): + # create a quantum device to run the gates + qdev = tq.QuantumDevice(n_wires=1) + + # add some trainable gates (need to instantiate ahead of time) + self.rx0(qdev, wires=0) + self.ry0(qdev, wires=0) + + # return the analytic expval from Z + return expval_joint_analytical(qdev, 'Z') + +# train function to get expval as low as possible (ideally -1) +def train(model, device, optimizer): + + outputs = model() + loss = outputs + optimizer.zero_grad() + loss.backward() + optimizer.step() + + return loss.item() + +# main function to run the optimization +def main(): + seed = 0 + torch.manual_seed(seed) + + use_cuda = torch.cuda.is_available() + device = torch.device("cuda" if use_cuda else "cpu") + + model = OptimizationModel() + n_epochs = 200 + optimizer = torch.optim.SGD(model.parameters(), lr=0.1) + + for epoch in range(1, n_epochs + 1): + # train + loss = train(model, device, optimizer) + output = (model.rx0.params[0].item(), model.ry0.params[0].item()) + + print(f"Epoch {epoch}: {output}") + + if epoch % 10 == 0: + print(f"Loss after step {epoch}: {loss}") + + +if __name__ == "__main__": + main() +