diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 139b508..0346b09 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,6 @@ jobs: key: poetry-${{ hashFiles('poetry.lock') }} - name: Check style run: | - sudo apt update . scripts/ci_install_deps poetry run make check-style @@ -42,7 +41,6 @@ jobs: key: poetry-${{ hashFiles('poetry.lock') }} - name: Check types run: | - sudo apt update . scripts/ci_install_deps poetry run make check-types @@ -64,7 +62,6 @@ jobs: key: poetry-${{ hashFiles('poetry.lock') }} - name: Test (Python ${{ matrix.python-version }}) run: | - sudo apt update . scripts/ci_install_deps docker run --rm -itd -p 5555:5555 --entrypoint bash rigetti/quilc -c "curl -L -o qelib1.inc https://raw.githubusercontent.com/Qiskit/qiskit-terra/0.16.2/qiskit/qasm/libs/qelib1.inc && ./quilc -S -P" docker run --rm -itd -p 5000:5000 rigetti/qvm -S @@ -88,6 +85,7 @@ jobs: SPHINXOPTS: "-W" run: | sudo apt update + sudo apt install pandoc . scripts/ci_install_deps "-E docs" poetry run make docs @@ -107,6 +105,5 @@ jobs: - name: Check Licenses # This is an exact match list, new dependencies will likely require their own entries run: | - sudo apt update . scripts/ci_install_deps poetry run pip-licenses --allow-only="MIT License;Apache Software License;BSD License;GNU Lesser General Public License v2 or later (LGPLv2+);Python Software Foundation License;Apache License 2.0;new BSD;Apache-2.0;ISCL;ISC License (ISCL);BSD;Mozilla Public License 2.0 (MPL 2.0)" diff --git a/.gitignore b/.gitignore index cccfdc7..4a0df74 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +README.rst # PyInstaller # Usually these files are written by a python script from a template diff --git a/README.md b/README.md index edaa0e1..d02ec3c 100644 --- a/README.md +++ b/README.md @@ -170,4 +170,4 @@ Dependencies are managed with [Poetry](https://python-poetry.org/) so you need t 1. Check style only: `make check-style` 1. Check types only: `make check-types` 1. Reformat all code (to make `check-style` pass): `make format` -1. Build documentation, serve locally, and watch for changes: `make watch-docs` +1. Build documentation, serve locally, and watch for changes: `make watch-docs` (requires `docs` extra: `poetry install -E docs`) diff --git a/docs/conf.py b/docs/conf.py index 304adc6..b9d223e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,6 +17,8 @@ "autoapi.extension", "sphinx.ext.napoleon", "myst_parser", + "nbsphinx", + "sphinx.ext.mathjax", ] source_suffix = { @@ -42,8 +44,9 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] +myst_update_mathjax = False # -- Options for HTML output ------------------------------------------------- html_theme = "furo" diff --git a/docs/examples/qaoa_pyquil.ipynb b/docs/examples/qaoa_pyquil.ipynb new file mode 100644 index 0000000..62d0940 --- /dev/null +++ b/docs/examples/qaoa_pyquil.ipynb @@ -0,0 +1,336 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "given-sunrise", + "metadata": {}, + "source": [ + "# Max-Cut QAOA on QCS with Qiskit\n", + "\n", + "> ℹ️ Originally written to demonstrate pyQuil, this notebook demonstrates how to take existing pyQuil work and run it on a Rigetti backend using Qiskit.\n", + "\n", + "In this notebook, we will walk through how to run the **Max-Cut QAOA** algorithm using the Qiskit Rigetti Provider." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "norman-yeast", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List, Tuple\n", + "\n", + "import networkx as nx\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "id": "yellow-purchase", + "metadata": { + "tags": [] + }, + "source": [ + "## Generate Random Weighted Graph\n", + "\n", + "Given a list of edges, we generate a graph with random edge weights in the range \\[-1,1)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "amber-engineer", + "metadata": {}, + "outputs": [], + "source": [ + "def generate_ising_graph(edges: List[Tuple[int, int]], seed: int) -> nx.Graph:\n", + " np.random.seed(seed)\n", + " graph = nx.from_edgelist(edges)\n", + " weights: np.ndarray = 2.0 * np.random.rand(graph.number_of_edges()) - 1.0\n", + " weights /= np.linalg.norm(weights)\n", + " nx.set_edge_attributes(graph, {e: {'w': w} for e, w in zip(graph.edges, weights)})\n", + " return graph" + ] + }, + { + "cell_type": "markdown", + "id": "civilian-vehicle", + "metadata": {}, + "source": [ + "## Compute Bitstring Cut Weight\n", + "\n", + "Given a graph and a bitstring, compute the [cut weight](https://en.wikipedia.org/wiki/Maximum_cut), which determines the cost of the particular bitstring." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "continuous-timeline", + "metadata": {}, + "outputs": [], + "source": [ + "def bitstring_cut_weight(b: List[List[int]], graph: nx.Graph) -> dict:\n", + " cost = 0\n", + " inverse_map = {qubit: idx for idx, qubit in enumerate(list(graph.nodes))}\n", + " for q0, q1 in graph.edges():\n", + " cost += graph.get_edge_data(q0, q1)['w'] * (-1) ** int(b[inverse_map[q0]] != b[inverse_map[q1]])\n", + " return cost" + ] + }, + { + "cell_type": "markdown", + "id": "differential-creation", + "metadata": {}, + "source": [ + "## Create QAOA Max-Cut Program\n", + "\n", + "For our problem graph, we generate the [QAOA](https://arxiv.org/abs/1411.4028) cost and driver unitaries:\n", + "\n", + "$$H_c = \\sum_{i,j} w_{i,j} \\sigma_i^z \\sigma_j^z \\qquad H_d = \\sum_i \\sigma_i^x$$\n", + "\n", + "From these, we create our parameterized circuit." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "understood-binding", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit.circuit import QuantumCircuit, Parameter\n", + "\n", + "def maxcut_qaoa_circuit(graph: nx.Graph, beta: Parameter, gamma: Parameter) -> QuantumCircuit:\n", + " circuit = QuantumCircuit(max(graph.nodes)+1, len(graph.nodes))\n", + " \n", + " circuit.h(graph.nodes)\n", + " \n", + " # cost\n", + " for i, j in graph.edges:\n", + " w = graph.get_edge_data(i, j)['w']\n", + " circuit.cx(i, j)\n", + " circuit.rz(2.0*w*gamma, j)\n", + " circuit.cx(i, j)\n", + " \n", + " # driver\n", + " for i in graph.nodes:\n", + " circuit.h(i)\n", + " circuit.rz(2.0*beta, i)\n", + " circuit.h(i)\n", + " \n", + " circuit.measure(graph.nodes, range(len(graph.nodes)))\n", + " \n", + " return circuit" + ] + }, + { + "cell_type": "markdown", + "id": "facial-trinidad", + "metadata": {}, + "source": [ + "## Run the Landscape\n", + "\n", + "Given a list of edges and a QPU- or QVM-based backend, generate the Max-Cut QAOA circuit, transpile it to a parametric circuit, and rapidly iterate through the landscape of (Ξ², 𝛾). For each job, we compute the average cost, which will become the $z$-axis of the landscape." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "criminal-childhood", + "metadata": {}, + "outputs": [], + "source": [ + "import itertools\n", + "from tqdm import tqdm\n", + "from qiskit import transpile\n", + "from qiskit.providers import Backend\n", + "from qiskit_rigetti.hooks.pre_execution import enable_active_reset\n", + "\n", + "def run_maxcut_qaoa_landscape(\n", + " backend: Backend,\n", + " edges: List[Tuple[int, int]],\n", + " width: int,\n", + " shots: int,\n", + " seed: int,\n", + ") -> np.ndarray:\n", + " graph = generate_ising_graph(edges, seed)\n", + " beta = Parameter(\"beta\")\n", + " gamma = Parameter(\"gamma\")\n", + " circuit = maxcut_qaoa_circuit(graph, beta, gamma)\n", + " transpiled = transpile(circuit, backend=backend)\n", + " \n", + " costs = []\n", + " angle_range = np.linspace(0, np.pi, width)\n", + " landscape = list(itertools.product(angle_range, angle_range))\n", + " \n", + " def to_array(bitstring: str) -> List[str]:\n", + " return [int(bit) for bit in bitstring]\n", + "\n", + " for b, g in tqdm(landscape):\n", + " results = backend.run(\n", + " transpiled.bind_parameters({beta: b, gamma: g}),\n", + " before_execute=[enable_active_reset], # enable active reset to speed up iteration on QPUs\n", + " shots=shots,\n", + " ).result()\n", + " bitstrings = np.array([to_array(bitstring) for bitstring in results.get_memory()])\n", + " costs.append(np.mean([bitstring_cut_weight(list(b), graph) for b in bitstrings]))\n", + "\n", + " return np.array(costs).reshape(width, width)" + ] + }, + { + "cell_type": "markdown", + "id": "respected-joining", + "metadata": {}, + "source": [ + "## Plot the Landscape\n", + "\n", + "Given results from running QAOA, plot the landscape and the max cost value (shown as a red dot)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "monthly-zambia", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "def plot_landscape(landscape: np.ndarray, *, device: str, edges: List[Tuple[int, int]],\n", + " width: int, shots: int):\n", + " max_x, max_y = (np.argmax(landscape) % width, np.argmax(landscape) // width)\n", + " plt.imshow(landscape, extent=[0, np.pi, np.pi, 0])\n", + " plt.plot((max_x + 0.5) * np.pi / width, (max_y + 0.5) * np.pi / width, 'ro')\n", + " plt.colorbar()\n", + " plt.xlabel('beta (radians)')\n", + " plt.ylabel('gamma (radians)')\n", + " plt.title(f'Max-Cut QAOA Landscape\\n{device}\\n{edges}\\nwidth = {width} shots = {shots}')\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "eastern-spell", + "metadata": {}, + "source": [ + "## Device Information\n", + "\n", + "We can execute our algorithm on either a QPU or a simulator." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "operating-pharmaceutical", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit_rigetti import RigettiQCSProvider\n", + "\n", + "provider = RigettiQCSProvider()\n", + "backend = provider.get_backend(name=\"Aspen-9\")\n", + "simulator = provider.get_simulator(num_qubits=3, noisy=False)" + ] + }, + { + "cell_type": "markdown", + "id": "analyzed-shift", + "metadata": {}, + "source": [ + "## Landscape Information\n", + "\n", + "In addition to providing the device that we want to run on, we need to provide some more information to build our QAOA landscape. The `width` parameter sets the resolution of the landscapeβ€”the width squared is the number of jobs we will run. The `shots` parameter specifies how many repetitions to perform for each (Ξ², 𝛾) angle pair. The `seed` parameter is used when randomly generating the edge weights of our graph, and we can reproduce the same graph by keeping the seed constant. Finally, the `edges` specify the qubits and the topology of the graph that we will run QAOA on. For this example, we use a line graph, but you can create more interesting topologies by changing the edge list." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fifth-revision", + "metadata": {}, + "outputs": [], + "source": [ + "width = 25\n", + "shots = 1000\n", + "seed = 19120623\n", + "edges_qpu = [(13, 14), (14, 15)] # edit as necessary\n", + "edges_sim = [(0, 1), (1, 2)] # edit as necessary" + ] + }, + { + "cell_type": "markdown", + "id": "timely-worthy", + "metadata": {}, + "source": [ + "## Run and Plot on QPU and QVM\n", + "\n", + "We run the QAOA algorithm on the QPU and the QVM, comparing the max value of each landscape, which should be nearly the same. Small differences can be attributed to gate infidelity and decoherence, and larger ones can come from the presence of more than one \"peak\" in the landscape (as seen by the presence of multiple yellow blobs)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "lesser-ecology", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 625/625 [18:47<00:00, 1.80s/it]\n", + "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 625/625 [02:38<00:00, 3.94it/s]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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uZVUq4rh4+ODJUuW4Pvvv8f3338Pf39/dO/eHUePHq3sqplFp9Nh9OjReOyxx9CyZUuT+arq57VYea+zKn9W//rrLzg6OsLOzg6vvPIKNm3ahICAAKN5q/rrSaWrcaup1mTBwcEGvyRCQkLQokULLF26FNOnT6/EmpGsZs2aoVmzZvrHISEhuHDhAj755BN89dVXlVgz84waNQonT57E3r17K7sqFaq811mVP6vNmjXD8ePHkZGRge+++w5RUVH4/fffTQYZVH1VqxYMd3d3WFlZITU11SA9NTUV3t7eRst4e3ublf9hIXOt97OxsUG7du1w/vz5iqhipTH1mjo7O8Pe3r6SavXgdOrUqUq9pjExMfj555+xa9cu+Pn5lZq3qn5eAfOu835V6bNqa2uLJk2aIDAwELGxsWjTpg0WLFhgNG9Vfj2pbNUqwLC1tUVgYCB27NihT9PpdNixY4fJPsDg4GCD/AAQFxdnMv/DQuZa76fVavHXX3/Bx8enoqpZKarqa2opx48frxKvqRACMTEx2LRpE3bu3ImGDRuWWaYqvrYy13m/qvxZ1el0yM/PN7qvKr6eZIbKHmVqaevWrRN2dnZi1apV4vTp0+Kll14Srq6uIiUlRQghxJAhQ8S7776rz79v3z5hbW0t5s6dK86cOSMmT54sbGxsxF9//VVZl1Bu5l7r1KlTxbZt28SFCxfEkSNHxIABA4RGoxGnTp2qrEsol7t374pjx46JY8eOCQBi3rx54tixYyIxMVEIIcS7774rhgwZos9/8eJF4eDgIN5++21x5swZsWjRImFlZSW2bt1aWZdQbuZe6yeffCI2b94s/vnnH/HXX3+JN998U6jVavHbb79V1iWU26uvvipcXFxEfHy8SE5O1m85OTn6PNXh8ypznVX1s/ruu++K33//XVy6dEmcOHFCvPvuu0KlUont27cLIarH60nlV+0CDCGEWLhwoahXr56wtbUVnTp1En/88Yd+X7du3URUVJRB/m+//VY88sgjwtbWVjz66KPil19+ecA1lmfOtY4ePVqf18vLS/Tu3VscPXq0EmptnuJbMe/fiq8tKipKdOvWrUSZtm3bCltbW9GoUSOxcuXKB15vGeZe66xZs0Tjxo2FRqMRtWvXFt27dxc7d+6snMqbydh1AjB4rarD51XmOqvqZ/U///mPqF+/vrC1tRUe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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "landscape_qpu = run_maxcut_qaoa_landscape(backend, edges_qpu, width, shots, seed)\n", + "landscape_sim = run_maxcut_qaoa_landscape(simulator, edges_sim, width, shots, seed)\n", + "\n", + "plot_landscape(landscape_qpu, device=backend.name(), edges=edges_qpu, width=width, shots=shots)\n", + "plot_landscape(landscape_sim, device=simulator.name(), edges=edges_sim, width=width, shots=shots)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.7.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/docs/examples/qaoa_qiskit.ipynb b/docs/examples/qaoa_qiskit.ipynb new file mode 100644 index 0000000..62d8342 --- /dev/null +++ b/docs/examples/qaoa_qiskit.ipynb @@ -0,0 +1,714 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "tags": [ + "remove_cell" + ] + }, + "source": [ + "# Solving combinatorial optimization problems using QAOA" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> ℹ️ Originally from [the Qiskit textbook](https://qiskit.org/textbook/ch-applications/qaoa.html), this notebook demonstrates how to take existing Qiskit work and run it on a Rigetti backend.\n", + "\n", + "In this tutorial, we introduce combinatorial optimization problems, explain approximate optimization algorithms, explain how the Quantum Approximate Optimization Algorithm (QAOA) works and present the implementation of an example that can be run on a simulator or on a real quantum system." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Combinatorial Optimization Problem\n", + "\n", + "Combinatorial optimization problems involve finding an optimal object out of a finite set of objects. We would focus on problems that involve \n", + "finding \"optimal\" bitstrings composed of 0's and 1's among a finite set of bitstrings. One such problem corresponding to a graph is the Max-Cut problem. \n", + "\n", + "### Max-Cut problem\n", + "A Max-Cut problem involves partitioning nodes of a graph into two sets, such that the number of edges between the sets is maximum. The example below\n", + "has a graph with four nodes and some of the ways in which it can be partitioned into two sets, \"red\" and \"blue\" is shown.\n", + "\n", + "![](https://qiskit.org/textbook/ch-applications/images/qaoa_maxcut.svg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For 4 nodes, as each node can be assigned to either the \"red\" or \"blue\" sets, there are $2^4=16$ possible assigments.\n", + "\n", + "Out of which we have to find one that gives maximum number of edges between the sets \"red\" and \"blue\". The number of such edges between two sets in the figure, as we go from left to right, are 0, 2, 2, and 4. We can see, after enumerating all possible $2^4=16$ assignments, that the rightmost figure is the assignment that gives the maximum number of edges between the two sets. Hence if we encode \"red\" as 0 and \"blue\" as 1, the bitstrings \"0101\" and \"1010\" that represent the assignment of nodes to either set are the solutions. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you may have realized, as the number of nodes in the graph increases, the number of possible assignments \n", + "that you have to examine to find the solution increases exponentially." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## QAOA\n", + "\n", + "QAOA (Quantum Approximate Optimization Algorithm) introduced by Farhi et al.[1] is a quantum algorithm that attempts to \n", + "solve such combinatorial problems.
\n", + "\n", + "It is a variational algorithm that uses a unitary $U(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma})$ characteized by the parameters \n", + "$(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma})$ to prepare a quantum state $\\lvert \\psi(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma}) \\rangle$. \n", + "The goal of the algorithm\n", + "is to find optimal parameters $(\\boldsymbol{\\beta}_{opt}, \\boldsymbol{\\gamma}_{opt})$ such that the \n", + "quantum state $\\lvert \\psi(\\boldsymbol{\\beta}_{opt}, \\boldsymbol{\\gamma}_{opt}) \\rangle$ encodes the solution to the problem. \n", + "\n", + "The unitary $U(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma})$ has a specific form and is composed of two unitaries \n", + "$U(\\boldsymbol{\\beta}) = e^{-i \\boldsymbol{\\beta} H_B}$ and $U(\\boldsymbol{\\gamma}) = e^{-i \\boldsymbol{\\gamma} H_P}$\n", + "where $H_B$ is the mixing Hamiltonian and $H_P$ is the problem Hamiltonian. Such a choice of unitary drives its inspiration \n", + "from a related scheme called quantum annealing.\n", + "\n", + "The state is prepared by applying these unitaries as alternating blocks of the two unitaries applied $p$ times such that \n", + "\n", + "$$\\lvert \\psi(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma}) \\rangle = \\underbrace{U(\\boldsymbol{\\beta}) U(\\boldsymbol{\\gamma}) \n", + " \\cdots U(\\boldsymbol{\\beta}) U(\\boldsymbol{\\gamma})}_{p \\; \\text{times}} \n", + "\\lvert \\psi_0 \\rangle$$\n", + "\n", + "where $\\lvert \\psi_0 \\rangle$ is a suitable initial state. \n", + "\n", + "We will demonstrate these steps using the Max-Cut problem discussed above. For that we would first define\n", + "the underlying graph of the problem shown above." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import networkx as nx\n", + "\n", + "G = nx.Graph()\n", + "G.add_nodes_from([0, 1, 2, 3])\n", + "G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0)])\n", + "nx.draw(G, with_labels=True, alpha=0.8, node_size=500)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The problem Hamiltonian specific to the Max-Cut problem up to a constant here is:\n", + "\n", + "$$\n", + "H_P = \\frac{1}{2}\\big(Z_0 \\otimes Z_1 \\otimes I_2 \\otimes I_3\\big) + \n", + " \\frac{1}{2}\\big(I_0 \\otimes Z_1 \\otimes Z_2 \\otimes I_3\\big) +\n", + " \\frac{1}{2}\\big(Z_0 \\otimes I_1 \\otimes I_2 \\otimes Z_3\\big) +\n", + " \\frac{1}{2}\\big(I_0 \\otimes I_1 \\otimes Z_2 \\otimes Z_3\\big)\n", + "$$\n", + "\n", + "To contruct such a Hamiltonian for a problem, one needs to follow a few steps that we'll cover in later sections of this page.\n", + "\n", + "And the mixer Hamiltonian $H_B$ is usually of the form:\n", + "\n", + "$$\n", + "H_B = \\big(X_0 \\otimes I_1 \\otimes I_2 \\otimes I_3 \\big) + \n", + " \\big(I_0 \\otimes X_1 \\otimes I_2 \\otimes I_3 \\big) +\n", + " \\big(I_0 \\otimes I_1 \\otimes X_2 \\otimes I_3 \\big) +\n", + " \\big(I_0 \\otimes I_1 \\otimes I_2 \\otimes X_3 \\big)\n", + "$$\n", + "\n", + "As individual terms in the summation of $H_P$ and $H_B$ both commute, we can write the unitaries as:\n", + "\n", + "$$ U(H_B) = e^{-i \\beta H_B} = e^{-i \\beta X_0}e^{-i \\beta X_1}e^{-i \\beta X_2}e^{-i \\beta X_3}.$$\n", + "\n", + "Notice that each term in the product above corresponds to an X-rotation on each qubit. And we can write $U(H_P)$ as:\n", + "\n", + "$$ U(H_P) = e^{-i \\gamma H_P} = e^{-i \\gamma Z_0 Z_1}e^{-i \\gamma Z_1 Z_2}e^{-i \\gamma Z_2 Z_3}e^{-i \\gamma Z_0 Z_3}$$\n", + "\n", + "Let's now examine what the circuits of the two unitaries look like. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Mixing Unitary" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”\n",
+       "q_0: ─ RX(2*$\\beta$) β”œ\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n",
+       "q_1: ─ RX(2*$\\beta$) β”œ\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n",
+       "q_2: ─ RX(2*$\\beta$) β”œ\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n",
+       "q_3: ─ RX(2*$\\beta$) β”œ\n",
+       "     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
" + ], + "text/plain": [ + " β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”\n", + "q_0: ─ RX(2*$\\beta$) β”œ\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n", + "q_1: ─ RX(2*$\\beta$) β”œ\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n", + "q_2: ─ RX(2*$\\beta$) β”œ\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n", + "q_3: ─ RX(2*$\\beta$) β”œ\n", + " β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister\n", + "from qiskit import Aer, execute\n", + "from qiskit.circuit import Parameter\n", + "\n", + "# Adjacency is essentially a matrix which tells you which nodes are\n", + "# connected. This matrix is given as a sparse matrix, so we need to\n", + "# convert it to a dense matrix\n", + "adjacency = nx.adjacency_matrix(G).todense()\n", + "\n", + "nqubits = 4\n", + "\n", + "beta = Parameter(\"$\\\\beta$\")\n", + "qc_mix = QuantumCircuit(nqubits)\n", + "for i in range(0, nqubits):\n", + " qc_mix.rx(2 * beta, i)\n", + " \n", + "qc_mix.draw()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Problem Unitary" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
                                  β–‘                              β–‘      Β»\n",
+       "q_0: ──■──────────────────────■───░───■──────────────────────■───░──────»\n",
+       "     β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘   β”‚                      β”‚   β–‘      Β»\n",
+       "q_1: ─ X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β–‘β”€β”€β”€β– β”€β”€Β»\n",
+       "     β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘   β”‚                      β”‚   β–‘ β”Œβ”€β”΄β”€β”Β»\n",
+       "q_2: ─────────────────────────────░───┼──────────────────────┼───░── X β”œΒ»\n",
+       "                                  β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β””β”€β”€β”€β”˜Β»\n",
+       "q_3: ─────────────────────────────░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”€β”€β”€Β»\n",
+       "                                  β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘      Β»\n",
+       "Β«                             β–‘                              β–‘ \n",
+       "Β«q_0: ────────────────────────░──────────────────────────────░─\n",
+       "Β«                             β–‘                              β–‘ \n",
+       "Β«q_1: ────────────────────■───░──────────────────────────────░─\n",
+       "Β«     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘                              β–‘ \n",
+       "Β«q_2: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β– β”€β”€β”€β–‘β”€\n",
+       "Β«     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ \n",
+       "Β«q_3: ────────────────────────░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€\n",
+       "Β«                             β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ 
" + ], + "text/plain": [ + " β–‘ β–‘ Β»\n", + "q_0: ──■──────────────────────■───░───■──────────────────────■───░──────»\n", + " β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β”‚ β”‚ β–‘ Β»\n", + "q_1: ─ X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β–‘β”€β”€β”€β– β”€β”€Β»\n", + " β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”‚ β”‚ β–‘ β”Œβ”€β”΄β”€β”Β»\n", + "q_2: ─────────────────────────────░───┼──────────────────────┼───░── X β”œΒ»\n", + " β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β””β”€β”€β”€β”˜Β»\n", + "q_3: ─────────────────────────────░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”€β”€β”€Β»\n", + " β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ Β»\n", + "Β« β–‘ β–‘ \n", + "Β«q_0: ────────────────────────░──────────────────────────────░─\n", + "Β« β–‘ β–‘ \n", + "Β«q_1: ────────────────────■───░──────────────────────────────░─\n", + "Β« β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β–‘ \n", + "Β«q_2: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β– β”€β”€β”€β–‘β”€\n", + "Β« β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ \n", + "Β«q_3: ────────────────────────░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€\n", + "Β« β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gamma = Parameter(\"$\\\\gamma$\")\n", + "qc_p = QuantumCircuit(nqubits)\n", + "for pair in list(G.edges()): # pairs of nodes\n", + " qc_p.rzz(2 * gamma, pair[0], pair[1])\n", + " qc_p.barrier()\n", + " \n", + "qc_p.decompose().draw()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Initial State\n", + "\n", + "The initial state used during QAOA is usually an equal superposition of all the basis states i.e.\n", + "\n", + "$$\\lvert \\psi_0 \\rangle = \\bigg(\\frac{1}{\\sqrt{2}}\\big(\\lvert 0 \\rangle + \\lvert 1 \\rangle\\big)\\bigg)^{\\otimes n}$$\n", + "\n", + "Such a state, when number of qubits is 4 ($n=4$), can be prepared by applying Hadamard gates starting from an all zero state as shown in \n", + "the circuit below. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
     β”Œβ”€β”€β”€β”\n",
+       "q_0: ─ H β”œ\n",
+       "     β”œβ”€β”€β”€β”€\n",
+       "q_1: ─ H β”œ\n",
+       "     β”œβ”€β”€β”€β”€\n",
+       "q_2: ─ H β”œ\n",
+       "     β”œβ”€β”€β”€β”€\n",
+       "q_3: ─ H β”œ\n",
+       "     β””β”€β”€β”€β”˜
" + ], + "text/plain": [ + " β”Œβ”€β”€β”€β”\n", + "q_0: ─ H β”œ\n", + " β”œβ”€β”€β”€β”€\n", + "q_1: ─ H β”œ\n", + " β”œβ”€β”€β”€β”€\n", + "q_2: ─ H β”œ\n", + " β”œβ”€β”€β”€β”€\n", + "q_3: ─ H β”œ\n", + " β””β”€β”€β”€β”˜" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qc_0 = QuantumCircuit(nqubits)\n", + "for i in range(0, nqubits):\n", + " qc_0.h(i)\n", + " \n", + "qc_0.draw()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The QAOA circuit\n", + "\n", + "So far we have seen that the preparation of a quantum state during QAOA is composed of three elements\n", + "- Preparing an initial state\n", + "- Applying the unitary $U(H_P) = e^{-i \\gamma H_P}$ corresponding to the problem Hamiltonian\n", + "- Then, applying the mixing unitary $U(H_B) = e^{-i \\beta H_B}$\n", + "\n", + "Let's see what it looks like for the example problem:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β–‘      Β»\n",
+       "q_0: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β– β”€β”€β”€β–‘β”€β”€β”€β– β”€β”€Β»\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘   β”‚  Β»\n",
+       "q_1: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€ X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”Όβ”€β”€Β»\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘   β”‚  Β»\n",
+       "q_2: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€β”€β”Όβ”€β”€Β»\n",
+       "     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                             β–‘ β”Œβ”€β”΄β”€β”Β»\n",
+       "q_3: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€ X β”œΒ»\n",
+       "     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             β–‘ β””β”€β”€β”€β”˜Β»\n",
+       "Β«                             β–‘                              β–‘      Β»\n",
+       "Β«q_0: ────────────────────■───░──────────────────────────────░──────»\n",
+       "Β«                         β”‚   β–‘                              β–‘      Β»\n",
+       "Β«q_1: ────────────────────┼───░───■──────────────────────■───░──────»\n",
+       "Β«                         β”‚   β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘      Β»\n",
+       "Β«q_2: ────────────────────┼───░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β– β”€β”€Β»\n",
+       "Β«     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”Œβ”€β”΄β”€β”Β»\n",
+       "Β«q_3: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€ X β”œΒ»\n",
+       "Β«     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘                              β–‘ β””β”€β”€β”€β”˜Β»\n",
+       "Β«                             β–‘ \n",
+       "Β«q_0: ────────────────────────░─\n",
+       "Β«                             β–‘ \n",
+       "Β«q_1: ────────────────────────░─\n",
+       "Β«                             β–‘ \n",
+       "Β«q_2: ────────────────────■───░─\n",
+       "Β«     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ \n",
+       "Β«q_3: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€\n",
+       "Β«     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ 
" + ], + "text/plain": [ + " β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–‘ Β»\n", + "q_0: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β– β”€β”€β”€β–‘β”€β”€β”€β– β”€β”€Β»\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β”‚ Β»\n", + "q_1: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€ X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”Όβ”€β”€Β»\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”‚ Β»\n", + "q_2: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€β”€β”Όβ”€β”€Β»\n", + " β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β–‘ β”Œβ”€β”΄β”€β”Β»\n", + "q_3: ─ U2(0,Ο€) β”œβ”€ R(2*$\\beta$,0) β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€ X β”œΒ»\n", + " β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–‘ β””β”€β”€β”€β”˜Β»\n", + "Β« β–‘ β–‘ Β»\n", + "Β«q_0: ────────────────────■───░──────────────────────────────░──────»\n", + "Β« β”‚ β–‘ β–‘ Β»\n", + "Β«q_1: ────────────────────┼───░───■──────────────────────■───░──────»\n", + "Β« β”‚ β–‘ β”Œβ”€β”΄β”€β”β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ Β»\n", + "Β«q_2: ────────────────────┼───░── X β”œβ”€ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β– β”€β”€Β»\n", + "Β« β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ β””β”€β”€β”€β”˜β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β”Œβ”€β”΄β”€β”Β»\n", + "Β«q_3: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–‘β”€β”€ X β”œΒ»\n", + "Β« β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ β–‘ β””β”€β”€β”€β”˜Β»\n", + "Β« β–‘ \n", + "Β«q_0: ────────────────────────░─\n", + "Β« β–‘ \n", + "Β«q_1: ────────────────────────░─\n", + "Β« β–‘ \n", + "Β«q_2: ────────────────────■───░─\n", + "Β« β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”Œβ”€β”΄β”€β” β–‘ \n", + "Β«q_3: ─ RZ(2*$\\gamma$) β”œβ”€ X β”œβ”€β–‘β”€\n", + "Β« β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β””β”€β”€β”€β”˜ β–‘ " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "qc_qaoa = QuantumCircuit(nqubits)\n", + "\n", + "qc_qaoa.append(qc_0, [i for i in range(0, nqubits)])\n", + "qc_qaoa.append(qc_mix, [i for i in range(0, nqubits)])\n", + "qc_qaoa.append(qc_p, [i for i in range(0, nqubits)])\n", + "\n", + "qc_qaoa.decompose().decompose().draw()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The next step is to find the optimal parameters $(\\boldsymbol{\\beta_{opt}}, \\boldsymbol{\\gamma_{opt}})$ such that the expectation value\n", + "\n", + "$$ \\langle \\psi(\\boldsymbol{\\beta}_{opt}, \\boldsymbol{\\gamma}_{opt}) \\rvert H_P \\lvert \n", + "\\psi(\\boldsymbol{\\beta}_{opt}, \\boldsymbol{\\gamma}_{opt}) \\rangle $$\n", + "\n", + "is minimized. Such an expectation can be obtained by doing measurement in the Z-basis. We use a classical optimization algorithm to find the optimal parameters. Following steps are involved as shown in the schematic\n", + "\n", + "\n", + "\n", + "1. Initialize $\\boldsymbol{\\beta}$ and $\\boldsymbol{\\gamma}$ to suitable real values.\n", + "2. Repeat until some suitable convergence criteria is met:\n", + " 1. Prepare the state $\\lvert \\psi(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma}) \\rangle$ using qaoa circuit\n", + " 2. Measure the state in standard basis\n", + " 3. Compute $\\langle \\psi(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma}) \\rvert H_P \\lvert \\psi(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma}) \\rangle$ \n", + " 4. Find new set of parameters $(\\boldsymbol{\\beta}_{new}, \\boldsymbol{\\gamma}_{new})$ using a classical optimization algorithm\n", + " 5. Set current parameters $(\\boldsymbol{\\beta}, \\boldsymbol{\\gamma})$ equal to the new parameters \n", + " $(\\boldsymbol{\\beta}_{new}, \\boldsymbol{\\gamma}_{new})$\n", + "\n", + "The code below implements the steps mentioned above." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def maxcut_obj(x, G):\n", + " \"\"\"\n", + " Given a bitstring as a solution, this function returns\n", + " the number of edges shared between the two partitions\n", + " of the graph.\n", + " \n", + " Args:\n", + " x: str\n", + " solution bitstring\n", + " \n", + " G: networkx graph\n", + " \n", + " Returns:\n", + " obj: float\n", + " Objective\n", + " \"\"\"\n", + " obj = 0\n", + " for i, j in G.edges():\n", + " if x[i] != x[j]:\n", + " obj -= 1\n", + " \n", + " return obj\n", + "\n", + "\n", + "def compute_expectation(counts, G):\n", + " \n", + " \"\"\"\n", + " Computes expectation value based on measurement results\n", + " \n", + " Args:\n", + " counts: dict\n", + " key as bitstring, val as count\n", + " \n", + " G: networkx graph\n", + " \n", + " Returns:\n", + " avg: float\n", + " expectation value\n", + " \"\"\"\n", + " \n", + " avg = 0\n", + " sum_count = 0\n", + " for bitstring, count in counts.items():\n", + " \n", + " obj = maxcut_obj(bitstring, G)\n", + " avg += obj * count\n", + " sum_count += count\n", + " \n", + " return avg/sum_count\n", + "\n", + "\n", + "# We will also bring the different circuit components that\n", + "# build the qaoa circuit under a single function\n", + "def create_qaoa_circ(G, theta):\n", + " \n", + " \"\"\"\n", + " Creates a parametrized qaoa circuit\n", + " \n", + " Args: \n", + " G: networkx graph\n", + " theta: list\n", + " unitary parameters\n", + " \n", + " Returns:\n", + " qc: qiskit circuit\n", + " \"\"\"\n", + " \n", + " nqubits = len(G.nodes())\n", + " p = len(theta)//2 # number of alternating unitaries\n", + " qc = QuantumCircuit(nqubits)\n", + " \n", + " beta = theta[:p]\n", + " gamma = theta[p:]\n", + " \n", + " # initial_state\n", + " for i in range(0, nqubits):\n", + " qc.h(i)\n", + " \n", + " for irep in range(0, p):\n", + " \n", + " # problem unitary\n", + " for pair in list(G.edges()):\n", + " qc.rzz(2 * gamma[irep], pair[0], pair[1])\n", + "\n", + " # mixer unitary\n", + " for i in range(0, nqubits):\n", + " qc.rx(2 * beta[irep], i)\n", + " \n", + " qc.measure_all()\n", + " \n", + " return qc\n", + "\n", + "\n", + "from qiskit_rigetti import RigettiQCSProvider\n", + "provider = RigettiQCSProvider()\n", + "\n", + "# Finally we write a function that executes the circuit on the chosen backend\n", + "def get_expectation(G, p, shots=512):\n", + " \n", + " \"\"\"\n", + " Runs parametrized circuit\n", + " \n", + " Args:\n", + " G: networkx graph\n", + " p: int,\n", + " Number of repetitions of unitaries\n", + " \"\"\"\n", + " backend = provider.get_simulator(num_qubits=len(G.nodes), noisy=False) # or provider.get_backend(name='Aspen-9')\n", + " \n", + " def execute_circ(theta):\n", + " \n", + " qc = create_qaoa_circ(G, theta)\n", + " counts = backend.run(qc, shots=512).result().get_counts()\n", + " \n", + " return compute_expectation(counts, G)\n", + " \n", + " return execute_circ" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " fun: -2.91796875\n", + " maxcv: 0.0\n", + " message: 'Optimization terminated successfully.'\n", + " nfev: 32\n", + " status: 1\n", + " success: True\n", + " x: array([2.06891637, 1.16583915])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from scipy.optimize import minimize\n", + "\n", + "\n", + "expectation = get_expectation(G, p=1)\n", + "\n", + "res = minimize(expectation, \n", + " [1.0, 1.0], \n", + " method='COBYLA')\n", + "res" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that different choices of classical optimizers are present in qiskit. We choose [COBYLA](https://github.com/Qiskit/qiskit-terra/blob/main/qiskit/algorithms/optimizers/cobyla.py) as our classical optimization algorithm here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Analyzing the result" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAc0AAAFLCAYAAAC0rNfYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABEa0lEQVR4nO3deXhU5fn/8fdNAoEIVBYBSVDAAJogwRiMWATciqLSat1wr1ZFixt1+9alakvV1h+1LSqttVVRwaUuaJWCCyAWwYAgiwLKUoIICCigEEh4fn88J3EyJDA7E/i8rmsuZs45c89zzoS5z3m2Y845REREZPca7OkCiIiI1BdKmiIiIhFS0hQREYmQkqaIiEiElDRFREQipKQpIiISocw9XYA9qXXr1q5jx457uhgiIpJGZs6c+ZVz7oDa1u3TSbNjx46Ulpbu6WKIiEgaMbPlda1T9ayIiEiElDRFREQilPKkaWbXmNlSM9tqZjPN7NhdbNvPzP5rZuvMbIuZfWpmN4Vtc4WZvWdmG8zsazN718z6JH9PRERkX5PSpGlm5wJ/An4HHAH8F3jTzA6q4y2bgT8DfYF84LfAPWZ2Tcg2/YHngOOBEmAh8B8z65KMfRARkX2XpXLCdjObDnzsnLsiZNli4EXn3P9FGOMloNw5N7iO9QasAoY75/6yq1jFxcVOHYFERCSUmc10zhXXti5lV5pm1gg4EpgQtmoCcEyEMY4Itp28i80aAY2BDTEUU0REpE6pHHLSGsgAVoctXw2cuKs3mlkZcAC+vPc450btYvPf4qt1x9UR60rgSoD27dszadIkADp37kyzZs2YM2cOAK1ataKgoIApU6YAkJmZSZ8+fZg1axYbN24EoLi4mNWrV7NixQoAunTpQlZWFvPmzQOgTZs2dO3alalTpwKQlZVF7969KS0tZfPmzQCUlJRQVlbGypUrAejWrRsZGRksWLAAgHbt2tGpUyemTZsGQJMmTSgpKWH69Ols2bIFgN69e7N06VK+/PJLAPLz86msrGThwoUA5OTkkJuby/Tp0wFo2rQpxcXFTJs2jfLycgD69OnDokWLWLNmDQDdu3envLycxYsXA9ChQwfatm1bPUSnefPmFBUVMXXqVCoqKgDo27cv8+fPZ926dQAUFhayadMmlixZAvghPi1btmTWrFkAtGjRgsLCQiZPnoxzDjOjX79+zJkzhw0b/DlPUVER69evZ9myZfqe9D3pe9L3lJLvaVdSVj1rZu2BlUA/59yUkOV3ARc457rt4r2dgKbA0cADwPXOudG1bHc98BvgROfcjN2VSdWzIiISblfVs6m80vwKqATahi1vC3y5qzc655YGT+eaWVvgbqBG0jSzG/AJ85RIEqaIiEi0Utam6ZzbBswETgpbdRK+F22kGgBZoQvMbBg+YZ7qnJsaTzlFRETqkupp9EYAo81sBvA+MARoD4wCMLOnAJxzFwevrwWW4oeRgB96chPwSFVAM7sZGA5cCCwys3bBqi3OuW+SvUMiIrLvSGnSdM49Z2atgDuAA4F5wEDnXNU8f+HjNTPwbZgdgQrgc+A2giQb+AXQED9WM9STwKUJLL6IiOzjUjpOM92oI5CIiIRLi3GaIiIi9Z2SpoiISISUNEVERCKkpCkiIhIhJU0REZEIKWmKiIhESElTREQkQkqaIiIiEVLSFBERiZCSpojUS+PHj6dbt27k5eVx//3377R+xIgR5Ofn06NHD0444QSWL/ezdb777rv07Nmz+tG4cWNeeeUVAC699FI6depUvW727Nkp3COpDzSNnqbRE6l3Kisr6dq1KxMnTiQ3N5devXoxZswY8vPzq7d59913KSkpITs7m0cffZRJkybx3HM1p6hev349eXl5lJWVkZ2dzaWXXsppp53GWWedlepdkjSiafREZK8yY8YM8vLy6Ny5M40aNeK8887j1VdfrbHNcccdR3Z2NgBHH300ZWVlO8V58cUXOeWUU6q3E9kdJU0RqXdWrlxJhw4dql/n5uaycuXKOrd//PHHOeWUU3ZaPnbsWAYPHlxj2e23306PHj248cYbKS8vT1yhZa+gpCkie7Wnn36a0tJSbr755hrLV61axdy5cxkwYED1svvuu49PP/2UDz/8kPXr1/PAAw+kuriS5pQ0RaTeycnJYcWKFdWvy8rKyMnJ2Wm7t956i+HDhzNu3DiysrJqrHv++ec544wzaNiwYfWyAw88EDMjKyuLn/3sZ8yYMSN5OyH1kpKmiNQ7vXr1YvHixSxdupRt27YxduxYBg0aVGObjz76iKuuuopx48bRpk2bnWKMGTNmp6rZVatWAeCc45VXXqF79+7J2wmplzL3dAFERKKVmZnJyJEjGTBgAJWVlVx22WUUFBRw1113UVxczKBBg7j55pvZvHkzZ599NgAHHXQQ48aNA2DZsmWsWLGCfv361Yh7wQUXsHbtWpxz9OzZk1GjRqV83yS9aciJhpyIiEgIDTkRERFJACVNERGRCClpioiIREhJU0REJEJKmiIiIhFS0hQREYmQkqaIiEiElDRFREQipKQpIiISISVNERGRCClpioiIREhJU/Y548ePp1u3buTl5XH//ffvtH7EiBHk5+fTo0cPTjjhBJYvX169LiMjg549e9KzZ88ad9W44IIL6NatG927d+eyyy5j+/btKdkXEUktTdiuCdv3KZWVlXTt2pWJEyeSm5tLr169GDNmDPn5+dXbvPvuu5SUlJCdnc2jjz7KpEmTeO655wBo2rQpmzdv3inuG2+8wSmnnALA+eefT9++fbn66qtTs1Oykyseim77x25IRimkvtKE7SKBGTNmkJeXR+fOnWnUqBHnnXcer776ao1tjjvuOLKzswE4+uijKSsr223cgQMHYmaYGUcddVRE7xGR+kdJU/YpK1eupEOHDtWvc3NzWblyZZ3bP/7449VXkABbt26luLiYo48+mldeeWWn7bdv387o0aM5+eSTE1puEUkPugm1SB2efvppSktLmTx5cvWy5cuXk5OTw5IlSzj++OM5/PDDOeSQQ6rXX3PNNfTt25djjz12TxRZRJJMV5qyT8nJyWHFihXVr8vKysjJydlpu7feeovhw4czbtw4srKyarwfoHPnzvTv35+PPvqoet0999zD2rVrGTFiRBL3QET2JCVN2af06tWLxYsXs3TpUrZt28bYsWNr9IIF+Oijj7jqqqsYN24cbdq0qV6+YcMGysvLAfjqq694//33qzsQ/f3vf+c///kPY8aMoUED/bcS2Vupelb2KZmZmYwcOZIBAwZQWVnJZZddRkFBAXfddRfFxcUMGjSIm2++mc2bN3P22WcDcNBBBzFu3Dg++eQTrrrqKho0aMCOHTu47bbbqpPmkCFDOPjgg+nduzcAZ555Jnfdddce208RSQ4NOdGQE5G9joacSDw05ERERCQBlDRFREQipKQpIiISISVNERGRCClpioiIREhJU0REJEJKmiIiIhFS0hQREYmQkqaIiEiElDRFREQipKQpIiISIU3YLhIimjlLNV+pyL5HV5oiIiIRUtIUERGJkJKmiIhIhJQ0RUREIqSkKSIiEqGUJ00zu8bM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\n", + "text/plain": [ + "
" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from qiskit.visualization import plot_histogram\n", + "\n", + "backend = provider.get_simulator(num_qubits=len(G.nodes), noisy=False)\n", + "\n", + "qc_res = create_qaoa_circ(G, res.x)\n", + "\n", + "counts = backend.run(qc_res, shots=512).result().get_counts()\n", + "\n", + "plot_histogram(counts)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we notice that the bitstrings \"0101\" and \"1010\" have the highest probability and are indeed the assignments of the graph (we started with) that gives 4 edges between the two partitions. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "1. Farhi, Edward, Jeffrey Goldstone, and Sam Gutmann. \"A quantum approximate optimization algorithm.\" arXiv preprint [arXiv:1411.4028 (2014)](https://arxiv.org/abs/1411.4028).\n", + "2. Goemans, Michel X., and David P. Williamson. [Journal of the ACM (JACM) 42.6 (1995): 1115-1145](http://www-math.mit.edu/~goemans/PAPERS/maxcut-jacm.pdf).\n", + "3. Garey, Michael R.; David S. Johnson (1979). Computers and Intractability: A Guide to the Theory of NP-Completeness. W. H. Freeman. ISBN 0-7167-1045-5\n", + "4. Kandala, Abhinav, et al. \"Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets.\" [Nature 549.7671 (2017): 242](https://www.nature.com/articles/nature23879).\n", + "5. Farhi, Edward, et al. \"Quantum algorithms for fixed qubit architectures.\" arXiv preprint [arXiv:1703.06199 (2017)](https://arxiv.org/abs/1703.06199).\n", + "6. Spall, J. C. (1992), [IEEE Transactions on Automatic Control, vol. 37(3), pp. 332–341](https://ieeexplore.ieee.org/document/119632).\n", + "7. Michael Streif and Martin Leib \"Training the quantum approximate optimization algorithm without access to a quantum processing unit\" (2020) [Quantum Sci. Technol. 5 034008](https://doi.org/10.1088/2058-9565/ab8c2b)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.7.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/index.md b/docs/index.md index a53452e..8e815ff 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,6 +9,14 @@ This documentation supports light β˜€οΈ and dark πŸŒ™ modes and will automatica :end-before: Development ``` +```{toctree} + :maxdepth: 1 + :caption: Examples + +examples/qaoa_qiskit.ipynb +examples/qaoa_pyquil.ipynb +``` + ```{toctree} :maxdepth: 2 :caption: API Reference diff --git a/poetry.lock b/poetry.lock index a357a1b..709829c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -14,6 +14,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "appnope" +version = "0.1.2" +description = "Disable App Nap on macOS >= 10.9" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "astroid" version = "2.6.3" @@ -28,6 +36,14 @@ typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpyth typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} wrapt = ">=1.11,<1.13" +[[package]] +name = "async-generator" +version = "1.10" +description = "Async generators and context managers for Python 3.5+" +category = "main" +optional = true +python-versions = ">=3.5" + [[package]] name = "atomicwrites" version = "1.4.0" @@ -61,6 +77,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pytz = ">=2015.7" +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "beautifulsoup4" version = "4.9.3" @@ -98,6 +122,19 @@ typing-extensions = ">=3.7.4" colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +[[package]] +name = "bleach" +version = "3.3.1" +description = "An easy safelist-based HTML-sanitizing tool." +category = "main" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +packaging = "*" +six = ">=1.9.0" +webencodings = "*" + [[package]] name = "cached-property" version = "1.5.2" @@ -194,6 +231,14 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +category = "main" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "dill" version = "0.3.4" @@ -245,6 +290,14 @@ category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "entrypoints" +version = "0.3" +description = "Discover and load entry points from installed packages." +category = "main" +optional = true +python-versions = ">=2.7" + [[package]] name = "fastdtw" version = "0.3.4" @@ -402,6 +455,46 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "ipython" +version = "7.25.0" +description = "IPython: Productive Interactive Computing" +category = "main" +optional = true +python-versions = ">=3.7" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = "*" +traitlets = ">=4.2" + +[package.extras] +all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["notebook", "ipywidgets"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] + +[[package]] +name = "ipython-genutils" +version = "0.2.0" +description = "Vestigial utilities from IPython" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "iso8601" version = "0.1.16" @@ -410,6 +503,21 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "jedi" +version = "0.18.0" +description = "An autocompletion tool for Python that can be used for text editors." +category = "main" +optional = true +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] + [[package]] name = "jinja2" version = "3.0.1" @@ -450,6 +558,49 @@ six = ">=1.11.0" format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] +[[package]] +name = "jupyter-client" +version = "6.2.0" +description = "Jupyter protocol implementation and client libraries" +category = "main" +optional = true +python-versions = ">=3.6.1" + +[package.dependencies] +jupyter-core = ">=4.6.0" +nest-asyncio = ">=1.5" +python-dateutil = ">=2.1" +pyzmq = ">=13" +tornado = ">=4.1" +traitlets = "*" + +[package.extras] +doc = ["sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] +test = ["async-generator", "ipykernel", "ipython", "mock", "pytest-asyncio", "pytest-timeout", "pytest", "mypy", "pre-commit", "jedi (<0.18)"] + +[[package]] +name = "jupyter-core" +version = "4.7.1" +description = "Jupyter core package. A base package on which Jupyter projects rely." +category = "main" +optional = true +python-versions = ">=3.6" + +[package.dependencies] +pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\""} +traitlets = "*" + +[[package]] +name = "jupyterlab-pygments" +version = "0.1.2" +description = "Pygments theme using JupyterLab CSS variables" +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +pygments = ">=2.4.1,<3" + [[package]] name = "lark" version = "0.11.3" @@ -525,6 +676,17 @@ category = "main" optional = true python-versions = ">=3.6" +[[package]] +name = "matplotlib-inline" +version = "0.1.2" +description = "Inline Matplotlib backend for Jupyter" +category = "main" +optional = true +python-versions = ">=3.5" + +[package.dependencies] +traitlets = "*" + [[package]] name = "mccabe" version = "0.6.1" @@ -549,6 +711,14 @@ code_style = ["pre-commit (==2.6)"] rtd = ["myst-parser (==0.14.0a3)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] +[[package]] +name = "mistune" +version = "0.8.4" +description = "The fastest markdown parser in pure Python" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "more-itertools" version = "8.8.0" @@ -631,6 +801,98 @@ linkify = ["linkify-it-py (>=1.0,<2.0)"] rtd = ["ipython", "sphinx-book-theme (>=0.1.0,<0.2.0)", "sphinx-panels (>=0.5.2,<0.6.0)", "sphinxcontrib-bibtex (>=2.1,<3.0)", "sphinxext-rediraffe (>=0.2,<1.0)", "sphinxcontrib.mermaid (>=0.6.3,<0.7.0)", "sphinxext-opengraph (>=0.4.2,<0.5.0)"] testing = ["beautifulsoup4", "coverage", "docutils (>=0.17.0,<0.18.0)", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] +[[package]] +name = "nbclient" +version = "0.5.3" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "main" +optional = true +python-versions = ">=3.6.1" + +[package.dependencies] +async-generator = "*" +jupyter-client = ">=6.1.5" +nbformat = ">=5.0" +nest-asyncio = "*" +traitlets = ">=4.2" + +[package.extras] +dev = ["codecov", "coverage", "ipython", "ipykernel", "ipywidgets", "pytest (>=4.1)", "pytest-cov (>=2.6.1)", "check-manifest", "flake8", "mypy", "tox", "bumpversion", "xmltodict", "pip (>=18.1)", "wheel (>=0.31.0)", "setuptools (>=38.6.0)", "twine (>=1.11.0)", "black"] +sphinx = ["Sphinx (>=1.7)", "sphinx-book-theme", "mock", "moto", "myst-parser"] +test = ["codecov", "coverage", "ipython", "ipykernel", "ipywidgets", "pytest (>=4.1)", "pytest-cov (>=2.6.1)", "check-manifest", "flake8", "mypy", "tox", "bumpversion", "xmltodict", "pip (>=18.1)", "wheel (>=0.31.0)", "setuptools (>=38.6.0)", "twine (>=1.11.0)", "black"] + +[[package]] +name = "nbconvert" +version = "6.1.0" +description = "Converting Jupyter Notebooks" +category = "main" +optional = true +python-versions = ">=3.7" + +[package.dependencies] +bleach = "*" +defusedxml = "*" +entrypoints = ">=0.2.2" +jinja2 = ">=2.4" +jupyter-core = "*" +jupyterlab-pygments = "*" +mistune = ">=0.8.1,<2" +nbclient = ">=0.5.0,<0.6.0" +nbformat = ">=4.4" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +testpath = "*" +traitlets = ">=5.0" + +[package.extras] +all = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pyppeteer (==0.2.2)", "tornado (>=4.0)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] +docs = ["sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] +serve = ["tornado (>=4.0)"] +test = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pyppeteer (==0.2.2)"] +webpdf = ["pyppeteer (==0.2.2)"] + +[[package]] +name = "nbformat" +version = "5.1.3" +description = "The Jupyter Notebook format" +category = "main" +optional = true +python-versions = ">=3.5" + +[package.dependencies] +ipython-genutils = "*" +jsonschema = ">=2.4,<2.5.0 || >2.5.0" +jupyter-core = "*" +traitlets = ">=4.1" + +[package.extras] +fast = ["fastjsonschema"] +test = ["check-manifest", "fastjsonschema", "testpath", "pytest", "pytest-cov"] + +[[package]] +name = "nbsphinx" +version = "0.8.6" +description = "Jupyter Notebook Tools for Sphinx" +category = "main" +optional = true +python-versions = ">=3.6" + +[package.dependencies] +docutils = "*" +jinja2 = "*" +nbconvert = "!=5.4" +nbformat = "*" +sphinx = ">=1.8" +traitlets = "*" + +[[package]] +name = "nest-asyncio" +version = "1.5.1" +description = "Patch asyncio to allow nested event loops" +category = "main" +optional = true +python-versions = ">=3.5" + [[package]] name = "networkx" version = "2.5.1" @@ -701,6 +963,26 @@ pytz = ">=2017.2" [package.extras] test = ["pytest (>=4.0.2)", "pytest-xdist", "hypothesis (>=3.58)"] +[[package]] +name = "pandocfilters" +version = "1.4.3" +description = "Utilities for writing pandoc filters in python" +category = "main" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "parso" +version = "0.8.2" +description = "A Python Parser" +category = "main" +optional = true +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + [[package]] name = "pathspec" version = "0.9.0" @@ -709,6 +991,25 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "main" +optional = true +python-versions = "*" + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "pip-licenses" version = "3.5.1" @@ -745,6 +1046,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "prompt-toolkit" +version = "3.0.19" +description = "Library for building powerful interactive command lines in Python" +category = "main" +optional = true +python-versions = ">=3.6.1" + +[package.dependencies] +wcwidth = "*" + [[package]] name = "psutil" version = "5.8.0" @@ -764,6 +1076,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "py" version = "1.10.0" @@ -987,6 +1307,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pywin32" +version = "301" +description = "Python for Window Extensions" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "pyyaml" version = "5.4.1" @@ -1532,6 +1860,17 @@ python-versions = ">=3.6" [package.dependencies] mpmath = ">=0.19" +[[package]] +name = "testpath" +version = "0.5.0" +description = "Test utilities for code working with files and commands" +category = "main" +optional = true +python-versions = ">= 3.5" + +[package.extras] +test = ["pytest", "pathlib2"] + [[package]] name = "threadpoolctl" version = "2.2.0" @@ -1556,6 +1895,20 @@ category = "main" optional = true python-versions = ">= 3.5" +[[package]] +name = "traitlets" +version = "5.0.5" +description = "Traitlets Python configuration system" +category = "main" +optional = true +python-versions = ">=3.7" + +[package.dependencies] +ipython-genutils = "*" + +[package.extras] +test = ["pytest"] + [[package]] name = "typed-ast" version = "1.4.3" @@ -1593,6 +1946,22 @@ brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +category = "main" +optional = true +python-versions = "*" + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "main" +optional = true +python-versions = "*" + [[package]] name = "websocket-client" version = "1.1.0" @@ -1637,12 +2006,12 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [extras] -docs = ["sphinx", "sphinx-autoapi", "furo", "myst-parser", "sphinx-autobuild"] +docs = ["sphinx", "sphinx-autoapi", "furo", "myst-parser", "sphinx-autobuild", "nbsphinx", "ipython"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "fab73749c30904dbc11c3556f9d347b1e29156dc53ad3b48ba16c23d405a1467" +content-hash = "605434dc12e3bd235516bc7991ef3e48a72bc6ad92f2de5b9edfcc51b0e9da2d" [metadata.files] alabaster = [ @@ -1653,10 +2022,18 @@ appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] +appnope = [ + {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, + {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, +] astroid = [ {file = "astroid-2.6.3-py3-none-any.whl", hash = "sha256:958c2aa6ba47e0b69773ce2b30cd6c2c99d15a5cc611e323d231f4c44db36d54"}, {file = "astroid-2.6.3.tar.gz", hash = "sha256:11e598e49e31f288ae43d13e8d0eb28454e5e2aa745cbc16cc799f147bb7e8dd"}, ] +async-generator = [ + {file = "async_generator-1.10-py3-none-any.whl", hash = "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b"}, + {file = "async_generator-1.10.tar.gz", hash = "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -1669,6 +2046,10 @@ babel = [ {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, ] +backcall = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] beautifulsoup4 = [ {file = "beautifulsoup4-4.9.3-py2-none-any.whl", hash = "sha256:4c98143716ef1cb40bf7f39a8e3eec8f8b009509e74904ba3a7b315431577e35"}, {file = "beautifulsoup4-4.9.3-py3-none-any.whl", hash = "sha256:fff47e031e34ec82bf17e00da8f592fe7de69aeea38be00523c04623c04fb666"}, @@ -1677,6 +2058,10 @@ beautifulsoup4 = [ black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] +bleach = [ + {file = "bleach-3.3.1-py2.py3-none-any.whl", hash = "sha256:ae976d7174bba988c0b632def82fdc94235756edfb14e6558a9c5be555c9fb78"}, + {file = "bleach-3.3.1.tar.gz", hash = "sha256:306483a5a9795474160ad57fce3ddd1b50551e981eed8e15a582d34cef28aafa"}, +] cached-property = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, @@ -1816,6 +2201,10 @@ decorator = [ {file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"}, {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"}, ] +defusedxml = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] dill = [ {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, @@ -1832,6 +2221,10 @@ docutils = [ {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] +entrypoints = [ + {file = "entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"}, + {file = "entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"}, +] fastdtw = [ {file = "fastdtw-0.3.4-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:28918c163dce9e736e09252a02073fce712bc4c7aa18f2a45d882cca84da2dbb"}, {file = "fastdtw-0.3.4.tar.gz", hash = "sha256:2350fa6ec36bcad186eaf81f46eff35181baf04e324f522de8aeb43d0243f64f"}, @@ -1892,10 +2285,22 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +ipython = [ + {file = "ipython-7.25.0-py3-none-any.whl", hash = "sha256:aa21412f2b04ad1a652e30564fff6b4de04726ce875eab222c8430edc6db383a"}, + {file = "ipython-7.25.0.tar.gz", hash = "sha256:54bbd1fe3882457aaf28ae060a5ccdef97f212a741754e420028d4ec5c2291dc"}, +] +ipython-genutils = [ + {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, + {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, +] iso8601 = [ {file = "iso8601-0.1.16-py2.py3-none-any.whl", hash = "sha256:906714829fedbc89955d52806c903f2332e3948ed94e31e85037f9e0226b8376"}, {file = "iso8601-0.1.16.tar.gz", hash = "sha256:36532f77cc800594e8f16641edae7f1baf7932f05d8e508545b95fc53c6dc85b"}, ] +jedi = [ + {file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"}, + {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, +] jinja2 = [ {file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"}, {file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"}, @@ -1908,6 +2313,18 @@ jsonschema = [ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] +jupyter-client = [ + {file = "jupyter_client-6.2.0-py3-none-any.whl", hash = "sha256:9715152067e3f7ea3b56f341c9a0f9715c8c7cc316ee0eb13c3c84f5ca0065f5"}, + {file = "jupyter_client-6.2.0.tar.gz", hash = "sha256:e2ab61d79fbf8b56734a4c2499f19830fbd7f6fefb3e87868ef0545cb3c17eb9"}, +] +jupyter-core = [ + {file = "jupyter_core-4.7.1-py3-none-any.whl", hash = "sha256:8c6c0cac5c1b563622ad49321d5ec47017bd18b94facb381c6973a0486395f8e"}, + {file = "jupyter_core-4.7.1.tar.gz", hash = "sha256:79025cb3225efcd36847d0840f3fc672c0abd7afd0de83ba8a1d3837619122b4"}, +] +jupyterlab-pygments = [ + {file = "jupyterlab_pygments-0.1.2-py2.py3-none-any.whl", hash = "sha256:abfb880fd1561987efaefcb2d2ac75145d2a5d0139b1876d5be806e32f630008"}, + {file = "jupyterlab_pygments-0.1.2.tar.gz", hash = "sha256:cfcda0873626150932f438eccf0f8bf22bfa92345b814890ab360d666b254146"}, +] lark = [ {file = "lark-0.11.3.tar.gz", hash = "sha256:3100d9749b5a85735ec428b83100876a5da664804579e729c23a36341f961e7e"}, ] @@ -1948,40 +2365,30 @@ lxml = [ {file = "lxml-4.6.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4"}, {file = "lxml-4.6.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51"}, {file = "lxml-4.6.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586"}, - {file = "lxml-4.6.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4c61b3a0db43a1607d6264166b230438f85bfed02e8cff20c22e564d0faff354"}, - {file = "lxml-4.6.3-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16"}, {file = "lxml-4.6.3-cp35-cp35m-win32.whl", hash = "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2"}, {file = "lxml-4.6.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4"}, {file = "lxml-4.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d"}, - {file = "lxml-4.6.3-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d916d31fd85b2f78c76400d625076d9124de3e4bda8b016d25a050cc7d603f24"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec"}, - {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617"}, {file = "lxml-4.6.3-cp36-cp36m-win32.whl", hash = "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04"}, {file = "lxml-4.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a"}, {file = "lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3"}, - {file = "lxml-4.6.3-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:36108c73739985979bf302006527cf8a20515ce444ba916281d1c43938b8bb96"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2"}, - {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92"}, {file = "lxml-4.6.3-cp37-cp37m-win32.whl", hash = "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade"}, {file = "lxml-4.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b"}, {file = "lxml-4.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa"}, {file = "lxml-4.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a"}, {file = "lxml-4.6.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927"}, - {file = "lxml-4.6.3-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e1cbd3f19a61e27e011e02f9600837b921ac661f0c40560eefb366e4e4fb275e"}, {file = "lxml-4.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791"}, - {file = "lxml-4.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:1b38116b6e628118dea5b2186ee6820ab138dbb1e24a13e478490c7db2f326ae"}, {file = "lxml-4.6.3-cp38-cp38-win32.whl", hash = "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28"}, {file = "lxml-4.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7"}, {file = "lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0"}, {file = "lxml-4.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1"}, {file = "lxml-4.6.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23"}, - {file = "lxml-4.6.3-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3082c518be8e97324390614dacd041bb1358c882d77108ca1957ba47738d9d59"}, {file = "lxml-4.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969"}, - {file = "lxml-4.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a"}, {file = "lxml-4.6.3-cp39-cp39-win32.whl", hash = "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f"}, {file = "lxml-4.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83"}, {file = "lxml-4.6.3.tar.gz", hash = "sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468"}, @@ -2026,6 +2433,10 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] +matplotlib-inline = [ + {file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"}, + {file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -2034,6 +2445,10 @@ mdit-py-plugins = [ {file = "mdit-py-plugins-0.2.8.tar.gz", hash = "sha256:5991cef645502e80a5388ec4fc20885d2313d4871e8b8e320ca2de14ac0c015f"}, {file = "mdit_py_plugins-0.2.8-py3-none-any.whl", hash = "sha256:1833bf738e038e35d89cb3a07eb0d227ed647ce7dd357579b65343740c6d249c"}, ] +mistune = [ + {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, + {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, +] more-itertools = [ {file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"}, {file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"}, @@ -2100,6 +2515,26 @@ myst-parser = [ {file = "myst-parser-0.15.1.tar.gz", hash = "sha256:7c3c78a36c4bc30ce6a67933ebd800a880c8d81f1688fad5c2ebd82cddbc1603"}, {file = "myst_parser-0.15.1-py3-none-any.whl", hash = "sha256:e8baa9959dac0bcf0f3ea5fc32a1a28792959471d8a8094e3ed5ee0de9733ade"}, ] +nbclient = [ + {file = "nbclient-0.5.3-py3-none-any.whl", hash = "sha256:e79437364a2376892b3f46bedbf9b444e5396cfb1bc366a472c37b48e9551500"}, + {file = "nbclient-0.5.3.tar.gz", hash = "sha256:db17271330c68c8c88d46d72349e24c147bb6f34ec82d8481a8f025c4d26589c"}, +] +nbconvert = [ + {file = "nbconvert-6.1.0-py3-none-any.whl", hash = "sha256:37cd92ff2ae6a268e62075ff8b16129e0be4939c4dfcee53dc77cc8a7e06c684"}, + {file = "nbconvert-6.1.0.tar.gz", hash = "sha256:d22a8ff202644d31db254d24d52c3a96c82156623fcd7c7f987bba2612303ec9"}, +] +nbformat = [ + {file = "nbformat-5.1.3-py3-none-any.whl", hash = "sha256:eb8447edd7127d043361bc17f2f5a807626bc8e878c7709a1c647abda28a9171"}, + {file = "nbformat-5.1.3.tar.gz", hash = "sha256:b516788ad70771c6250977c1374fcca6edebe6126fd2adb5a69aa5c2356fd1c8"}, +] +nbsphinx = [ + {file = "nbsphinx-0.8.6-py3-none-any.whl", hash = "sha256:133149fd01cbf3c89a2f1a3ca0edfaaddaf55bafbf69b086017df602161b26c8"}, + {file = "nbsphinx-0.8.6.tar.gz", hash = "sha256:097dee333558f400e9abbb53ce7d4fa64a257cfa89dd20f7554dca7f0cd5e143"}, +] +nest-asyncio = [ + {file = "nest_asyncio-1.5.1-py3-none-any.whl", hash = "sha256:76d6e972265063fe92a90b9cc4fb82616e07d586b346ed9d2c89a4187acea39c"}, + {file = "nest_asyncio-1.5.1.tar.gz", hash = "sha256:afc5a1c515210a23c461932765691ad39e8eba6551c055ac8d5546e69250d0aa"}, +] networkx = [ {file = "networkx-2.5.1-py3-none-any.whl", hash = "sha256:0635858ed7e989f4c574c2328380b452df892ae85084144c73d8cd819f0c4e06"}, {file = "networkx-2.5.1.tar.gz", hash = "sha256:109cd585cac41297f71103c3c42ac6ef7379f29788eb54cb751be5a663bb235a"}, @@ -2168,10 +2603,25 @@ pandas = [ {file = "pandas-1.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:edda9bacc3843dfbeebaf7a701763e68e741b08fccb889c003b0a52f0ee95782"}, {file = "pandas-1.1.5.tar.gz", hash = "sha256:f10fc41ee3c75a474d3bdf68d396f10782d013d7f67db99c0efbfd0acb99701b"}, ] +pandocfilters = [ + {file = "pandocfilters-1.4.3.tar.gz", hash = "sha256:bc63fbb50534b4b1f8ebe1860889289e8af94a23bff7445259592df25a3906eb"}, +] +parso = [ + {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, + {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, +] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] +pexpect = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] +pickleshare = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] pip-licenses = [ {file = "pip-licenses-3.5.1.tar.gz", hash = "sha256:6c60096cfa1ee04d7db8d374d4326939369d5871368421e7a7d5da026519bc24"}, {file = "pip_licenses-3.5.1-py3-none-any.whl", hash = "sha256:e44e4e92e6af2b9d11dfafbf22a3052bf9a05fdaa5654befdba9db735832ac7f"}, @@ -2184,6 +2634,10 @@ ply = [ {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, ] +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.19-py3-none-any.whl", hash = "sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"}, + {file = "prompt_toolkit-3.0.19.tar.gz", hash = "sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f"}, +] psutil = [ {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"}, {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"}, @@ -2217,6 +2671,10 @@ psutil = [ ptable = [ {file = "PTable-0.9.2.tar.gz", hash = "sha256:aa7fc151cb40f2dabcd2275ba6f7fd0ff8577a86be3365cd3fb297cbe09cc292"}, ] +ptyprocess = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, @@ -2362,6 +2820,18 @@ pytz = [ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] +pywin32 = [ + {file = "pywin32-301-cp35-cp35m-win32.whl", hash = "sha256:93367c96e3a76dfe5003d8291ae16454ca7d84bb24d721e0b74a07610b7be4a7"}, + {file = "pywin32-301-cp35-cp35m-win_amd64.whl", hash = "sha256:9635df6998a70282bd36e7ac2a5cef9ead1627b0a63b17c731312c7a0daebb72"}, + {file = "pywin32-301-cp36-cp36m-win32.whl", hash = "sha256:c866f04a182a8cb9b7855de065113bbd2e40524f570db73ef1ee99ff0a5cc2f0"}, + {file = "pywin32-301-cp36-cp36m-win_amd64.whl", hash = "sha256:dafa18e95bf2a92f298fe9c582b0e205aca45c55f989937c52c454ce65b93c78"}, + {file = "pywin32-301-cp37-cp37m-win32.whl", hash = "sha256:98f62a3f60aa64894a290fb7494bfa0bfa0a199e9e052e1ac293b2ad3cd2818b"}, + {file = "pywin32-301-cp37-cp37m-win_amd64.whl", hash = "sha256:fb3b4933e0382ba49305cc6cd3fb18525df7fd96aa434de19ce0878133bf8e4a"}, + {file = "pywin32-301-cp38-cp38-win32.whl", hash = "sha256:88981dd3cfb07432625b180f49bf4e179fb8cbb5704cd512e38dd63636af7a17"}, + {file = "pywin32-301-cp38-cp38-win_amd64.whl", hash = "sha256:8c9d33968aa7fcddf44e47750e18f3d034c3e443a707688a008a2e52bbef7e96"}, + {file = "pywin32-301-cp39-cp39-win32.whl", hash = "sha256:595d397df65f1b2e0beaca63a883ae6d8b6df1cdea85c16ae85f6d2e648133fe"}, + {file = "pywin32-301-cp39-cp39-win_amd64.whl", hash = "sha256:87604a4087434cd814ad8973bd47d6524bd1fa9e971ce428e76b62a5e0860fdf"}, +] pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, @@ -2749,6 +3219,10 @@ sympy = [ {file = "sympy-1.8-py3-none-any.whl", hash = "sha256:3b0b3776e357f789951bb14776c6a841f931680f20d5f8fe55977885657c9b7a"}, {file = "sympy-1.8.tar.gz", hash = "sha256:1ca588a9f6ce6a323c5592f9635159c2093572826668a1022c75c75bdf0297cb"}, ] +testpath = [ + {file = "testpath-0.5.0-py3-none-any.whl", hash = "sha256:8044f9a0bab6567fc644a3593164e872543bb44225b0e24846e2c89237937589"}, + {file = "testpath-0.5.0.tar.gz", hash = "sha256:1acf7a0bcd3004ae8357409fc33751e16d37ccc650921da1094a86581ad1e417"}, +] threadpoolctl = [ {file = "threadpoolctl-2.2.0-py3-none-any.whl", hash = "sha256:e5a995e3ffae202758fa8a90082e35783b9370699627ae2733cd1c3a73553616"}, {file = "threadpoolctl-2.2.0.tar.gz", hash = "sha256:86d4b6801456d780e94681d155779058759eaef3c3564758b17b6c99db5f81cb"}, @@ -2800,6 +3274,10 @@ tornado = [ {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, ] +traitlets = [ + {file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"}, + {file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"}, +] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, @@ -2845,6 +3323,14 @@ urllib3 = [ {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"}, {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, ] +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, +] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] websocket-client = [ {file = "websocket-client-1.1.0.tar.gz", hash = "sha256:b68e4959d704768fa20e35c9d508c8dc2bbc041fd8d267c0d7345cffe2824568"}, {file = "websocket_client-1.1.0-py2.py3-none-any.whl", hash = "sha256:e5c333bfa9fa739538b652b6f8c8fc2559f1d364243c8a689d7c0e1d41c2e611"}, diff --git a/pyproject.toml b/pyproject.toml index df57ef2..e248e2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ sphinx-autoapi = { version = "^1.8.1", optional = true } furo = { version = "^2021.7.5-beta.38", optional = true } myst-parser = { version = "^0.15.1", optional = true } sphinx-autobuild = { version = "^2021.3.14", optional = true } +nbsphinx = { version = "^0.8.6", optional = true } +ipython = {version = "^7.25.0", optional = true} [tool.poetry.dev-dependencies] black = "^20.8b1" @@ -40,7 +42,7 @@ pytest-mock = "^3.6.1" pip-licenses = "^3.5.1" [tool.poetry.extras] -docs = ["sphinx", "sphinx-autoapi", "furo", "myst-parser", "sphinx-autobuild"] +docs = ["sphinx", "sphinx-autoapi", "furo", "myst-parser", "sphinx-autobuild", "nbsphinx", "ipython"] [tool.black] line-length = 120 diff --git a/setup.py b/setup.py index 9646bbb..188d712 100644 --- a/setup.py +++ b/setup.py @@ -39,13 +39,7 @@ "Topic :: Scientific/Engineering :: Physics", "Typing :: Typed", ], - packages=[ - "node_modules.npm.node_modules.node-gyp.gyp.pylib.gyp", - "node_modules.npm.node_modules.node-gyp.gyp.pylib.gyp.generator", - "qiskit_rigetti", - "qiskit_rigetti.gates", - "qiskit_rigetti.hooks", - ], + packages=["qiskit_rigetti", "qiskit_rigetti.gates", "qiskit_rigetti.hooks"], package_dir={"": "."}, package_data={"qiskit_rigetti": ["*.typed"]}, install_requires=[ @@ -67,7 +61,9 @@ ], "docs": [ "furo==2021.*,>=2021.7.5.b38", + "ipython==7.*,>=7.25.0", "myst-parser==0.*,>=0.15.1", + "nbsphinx==0.*,>=0.8.6", "sphinx==4.*,>=4.1.1", "sphinx-autoapi==1.*,>=1.8.1", "sphinx-autobuild==2021.*,>=2021.3.14",