diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index 8955017e5..1b254088b 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -1213,9 +1213,9 @@ Matrix Hamiltonian ^^^^^^^^^^^^^^^^^^ The first implementation of Hamiltonians uses the full matrix representation -of the Hamiltonian operator in the computational basis. This matrix has size -``(2 ** nqubits, 2 ** nqubits)`` and therefore its construction is feasible -only when number of qubits is small. +of the Hamiltonian operator in the computational basis. +For :math:`n` qubits, this matrix has size :math:`2^{n} \times 2^{n}`. +Therefore, its construction is feasible only when :math:`n` is small. Alternatively, the user can construct this Hamiltonian using a sparse matrices. Sparse matrices from the diff --git a/doc/source/code-examples/examples.rst b/doc/source/code-examples/examples.rst index 1d3d43b52..081e8fc71 100644 --- a/doc/source/code-examples/examples.rst +++ b/doc/source/code-examples/examples.rst @@ -327,3 +327,46 @@ For example q2: ──────o──|──|────o──|──|──H─U1─U1────────|─|─ q3: ─────────o──|───────o──|────o──|──H─U1───|─x─ q4: ────────────o──────────o───────o────o──H─x─── + +How to visualize a circuit with style? +-------------------------------------- + +Qibo is able to draw a circuit using ``matplotlib`` library by calling the function ``plot_circuit``. It also have built-in styles ready to use +and also it is possible to apply custom styles to the circuit. The function is able to cluster the gates to reduce the circuit depth. +The built-in styles are: ``garnacha``, ``fardelejo``, ``quantumspain``, ``color-blind``, ``cachirulo`` or custom dictionary. + +For example, we can draw the QFT circuit for 5-qubits: + +.. testcode:: + + import matplotlib.pyplot as plt + import qibo + from qibo import gates, models + from qibo.models import QFT + + # new plot function based on matplotlib + from qibo.ui import plot_circuit + + # create a 5-qubits QFT circuit + c = QFT(5) + c.add(gates.M(qubit) for qubit in range(2)) + + # print circuit with default options (default black & white style, scale factor of 0.6 and clustered gates) + plot_circuit(c); + + # print the circuit with built-int style "garnacha", clustering gates and a custom scale factor + # built-in styles: "garnacha", "fardelejo", "quantumspain", "color-blind", "cachirulo" or custom dictionary + plot_circuit(c, scale = 0.8, cluster_gates = True, style="garnacha"); + + # plot the Qibo circuit with a custom style + custom_style = { + "facecolor" : "#6497bf", + "edgecolor" : "#01016f", + "linecolor" : "#01016f", + "textcolor" : "#01016f", + "fillcolor" : "#ffb9b9", + "gatecolor" : "#d8031c", + "controlcolor" : "#360000" + } + + plot_circuit(c, scale = 0.8, cluster_gates = True, style=custom_style); diff --git a/examples/circuit-draw-mpl/qibo-draw-circuit-matplotlib.ipynb b/examples/circuit-draw-mpl/qibo-draw-circuit-matplotlib.ipynb new file mode 100644 index 000000000..754592147 --- /dev/null +++ b/examples/circuit-draw-mpl/qibo-draw-circuit-matplotlib.ipynb @@ -0,0 +1,470 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f3c96f32", + "metadata": {}, + "source": [ + "## Matplotlib circuit drawing for Qibo" + ] + }, + { + "cell_type": "markdown", + "id": "e79c7a54", + "metadata": {}, + "source": [ + "Qibo now uses matplotlib to draw circuit, this new feature is base on `plot` function, you can pass the Qibo circuit along a built-in or custom style among other options." + ] + }, + { + "cell_type": "markdown", + "id": "d54ec28a", + "metadata": {}, + "source": [ + "Follow the examples below to learn how to use it." + ] + }, + { + "cell_type": "markdown", + "id": "9fb3188e", + "metadata": {}, + "source": [ + "The default function signature for `plot`:\n", + " \n", + "```python\n", + "plot(circuit, scale=0.6, cluster_gates=True, style=None)\n", + "```\n", + "The parameters on nthis function are:\n", + "\n", + "- `circuit`: Qibo circuit (mandatory)\n", + "- `scale`: Scale up or down the output plot (optional, default value: 0.6)\n", + "- `cluster_gates`: Group gates (optional, default value: True)\n", + "- `style`: Style your circuit with a built-n style or custom style (optional, default vale: None)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "66e4921b-c1ea-479d-9926-d93a7c784be9", + "metadata": {}, + "outputs": [], + "source": [ + "# General libraries\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "# Qibo libraries\n", + "import qibo\n", + "from qibo import gates, models\n", + "from qibo.models import Circuit, QFT\n", + "\n", + "# new plot function based on matplotlib\n", + "from qibo.ui import plot_circuit\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "eda54008", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ─RY─o─o───o─────RY─o─o───o─────RY─o─o───o─────RY─M─\n", + "q1: ─RY─X─|─o─|─o───RY─X─|─o─|─o───RY─X─|─o─|─o───RY─M─\n", + "q2: ─RY───X─X─|─|─o─RY───X─X─|─|─o─RY───X─X─|─|─o─RY───\n", + "q3: ─RY───────X─X─X─RY───────X─X─X─RY───────X─X─X─RY───\n" + ] + } + ], + "source": [ + "nqubits = 4\n", + "nlayers = 3\n", + "\n", + "# Create variational ansatz circuit Twolocal\n", + "ansatz = models.Circuit(nqubits)\n", + "for l in range(nlayers):\n", + " \n", + " ansatz.add((gates.RY(q, theta=0) for q in range(nqubits)))\n", + " \n", + " for i in range(nqubits - 3):\n", + " ansatz.add(gates.CNOT(i, i+1))\n", + " ansatz.add(gates.CNOT(i, i+2))\n", + " ansatz.add(gates.CNOT(i+1, i+2))\n", + " ansatz.add(gates.CNOT(i, i+3))\n", + " ansatz.add(gates.CNOT(i+1, i+3))\n", + " ansatz.add(gates.CNOT(i+2, i+3))\n", + " \n", + "ansatz.add((gates.RY(q, theta=0) for q in range(nqubits)))\n", + "ansatz.add(gates.M(qubit) for qubit in range(2))\n", + "print(ansatz.draw())" + ] + }, + { + "cell_type": "markdown", + "id": "7fdbf16f", + "metadata": {}, + "source": [ + "#### Plot circuit with default black and white style" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ea99c3d4-e36f-46ca-81c4-c8f10d6bcbe5", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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xl133aWRI0fqwoULmjRpksaNG6fp06dblis2NlbBwcGWzQf81axZsxQXF6cvv/zS1A069+7dqz59+mju3Lk3vSfj6NGjde7cOc2ZM8eitP8THx+vESNGaN26dbr77rtvuv+t5J43b56io6P19ddfy8vL0ltdKjk5WR06dNC//vWvPLvur24l9/bt2zV48GAtX75c1apVsyYwkA96E56K3syN3gRujt6Ep6I3c6M3gZujN1EYlix4+fr6Srp6yuxfXblyRe+8844kqV69enk+/8qVK4qKilLp0qX1wAMP5LnPqlWrlJWVpSeffDLfHKZPawMs9sorryg6OlozZ87UsGHDLCv/4OBgjmsUqU6dOunjjz9W+fLlValSJdPPq1u37k2PzaNHjyosLKxIjuG7775bI0aM0OXLl29pfjO5J0+erIYNG+b7IY7CMAxDd999t86dO2d57i+//FJ33HGHunTpYvkvToDV6E24K3ozN3oTKHr0JtwVvZkbvQkUPXrTs1nyDhUYGKiqVavqwIEDOnDgQPb2y5cvq1evXrLb7fLy8sq1mLV161bdfvvt8vf317Rp0/TVV1/leyPLuLg4VaxYUY0aNbIiMmApf39/jRkzRunp6YqMjHR2HMC0xo0by8vLS2vWrLF03kOHDikpKUnNmjWzdN5rKlWqpCpVqlie+88//9SmTZuKLLfNZlOzZs20Zs0aGYZh6dxr167Vww8/zC8fcAv0JtwVvZkTvQk4Br0Jd0Vv5kRvAo5Bb3o2y96lRo4cqaysLLVo0UIREREaPny47r//fp05c0Z+fn6qVauWAgICcjynQYMG2rt3r7Zt26b/+7//U9euXbNvgni9CxcuaPPmzerSpYupU6ABZ+jfv78qVqyomJgYHT161NlxAFPKly+vzp07a+bMmZb+h3jWrFkqV66cOnXqZNmc17PZbOrbt68WLVqkCxcuWDbvkiVLdP78efXu3duyOf+qb9++2rNnj3bu3GnZnPv379e3336rfv36WTYnUNToTbgjejMnehNwHHoT7ojezIneBByH3vRcli14DR48WJGRkQoMDFR0dLTWr1+vAQMG6MMPP9SlS5fyvBasv7+/atSoocaNG+vjjz+Wl5eX5s2bl2u/tWvXKj09/YaXMwSczc/PT2PHjlVGRoYmTpzo7DiAaf/4xz+0f/9+LV682JL5fvzx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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(ansatz, scale = 0.6, cluster_gates = False);" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "81b65ea2-06a0-437d-b8f3-2ac176ea9b25", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABRgAAADrCAYAAAACJvoNAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB2h0lEQVR4nO3dd1gUZ/c38O9SpCk2VBQFgxU7oGAUC0RFoyJiQyWK2EtCTOwVxdgLib03LFERxUoUS4hoVBALEhONiBUlUUQRpNzvH77yCw8Iu+vALOv3c11zPU92Z86eW9izw9mZ+1YIIQSIiIiIiIiIiIiI1KAjdwJERERERERERERUfLHBSERERERERERERGpjg5GIiIiIiIiIiIjUxgYjERERERERERERqY0NRiIiIiIiIiIiIlIbG4xERERERERERESkNjYYiYiIiIiIiIiISG1sMBIREREREREREZHa2GAkIiIiIiIiIiIitbHBSERERERERERERGpjg5GIiIiIiIiIiIjUxgYjERERERERERERqY0NRiIiIiIiIiIiIlIbG4xERERERERERESkNjYYiYiIiIiIiIiISG1sMBIREREREREREZHa2GAkIiIiIiIiIiIitbHBSERERERERERERGpjg5GIiIiIiIiIiIjUpid3AnKLj49HYmKi3GlkMzMzg6WlpdxpEBFpDU2q86zxRETSYo0nItJemlTjgcKr80U9zsIaxyfdYIyPj4eNjQ1SUlLkTiWbsbExYmNjeXJCRCQBTavzrPFERNJhjSci0l6aVuOBwqnzcoyzsD6vPukGY2JiIlJSUhAYGAgbGxu500FsbCy8vLyQmJjIExMiIgloUp1njScikhZrPBGR9tKkGg8UXp0v6nEW5ufVJ91gfM/GxgZ2dnZyp0FERIWEdZ6ISHuxxhMRaa9PpcZrwzi5yAsRERERERERERGpjQ1GIiIiIiIiIiIiUhsbjERERERERERERKQ2tRqMfn5+UCgUiIuLkzgdIiIiIiIiIiIiKk40/grG0NBQKBQK7N69W5bXj4uLg0KhyLHp6+vDwsICvXv3xuXLlwEAAQEBUCgUGDRo0AdjnTlzBjo6OmjWrBkyMjKKaghERPQBrPFERNqLNZ6ISLt9CnX+v2M0Nzf/YG6xsbHZ+1WvXr1ok/z/NH4VaRcXF5QuXRoHDhyAp6enbHnU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RiIiIiIiIiIiIlIbG4xERERERERERESkNjYYiYiIiIiIiIiISG1sMBIREREREREREZHa2GAkIiIiIiIiIiIitbHBSERERERERERERGpjg5GIiIiIiIiIiIjUxgYjERERERERERERqY0NRiIiIiIiIiIiIlIbG4xERERERERERESkNjYYiYiIiIiIiIiISG1sMBIREREREREREZHa2GAkIiIiIiIiIiIitbHBSERERERERERERGpjg5GIiIiIiIiIiIjUxgYjERERERERERERqY0NRiIiIiIiIiIiIlKbntwJyC0+Ph6JiYlyp5HNzMwMlpaWcqdBRKQ1NKnOs8YTEUmLNZ6ISHtpUo0HCq/OF/U4C2scn3SDMT4+HjY2NkhJSZE7lWzGxsaIjY3lyQkRkQQ0rc6zxhMRSYc1nohIe2lajQcKp87LMc7C+rz6pBuMiYmJSElJQWBgIGxsbOROB7GxsfDy8kJiYiJPTIiIJKBJdZ41nohIWqzxRETaS5NqPFB4db6ox1mYn1efdIPxPRsbG9jZ2cmdBhERFRLWeSIi7cUaT0SkvT6VGq8N42SDkbJdv34dO3bswKVLl3D16lX8888/AIDOnTujVatWaN26Nfr374+yZcvKnCkREanq2bNn2L59O86dO4fIyEg8ePAAAPDFF1+gWbNmcHBwwFdffYU6derInCkREanq7du3CA4ORmhoKCIjIxEbGwsAaNmyJRo1agR7e3u4u7ujXbt20NHhOp9ERCQ9froQzp8/j1atWqFRo0bYvHkzSpcuDV9fXwwaNAgAYGtri6dPn+K7776DhYUFRowYgX///VfmrImISBkJCQkYNGgQqlatiilTpuDFixfo3bs3vLy8AAAuLi4wMjLCmjVrULduXbRr1w5XrlyROWsiIlJGRkYGFi5cCEtLS3h6euLKlStwdHRE7969AQDdu3dHnTp1cPLkSbi6uqJOnTrYvn07hBAyZ05ERNqGDcZP2Nu3bzF+/Hg4OTnhzZs32Lt3Lx48eID9+/dj+vTp+OKLLwAA/fv3x5kzZ3D//n1MnToVP//8M+rXr48jR47IPAIiIsrP3r17Ua9ePRw5cgQ//PADHj58iLCwMCxcuBDt27cHAHh4eODgwYN4+PAhduzYgYSEBDg4OGDmzJnIzMyUeQRERPQhsbGxaN68OSZPnozu3bsjJiYGV65c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lpaWcqdBRKQVNK3Os8YTEUmHNZ6ISHtpWo0HWOcL8kk3GAFkz21ERETaiXWeiEh7scYTEWkv1vjihUtTERERERERERERkdrYYCQiIiIiIiIiIiK1scFIREREREREREREamODkYiIiIiIiIiIiNTGBiMRERERERERERGpjQ1GIiIiIiIiIiIiUhsbjERERERERERERKQ2NhiJiIiIiIiIiIhIbWwwEhERERERERERkdrYYCQiIiIiIiIiIiK1scFIREREREREREREamODkYiIiIiIiIiIiNTGBiMRERERERERERGpjQ1GIiIiIiIiIiIiUhsbjERERERERERERKQ2NhiJiIiIiIiIiIhIbWwwEhERERERERERkdrYYCQiIiIiIiIiIiK1scFIREREREREREREamODkYiIiIiIiIiIiNSmJ3cCcouPj0diYqLcaWQzMzODpaWl3GkQEWkNTarzrPFERNJijSci0l6aVOMB1vmCfNINxvj4eNjY2CAlJUXuVLIZGxsjNjaWv7RERBLQtDrPGk9EJB3WeCIi7aVpNR5gnS/IJ91gTExMREpKCgIDA2FjYyN3OoiNjYWXlxcSExP5C0tEJAFNqvOs8URE0mKNJyLSXppU4wHWeWV80g3G92xsbGBnZyd3GkT0H2/fvsXff/+NW7duZf+3Nnjz5g3+/vtvAMC9e/fQsGFD6Ovry5zVx3v16hXu3LkDALh//z4aN24MXV1dmbP6P6zzRJpFCIH4+PjsGv/y5UuZM5JGVlYW7t69mz2uV69eyZyRNDIyMnJ8Jr9580bmjHJijSfSPImJifjrr78AAE+ePIEQAgqFQuasPt6TJ0+yx/Xs2TOtGJcQAg8fPsSff/4JAHj+/LnMGeXEGl98cJEXItIYDx8+hJ+fH+zt7VGyZEnY2NigX79+AICWLVvC1tYWU6dORXx8vMyZqubOnTsYP348GjVqhFKlSqFXr14AAA8PD5QqVQoODg6YO3cuEhISZM5UNTdu3MCYMWNgY2MDU1NT9O7dGwDg7u4OU1NTODk54ccff8SLFy/kTZSINMKbN2+wefNmtG/fHuXKlUP16tWza7yzszOsra3h7e2NiIgICCFkzlZ5L1++xMqVK9G6dWuULl0aNWvWzB5XmzZtUKdOHYwYMQLR0dHyJqqixMRELFy4EM2bN0epUqVQp06d7HE5OTmh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v3KnJYTQrLqqSbkQyS05OVlERESI5cuXCwBi7969IiMjQ+60Ptrz589FeHh49mdXcHBwsWoqfsizZ8/EmTNnssd1+PBh2ZqK/6VJdVWTciGSW3p6urh27ZpYsWKFACC2bNkiXr9+LXdaHy0tLU1ERUVljyswMFCkpqbKndZHS0lJERcvXsz+TN61a5dGfNGnaXVV0/LRRJp3PTIREQBzc3OYm5vD0dERLVu2RN26deVO6aMpFApUq1YNAwYMgIODA+rWrSv7ytdSUCgUsLa2xsCBA+Ho6Kg14yKiwlOyZMns225btGiBunXratQ8i+oqU6YMnJycYGdnl/3ZpaNT6FOeFzozMzO0adMGzZo1yx6XJt7+R0SaQU9PDw0bNkSNGjXw+eefa825YYkSJWBra4s6depkj8vAwEDutD7a+7mS69evn/2ZrAmL7lDxwwYjoNRktEVBU/Ig0iTGxsaws7OTOw1JaeOYAM0elybUV03IgUjTaHLd+BgcV9HShPqqCTkQaRpNrRkfi+MqWppSXzUlD032STcYzczMYGxsDC8vL7lTyWZsbJxrxW0iIlKPptV51ngiIumwxhMRaS9Nq/EA63xBFEL8/+VMP1Hx8fHZqyVpAjMzM1haWsqdBhGR1tCkOs8aT0QkLdZ4IiLtpUk1HmCdL8gn32AkIiIiIiIiIiIi9RX/WaeJiIiIiIiIiIhINmwwEhERERERERERkdrYYCQiIiIiIiIiIiK1scFIREREREREREREamODkYiIiIiIiIiIiNTGBiMRERERERERERGpjQ1GIiIiIiIiIiIiUhsbjERERERERERERKQ2NhiJiIiIiIiIiIhIbWwwEhERERERERERkdrYYCQiIiIiIiIiIiK1scFIREREREREREREamODkYiIiIiIiIiIiNTGBiMRERERERERERGpjQ1GIiIiIiIiIiIiUhsbjERERERERERERKQ2NhiJiIiIiIiIiIhIbWwwEhERERERERERkdrYYCQiIiIiIiIiIiK1/T+f1i43EzqMUwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(ansatz, scale = 0.7, cluster_gates = True);" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "62d00656-b40d-44f1-b56a-6733eeed6759", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ──────o───o───────────o──X─M─\n", + "q1: ─H──X─|───o─o─x─si─fx─o──X─M─\n", + "q2: ─SX───CSX─X─X─x─si─fx─DE─────\n" + ] + } + ], + "source": [ + "c = models.Circuit(3)\n", + "c.add(gates.H(1))\n", + "c.add(gates.X(1))\n", + "c.add(gates.SX(2))\n", + "c.add(gates.CSX(0,2))\n", + "c.add(gates.TOFFOLI(0,1, 2))\n", + "c.add(gates.CNOT(1, 2))\n", + "c.add(gates.SWAP(1,2))\n", + "c.add(gates.SiSWAP(1,2))\n", + "c.add(gates.FSWAP(1,2))\n", + "c.add(gates.DEUTSCH(1, 0, 2, np.pi))\n", + "c.add(gates.X(1))\n", + "c.add(gates.X(0))\n", + "c.add(gates.M(qubit) for qubit in range(2))\n", + "print(c.draw())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f68eb0c1-9ae4-436b-948d-74d24d782a80", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjkAAACeCAYAAADQbRsSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAw40lEQVR4nO3dfVzN9/8/8Me7Cx3RIslFSamhqVGu2kRpI9frysZctdKVmA+KtZmrtqHJQrR8VKi52KikpA8RbY2Uq2znMzYlvqY0IiKl1+8Pv85HOtU5p/e56Hjeb7dz223v9+u83o9T5/3u6fW+eHGMMQZCCCGEEDWjoewAhBBCCCHyQEUOIYQQQtQSFTmEEEIIUUtU5BBCCCFELVGRQwghhBC1REUOIYQQQtQSFTmEEEIIUUtU5BBCCCFELVGRQwghhBC1REUOIYQQQtQSFTmEEEIIUUtU5BBCCCFELVGRQwghhBC1REUOIYQQQtQSFTmEEEIIUUtayg5ACCGEvE5KSkpQXl4ut/4NDQ1hamrKW3/yzvsqPvNTkUMIIYQoSElJCaysrFBVVSW3bejq6kIoFPJSKCgi76v4zE9FDiGEEKIg5eXlqKqqQmJiIqysrHjvXygUYubMmSgvL+elSJB33lfxnZ+KHEIIIUTBrKysYGdnp+wYEmtreevRhceEEEIIUUtU5BBCCCFELVGRQwghhBC1REUOIYQQQtSSTEXOqlWrwHEciouLeY5DCCGEEMIPlR/JyczMBMdx2Ldvn7KjEEIIIXK1ZcsWcByH2bNni11///59GBsbQ1dXF1evXlVwOvGKi4vBcRw4jkP37t1RW1srtp1QKBS1MzMzU0g2lS9ynJ2doa+vj5SUFGVHIYQQQuRq/vz5cHJyQkJCAg4dOtRofVBQEG7fvo1169ahb9++SkjYNC0tLZSWluLIkSNi18fGxkJDQwMaGoorPVS+yNHW1sbEiRNx5MgRVFdXKzsOIYQQIjccxyE+Ph4dO3aEn59fg+kUDhw4gL1792L06NFYsGCBElOK9+6770JfXx9xcXGN1tXW1iIxMRHvv/8+tLW1FZaJ9yKnqqoKYWFh6Nu3LwQCAfr06YOIiAhcuHABHMchJCRE6j7d3d1RWVmJrKwsvuMSQgghKsXMzAwREREoKytDYGAgAKC0tBSBgYHQ09NDfHw8OI5TcsrG2rdvj2nTpiE9PR1lZWUN1qWlpaG0tBTe3t4KzcTrE48rKyvh7OyM/Px8ODs7w83NDX/++SdCQkIwduxYAICtra3U/Y4bNw4CgQDJycmYMGECn5GJimGMIS0tDZcvX0aPHj0wY8YM6OjoKDuWRM6cOYNTp06hQ4cO+Oijj9C1a1dlRyKEoG3um35+fkhKShKN3uzbtw/l5eWIjY1F7969lR2vSd7e3oiJiUFCQgKWLFkiWh4XFwcDAwO4uroqNhCTwcqVKxkAVlRU1GC5p6cn09DQYAkJCQ2Wf/vttwwAA8B+++03WTbJpkyZwoyMjNjz589lej9pG+bPn88AMC0tLQaADR06lFVVVSk7VotiY2MZx3FMU1OTcRzHunXrxoqLi5Udi5DXnqrtmwUFBQwAKygoaLHtrVu3WKdOnZiOjg4DwCZNmsRr/5KQpL+ioiIGgLm4uDDGGLO2tmYDBgwQrf/777+ZlpYWW7BgAWOMMR0dHda7d2+F5OftdFVWVhYOHDgAPz8/zJw5s8G6OXPmAHgxlNWvXz+Z+nd3d0dZWRlyc3NbnZWoptzcXERFRQGA6Or8goICbN68WZmxWvTw4UMEBASAMYbnz5+DMYby8nIEBwcrOxohr7W2vm8aGxtj/vz5qK6uhra2NrZv367sSBLx9vbGb7/9hrNnzwIAdu3ahdraWoWfqgJ4PF21detWAMDSpUsbrTMwMAAA2NjYQFNTU7R806ZN2LhxI0pLSzFkyBBs3boVAwcOFNv/5MmToaWlheTkZDg4OIhtc/78+dZ+DKJEJ06caLSM4zjk5eWp9O+2qKgINTU1DZY9f/4cFy9eVOnchKg7Vdw3hUKhxG3LysoQExMDAKipqUFaWhp8fX153w7f/cycORPLli1DXFwchg8fjvj4eNja2mLQoEG8bVfiyUJlGf4Rd7pKT0+PWVpaim1/8+ZNBoD5+/uLlv3www9MR0eH7dq1i125coXNmTOHdevWjT148KDJ7Q4YMIDZ29s3uR7//5QYvehFL3rRi16q/JLkdIybmxsDwNatW8cMDQ2Znp4eu3HjRrPvqT/do8i8r56uYowxd3d39sYbb7Bjx44xAGzLli2idZKcrmrpJSleRnIqKipQWVmJIUOGiF1//PhxAGhQxX333XcICAgQPfBox44d6N69O/bs2YOAgIBGfZSWlkIoFDZ7d1ZBQUErPgVRBevXr8ePP/4IDQ0N1NXVwdzcHImJiRAIBMqO1qxDhw5hzZo14DgOjDG88cYb2LNnD3r06KHsaIS81lRt3xQKhY0u6RAnISEBycnJmDRpEpYtWwYzMzNMmzYNPj4+OHbsWIvvT0xMhJWVlcLyvsrHxwdJSUnw8vKCQCDAjBkzpHo/X/l5Gcl59OgRA8AGDhzYqG11dTWzsrJiANiZM2dEyzQ1Ndnhw4cbtPXw8GCzZ88Wu82YmJgGfRD1VFdXx1JTU9m8efMYAPbrr78qO5LEfv31V7ZgwQIGgB0/flzZcQgh/58q7ZuSXFhbf8GxgYEBu337tmi5p6cnA8C+//77VvXPd15xIzm1tbXM2NiYAWDTpk1r0L7NXXjcoUMH9O7dG4WFhSgsLBQtr66uhpeXF4RCITQ0NGBjYwMAKC8vx/Pnz9GtW7cG/RgZGeHOnTtit5GUlISePXti2LBhfEQmKorjOEyePBk+Pj4AgHbt2ik5keTs7e3h5eUFAOjcubNywxBCRNravunj44OKigpERUU1GHHatm0bunbtipCQENy4cUOJCVumqamJlJQUJCcnY+3atUrLwdvdVcHBwairq8OoUaMQGBiIRYsW4a233sLdu3chEAjQr18/6OrqytT3gwcPcOLECbi6uqrkA5AIIYQQPsTExCAzMxOenp6YPn16g3Vdu3ZFdHQ0Kisr4e3tDcaYklJKZsiQIXB1dVXYPFXi8FbkBAUFISwsDB06dEBcXByOHj0Kf39/REVF4enTpw2uxzE0NISmpiZKS0sb9FFWVobu3bs36js9PR01NTVwc3PjKy4hhBCiUoqKihAcHAwjIyNER0eLbePh4YHp06fjxIkTTbYh/8PbLeQcx2H58uVYvnx5g+VJSUkAGj7puF27drC1tUVWVhYmTZoE4MVzUbKzs/HVV1816js5ORmdO3eGk5MTX3EJIYQQlWJubo7KysoW2+3Zswd79uxRQCLJmJmZSTWq9PTpUzmmaYjXaR3EuXTpEgA0uj9+0aJF8PHxweDBg2FnZ4cNGzZAS0sLH3/8cYN2T58+RUZGBtzd3aGlJfe4hBBCCFETcq8aLl68CKDxnFUff/wx7t69i88//1z0MMDMzEy88cYbDdrl5ORAIBDA09NT3lEJIYQQokYUMpJjbGwMQ0PDRusWLlyIhQsXNvv+MWPGNJhqnhBCCCFEEjIVOfXXxnTq1KnFtsXFxbJsghBCCCGkVWQucugiYEIIIYSoMt5uISeEEEIIUSVU5BBCCCFELdE92YQQQoiCCYVC6lcB26EihxBCCFEQQ0ND6OrqyjSzt6R0dXXF3tEsC0XkfRWf+anIIYQQQhTE1NQUQqFQro9GMTQ0hKmpKS99KSLvq/jMT0UOIYQQokCmpqa8/RFXhLaW92V04TEhhBBC1BIVOYQQQghRS1TkEEIIIUQtUZFDCCGEELVERQ4hhBBC1BIVOYQQQghRS1TkEEIIIUQtUZFDCCGEELVERQ4hhBBC1BIVOYQQQghRS1TkEEIIIUQtUZFDCCGEELX0Wk7QWVJSopAZVfmcSbWeIrLLIzch6kpRx5OXybqPKiNrc17XY428fw98/1wV/b2hWchboaSkBFZWVqiqqpL7tnR1dSEUCnn7ZSkqO9+5CVFXijyevEyWfVRZWZvzOh5rFPF74PPnqozvDZ/5X7sip7y8HFVVVUhMTISVlZXctiMUCjFz5kyUl5fztgMrIrs8chOirhR1PHmZrPuoMrI253U91sj798D3z1XR3xu+8792RU49Kysr2NnZKTuGTNpydkLUUVvaJ9tSVnXW1n4PbS1vPbrwmBBCCCFqiYocQgghhKglKnIIIYQQopZkKnJWrVoFjuNQXFzMcxxCCCGEEH6o/EhOZmYmOI7Dvn37FLbN4uJicByHcePGNdkmOzsbHMchICBAYblasmXLFnAch9mzZ4tdf//+fRgbG0NXVxdXr15VcDpCZPfPP/9I9Y8qxhjOnz8vv0BSePz4Mb755hvY2dmhY8eO0NHRgYmJCUaOHInQ0FD89ddforZOTk7gOA537txReM76415zr4qKCpw/fx7a2tro168fnjx5IravCRMmgOM4JCYmKvhTtH1t8Tj+8nene/fuqK2tFdtOKBSK2pmZmSkkm8rfXeXs7Ax9fX2kpKRg2rRpyo6j0ubPn4+kpCQkJCTAw8MDH3zwQYP1QUFBuH37NjZt2oS+ffsqKSUh0vP398e5c+eQnZ0Nc3PzZtsyxrBo0SJs3boVf/zxB/r06aOglI1VVlbCwcEBly9fhqWlJWbOnIkuXbqgvLwceXl5WLduHSwsLGBhYaG0jK+ysLDAzJkzxa4TCASws7PDF198gdWrVyM0NBSRkZEN2mzfvh0ZGRlwc3Nrsh/StLZ8HNfS0kJpaSmOHDmCKVOmNFofGxsLDQ3Fjq2ofJGjra2NiRMn4vDhw6iuroaOjo6yI6ksjuMQHx8PGxsb+Pn5YcSIETA0NAQAHDhwAHv37sXo0aOxYMECJSclRDqRkZFwcnKCk5NTs4VOfYGzadMmbNu2TakFDvAi9+XLlzF37lxs374dHMc1WF9UVITq6molpRPP0tISq1atarbNF198gdTUVGzevBlubm5wdHQE8OLzLFmyBF27dkVMTIwC0qqftnwcf/fdd3Hp0iXExcU1KnJqa2uRmJiI999/H6dOnVJYJt5LqqqqKoSFhaFv374QCATo06cPIiIicOHCBXAch5CQEKn7dHd3R2VlJbKysviOq3bMzMwQERGBsrIyBAYGAgBKS0sRGBgIPT09xMfHNzrQEqLqTExMkJ2dDW1tbTg5OaGoqKhRm1cLnPrvvzL9+uuvAF7861vcfmdubo7+/fsrOlaraWtrY/fu3dDW1sYnn3yCR48eoa6uDl5eXnj06BFiYmLQtWtXZcdss9rqcbx9+/aYNm0a0tPTUVZW1mBdWloaSktL4e3trdBMvBY5lZWVcHR0xIoVK9CrVy8sXLgQtra2CAkJQWhoKADA1tZW6n7HjRsHgUCA5ORkPuOqLT8/P7i4uIiqfj8/P5SXlyMyMhK9e/dWdjy1dffuXZw9exYAmjwnrYoeP36MU6dOITs7G5WVlcqO06TmCh1VLHAAoEuXLgCgMtdO8Mna2hqrV68Wjd5ERkbi9OnTmDVrFtzc3JQdr4G2uG+21eO4t7c3amtrkZCQ0GB5XFwcDAwM4OrqqtA8vJ6u8vb2xvnz55GQkNDgXOyGDRtEIziDBg2Sut8OHTpg7NixSE1NRUxMjMLO6f35559NDtuq+p1lsbGxsLa2xieffILq6mpMmjRJ4RX06+T06dOYPHkyHj58CADw9fXFzz//DD09PSUna15xcTHee+89XL9+HQDQq1cvZGVl4c0331RyMvHqC52XT12ZmZmpZIEDAFOnTkViYiLmzp2LvLw8jB07FoMHDxYVP6qoqePeuHHjYG9v32BZSEgIUlJSsH37drRr1w4mJibYvHmzgpJKpq3um0DbPI4PGzYM1tbWiI+Px5IlSwAAd+7cQUZGBgIDAxV/yQmTwcqVKxkAVlRUJFp2/PhxBoAFBAQ0al9WVsYAsPbt27Pa2lpZNsl27tzJALCcnByZ3l+voKCAAWAFBQVNtikqKmIAJHr5+/vLvB15ZH/Z8uXLGQCmra3Nbt++LZdtyIuq5JBEVVUVMzAwYBoaGqLvhYaGhth9QdWMHDmSaWlpiXJramoyOzs7Zcdq0c2bN5mFhQUzNTVlXl5eDADbtm2bwnNI8j2NiIhgHTt2bHDcsLCwYEFBQezq1asN2jo6OjIA7O+//27VNmV5X0vHve+++07s++qP/QDYgQMHeMvDB1XcN+V9HOf75yrN30wXFxfGGGMbN25kANiZM2cYY4ytW7eOAWAXLlxgjDGmo6PDevfurZD8vI3kbN26FQCwdOnSRusMDAwAADY2NtDU1AQAJCUlITo6GgUFBbh//z6KioqavaVs8uTJ0NLSQnJyMhwcHMS2keSWUaFQ2GKbei4uLjh69KjYddnZ2Rg9ejSv2+Ozr7KyMtGFfzU1NUhLS4Ovr69ctiUP9dtXdg5JFBUV4d69ew2W1dXV4cSJEypzG3NTzp4922D4/vnz57hw4QLy8/MVfheEtDZv3owPP/wQO3fuhI+PD4YPH67wn7ck38/FixfD19cXR48eRW5uLvLz83H27Fls3boVsbGx2L9/v9g7UfjYtiztmzvuvYoxhq+++kr0/0lJSfDw8JBLLlmo4r6pqOM4Xz9XWfqZOXMmli1bhri4OAwfPhzx8fGwtbWV6kxOS9uVeB4tWSojcSM5enp6zNLSUmz7mzdvNhr12L17N1uzZg3bsmVLo76aMmDAAGZvb9/kekg4+gIpq1JxTp48KdFIjjxeklS4bm5uDABbt24dMzQ0ZHp6euzGjRstvk+euelFL3V9SfuvzoqKCjZv3jwGgBkaGrLq6mrGmHQjOXxnleS496rIyEgGgM2aNUuUPTk5WaL3vu7HGnkdx+X1c5X2b6a7uzt744032LFjxxgAtmXLFtE6SUZyWnpJipeRnIqKClRWVmLIkCFi1x8/fhxAw+txZs2aBQC4cuWKRNsoLS2FUChs9u6sgoKCFvupn8ZdUficnl7S7AkJCUhOTsakSZOwbNkymJmZYdq0afDx8cGxY8ck2hafuWVR/1mVnUNSERER2LNnj+j/NTU1sWPHDrz99ttKTNWyI0eO4MsvvwTHcWCMAXhxe7C7u7uSkzWNMYaIiAjs3bsXXl5e2LlzJ4yMjKChoYHt27fD2NhYYVlkPZ7o6+sjKioK6enpuHHjBgoLCzF48GCp+pB23+D72Hf16lWEhobCxMQEW7ZswT///IO3334bAQEBGDlypMTXHcl7H1e1fVNRx3G+fq6yfm98fHyQlJQELy8vCAQCzJgxQ6r38/a9kLgcesmrIzmPHj1iANjAgQMbta2urmZWVlYM+N/5uZcVFhY26KspMTExTfYhDVnOL4oj6UiOoq/JuXXrFuvUqRMzMDBocP7W09OTAWDff/99q7ehCKqSQ1J1dXUsOjqavf/++wwAS0hIUHYkiaWlpbHx48czAOzbb79Vdpxm1dXVsYULFzLgxTU49d+TI0eOiK7RuX79usLytPZ7+tZbbzEALD8/nzGmGtfkSDKSU1tby+zt7RkAdvToUdHyqKgoBoBNmzat1Xn4omr7pryP46pwTQ5jL74jxsbGYr8Pirwmh5eT7h06dEDv3r1RWFiIwsJC0fLq6mp4eXlBKBRCQ0MDNjY2Mm8jKSkJPXv2xLBhw/iIrLZ8fHxQUVGBqKgo9OjRQ7R827Zt6Nq1K0JCQnDjxg0lJlRP9VN8rF+/HgDw1ltvKTmR5CZOnCi6rsLZ2VnJaZrGmrlNvFu3bi0+R0cZYmJicO7cObHrUlJSIBQK0alTJ1hbWys4WeuEh4fjzJkzotuc682bNw/Ozs7Yt28fkpKSlJjwf9rivqkOx3FNTU2kpKQgOTkZa9euVVoO3q4sDA4ORl1dHUaNGoXAwEAsWrQIb731Fu7evQuBQIB+/fpBV1dXpr4fPHiAEydOwNXVVSUfgKQqYmJikJmZCU9PT0yfPr3Buq5duyI6OhqVlZXw9vYWnZogpC1orsCpJ8kDAxUtIyMDw4YNw5tvvgkvLy98/vnnWLhwIUaNGgU3NzdwHIdt27a1qSe5FxYWYtWqVTA3N0dERESDdRzHITY2Fh07dkRgYCDKy8uVlLLtUqfj+JAhQ+Dq6qqwearE4a3ICQoKQlhYGDp06IC4uDgcPXoU/v7+iIqKwtOnT2V6Pk699PR01NTUqNwDplRJUVERgoODYWRkhOjoaLFtPDw8MH36dJw4caLJNoSooqVLl0r0HJxXC51bt24pMGVj69evR3h4OMzNzXH69Gl899132L59O27fvo05c+YgLy+v0R8yVVZTU4PZs2ejpqYGcXFx6NixY6M2Lz+td968eUpI2XbRcZx/vN1CznEcli9fjuXLlzdYXj9kKcuTjuslJyejc+fOcHJyak1EiZmZmbVYITs5OalUFW1ubi7R02r37NnT4CI8QtoCBwcHWFhYICAgoMW29YXO2rVrlT61QL9+/RASEiLxdDbZ2dnyDdQMSY572trauHDhQot9+fn5wc/Pj69or422ehyX5LvzsqdPn8oxTUNyn6Dz0qVLABo/6fjevXsoKSnBX3/9BQD4/fffUVFRAVNTU9FzdYAXP4yMjAy4u7tDS0vl5xMlhMjBqzMxt8TExET07C5CyOtL7k/7unjxIoDGIzmpqamwtbWFp6cngBcXP9ra2iI1NbVBu5ycHAgEAlE7QgghhBBJKGQkx9jYWDRVfD0vLy94eXm1+P4xY8bQxWuEEEIIkZpMRU79tTGdOnVqsa2qT2RJCCGEEPUkc5GjqIuACSGEEEJkodoz8BFCCCGEyIiKHEIIIYSopdf2nmy+pqFXRv9ttW9C1JUi95vWbktV9nFVyaEs8vr8ba1feW/ntStyDA0Noaurq5CZyHV1dRvdVdYaisrOd25C1JUijycvk2UfVVbW5ryOxxpF/B74/Lkq43vDZ/7XrsgxNTWFUChUyG3phoaGMDU15a0/RWXnOzch6krWfVIoFGLmzJlITEyElZWV1NuVZR/l6/jR2uwvex2PNYo4jvP5c1Xk38x6fOZ/7Yoc4MUvra3uWG05OyHqqDX7pJWVFezs7HhO1DQ+jx+Kzq5O2tpxvK3lfRldeEwIIYQQtURFDiGEEELUEhU5hBBCCFFLVOQQQgghRC1RkUMIIYQQtURFDiGEEELUEhU5hBBCCFFLVOQQQgghRC1RkUMIIYQQtURFDiGEEELU0ms5rYOqKykpUeg8IdJoaU4RvrLXz0TL14y0r+McOYQQ8rqjIkfFlJSUwMrKClVVVcqOIpauri6EQqHYgkEe2fma+ba53IQQQtQTFTkqpry8HFVVVbzM8Mu3+tmHy8vLxRYLqpq9pdyEtIYso5etHamUdWSSj5FWPkdZJfkcNDpMWoOKHBXVlmf4bcvZCZFGa0cvZR2plGVkku+RVj5GWVv6HDQ6TFqLihxCCJGRMkYvZR2ZVLWRVkk+h6plrkejw20HFTmE8KC0tBSXLl3C2bNnAQD5+fmwsrJC+/btlZyseQ8fPsSFCxeQk5MDAPjll1/Qp08fdOrUSbnB2pi2NHrZlrLWa4uZiWqgW8gJkVFxcTFCQ0NhamqK7t27w8XFBStWrAAA+Pv7Q09PD++88w7i4+Px5MkTJaf9n3v37mHjxo2wsbGBvr4+nJyc8OWXXwIAPv30U3Tu3BlWVlYIDw9X2bv8CCFEElTkECKlqqoq/Otf/0KfPn0QHR2NKVOm4Mcff8S1a9fw73//GwAQFhaGrVu3onPnzvDx8YGZmRkOHjyo1Nx1dXXYvHkzevXqhc8++wzW1tbYuXMnCgsLsX37dgDA+vXrsXv3bgwZMgQrVqxAr1698O233+L58+dKzU4IIbKgIkcNcRzHy4tyNyYUCjFw4EDExMRg/fr1+L//+z9ERUVh6tSpsLS0FJ2eMjc3h7+/P44cOYJr167h3XffhaenJ2bPno1nz57JNaM49+7dw3vvvYeFCxfik08+wc2bN7F3717MmTMH1tbW0NXVBQAYGxtj1qxZSEhIwK1btxAYGIhly5Zh5MiRKCsrU3huQghpDZmKnFWrVoHjOBQXF/Mch7TWw4cPER4eDsZYq1+Uu6Hff/8do0aNgkAgwKVLlxASEoIOHTq0+D4LCwskJSVh9+7d2L9/Pzw8PFBTUyO3nK+6f/8+nJ2dceXKFZw4cQJRUVHo1q1bi+8zNDTExo0bkZOTg6KiIjg6OuLu3bsKSEwIIfxQ+ZGczMxMcByHffv2KTtKm5CRkYHx48crO4bUVD13ZWUlJk6ciB49euDUqVPo27evVO/nOA6zZs1CamoqMjMzsXTpUjklbYgxhunTp+PWrVvIzs7G6NGjpe5jxIgROH36NO7fv4+pU6eirq5ODkmbV1NTg8ePH0v1noqKCvmEkdLjx4/xzTffwM7ODh07doSOjg5MTEwwcuRIhIaG4q+//hK1dXJyAsdxuHPnjsJzFhcXtzhKWlFRgfPnz0NbWxv9+vVr8lqzCRMmgOM4JCYmKjyzrq4uevbsiffeew8rVqxo8POtl52d3eJndXJykmt2ohgqf3eVs7Mz9PX1kZKSgmnTpik7jsq7cuUKPvroI2XHkJqq5162bBnu3r2LrKwsGBgYyNyPi4sL1q5di5CQEHh4eMDBwYHHlI3FxcUhMzMT6enpGDBggMz9vPnmm9i7dy+cnZ2xdetWLFiwgMeULfP398e1a9eQkZGBjh07tth+586dCA4Oxrlz52Bubq6AhOJVVlbCwcEBly9fhqWlJWbOnIkuXbqgvLwceXl5WLduHSwsLGBhYaG0jK+ysLBo8lkyAoEAdnZ2+OKLL7B69WqEhoYiMjKyQZvt27cjIyMDbm5uvD2TpiUvZ66urkZZWRny8vIQFhaGb775BkuXLsXXX3/d6HT24MGDMWnSJLF9mpmZyTs2UQQmg5UrVzIArKioSJa3S+3jjz9menp67OnTpwrZnjIVFBQwAKygoEDq99bU1LA1a9Y0WDZjxgymo6PD/vjjj0bt165dywCww4cP85JN1uzKzt2S33//nQFgmzdvbrFtYmIiA8ASExObbFNbW8vs7e3ZkCFDZMojqaqqKmZgYMDmzJnTYltJcjPGWGBgIOvYsSN7+PAhTyklk5uby/T09JiDgwOrrKwULRf3u42Pj2ccxzE/Pz/2/PlzueZq6bu1Zs0aBoDNnTuX1dXVNVp//fp1JhQKRf/v6OjIALC///5b5m3K+r6ioiIGgLm4uLTY17Nnz5itrS3jOI5lZ2eLll+/fp117NiRde3alZWVlbUqDx+Zc3JymJmZGQPAli9fLlp+8uRJBoD5+/s3m7E12Ylq4P10VVVVFcLCwtC3b18IBAL06dMHERERuHDhAjiOQ0hIiNR9uru7o7KyEllZWXzHVSunTp3CqFGjGizbuHEjdHV1ERAQ0GB5UVER1qxZAw8Pjyb/JaMoqp47OjoaRkZG8Pf356U/TU1NLF++HPn5+Th37hwvfYrz448/4t69e1i+fDlvfX7++ed48uSJ3E9DvOqdd95BZmYmLl26hPHjx+PRo0di2+3cuRPe3t7w9fVFdHQ0NDSUe0b+119/BQAEBQWJvSje3Nwc/fv3V3SsVtPW1sbu3buhra2NTz75BI8ePUJdXR28vLzw6NEjxMTEoGvXrsqOCQcHBxw9ehQ6OjoIDw/HzZs3lR2JKBivR4DKyko4OjqKbj1duHAhbG1tERISgtDQUACAra2t1P2OGzcOAoEAycnJfMZVOz///HOj0x9GRkZYv349Tp48iV27domWz5s3D9ra2ti0aZOiYzaiyrnr6uqQkJAAb29vtGvXjrd+x40bB1NT0wafjW+7d+/GmDFjYGlpyVufJiYmmDRpklxzN6WlQkfVChwA6NKlCwDg6tWrSk7CP2tra6xevRpFRUVYsmQJIiMjcfr0acyaNQtubm7KjifSr18/fPjhh3j27BlSUlKUHYcoGK/X5Hh7e+P8+fNISEhocC52w4YNohGcQYMGSd1vhw4dMHbsWKSmpiImJkYlDl6qqLa2Fpqamo2Wz507F7t27UJwcDAmTZqEY8eO4ejRo9i8eTOMjY2VkLQhVc597do1VFRUwNnZmdd+NTU14eTkhLy8PF77rVdXV4dz587h888/571vZ2dnhISE4NmzZ7wWfpKoL3RcXFwwfvx4rF27FgCQmpqKNWvWqFSBAwBTp05FYmIi5s6di7y8PIwdOxaDBw8WFT+q6M8//8SqVasaLR83bhzs7e0bLAsJCUFKSgq2b9+Odu3awcTEBJs3b1ZQUsk5OTkhISGh0chpfn6+2M8KiP+8pO3hrcjJysrCgQMHEBAQ0Ohiszlz5iAkJATt27dHv379ZOrf3d0dqampyM3NlfvFmqru9u3b+OabbxAVFSVadvHixSYLSI7jEBMTA1tbWwQGBiInJwdDhgxBUFCQghK/0BZzX7x4EcCLCxT5NnjwYOzfvx/Pnz8XW+S1xvXr11FZWSm33M+ePRM9M0jRXi506i+AVsUCBwCmTJmCiIgIrFy5EhEREYiIiADw4kLZcePGYeHChXjzzTeVnLKhv/76C6tXr260vFOnTo3+6GtqauLrr7/G+++/j2fPniEyMlIlpwTp2bMnADR6gndBQQEKCgrEvkfc5yVtD29FztatWwFA7K2x9Xej2NjYiA7ma9euxcGDB/HHH39AV1cXjo6OCA8Pb/KK9smTJ0NLSwvJyclNFjnnz5/n4ZMol1AobLHNpUuXRA+Zqz9AZmZmNvvHf8CAAQgODsbatWuhqamJ9PR0mf8YNJWxpeyqmrs5Fy5cgKamJoqLiyV6LlRRUZHovy19H6uqqlBdXY3c3FyJnrcjjStXrgB48RBASfYLaXLX/6E4c+aM0p6ErKOjg82bN8PPzw/Ai2svfH19RUWpokjynVq8eDF8fX1x9OhR5ObmIj8/H2fPnsXWrVsRGxuL/fv3Y8qUKXLZtiztXVxccPToUYnaMsbw1Vdfif4/KSkJHh4evOWSZZ+Vhr+/P77//nuZ3y/vfKRpEs9lJsvVyuLurtLT02OWlpZi29+8ebPRlewuLi5s586d7LfffmPnz59n7733Huvfvz+rqalpcrsDBgxg9vb2Ta4HoDavlq7aX7lyJQsPDxf9/8t3DjQlIiKCAWC9evVi1dXVLbZ/Vf0dBa3Jrsq56UUvWV/S3mVTUVHB5s2bxwAwQ0ND0fdamrur+M4qzd1V9SIjIxkANmvWLFH25ORkid4rzedobebY2FgGgM2ePZsxxt/dVfRS3ktSvIzkVFRUoLKyEkOGDBG7/vjx4wAaXo/z6r8U/v3vf6NPnz74/fff8fbbbzfqo7S0FEKhsNm7s5oadmxLhEKhRM+WcHV1RVBQEEJCQnDz5k2Ympo22/7mzZtYuXIlrK2tceXKFYSHh8t8101iYiKsrKxkyq6KuZuTnZ2NJUuWICMjA0ZGRi22v3jxInx8fBAbG9vi9Wfx8fGIi4vDqVOneD/FUlpaigkTJmDjxo1wdHRssb00uc+cOYOgoCAcPHhQac8Sqb8GZ/LkyRg4cCAiIiLQt29fbNmyRTRFhSJIur++Sl9fH1FRUUhPT8eNGzdQWFgo9alFab/PsmZtytWrVxEaGgoTExNs2bIF//zzD95++20EBARg5MiREl931Nzn4CtzdnY2AGDo0KGt7utlshxTiGLxUuRoa2sDeDE0/qpnz54hPDwcQPN3Vj148AAAmnzQ2qFDh1BXV9fsVfsSD1+pgUGDBuHOnTsoLS1FWloaXF1dm20/f/58AC+eLLx48WJ8/fXX+Pjjj9GnTx+pt21lZSXzz7qt5TYyMsKSJUtQXV0t1XsHDRrUYvu1a9di6NChTf7joDUYYzAyMsL9+/d5z/2f//wHenp6cHV1Vcr1Lzt37mx0Dc748ePh4uKC0NBQiR8YqGwcx7XqNGVr9sPWev78OebMmYMnT55gx44d0NfXh76+PtavX4/58+dj/vz52Lt3r0R9yftzXL16FT/++CN0dHR4v+tLmb8DIhlejlAdOnRA7969UVhYiMLCQtHy6upqeHl5QSgUQkNDAzY2NmLf//z5cwQHB2PChAkwMTER2yYpKQk9e/bEsGHD+IisFiZPnozDhw/j9u3b6NGjR5PtkpOTkZqairCwMJiYmCAyMhLt2rVT+IXH9dpSbmNjY5iamiItLY3Xfp88eYKsrCyMGDGC137rcRyHESNGIC0tjff5vNLT0/HOO+8orcARd5u4pM/RUbSYmJgmn4WUkpICoVCITp06wdraWsHJWic8PBxnzpyBn58fXFxcRMvnzZsHZ2dn7Nu3D0lJSUpM+MIvv/wCFxcXVFdX47PPPlOJu0mJYvF24XFwcDAWLFiAUaNGYdq0aRAIBEhNTUWfPn0gEAhgbm4udhiZMYaAgACUlJTgl19+Edv3gwcPcOLECfj6+ipldmxV9cEHH2DFihXNjoZUVlbi008/ha2trehOlJ49eyIsLAwLFy7ETz/9hKlTpyoo8QttKTfHcZg7dy7WrVuHDRs2QF9fn5d+9+/fj4qKCnh7e/PSnzhz587FxIkTkZeXh+HDh/PS5+XLl/Hzzz/jp59+4qU/abT0HJxXby9XhRGdjIwMBAQEwNLSEiNGjEDPnj3x+PFjXLhwATk5OdDQ0MC2bdugo6Oj1JzSKCwsxKpVq2Bubi66W6wex3GIjY2FjY0NAgMDMWrUKBgaGso908u3vT979kw0rUNhYaHo4ZsrV65s9L7mbiEXCAT47LPP5JiaKIQsF12Ju/C4rq6OhYWFMWNjY9auXTvWv39/tn79evbf//6XAWDTp09v1E9dXR0LCAhgZmZmrKSkpMnt/fDDDwwAO3bsmCxx2xRpHhdeW1vLDAwM2G+//dZkm08//ZRpaGiwvLy8Ru+1s7NjPXv2lPgR/XxN66BquVty+/ZtpqOjwxYvXszLtiorK5m5uTmbNGmSTHkkVVtbyywtLZmTk1OL0xtIkruuro6NHz+emZiYsGfPnvEdt1nSTNXQ1BQQ8tDSz+2///0vCw8PZ2PGjGHm5uZMIBAwgUDALCws2Jw5c1h+fn6D9qo+rcOzZ8/YoEGDGMdx7OTJk022i4mJYQDY1KlTZc4jTeaXX+3bt2c9evRgo0ePZl9++SX7888/G72v/sLj5l76+vqtyk5Ug9znrjp48CAD0OCOGsZeHDADAwNZr1692PXr15vtw9PTk3Xu3LnZO6/UhbQ7z44dO5pcl5+fzzQ1Ndn8+fPFrs/Ly2MaGhrs008/5SWbNNlVKbckvv32W8ZxHDt9+nSrtxUYGMh0dXXFHnz5lpWVxYCW592SJPeOHTsYAJaWlsZ3zBZ99dVXUs1FlZuby+zt7Vlpaalccynjj528ihxF46PIURZVzUUak/ss5JcuXQLQ+EnHQUFB2Lt3Lw4fPoz27dvjzp07AF5cePzyU1SfPn2KjIwMuLu7Q0tL5SdNVzgfH58m1w0ePBi1tbVNrh86dKjSnnPS1nIvWrQIhw4dgru7O06ePCnzNRQRERGIjo7Gtm3bFDLztLOzM+bPn4/FixfD1NQUH3zwgUz9ZGZmYt68efDx8cHEiRN5TtmyL774AowxiU9Xv/POO8jNzaXT24S85uR+5WD9w7levbMqOjoaFRUVGDlyJHr06CF65ebmNmiXk5MDgUAAT09PeUclpEmampo4dOgQjI2N4ejoKPUcOFVVVfjXv/6F4OBghIaGIjAwUD5Bxfjuu+/g6uoKT09PbNy4UaoCsa6uDlFRUZgyZQrGjh2Lbdu2yTFp86QtWKjAIYTIvci5dOkSjI2NG118xl6cKmv0cnJyatBuzJgxKC8vl+mJoITwycDAANnZ2XBwcICbmxs++ugj0UhlU2pqavDTTz9h0KBBiImJwaZNm/D1118rKPELWlpa2Lt3LxYuXIjg4GCMHDkSx48fb/auK8YYsrOz4ezsjAULFsDX1xcHDx5U+FxVhBDSGjKd/6kvRCSZo0SSR+ET0lZ06tQJKSkp2LNnD5YuXYpBgwZh+PDhcHR0hJ2dHe7fvw8AOHDgAKKjo5Geno6///4bo0ePxuHDh2Weu621tLS0sGHDBri6umLevHkYM2YM+vbtK5ow8smTJwCAtLQ07Nq1C8eOHYNQKET//v2RlZXF+wSlhBCiCDIXOa+OuBDyuuA4DjNmzMCHH36I1NRU/PDDD9izZ4/ooZcAsH79etjY2MDDwwO+vr5in+KtDA4ODrh06RJycnIQFxeH//znPw0mTF25ciUsLS1hb2+PqKgojB49mk77EELaLLqSlxAZaWtrw8PDQzQh4T///IM7d+6guLgY9vb2Ej/WXtE4jsOoUaMwatQoAC+eSXTr1i1cu3YNQ4cObfYBjYQQ0pZQkUMIT7p06YIuXbpgwIAByo4iFT09PVhZWdEcPIQQtUNFDiGEtJJQKGwz21Jk1uZIk0NVMtdTtTykaVTkqChV3IkkzaRq2VUtD1EfhoaG0NXV5XV2b0no6upKPV2CsrI2p6XPoYqZ68nyOyCKx7Hm7iMlCldSUgIrKytUVVUpO4pYurq6EAqFMDU1bbROlbM3l5uQ1igpKUF5eblCt2loaCjTd1kZWZsjyedQtcz1ZP0dEMWiIkcFqepODbS8Y6tqdjogEULI64eKHEIIIYSoJbk/8ZgQQgghRBmoyCGEEEKIWqIihxBCCCFqiYocQgghhKglKnIIIYQQopaoyCGEEEKIWqIihxBCCCFqiYocQgghhKglKnIIIYQQopaoyCGEEEKIWqIihxBCCCFqiYocQgghhKglKnIIIYQQopaoyCGEEEKIWvp/uB6Hj9G0XlUAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c);" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5f5896a5-e639-401c-992a-19b960720ec4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ─H─U1─U1─U1─U1───────────────────────────x───M─\n", + "q1: ───o──|──|──|──H─U1─U1─U1────────────────|─x─M─\n", + "q2: ──────o──|──|────o──|──|──H─U1─U1────────|─|───\n", + "q3: ─────────o──|───────o──|────o──|──H─U1───|─x───\n", + "q4: ────────────o──────────o───────o────o──H─x─────\n" + ] + } + ], + "source": [ + "c = QFT(5)\n", + "c.add(gates.M(qubit) for qubit in range(2))\n", + "\n", + "print(c.draw())" + ] + }, + { + "cell_type": "markdown", + "id": "8ce6b04d", + "metadata": {}, + "source": [ + "#### Plot circuit with built-in styles" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "afa80613-6330-4a85-928f-4cb884d81990", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c, scale = 0.8, cluster_gates = True, style=\"garnacha\");" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "916f7b83-1ad7-4984-8573-eb55dfeb125d", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABJkAAAFICAYAAADzkC8GAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA8pklEQVR4nO3de3xU9Z3/8ffM5DIzuZCEhAASFOIFImRZb0VQuwpiEEEstnipVre6ta6XpWV1f3XX7Q22Kt3dirpda1dbq1Vbq2BVvBa8oFWqiHITMFIgEAhJSMhMMjNn5vcHEAlJSDLnzJyZOa/nPz485zvn+/mczCQzb875jmvr99wxAQAAAAAAACa47S4AAAAAAAAA6Y+QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaVl2F5COPAXD5fYXJ3yeaKBJRmtdwuc5XLJ6G6hEnwsn9u3EniXn9g0AAAAgdST7c0myPm8QMg2Qp2C4yq97VZ4cf8LnMkIB1T80NWkfPJPZ20Al8lw4sW8n9iw5t28AAAAAqcOOzyXJ+rxByDRAbn+xPDl+Pf+z76lxe23C5ikZMUozbl0ot784aR86k9XbQCX6XDixbyf2LDm3bwAAAACpI9mfS5L5eYOQKU6N22u1u3aD3WUkRCb3djRO7NuJPUvO7RsAAABA6sjEzyUs/A0AAAAAAADTCJkAAAAAAABgWlwh06Dz7tTIBYY8RcdaXQ8AAAAAAADSUMpfyeQ9fppGLjDkHz/X7lL6pbC8QvNfbtCcBU/2OqaierLmv9ygqbcsSmJl1jhUe838xQMaUzZ6nM669g7NWfiUbnxqg+a/3KC59yxJRsmmObFnyZl9O7FnAAAAAKnlUK4w/+UGffuJtXK5PT2OK6k4oXPc9b/+IMlV9izlQ6b2z15XNNgsX9XFdpcCE06YfKEmXj5PFdWT1da02+5yksKJPUvO7NuJPQMAACC5PIXHDGx8wTBJrsQUg6QwImHllZRr9Bnn97h/fM3XFTUMRQ0jyZX1LvW/XS4aUXDjC/KNuUjy5EhGyO6KEIeNbyzR5neWqaF2nbyFJbrxyXV2l5RwTuxZcmbfTuwZAAAAyZN77CSVffUR7V16i4KfLutzfNbgSg257Ant//BRtay8NwkVIhHq1r2vstEna1zNFdrybtefu8vtUdWUS7X1wxWqqJ5kU4XdWX4lkyvbp8Jz79CweetV8f02Df/uJhVMnqfsYRM0coGhopq7BnzMwLpn5PYWyls5xepykSR7t27U7s1rFDUidpeSNE7sWXJm307sGQAAAMnT8dc/K7DxRQ2etVi+E2uOOvZQwGQE92r/h79JUoVIhEhHUBuWP6PRZ5wvf1Fpl32VE6cpr6Rcn7z0uE3V9czSkMmVk68h1/1JRVN/KGPfNrW+c69CdatVVHO3iqYtlCSF6lYP+Ljtny5TNByUv2q2leUCAAAAAJD6YoYa//gdBTa+cNSg6fCAac9vr1A02JjkQmG1T156TJ6sbFVN+VqX7eMuuFLBlkZtXvmCTZX1zNLb5QZ/5ZfKGX6KGp66WoGPHuvcXnDWd1Q8/R5JUmjn6gEfNxYOqH3zK/KNnSktuUGKxawqOWGKho/SpKtu63FfYXlFkqsBAAAAAKS1g0GTJA2etVh7l97c5dY5AqbMtGvjh9pTu07jLrhcq55+QJLkLx6iUadP0Ud/fFhGOLWWFLIsZModfZ784y9V659/3iVgkqS2D36t4un3KBoKKNKwMa7jB9c+I//YWcodOUkdW9+2ouSEKj5mdK8hEwAAAAAAA9ZL0ETAlNk+eelxnXvDjzV0zCnateEDjTt/rjxZ2fp4WWrdKidZGDIVTLxRktTy5j3d9h16gofrP5Zi0S8ec+bNKpg8T578cnXsWKWm525WeNeaHo8f3PCcYkZYvqrZaREy1b7/mp6+Y26P+yqqJ2vuIr7eHAAAAAAwQEcETc1/WqDCif9IwJTB1r32O53zzTs1/oIrtWvDBzr5gitUv2mN9nz2id2ldWNZyOStnKJwwyYZTZ9323fgqxO73irnr75cRRf8RI3P3qBQ3V9UcPZ8DbnmRdX91xjFOlq7HSMabFK4YaNyR54Zd43Z5SfH/dhDskoqTR8jVefrz1yxgyGhy3WU5bzcB/bFotHex8QhUeeir+Pa2bOUmL75WfcsE3/WAAAAyEyt7z8kT8EwFU35dxnBJjX96T/kKRwmT+Ewu0tDHwb6vj+4b6+2vPuSxvzdJdr4xhINrjhBr913e8LnPVK4fm3fc5ia4SCXd5Dc3kKFdqzqcb+3cuqBgnZ+1LmtYPKtan3vf9W2+lFJUuMz1+uYf6lT3t9cof3v/W+3Y7jzhii7bKxa3lwUd51Dr3k+7sfapXRWan3dZEdbiyTJV1jS6xj/wX0dge5hoRl2nQs7e5ac2bcTe5ZS7/UOAACA9JDlL1H5135ldxlIoI+XPaYTz56p6fPvU7gjqHWv/37AxzD7eWPbXcf1OcaaK5mMsCTJ7e/hg5knW4XnzJckheo+7NyWM+xvte/1H30xLmqoo3aFciomSj2ETL6qi+VyexRc92zcZe56ZEbcjz0kq6QyqR8EG5beokjjlqTM1Z/eGrdtViTUoaEnTZDL7VEsanQbM6zqdElSw2d9p5wDkahz0VffdvYsJaZvftY9y8SfNQAAADKPZ1CFSmr+Q9H2fWp57xcafMECxaIRNa+4Sx1bV9pdHvoQT67w+V9eV+ueOhWUDdf6P/1BHfv3DXjeZHzesCRkioUDijR9ruzy8couH6dw/cH7Aj05Gjzn/5Q9pEqxqHFgTSZJHn+pXJ4sRffXdzmO0ba718u3/FWXKNKyQ6Ht78VdZ38u7Uo1kcYtKVW3Ee7QxjeW6OSpX9OZV35XKx+9u8v+0uPGqrrm6+poa9Wmt629csyuc2Fnz5Iz+3Ziz1Lqvd4BAACQerIGV6rk/B/J2F+vPb+9ovP2uPbP31LRObd1+9Y5ZIZYNKpnv3+1CsqGafeW+NZiSsbnDcvWZGp566cqmblY5dcvV9uaJxWLtMs3ZqYiTbWKhoMymmoVCwfjOrYrt1De0edq/6qHrCoXJqx48E4NG3OqJl11m0Z/aZq2r1mpSKhdxSMqVTmxRi6XS8//5IbOW48kqaTieJ0x91ZJUlaOr3NbzfzFnWOWLbo5uY0MgBN7lpzZtxN7BgAAQHro6VvkDoVM+978T0Xb93X51jlklvpNq1W/abXdZRyVZSHT/ncfkNtbpPwzvqX8U69VpPEz7X//QQXXL9XweesVPGw9JiPQoJgRkTu/vMsxPHlDZLTu6nZs30kz5MrKUcDErXKwTqC5Qb+5aapOm/NtHT9puqpnXC1PVo7amnbr07ee06rf3a/dWz7u8pi84nKNm3Z5120lXbel8odwJ/YsObNvJ/YMAACA1NdTwNTFEd86R9AEO1gWMklSy/KFalm+sMs2X9Ulkg5bj0mSjLBCOz+Ut/I8tW88eMuJ26PcUV/Wvlfv7HZcf9VsGYFGddQut7LchGip36ZF00qPOmbbmrf7HJPqQoFWrXz07m63E/WGntOXE/t2Ys8AAABIXVklfQRMh3QLmm5S8NOXklgprNCfXOFw/33RiARWMzCWhkw9yRlWLanrN8tJUuvbP1PJV36h0I4PFKr7QIVnf1eKRtT20eNHVJgr74k1Cq57RuphEV4AAAAAADJZLBxUaOdqNb54e+8BU+fgA0FTLNKuaIf134gMHE3CQ6bsYRMkSaGdH3bZHljzW3nySlU07cfy5JcrtGOVdj8yXbEjXgTeY89WLNKuwCdPJ7pUAAAAAABSjtFap4Y/XN//B8QMNb14e+IKAnqR+CuZhlYrsm+7ooG93fa1vrNYre8s7uFRX2jf8qp2LCw/6hgAAAAAAADYK66Qqb12hfTaDxRtb+5zbN2iynimAAAAAAAAQBqJK2TqqF2hjtoVVtcCAAAAAACANOW2uwAAAAAAAACkP0ImAAAAAAAAmEbIBAAAAAAAANMS/u1ymapkxKi0Pn6qzt2TZNXjxL6d2HMy5+mvVKsHAAAAQOJl4ucfQqYBigaaZIQCmnHrwoTPZYQCigaaEj7PIcnsbaASeS6c2LcTe5ac2zcAAACA1GHH55Jkfd5wbf2eO5bwWTKMp2C43P7ihM8TDTTJaK1L+DyHs6q3rJJKlc66Vw1Lb1GkcYvp4yX6XDixbyf2LDm3bwAAAGSm7PKTNfSa57XrkRkK16+1uxz0U7JyhUOS9XmDK5niYLTWZeyHQat7izRuSYtfdE7s24k9S87tGwAAAEDqyNRcgYW/AQAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaYRMAAAAAAAAMI2QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBpWXYXAACwj6dguNz+4oTPEw00yWitS/g8h0tWbwOV6HPhxL6d2DMAAEhvyX7/kqz3JYRMAOBQnoLhKr/uVXly/AmfywgFVP/Q1KR94E5mbwOVyHPhxL6d2DMAAEhvdrx/Sdb7EkImAHAot79Ynhy/nv/Z99S4vTZh85SMGKUZty6U21+ctA/byeptoBJ9LpzYtxN7BgAA6S3Z71+S+b6EkAkAHK5xe612126wu4yEyOTejsaJfTuxZwAAkN4y8f0LC38DAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANPiCpkGnXenRi4w5Ck61up6AAAAAAAAkIZS/kom7/HTNHKBIf/4uXaXAgCOUlheofkvN2jOgid7HVNRPVnzX27Q1FsWJbEyaxyqvWb+4gGNKRs9Tmdde4fmLHxKNz61QfNfbtDce5Yko2TTnNiz5Ny+AQBAejr0Pnz+yw369hNr5XJ7ehxXUnFC57jrf/1BkqvsWcqHTO2fva5osFm+qovtLgUAAJ0w+UJNvHyeKqonq61pt93lJIUTe5ac2zcAAKki55jT5Dvxgn6Pd+UWquDMf5TkSlxRSWREwsorKdfoM87vcf/4mq8rahiKGkaSK+tdlt0F9CkaUXDjC/KNuUjy5EhGyO6KAAAOtvGNJdr8zjI11K6Tt7BENz65zu6SEs6JPUvO7RsAgFSRN36O8sZ/VXuX3KTgp8uOOtaVW6ghlz0mT+ExCqxdIqNle5KqTJy6de+rbPTJGldzhba827V/l9ujqimXauuHK1RRPcmmCruz/EomV7ZPhefeoWHz1qvi+20a/t1NKpg8T9nDJmjkAkNFNXcN+JiBdc/I7S2Ut3KK1eUCADAge7du1O7NaxQ1InaXkjRO7Flybt8AAKSKppf+VYENL2jwxffJd2JNr+MOD5j2PHFlRgRMkhTpCGrD8mc0+ozz5S8q7bKvcuI05ZWU65OXHrepup5ZGjK5cvI15Lo/qWjqD2Xs26bWd+5VqG61imruVtG0hZKkUN3qAR+3/dNlioaD8lfNtrJcJIo7W7kjTpckefLKbS4GAAAAAJCWYoYa/zjvqEHTkQFTeM96GwpNnE9eekyerGxVTflal+3jLrhSwZZGbV75gk2V9czS2+UGf+WXyhl+ihqeulqBjx7r3F5w1ndUPP0eSVJo5+oBHzcWDqh98yvyjZ0pLblBisWsKhkWy634kgbP/h95/CWSpNJLH1Lb6sfV9MqdUixqc3UA4lE0fJQmXXVbj/sKyyuSXA0AAAAc5WDQJEmDL76vy61zmR4wSdKujR9qT+06jbvgcq16+gFJkr94iEadPkUf/fFhGeHUWlLIspApd/R58o+/VK1//nmXgEmS2j74tYqn36NoKKBIw8a4jh9c+4z8Y2cpd+QkdWx924qSYTG3t0illz4sV1Zu5zaXy628CVco0vxXtb73oI3VAYhX8TGjew2ZAAAAgITrIWhq37oy4wOmQz556XGde8OPNXTMKdq14QONO3+uPFnZ+nhZat0qJ1kYMhVMvFGS1PLmPd32RYONkqRw/cedV7P4qi5R/pduUM7wU+Txl2jHPaNlNG/t9fjBDc8pZoTlq5odd8iUXX5yXI9D//jHzpIr2yuX68i7MF3KP/16tTsgHMwqqezyXydwYs9SZvTd39pr339NT98xt8d9FdWTNXdR/77SPZnnKtV/Lomqz4l9O7FnAAAOlwnvS/ur9f1fyO0dpMEX3y8j0Ch3Vo4aX7pDcrvT6vP+QH9W6177nc755p0af8GV2rXhA518wRWq37RGez77JKHzHilcv7bvOUzNcBhv5RSFGzbJaPq82z5PwTBJXW+Vc+XkqePzNxRcv0QlMxf3efxosEnhho3KHXlm3DUOveb5uB+L+LlcLmXllznq/JfOutfuEpLOiT1Lzu07Hql2rmIH/9GjezB+GPeBfbGotbf72nUu7OxZcmbfqfa8BwBkLqf9zcnKL5MklV58n82VJF5w315tefcljfm7S7TxjSUaXHGCXrvv9gEfx+xzZNtdx/U5xpKQyeUdJLe3UKEdq3rc762cKkkK7/yoc1tg9W8kSdlD+pc2uvOGKLtsrFreXBR3nbsemRH3Y9E37+jzVHTOd7ttj0WjijRv1d6lN9lQVXJllVSqdNa9alh6iyKNW+wuJymc2LOUGX0f6iFZknmu+tNbR1uLJMlXWNLrGP/BfR2BVuuKU+LORV9929mzlJi+nfqzBgDgkEx4X9pfrpx8lUxbIE9Budy5BYpFDTWv+Ik6tq60u7QBied9+MfLHtOJZ8/U9Pn3KdwR1LrXfz/geZPxHLHmSiYjLEly+3t48+bJVuE58yVJoboP457CV3WxXG6PguuejfsY/bm0C/GL7N2s/L+5TJ6CcrncXzy1XG639r25yFHnP9K4xVH9Ss7sWXJu3/FItXPVuG2zIqEODT1pglxuj2JRo9uYYVUHvimz4TNr67brXNjZs+TMvlPteQ8AyFyZ/jfn0CLfbn+JGpf9P5VefJ/aP39LRV++vcti4Jnq87+8rtY9dSooG671f/qDOvbvG/AxkvEcOcp14/0XCwcUafpc2eXjlV0+7osdnhwNnvOwsodUKRY1DqzJFCd/1SWKtOxQaPt7FlSMRIhFOrT78bnq2Pbnzm1GW4MaX7xdwQ3OuVUOQHowwh3a+MYS+YvKdOaV3a/CLD1urKprvq6OtlZtejszfoc5sWfJuX0DAJApjvwWuUhTrSRp35s/VWDDCxp88X3ynVhjc5WJFYtG9ez3r9az379Kb/7fj+wup1eWrcnU8tZPVTJzscqvX662NU8qFmmXb8xMRZpqFQ0HZTTVKhYOxnVsV26hvKPP1f5VD1lVLhLEaNmuPU9cKXdemdy5hYo0b5WiEbvLAoAerXjwTg0bc6omXXWbRn9pmravWalIqF3FIypVObFGLpdLz//khs7brSSppOJ4nTH3VklSVo6vc1vN/C/WF1y26ObkNjIATuxZcm7fAACkuyMDpvCe9V8s8t3Dt85l8hVN9ZtWq37TarvLOCrLQqb97z4gt7dI+Wd8S/mnXqtI42fa//6DCq5fquHz1it42HpMA+U7aYZcWTkKmLhVDskVbdujaNseu8sAgKMKNDfoNzdN1Wlzvq3jJ01X9Yyr5cnKUVvTbn361nNa9bv7tXtL16tw84rLNW7a5V23lXTdlsrBgxN7lpzbNwAA6ayngKkbhwVNqc6ykEmSWpYvVMvyhV22+aoukWRuPSZ/1WwZgUZ11C43Ux4AYABa6rdp0bTSo47ZtubtPsekulCgVSsfvVsrH727X+PpOX05tW8AANJVyfSfHD1gOuTwoGnWYu38xXky9m1LUpXW68/78MP990UjEljNwFgaMvUkZ1i1pK7fLCdJbl+xPEUjlVVSKUnKHlIlt69IRvNfFQ02HVZhrrwn1ii47hmph4U6AQAAAABA5ml+7cdyewsV3rOh78EHg6bA2j+kdcCU7hIeMmUPmyBJCu3seiWTb8wsDb70/zr/f8g3/ihJ2vv7v1fbh7/q3O499mzFIu0KfPJ0oksFAAAAAAApwmitk9Fa1/8HxAy1f7Y8YfWgb4m/kmlotSL7tisa2Ntle9uHv+oSJvWmfcur2rGwPFHlAQAAAAAAwAJxhUzttSuk136gaHtzn2PrFlXGMwUAAAAAAADSSFwhU0ftCnXUrrC6FgAAAAAAAKQpt90FAAAAAAAAIP0RMgEAAAAAAMA0QiYAAAAAAACYlvBvlwMApLaSEaPS+vipOndPklWPE/t2Ys8AACC9ZeJ7Q0ImAHCoaKBJRiigGbcuTPhcRiigaKAp4fMckszeBiqR58KJfTuxZwAAkN7seP+SrPclhEwA4FBGa53qH5oqt7844XNFA00yWusSPs8hVvaWVVKp0ln3qmHpLYo0bjF9vESeCyf27cSeAQBAekvm+/BDkvW+hJAJABzMaK3L2A/BVvcWadyicP1ay46XKE7s24k9AwCA9Jap78NZ+BsAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaYRMAAAAAAAAMI2QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmJZldwEAAACwjqdguNz+4oTPEw00yWitS/g8R0pWfwOVyPPhxJ4BAOmJkAkAACBDeAqGq/y6V+XJ8Sd8LiMUUP1DU5MaMiSzv4FK1PlwYs8AgPRFyAQAAJAh3P5ieXL8ev5n31Pj9tqEzVMyYpRm3LpQbn9xUgOGZPU3UIk8H07sGQCQvgiZAAAAMkzj9lrtrt1gdxkJk+n99cSJPQMA0g8LfwMAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0+IKmQadd6dGLjDkKTrW6noAAAAAAACQhlL+Sibv8dM0coEh//i5dpcCAACQ9grLKzT/5QbNWfBkr2Mqqidr/ssNmnrLoiRWZt6humvmLx7QmLLR43TWtXdozsKndONTGzT/5QbNvWdJMkq2hFP7BgCknpQPmdo/e13RYLN8VRfbXQoAAAAy0AmTL9TEy+eponqy2pp2211O0ji1bwBA4mTZXUCfohEFN74g35iLJE+OZITsrggAAAAZZOMbS7T5nWVqqF0nb2GJbnxynd0lJYVT+wYAJI7lIZMr26eCs76jvAlfV9agkTJa69T67gNq/+xPGnbTX9Ty5iI1L7t9QMcMrHtGeROukLdyito/fdHqkgEAAOBge7dutLsEWzi1bwBA4lgaMrly8jXkm68qd8Tpat/ymoLrnlVWyfEqqrlb7ZtfkSSF6lYP+Ljtny5TNByUv2o2IRNSkttXovxTrpbvhPMlSd5RX1a4fp2kmL2FATDFd9J05Z96rSQp72+vUsubP1W0bY/NVQEAAACpydKQafBXfqmc4aeo4amrFfjosc7tBWd9R8XT75EkhXauHvBxY+GA2je/It/YmdKSG6QYH9yROjwFQzXkqmflySuTy+2RJBV9+TZll4xW4wvzba4OQLyKz/+R8k+5SrGoIUnKH/9V+Y+fqvpHZ8vYt93m6gDzioaP0qSrbutxX2F5RZKrAQAAmcCykCl39Hnyj79UrX/+eZeASZLaPvi1iqffo2gooEhDfJflBtc+I//YWcodOUkdW9+2omTAEoWTbpEnr7QzYDokb/ylalvzlDq2v2dTZQDilTO0WvmnXCVJna9tl9sjt69Ig86er8Y//pON1QHWKD5mdK8hEwAAQDwsC5kKJt4oSWp5855u+6LBRklSuP5jKRaVJBWec7t8476i7NKTDlypVPuGmpfdLqN5a4/HD254TjEjLF/V7LhDpuzyk+N6HHA0vjEz5XJ3fynFjLDyJlyhaLjNhqqSJ6uksst/ncKpfTuFf8IVihkRuTxdX9sud5b8J01X6/u/sKmy5HHiczwTeh5I7bXvv6an75jb476K6smau6jvr7JP9rlK9Z9NIupzYs8ABiYT/n4NlBN7TgXh+rV9jrEsZPJWTlG4YZOMps+77fMUDJPU9Va53FFf1v537lfH9vflyspVcc1dGvKN57Vz8d9IB29NOFw02KRww0bljjwz7hqHXvN83I8FBsrlyVbeybOVd/Jsu0tJitJZ99pdgi2c2reTubJyHfX3xInPcSf2HK9UO1exg/+Y6XK5ex/kPrAvFo1aPr9d58POvlPtOQA4mRNfj07s2U7b7jquzzGWhEwu7yC5vYUK7VjV435v5VRJUnjnR53b9vzqwi5j9j77LR0zf4uyy6oOXPF0BHfeEGWXjVXLm4virnPXIzPifizQm8Izb5LvhPN7vJqp8YXbFdr9iQ1VJU9WSaVKZ92rhqW3KNK4xe5yksapfTtF1uATVDrzv7ttj0Ujaq99U/tM/C1KF058jmdCz4d6SJZkn6u++utoa5Ek+QpLeh3jP7ivI9BqbXFKzPnoz8/Uzr7T+fUCZIpM+Ps1UE7sOV1YcyWTEZYkuf09/GHzZKvwnAOLH4fqPuz1EG7vIElf3Fp3JF/VxXK5PQquezbuMvtzaRcwUM2v/UA5w/+2c+HvWNSQy+1R28e/V9vHT9pdXtJEGrc48jXm1L4zXbh+rfYfc+rBhb8jcrmzFIsaigab1fTKvzlq4W8nPsed2HO8Uu1cNW7brEioQ0NPmtD5N/lIw6pOlyQ1fGZ93XadDzv7TrXnAOBkTnw9OrHnVHeUa2r7LxYOKNL0ubLLxyu7fNwXOzw5GjznYWUPqVIsavR4hZIkyeVWcc3dCm58QUbLjh6H+KsuUaRlh0IsoowUY7TuUv3DF6pl5b3q2P6+2mvf0N6lt6jxhX+2uzQAJjS98m9qePbbav9shTq2r1LLu/dr18PTHRUwAenGCHdo4xtL5C8q05lXfrfb/tLjxqq65uvqaGvVprcz57ZXp/YNAEg9lq3J1PLWT1Uyc7HKr1+utjVPKhZpl2/MTEWaahUNB2U01SoWDvb42JKL/0eeopGq/9+ze9zvyi2Ud/S52r/qIavKBSwVDTaq5e2fqeXtn9ldCgALBTe+qODGF+0uA8AArHjwTg0bc6omXXWbRn9pmravWalIqF3FIypVObFGLpdLz//khs5bzCSppOJ4nTH3VklSVo6vc1vN/MWdY5Ytujm5jQyQU/sGAKQWy0Km/e8+ILe3SPlnfEv5p16rSONn2v/+gwquX6rh89YreNh6TIcrnnW/vJVTVP/Q3ykaaOhxjO+kGXJl5Shg4lY5AAAAZL5Ac4N+c9NUnTbn2zp+0nRVz7hanqwctTXt1qdvPadVv7tfu7d0vbo+r7hc46Zd3nVbSddtqR62OLVvAEBqsSxkkqSW5QvVsnxhl22+qksk9bweU/Gs++Q76ULVP3TuUW8/8FfNlhFoVEftcivLBQAAcJyW+m1aNK30qGO2rXm7zzGpLBRo1cpH79bKR+/u1/h07/cQp/YNAEgdloZMPckZVi2p6zfLSQcCprzqy7Tn0YsVCwflzi+XdHDh74MLiR+oMFfeE2sUXPeM1MMihgAAAAAAALBfwkOm7GETJEmhnV2vZCr40rclSeX/8EaX7fUPnaeO2hWd/+899mzFIu0KfPJ0YgsFAAAAAABA3BJ/JdPQakX2bVc0sLfL9r/e4enX49u3vKodC8sTURoAAAAAAAAsElfI1F67QnrtB4q2N/c5tm5RZTxTAAAAAAAAII3EFTJ11K7ocksbAAAAAAAAnM1tdwEAAAAAAABIf4RMAAAAAAAAMC3hC38DAAAguUpGjErr46f6/EdKRj1O7BkAkH4ImQAAADJENNAkIxTQjFsXJnwuIxRQNNCU8HkOl8z+BipR58OJPQMA0hchEwAAQIYwWutU/9BUuf3FCZ8rGmiS0VqX8HkOZ2V/WSWVKp11rxqW3qJI4xbTx0vU+XBizwCA9EXIBAAAkEGM1rqM/uBvdX+Rxi0K16+17HiJ4MSeAQDpiYW/AQAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaYRMAAAAAAAAMI2QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBpWXYXAAAAAAD95SkYLre/OOHzRANNMlrrEj7P4ZLV20DZcS4ApCdCJgAAAABpwVMwXOXXvSpPjj/hcxmhgOofmpq0cCWZvQ1Uss8FgPRFyAQAAAAgLbj9xfLk+PX8z76nxu21CZunZMQozbh1odz+4qQFK8nqbaDsOBcA0hchEwAAAIC00ri9VrtrN9hdRkJkcm8AMh8LfwMAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0+IKmQadd6dGLjDkKTrW6noAAAAAAACQhlL+Sibv8dM0coEh//i5dpcCAAAAIIUVlldo/ssNmrPgyV7HVFRP1vyXGzT1lkVJrMwah2qvmb94QGPKRo/TWdfeoTkLn9KNT23Q/JcbNPeeJckoGYDDpHzI1P7Z64oGm+WrutjuUgAAAAAg7Zww+UJNvHyeKqonq61pt93lAP3mKRiu7LIx/X+AyyPv6L9LWD3oW5bdBfQpGlFw4wvyjblI8uRIRsjuigAAAAAgbWx8Y4k2v7NMDbXr5C0s0Y1PrrO7JKBfiqb8q3IrJmrPE1cqvGf90Qe7PCq56L/kP2m6dv7iPBn7tiWnSHRh+ZVMrmyfCs+9Q8PmrVfF99s0/LubVDB5nrKHTdDIBYaKau4a8DED656R21sob+UUq8sFAAAAgIy2d+tG7d68RlEjYncpwIA0vvgvMlp2qOyyx5RdNrb3gYcCpjEXau/SmwmYbGRpyOTKydeQ6/6koqk/lLFvm1rfuVehutUqqrlbRdMWSpJCdasHfNz2T5cpGg7KXzXbynIBWMCdky9JcmV5ba4EgGVcHnkKR9hdBZAwriyvPIMq7C4DANCHWEeLdj9x5dGDpsMDpiU3KfjpsuQXik6W3i43+Cu/VM7wU9Tw1NUKfPRY5/aCs76j4un3SJJCO1cP+LixcEDtm1+Rb+xMackNUixmVckA4uTKyVPx1B/If/JsSVLZ3Me0/y8Pa98bi6SYYW9xAOLmP/kSFf3d/5Mnf4gkqaTmLu1depMiTZ/bWxhgCZcKz/onFZx+ndw5eZKkQefcpr1Lb1aso8Xm2mClouGjNOmq23rcV1hOwAikk0NB05DLHlPZZY9pzxNXfrHT5SZgSjGWhUy5o8+Tf/ylav3zz7sETJLU9sGvVTz9HkVDAUUaNsZ1/ODaZ+QfO0u5IyepY+vbVpQMwITBsxbLO+rLcrk9kiR3tlcFX/qWJJf2rfiJvcUBiIu3cooGX/Rfih32jznZQ8ZoyBVPaecvzlUs1GZjdYB5hZNvUeGkW+RyuTq3eY+brNJL/ld7nrjcxspgteJjRvcaMgFIP0cGTU2v3ClJGnT2fHmPm0zAlEIsC5kKJt4oSWp5855u+6LBRklSuP5jKRY9MH7Srco77ZvKKjpWikYUqvtAzS/fodD293o8fnDDc4oZYfmqZhMyATbLKj1Bvsrzum13udzKP/UatbyzmA+jQBoqPPMfFYsaneGxJLncWXLnlclfNVttqx87yqOB1ObKylXB6dd3CZikA89x77FnKnvoeIV3fWxTdbBa7fuv6ek75va4r6J6suYuWpLkigCYdXjQVHLBgeV4vMedpb1L/pGAKYVYFjJ5K6co3LBJRg+X03sKhknqeqtcpPmvan5hviKNmyVPrgon36oh17youp+e0BlKHS4abFK4YaNyR54Zd43Z5SfH/VgAX8g97uxe97mzvfKOPleRptokVpR8WSWVXf4LZILsIWO7BEydohHljjwzrlve0wmv68zmKRgmd25+r/t9lVM6/zE0U2XCczzZtSdzvv7MFTv4HHW5jrK0rvvAvljU2udzOj9vMl0mvLYHoulPC1Q255eSpLZ1SxXZt43P+kkSrl/b5xhLQiaXd5Dc3kKFdqzqcb+3cuqBgnZ+1LktuO6ZLmOaXvxn5Z9+vbLLx6nj8ze6HcOdN0TZZWPV8uaiuOsces3zcT8WQP+VXnyf3SUkTemse+0uAUg4lydbeWMvUt7Yi+wuJSl4XTvToLP+SYPO+ie7y0gKnuP9l2rnqqPtwNphvsKSXsf4D+7rCLRaOneqnQt058SfUf64S5Q/7hK7y3CMbXcd1+cYa65kMsKSJLe/h192nmwVnjNfkhSq+7Dnx3uylX/69TICjQduqeuBr+piudweBdc9G3eZux6ZEfdjAXQ1+OIHlDXoGLncX/waiUUjat+6UvtW3GVjZcmRVVKp0ln3qmHpLYo0brG7HMAS/pMuVOGZ/9hlWywalaIR7Xn6mz1eaZxJeF1nvsLJt8pXOaXLFXuxaETG/j1qeOYfHHElU7o/xw/1kCzJPFf96a1x22ZFQh0aetIEudwexaLdv2xlWNXpkqSGz/q+4mAg0vl5k+ky4bXdLy73wTWYzlLzmz9VNLBXhWf8gzx5pWp86Y6Mv5MiXVgSMsXCAUWaPld2+Xhll49TuP6TAzs8ORo85/+UPaRKsajRLUDKPfYslX3jebmyfTL279Luhy9QNNjU4xz+qksUadnR65pN/dGfS7sA9M+eJ69U2aUPK7v0hM5tHX/9s/YuuclR39ATadzC7xZkjH316+TKylX+aX/feStGrKNFDUtvUsfnb9lcXfLwus5cjX+cp8GzFndZVzDSvE0Nv/97R3044Tnef6l2roxwhza+sUQnT/2azrzyu1r56N1d9pceN1bVNV9XR1urNr1t7V0cqXYu0F1G/4xcHpVc9F8HF/n+Yg2m4MYXNeSyx1R8/g+154krFd6z3uZCYdmaTC1v/VQlMxer/PrlalvzpGKRdvnGzFSkqVbRcFBGU61i4WCXx4R2rNKu+06R2z9Y+adfp9LLnlD9z89UNLC3yzhXbqG8o8/V/lUPWVUuAJOMfdu165fnK3fEGfIUDle4YZPCuzP0jxrgGDE1v/5jtb7/S+WOOF3RUJvaP39LMjrsLgywRCzUpobf/72yy8You2yMjP316vjru5JifT4WSBUrHrxTw8acqklX3abRX5qm7WtWKhJqV/GISlVOrJHL5dLzP7mh89Y6SSqpOF5nzL1VkpSV4+vcVjN/ceeYZYtuTm4jQH8dDJj8Yy7s9i1yR37rHEGT/SwLmfa/+4Dc3iLln/Et5Z96rSKNn2n/+w8quH6phs9br+Bh6zEdEou0H7icr3GLGre/p2HzNijvlGvU+tZPu4zznTRDrqwcBUzcKgcgMTpMXF0IIDUZrTsVWL/U7jKAhAnv2aDwng12lwHEJdDcoN/cNFWnzfm2jp80XdUzrpYnK0dtTbv16VvPadXv7tfuLV3vIMkrLte4aZd33VbSdRshE1LSUQKmQwiaUotlIZMktSxfqJblC7ts81UdWISr1/WYDudyyZWV222zv2q2jECjOmqXW1EmAAAAgAzUUr9Ni6aVHnXMtjVv9zkm1YUCrVr56N3dbpfrTSb0DGcqvuDHRw2YDjkyaKr/1SwZLduTWCkOsTRk6knOsGpJXb9ZTpKKLvgPBdY/J6Nlu9y+EhV86dvKKhyhwNo/HFFhrrwn1hz4NroeFrYDAAAAAACZp+3jp9X+2XIFP32pz7GHgqb8U66S0bIjCdWhJwkPmbKHTZAkhXZ2vZLJUzBcpXMflyd/iKLBRnVsX6X6X3xZkSMuXfYee7ZikXYFPnk60aUCAAAAAIAUEdqxakDjYx0tan3n/gRVg/5I/JVMQ6sV2be922Lee3//jX49vn3Lq9qxsDwRpQEAAAAAAMAicYVM7bUrpNd+oGh7c59j6xZVxjMFAAAAAAAA0khcIVNH7Qp11K6wuhYAAAAAAACkKbfdBQAAAAAAACD9ETIBAAAAAADANEImAAAAAAAAmJbwb5cDAAAAACuVjBiV1sdP1bl7kmr1AEhthEwAAAAA0kI00CQjFNCMWxcmfC4jFFA00JTweQ5JZm8DlexzASB9ETIBAAAASAtGa53qH5oqt7844XNFA00yWusSPs8hVvaWVVKp0ln3qmHpLYo0bjF9vGSfCwDpi5AJAAAAQNowWusyNvCwurdI4xaF69dadjwA6AsLfwMAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaYRMAAAAAAAAMI2QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA07LsLgAAAAAAgCN5CobL7S9O+DzRQJOM1rqEzwM4ASETAAAAACCleAqGq/y6V+XJ8Sd8LiMUUP1DUwmaAAsQMgEAAAAAUorbXyxPjl/P/+x7atxem7B5SkaM0oxbF8rtLyZkAixAyAQAAAAASEmN22u1u3aD3WUA6CcW/gYAAAAAAIBphEwAAAAAAAAwjZAJAAAAAAAApsUVMg06706NXGDIU3Ss1fUAAAAAAAAgDaX8lUze46dp5AJD/vFz7S4FAAAAAJAiCssrNP/lBs1Z8GSvYyqqJ2v+yw2aesuiJFYGOFfKh0ztn72uaLBZvqqL7S4FAAAAAICk8xQMV+lXfiG3r6R/D3B5VDz9LuUeOymxhQFHSPmQSdGIghtfkO/E6ZInx+5qAAAAAABIKle2TznDJqjs8sf7DppcHpVc9J/KO/krcucWJKdA4CDLQyZXtk+F596hYfPWq+L7bRr+3U0qmDxP2cMmaOQCQ0U1dw34mIF1z8jtLZS3corV5QIAAAAAkNIijVu0+4nL5PENPnrQdDBg8p90ofYuvVnBT19KbqFwPEtDJldOvoZc9ycVTf2hjH3b1PrOvQrVrVZRzd0qmrZQkhSqWz3g47Z/ukzRcFD+qtlWlgsAcckZNkH5p1wjScoeMtbeYgBYwu0r7nyf4TvxArmy/fYWBFgsq+hY5f3NFZKk3JFnSi6PzRUhUfh9lrkie/sImlzuIwKmZfYUCkfLsvJgg7/yS+UMP0UNT12twEePdW4vOOs7Kp5+jyQptHP1gI8bCwfUvvkV+cbOlJbcIMViVpUMAANSfP6PlH/KVYoZEUnS4AsXyVsxUY0v/LMkfjcB6Sh3xBkq/eojcmXlSpIKz7xZ+dWXaffjX1Ok6XN7iwMskPc3l6v4ggVSLCpJKj7vX+UfM1N7nrxSsdB+m6uDlZz6+6xo+ChNuuq2HvcVllckuZrEOhQ0DbnsCZVd/rj2/PaKzn2Dzv6uvMdOJmCCrSwLmXJHnyf/+EvV+uefdwmYJKntg1+rePo9ioYCijRsjOv4wbXPyD92lnJHTlLH1retKBkABsR3wgXKP+UqSZLL88Wvz7zxl6r987cUWPesTZUBiJs7W4NnPyBXVq5c7gNXdrhcLrn9JSq5cJF2P3apzQUC5ngGVaj4ggVyudyS64ubGHKGjtOgs+ap+fUf2VgdLOXg32fFx4zuNWTKREcGTU2vHXgde487S3uX3ETABFtZFjIVTLxRktTy5j3d9kWDjZKkcP3Hnf+CcrjiWfer4Es3qPG5m7X/3Qd6PH5ww3OKGWH5qmbHHTJll58c1+MAQJLyTv2GYtGIXO6uvzpjUUN5p1yt8N5NNlUGIF65w0+VJ6+023aXO0u5I06Td/S5Mtp221AZYI286q8duAvA1XW7y+1RXvXX1Lb2D/YUBstl2u+zrJLKfo+tff81PX3H3B73VVRP1txFSyydL1U0vvJvKqn5D5XN+YUkqfUvv1Jk3zY+9yJhwvVr+xxjWcjkrZyicMMmGT1chukpGCap51vlvCfNUO7IiYq07Djq8aPBJoUbNh64hzxOQ695Pu7HAkBvXG6PvMecwu8YIAOVffVhu0sAEsadW8DfLgfh99nRlc661+4STCs8/ZsqPP2bdpeBDLbtruP6HGNJyOTyDpLbW6jQjlU97vdWTpUkhXd+1GW7O2+ISmbdrz2/vkhlVx09XXbnDVF22Vi1vLko7jp3PTIj7scCQF71XOVPuLLzEvRDYtGI2j55Wvs/+LVNlQGIl8c3WKVffbjb61qSjGCz9jz1DSkWsaEywBq5x5ym4vN/0G17LBpRaNcaNb38bzZUhUTItN9nWSWVSQ1+GpbeokjjlqTNZ5rLfWANpuPOUstfHlHB+K/JCDapcdm/KNbRYnd1cDBrrmQywpIkt7+Hr1H0ZKvwnPmSpFDdh112DZ7zf2p9Z7HC9Z/0OYWv6mK53B4FTax50p9LuwCgNy1v/Zd8J5wvT15Z5y1zsWhE0WCz9r2xSNG2PTZXCGCgwpL2/+Vh5Z/2TUkxuVxuxaKGXG6P9q34icK7PurrEEBKC9evk2/Mhco95rTO8CEWjUixmJpf+zHvjzMIv8/MiTRuSZ/Xg8ujkov+88Ai3wfXYAp89FsNuewJFU/9d+357RWdS9YAyebue0jfYuGAIk2fK7t8vLLLx32xw5OjwXMeVvaQKsWixoE1mQ7Kn3ijXDl+tb79n/2aw191iSItOxTa/p4VJQPAgEWDTdr96FfU9snTinbsVzTUpsDaJap/dDYBE5DGml9foOZXv69I8zbFIh0K79mghmdvVNtHT9hdGmCBmBp+d41a33tQRluDYpF2tW9dqd2Pz1Wo7gO7i4PF+H3mAAcDJv9JF3b5FrlDi4F7fINVdvnjcvt6uAAESALL1mRqeeunKpm5WOXXL1fbmicVi7TLN2amIk21ioaDMppqFQsHD0xaepIGnfuv2vU/Zx5YiLAPrtxCeUefq/2rHrKqXACIi9G6U00v3q6mF2+3uxQAlolp/we/0v4PfmV3IUBCxMJB7Vtxl/atuMvuUpBw/D7LaL0ETIcc+a1zXNEEO1hyJZMk7X/3ATW/8m+KhtqUf+q18p1wgfa//6CanrtZ7myfQoetx5RbMVFuf5mGf+dTVfywQxU/7FBW8XEqnvHfGnrTX7od23fSDLmycvh6cAAAAACA8/QRMB3CFU2wm2VXMklSy/KFalm+sMs2X9UlkrquxxRY/6xCi7suEl527Ytq++BXavvLI92O66+aLSPQqI7a5VaWCwAAAABIUy3127RoWulRx2xb83afY9JBbsUZ8p80/agB0yGHX9GU/7dfV8vK9P/mPKQPS0OmnuQMq5bU9ZvlYu37FG7f13WgEZbRurP7iv5ZufKeWKPgumekqJHocgEAAAAASCkdf31HOx88V0bLjn6Nj+zdovpfz5LRuivBlQFdJTxkyh42QZIU2vnh0Qf2wnvs2YpF2hX45GkLqwIAAAAAIH30N2DqHN+6M0GVAL1L/JVMQ6sV2bdd0cDeo46rW1TZ4/b2La9qx8LyRJQGAAAAAAAAi8QVMrXXrpBe+4Gi7c19ju0tPAIAAAAAAEDmiCtk6qhdoY7aFVbXAgAAAAAAgDTltrsAAAAAAAAApD9CJgAAAAAAAJiW8IW/AQAAAACIR8mIUWl9fMBpCJkAAAAAACklGmiSEQpoxq0LEz6XEQooGmhK+DyAE7i2fs8ds7sIAAAAAAAO5ykYLre/OOHzRANNMlrrEj4P4ARcyQQAAAAASDlGax3hD5BmWPgbAAAAAAAAphEyAQAAAAAAwDRCJgAAAAAAAJhGyAQAAAAAAADTCJkAAAAAAABgGiETAAAAAAAATCNkAgAAAAAAgGmETAAAAAAAADCNkAkAAAAAAACmETIBAAAAAADANEImAAAAAAAAmEbIBAAAAAAAANMImQAAAAAAAGAaIRMAAAAAAABMI2QCAAAAAACAaYRMAAAAAAAAMI2QCQAAAAAAAKYRMgEAAAAAAMA0QiYAAAAAAACYRsgEAAAAAAAA0wiZAAAAAAAAYBohEwAAAAAAAEwjZAIAAAAAAIBp/x+6u61lcUyfKAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c, scale = 0.8, cluster_gates = True, style=\"fardelejo\");" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b9e1176c-d8dc-47e4-9607-ad24f6f536b9", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c, scale = 0.8, cluster_gates = True, style=\"quantumspain\");" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "eaefdf76-af68-4187-996d-bdc9c33a4242", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c, scale = 0.8, cluster_gates = True, style=\"color-blind\");" + ] + }, + { + "cell_type": "markdown", + "id": "50f4eb75", + "metadata": {}, + "source": [ + "#### Plot circuit with custom style" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "56f4f3cc-6864-4ef2-aa19-9c209fc217e5", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "custom_style = {\n", + " \"facecolor\" : \"#6497bf\",\n", + " \"edgecolor\" : \"#01016f\",\n", + " \"linecolor\" : \"#01016f\",\n", + " \"textcolor\" : \"#01016f\",\n", + " \"fillcolor\" : \"#ffb9b9\",\n", + " \"gatecolor\" : \"#d8031c\",\n", + " \"controlcolor\" : \"#360000\"\n", + "}\n", + "\n", + "plot_circuit(c, scale = 0.8, cluster_gates = True, style=custom_style);" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f5077d51", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "q0: ─[─H─U1───]─U1─U1─U1─────────────────────────────────────x───M─\n", + "q1: ─[───o──H─]─|──|──|──[─U1───]─U1─U1──────────────────────|─x─M─\n", + "q2: ────────────o──|──|──[─o──H─]─|──|──[─U1───]─U1──────────|─|───\n", + "q3: ───────────────o──|───────────o──|──[─o──H─]─|──[─U1───]─|─x───\n", + "q4: ──────────────────o──────────────o───────────o──[─o──H─]─x─────\n" + ] + } + ], + "source": [ + "print(c.fuse().draw())" + ] + }, + { + "cell_type": "markdown", + "id": "c30e59fc", + "metadata": {}, + "source": [ + "#### Plot fused circuit with built-in style" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "259e5c4f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c.fuse(), scale = 0.8, cluster_gates = True, style=\"quantumspain\");" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a9f50b42", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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X8p3vvOdHH300fm7v/u7jBkzJk8++WTe9ra3tdvGgAEDMmzYsCxZsqTTNT732GOdfu3eqLmpqc1/d9auu1Tb/rY8unDz5s07bLNlXVc85rC7349q09Fxyo4VcYx3ZJuV7HdXjeciHmsAAACoZqfOmJE5n/xkfvz5z2fQ8OH5wF/+ZV741a8qXRYdsKvXMQYOHJgzzjgjt99+e84+++z89re/zTe/+c0u3++b7TdiRIfalSUYWrNmTdatW5djjjlmu+sXLlyYpO38Qtdee22mTJmSc889N0ly0003ZdCgQfnBD36QKVOmtNvGqlWr0tTUtHWuos74ztFHd/q1e7M52zz6r9KqrZ76+vokyYsvvrjDNs3NzW3allO1vR+V4n3oOkUd45XsdxH7nPgcAwAAUGzPP/54vvenf1rpMuhCn/nMZzJnzpxMmjQptbW1+eQnP7nL29id6yd/1draoXZlCYZ69eqVJHnppZfardu4cWOuvvrqJP99x9DGjRvz+OOP56/+6q/+u5CamowaNSoPP/zwdoOhO++8M5s3b85ZZ53V6To/++ijnX7t3qi5qSlzJk7MuNmz09DYuNN23WVn9ZTbzvo3bNiw9O7dO4888khaWlpSU9P+Y/Pwww8nSY444oiy19fd70e16eg4ZceKOMY7ct6qZL+7ajwX8VgDAABAtVr50EP512nT8s4jjshzjz6afkOG5LWXX86Hbrghbz/00EqXx0505rr4mDFjcsABB+R3v/tdJkyYkP79++/yfrvj+klZgqG+ffvmoIMOyvLly7N8+fIcfvjhSZINGzbk05/+dJqamtKjR4+ty5ubm/PGG2/kne98Z5vtvOMd78jTTz+93X3MmTMn+++/f4499thO19nR26iKpqGxsarem2qrp7a2Nuecc05mz56dr371q5k+fXqb9cuXL89NN92Ufffdd7eCyx2ptvejUrwPXaeoY7yS/S5inxOfYwAAAIrjyQULcv+ll+bQ00/PB/7yL/O9P/3TfPjmm3P/F7+Yez73uZy7aFEGHXlkpcukzHr27Jl58+blP/7jPzo9t1B3XD8p2xxDl1xySS666KKccMIJmTBhQmprazN//vwMHTo0tbW1Ofjgg1NXV9epba9duzYPPPBAzj///JRKpXKVDB02Y8aMLF26NFdccUXuvvvujBw5MrW1tXnyySczf/78tLa2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UlmDocmTJ+exxx7LrFmzMnHixK3Lr7nmmq13Ch111FG7vN2+ffvm1FNPzfz583PjjTemR4+qfwIewF5j5c9/nlknn5zNLS3Z3NKSJLn7ggvS8vrrOe7zn69wdUBntLz+emadckqeXbIkaW1Nkjw8Y0ZWPPhgJv30p3ttOPTUU09l+vTp2123YsWKbq0FAAAAKqVswdCiRYtyxx13ZMqUKW1CoSQ577zzMm3atPTp0yfDhg3r1PbHjRuX+fPnZ8mSJTn++OPLUTIAO9Ha2poFF16YNzZuTOvmzW3W/esll+TwT34ydW9/e4WqAzpr2a23tgmFtnju8cfz6He+kz/7i7+oUGVd6+mnn84VV1xR6TIAAACgosoWDF1//fVJkksvvbTdugEDBiRJDj/88PTs2TNJctVVV+Vf/uVf8tvf/jZ1dXUZOXJkrr766gwZMmS72z/jjDNSU1OTuXPndjoYeu6xxzr1OoCieuW55/LC8uXbXbd506b84tvfznv28kd8Njc1tflvURS139Wq3MfjiVtuaRcKJUlaW7PsllsyZOTIsuynu3T0fRkzZkx+/OMfb3fd4sWLc+KJJ5Zlfz4/1aWIx6OIfa522x6Taj821V5fV9pTjlE1q/b3rtrrA/ZORf37UtR+V1JHp34oWzC0cOHCHHLIITn44IPbrXvuueeStJ1f6Cc/+UkuuuiivO9978uGDRsybdq0fPCDH8zy5ctTU9O+rAEDBmTYsGFZsmRJp2v8ztFHd/q1ALT34P/+33nwf//vSpfRLeZsczdsURS139WqO47HC7/8pe9MO9HR4+DzU12KeDyK2Odq19FjsuXx6Zu3uWP7zbas64pHrRs73oOuVskx7tgClVTUc1BR+10Jf7W9H4FuR1mCoTVr1mTdunU55phjtrt+4cKFSdrOL7TtrzW/+93vZujQofn1r3+dI444ot02Vq1alaampq1zFXXGZx99tNOvBSii1tbW3DFhQl5++ul2dxeUamryqfvuS22/fpUprps0NzVlzsSJGTd7dhoaGytdTrcpar+rVbmPx6//5V/ys699bbvr/vQLX8gRn/zkbu+jO215f7rLzo6Dz091KeLxKGKfq922x2Rn5636+vokyYsvvrjjbTY3t2lbTkUeOz4/u68jf5crOcYdW6ASivr3paj93hOUJRjq1atXkuSll15qt27jxo25+uqrk7S9Y2hba9euTfLfj53b1p133pnNmzfnrLPO6nSdHb2NCoD/9pFbbsmsk0/O5paWbG5pSY+ammxuacmYb3wjB48eXenyuk1DY2Mh/44Utd/VqlzHY+Af/3Ge+clP/mueoTfZb8SInPjXf53effvu9j72Zh09Dj4/1aWIx6OIfa52HT0mw4YNS+/evfPII4+kpaVlu0/VePjhh5Nkuz+s7K4692beg65VyTHu2AKVVNRzUFH7Xc3Kcj9u3759c9BBB2X58uVZ/qa5KDZs2JBJkyalqakpPXr0yOGHH77d17/xxhu55JJLctppp+Vd73rXdtvMmTMn+++/f4499thylAxABw3+wAcy5YkncvQFF+Rdf/Znee+4cTnvwQdz3EUXVbo0oJNqamtz7sKFOe3663PwiSfmoJEjM/a66zLpJz8RCgFUgdra2pxzzjlZvXp1vvrVr7Zbv3z58tx0003Zd999d+vHk1ApxjgAVFbZ5hi65JJLctFFF+WEE07IhAkTUltbm/nz52fo0KGpra3NwQcfnLq6unava21tzZQpU7Jy5cr8/Oc/3+62165dmwceeCDnn39+SqVSuUoGoIPefuihOe1b36p0GUAZ1dTW5n0XXpj3XXhhpUsBYDtmzJiRpUuX5oorrsjdd9+dkSNHpra2Nk8++WTmz5+f1tbW3Hbbben3psf6/uY3v8nXv/71JMlrr722ddmkSZO2trnlllu6sRewY8Y4AFRO2YKhqVOnZs2aNbnhhhsyc+bMDB06NBdccEHOPPPMvPe9720zv9AWra2t+V//639l4cKF+elPf5qBAwdud9sLFizIpk2b/EoEAACAQnjHO96RRx55JNdee23mzZuXG2+8MRs3bsygQYMyfvz4XHLJJe0e1/7888/n1ltvbbNs1apVbZa5aE61MMYBoHLKFgyVSqVcfvnlufzyy9ssnzNnTpL28wu1trZm6tSpWbBgQX7yk5/kwAMP3OG2586dm/79+2fUqFHlKhcAgIIYMmRIWltb37LNqFGjdtoGoLvV19dn+vTpmT59eofaO5expzHGAaAyyhYM7cgTTzyRJO3uGJo6dWr+6Z/+KXfddVf69OmT559/PkkyYMCA9O7de2u7119/Pffee2/GjRu33ckIAQAAAAAA6JguT1qWLVuWpP0dQ9/+9reTJP/jf/yPNssffPDBNncGPfTQQ6mtrc348eO7tE4AAAAAAIC9XbfcMXTAAQekoaGhzfKO3vp7yimnpLm5uStKAwAAAAAAKJROBUNb7ujp16/fTtuuWLGiM7sAAAAAAACgzDodDL35cW8AAAAAAABUvx6VLgAAAAAAAIDuIRgCAAAAAAAoiE49Sg4AAKrN6qamPXr7QPFU23ml2uphz1Zt46na6gGAShIMAQCwR6traEivurrMnTixy/fVq64udQ0NXb4fYO/WneetXeU8x+4yvgGg+gmGAADYo9UPHpypTU1Z39zc5fuqa2hI/eDBXb4fYO9WzvNWc1NT5kycmHGzZ6ehsXG3t+c8x+4yvgGg+gmGAADY49UPHuxCD7BHKfd5q6GxMfuNGFG27cHuML4BoLoJhgAA9hCejb9ncJwAAACoZoIhAIAqV83P6mf7zGEAAABAtRIMAQBUue6cQ4fyMIcBAAAA1UowBACwBzCHDgAAAFAOPSpdAAAAAAAAAN1DMAQAAAAAAFAQgiEAAAAAAICCEAwBAAAAAAAUhGAIAAAAAACgIARDAAAAAAAABSEYAgAAAAAAKAjBEAAAAAAAQEEIhgAAAAAAAApCMAQAAAAAAFAQgiEAAAAAAICCEAwBAAAAAAAUhGAIAAAAAACgIARDAAAAAAAABSEYAgAAAAAAKAjBEAAAAAAAQEEIhgAAAAAAAApCMAQAAAAAAFAQgiEAAAAAAICCqKl0AQAAAADAnmHtypVZ39xc6TLogLqGhtQPHlzpMoAqJBgCAAAAAHZq7cqVub6xMZvWr690KXRAr7q6TG1qEg4B7QiGAAAAAICdWt/cnE3r1+es2bMzsLGx0uXwFlY3NWXuxIlZ39wsGALaEQwBAAAAAB02sLEx+40YUekyAOgkwRAAAABQMd01X4m5NqBrVOucQz7zADsmGAIAAAAqojvnKzHXBpRfNc855DMPsGOCIQAAAKAiumu+EnNtQNeo1jmHfOYB3ppgCAAAAKgo85XAns1nGGDP0qPSBQAAAAAAANA9BEMAAAAAAAAFIRgCAAAAAAAoiE4FQ9OnT0+pVMqKFSvKXA4AAAAAAABdpervGLrvvvtSKpVy++23V7oUAAAAoJutWLEipVIpY8eO3WGbxYsXp1QqZcqUKd1YGbAzWz6bkyZN2qU2y5Yty5e//OWMGTMmAwcOTKlUyqhRo7q8XoCiqPpgaPTo0amvr8+8efMqXQoAAAAA0MXmzZuXq666KosXL86gQYMqXQ6wE/+xdGleXb26w+1fe/nlrPz5z7uwInam6oOhXr165fTTT88999yTDRs2VLocAAAAAKALnX322Xn00Ufzyiuv5P777690OcBb2NzSkrkTJ+b7o0d3KBx67eWXM+vkk/MvH/94Wlzvr5iyB0Pr16/PlVdemUMPPTS1tbUZOnRoZsyYkccffzylUinTpk3b5W2OGzcu69aty6JFi8pdLgAAAABQRQ477LCMGDEivXr1qnQpwE70qKnJhPnz8+rq1TsNh7aEQmueeSYfv+uu1OyzTzdWypuVNRhat25dRo4cma985Ss58MADc/HFF2f48OGZNm1aLrvssiTJ8OHDd3m7Y8eOTW1tbebOnVvOcgFgp7Z8oXmjpaXClQCwqza3tGTNihWVLgO6zKb16/Pyv/97pcsAAApuYGNjznvwwbcMh94cCp27aFEGHXlkBSpli5pybmzy5Ml57LHHMmvWrEycOHHr8muuuWbrnUJHHXXULm+3b9++OfXUUzN//vzceOON6dGj6p+AB8Aebs2KFblz8uSsePDBJMltY8bklL/7u4z4n/+zwpUB0BFPzJqVhZdemleefz5JMv8zn8n4H/0ob3/PeypcGey+1s2bs/iKK/LwjBnZ9OqrSZKFl12Ws3/4w9T261fZ4rrQU089lenTp2933QohMABU1JZw6NYTT8z3R4/OuQ88sHXdht//XihUZcoWDC1atCh33HFHpkyZ0iYUSpLzzjsv06ZNS58+fTJs2LBObX/cuHGZP39+lixZkuOPP74cJQPAdm167bXcMnJkfv+7321d9vqaNbnr/PPTe9998ycf+1gFqwNgZ357112Zd+65bZY9/8tf5pYTTsjnnnwy++y7b4Uqg/L4yZVX5qd//ddtlv3bwoX54Vln5bw//Khlb/T000/niiuuqHQZAMAObBsOjbnuuiTJggsvzKurVwuFqkjZbr25/vrrkySXXnppu3UDBgxIkhx++OHp2bNnkuTaa6/NYYcdlj/6oz9Kv379Mnr06CxdunSH2z/jjDNSU1PjcXIAdLlf//M/Z+3KlWl94422K0qlPPQ3f1OZogDosIe+9rWUtn3KwObNeWXVqiy/7bbKFAVlsum11/LwjBntV2zenBWLF+c/f/GL7i+qm4wZMyatra3b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amtrM3To0MyYMSOPP/54SqVSpk2btsvbHDduXNatW5dFixaVu1wAAAAAANht7znttJwzZ07+3z335I6PfWyHdw69ORQ6d9GivPOII7q5UoqurMHQunXrMnLkyHzlK1/JgQcemIsvvjjDhw/PtGnTctlllyVJhg8fvsvbHTt2bGprazN37txylgsAbGPzG2/kybvvzsPf+EaSZM2KFZUtCIBdsr65Ob+87bYkSdOcOdn4yisVrgigc5zPimPT+vVZdsstWTJjRpJk/YsvVrgi2D2Hnn76W4ZD24ZCg448skKVUmRlfZTc5MmT89hjj2XWrFmZOHHi1uXXXHPN1juFjjrqqF3ebt++fXPqqadm/vz5ufHGG9OjR9VPjQQAe5xN69dn9tixWfnQQynV/NdXhB999KMZc911+dOLL65wdQDszDM//Wlu++AHs+m115IkD/3N3+Tx730vk37607z9Pe+pcHUAHed8VhxrVqzIzSeckN8/++zWf4P804c+lI/ffXfefcopFa6u6zz11FOZPn36dtet8OO8vcKWcOhH48bljo99LB/4y79M8l+PmhMKUQ3KFgwtWrQod9xxR6ZMmdImFEqS8847L9OmTUufPn0ybNiwTm1/3LhxmT9/fpYsWZLjjz++HCUDAG/y0Ne+lmd//vMkSWtLy9bl9/35n+fdp5ySgX/8x5UqDYCdeGPjxvxo/Pi0vP560tq6dfmrq1dn3qRJ+cwfzu8A1c75rFjuOv/8rPvP/0zy3/8GeWPjxvzz2Wfni889l159+lSyvC7z9NNP54orrqh0GXSxN4dDr69ZkyRZcOGFeXX1aqEQFVe2YOj6669Pklx66aXt1g0YMCBJcvjhh6dnz57t1l944YW54YYb8s1vfjOf+9zntrv9M844IzU1NZk7d26ng6HnHnusU68DgCL4xY03pnXz5nbLSz17ZsmMGTl26tQKVAVARzy7ZEnWr17dbnnrG2/kP5YsyZMLFmTf/farQGUAu8b5rLo1NzW1+e/ueO2ll/JvCxdud92GtWvzyPXX5+DRo3d7P91lV96TMWPG5Mc//vF21y1evDgnnnjibu+vnMeKztt3v/1yytVX518vuSRJsvbZZ/Phm25K6xtvuFZNl9hvxIgOtStbMLRw4cIccsghOfjgg9ute+6555Jsf36hu+++Ow8//HD233//t9z+gAED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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_circuit(c.fuse(), scale = 0.8, cluster_gates = True, style=\"cachirulo\");" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa46e167", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "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.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/qibo/backends/__init__.py b/src/qibo/backends/__init__.py index f9334d00c..77aaab344 100644 --- a/src/qibo/backends/__init__.py +++ b/src/qibo/backends/__init__.py @@ -14,6 +14,10 @@ QIBO_NATIVE_BACKENDS = ("numpy", "tensorflow", "pytorch", "qulacs") +class MissingBackend(ValueError): + """Impossible to locate backend provider package.""" + + class MetaBackend: """Meta-backend class which takes care of loading the qibo backends.""" @@ -89,7 +93,7 @@ def __new__(cls): try: cls._instance = construct_backend(**kwargs) break - except (ModuleNotFoundError, ImportError): + except (ImportError, MissingBackend): pass if cls._instance is None: # pragma: no cover @@ -228,7 +232,7 @@ def construct_backend(backend, **kwargs) -> Backend: if provider not in e.msg: raise e raise_error( - ValueError, + MissingBackend, f"The '{backend}' backends' provider is not available. Check that a Python " f"package named '{provider}' is installed, and it is exposing valid Qibo " "backends.", diff --git a/src/qibo/backends/clifford.py b/src/qibo/backends/clifford.py index 5fd2d1cd6..1ba071cd4 100644 --- a/src/qibo/backends/clifford.py +++ b/src/qibo/backends/clifford.py @@ -259,7 +259,7 @@ def execute_circuit_repeated(self, circuit, nshots: int = 1000, initial_state=No samples = self.np.vstack(samples) for meas in circuit.measurements: - meas.result.register_samples(samples[:, meas.target_qubits], self) + meas.result.register_samples(samples[:, meas.target_qubits]) result = Clifford( self.zero_state(circuit.nqubits), diff --git a/src/qibo/derivative.py b/src/qibo/derivative.py index 65d4ef87b..51ff7c39e 100644 --- a/src/qibo/derivative.py +++ b/src/qibo/derivative.py @@ -13,41 +13,43 @@ def parameter_shift( nshots=None, ): """In this method the parameter shift rule (PSR) is implemented. - Given a circuit U and an observable H, the PSR allows to calculate the derivative - of the expected value of H on the final state with respect to a variational + Given a circuit :math:`U` and an observable :math:`H`, the PSR allows to calculate the derivative + of the expected value of :math:`H` on the final state with respect to a variational parameter of the circuit. There is also the possibility of setting a scale factor. It is useful when a circuit's parameter is obtained by combination of a variational parameter and an external object, such as a training variable in a Quantum Machine Learning problem. For example, performing a re-uploading strategy to embed some data into a circuit, we apply to the quantum state rotations - whose angles are in the form: theta' = theta * x, where theta is a variational - parameter and x an input variable. The PSR allows to calculate the derivative - with respect of theta' but, if we want to optimize a system with respect its - variational parameters we need to "free" this procedure from the x depencency. - If the `scale_factor` is not provided, it is set equal to one and doesn't + whose angles are in the form :math:`\\theta^{\\prime} = x \\, \\theta`, + where :math:`\\theta` is a variational parameter, and :math:`x` an input variable. + The PSR allows to calculate the derivative with respect to :math:`\\theta^{\\prime}`. + However, if we want to optimize a system with respect to its + variational parameters, we need to "free" this procedure from the :math:`x` depencency. + If the ``scale_factor`` is not provided, it is set equal to one and doesn't affect the calculation. If the PSR is needed to be executed on a real quantum device, it is important - to set `nshots` to some integer value. This enables the execution on the + to set ``nshots`` to some integer value. This enables the execution on the hardware by calling the proper methods. Args: circuit (:class:`qibo.models.circuit.Circuit`): custom quantum circuit. hamiltonian (:class:`qibo.hamiltonians.Hamiltonian`): target observable. if you want to execute on hardware, a symbolic hamiltonian must be - provided as follows (example with Pauli Z and ``nqubits=1``): + provided as follows (example with Pauli-:math:`Z` and :math:`n = 1`): ``SymbolicHamiltonian(np.prod([ Z(i) for i in range(1) ]))``. parameter_index (int): the index which identifies the target parameter in the ``circuit.get_parameters()`` list. initial_state (ndarray, optional): initial state on which the circuit - acts. Default is ``None``. - scale_factor (float, optional): parameter scale factor. Default is ``1``. + acts. If ``None``, defaults to the zero state :math:`\\ket{\\mathbf{0}}`. + Defaults to ``None``. + scale_factor (float, optional): parameter scale factor. Defaults to :math:`1`. nshots (int, optional): number of shots if derivative is evaluated on hardware. If ``None``, the simulation mode is executed. - Default is ``None``. + Defaults to ``None``. Returns: - (float): Value of the derivative of the expectation value of the hamiltonian + float: Value of the derivative of the expectation value of the hamiltonian with respect to the target variational parameter. Example: @@ -167,27 +169,28 @@ def finite_differences( step_size=1e-7, ): """ - Calculate derivative of the expectation value of `hamiltonian` on the - final state obtained by executing `circuit` on `initial_state` with - respect to the variational parameter identified by `parameter_index` + Calculate derivative of the expectation value of ``hamiltonian`` on the + final state obtained by executing ``circuit`` on ``initial_state`` with + respect to the variational parameter identified by ``parameter_index`` in the circuit's parameters list. This method can be used only in exact simulation mode. Args: circuit (:class:`qibo.models.circuit.Circuit`): custom quantum circuit. hamiltonian (:class:`qibo.hamiltonians.Hamiltonian`): target observable. - if you want to execute on hardware, a symbolic hamiltonian must be - provided as follows (example with Pauli Z and ``nqubits=1``): + To execute on hardware, a symbolic hamiltonian must be + provided as follows (example with Pauli-:math:`Z` and :math:`n = 1`): ``SymbolicHamiltonian(np.prod([ Z(i) for i in range(1) ]))``. parameter_index (int): the index which identifies the target parameter - in the ``circuit.get_parameters()`` list. + in the :meth:`qibo.models.Circuit.get_parameters` list. initial_state (ndarray, optional): initial state on which the circuit - acts. Default is ``None``. - step_size (float): step size used to evaluate the finite difference - (default 1e-7). + acts. If ``None``, defaults to the zero state :math:`\\ket{\\mathbf{0}}`. + Defaults to ``None``. + step_size (float, optional): step size used to evaluate the finite difference. + Defaults to :math:`10^{-7}`. Returns: - (float): Value of the derivative of the expectation value of the hamiltonian + float: Value of the derivative of the expectation value of the hamiltonian with respect to the target variational parameter. """ diff --git a/src/qibo/gates/abstract.py b/src/qibo/gates/abstract.py index b82939299..250c30993 100644 --- a/src/qibo/gates/abstract.py +++ b/src/qibo/gates/abstract.py @@ -14,7 +14,18 @@ "_target_qubits", "_control_qubits", ] -REQUIRED_FIELDS_INIT_KWARGS = ["theta", "phi", "lam", "phi0", "phi1"] +REQUIRED_FIELDS_INIT_KWARGS = [ + "theta", + "phi", + "lam", + "phi0", + "phi1", + "register_name", + "collapse", + "basis", + "p0", + "p1", +] class Gate: @@ -107,6 +118,8 @@ def from_dict(raw: dict): raise ValueError(f"Unknown gate {raw['_class']}") gate = cls(*raw["init_args"], **raw["init_kwargs"]) + if raw["_class"] == "M" and raw["measurement_result"]["samples"] is not None: + gate.result.register_samples(raw["measurement_result"]["samples"]) try: return gate.controlled_by(*raw["_control_qubits"]) except RuntimeError as e: diff --git a/src/qibo/gates/measurements.py b/src/qibo/gates/measurements.py index 34e1ca4f1..7e1559e9d 100644 --- a/src/qibo/gates/measurements.py +++ b/src/qibo/gates/measurements.py @@ -1,5 +1,5 @@ import json -from typing import Dict, Optional, Tuple +from typing import Dict, Optional, Tuple, Union from qibo import gates from qibo.config import raise_error @@ -23,11 +23,13 @@ class M(Gate): performed. Can be used only for single shot measurements. If ``True`` the collapsed state vector is returned. If ``False`` the measurement result is returned. - basis (:class:`qibo.gates.Gate`, list): Basis to measure. - Can be a qibo gate or a callable that accepts a qubit, - for example: ``lambda q: gates.RX(q, 0.2)`` - or a list of these, if a different basis will be used for each - measurement qubit. + basis (:class:`qibo.gates.Gate`, str, list): Basis to measure. + Can be either: + - a qibo gate + - the string representing the gate + - a callable that accepts a qubit, for example: ``lambda q: gates.RX(q, 0.2)`` + - a list of the above, if a different basis will be used for each + measurement qubit. Default is Z. p0 (dict): Optional bitflip probability map. Can be: A dictionary that maps each measured qubit to the probability @@ -46,7 +48,7 @@ def __init__( *q, register_name: Optional[str] = None, collapse: bool = False, - basis: Gate = Z, + basis: Union[Gate, str] = Z, p0: Optional["ProbsType"] = None, p1: Optional["ProbsType"] = None, ): @@ -61,15 +63,24 @@ def __init__( # relevant for experiments only self.pulses = None # saving basis for __repr__ ans save to file + to_gate = lambda x: getattr(gates, x) if isinstance(x, str) else x if not isinstance(basis, list): - self.basis_gates = len(q) * [basis] + self.basis_gates = len(q) * [to_gate(basis)] + basis = len(self.target_qubits) * [basis] + elif len(basis) != len(self.target_qubits): + raise_error( + ValueError, + f"Given basis list has length {len(basis)} while " + f"we are measuring {len(self.target_qubits)} qubits.", + ) else: - self.basis_gates = basis + self.basis_gates = [to_gate(g) for g in basis] self.init_args = q self.init_kwargs = { "register_name": register_name, "collapse": collapse, + "basis": [g.__name__ for g in self.basis_gates], "p0": p0, "p1": p1, } @@ -88,20 +99,25 @@ def __init__( # list of gates that will be added to the circuit before the # measurement, in order to rotate to the given basis - if not isinstance(basis, list): - basis = len(self.target_qubits) * [basis] - elif len(basis) != len(self.target_qubits): - raise_error( - ValueError, - f"Given basis list has length {len(basis)} while " - f"we are measuring {len(self.target_qubits)} qubits.", - ) self.basis = [] - for qubit, basis_cls in zip(self.target_qubits, basis): + for qubit, basis_cls in zip(self.target_qubits, self.basis_gates): gate = basis_cls(qubit).basis_rotation() if gate is not None: self.basis.append(gate) + @property + def raw(self) -> dict: + """Serialize to dictionary. + + The values used in the serialization should be compatible with a + JSON dump (or any other one supporting a minimal set of scalar + types). Though the specific implementation is up to the specific + gate. + """ + encoded_simple = super().raw + encoded_simple.update({"measurement_result": self.result.raw}) + return encoded_simple + @staticmethod def _get_bitflip_tuple( qubits: Tuple[int, ...], probs: "ProbsType" @@ -178,7 +194,7 @@ def apply(self, backend, state, nqubits): qubits = sorted(self.target_qubits) # measure and get result probs = backend.calculate_probabilities(state, qubits, nqubits) - shot = self.result.add_shot(probs) + shot = self.result.add_shot(probs, backend=backend) # collapse state return backend.collapse_state(state, qubits, shot, nqubits) @@ -190,7 +206,7 @@ def apply_density_matrix(self, backend, state, nqubits): qubits = sorted(self.target_qubits) # measure and get result probs = backend.calculate_probabilities_density_matrix(state, qubits, nqubits) - shot = self.result.add_shot(probs) + shot = self.result.add_shot(probs, backend=backend) # collapse state return backend.collapse_density_matrix(state, qubits, shot, nqubits) @@ -204,25 +220,12 @@ def apply_clifford(self, backend, state, nqubits): self.result.add_shot_from_sample(sample[0]) return state - def to_json(self): - """Serializes the measurement gate to json.""" - encoding = json.loads(super().to_json()) - encoding.pop("_control_qubits") - encoding.update({"basis": [g.__name__ for g in self.basis_gates]}) - return json.dumps(encoding) - @classmethod def load(cls, payload): """Constructs a measurement gate starting from a json serialized one.""" args = json.loads(payload) - # drop general serialization data, unused in this specialized loader - for key in ("name", "init_args", "_class"): - args.pop(key) - qubits = args.pop("_target_qubits") - args["basis"] = [getattr(gates, g) for g in args["basis"]] - args.update(args.pop("init_kwargs")) - return cls(*qubits, **args) + return cls.from_dict(args) # Overload on_qubits to copy also gate.result, controlled by can be removed for measurements def on_qubits(self, qubit_map) -> "Gate": diff --git a/src/qibo/hamiltonians/abstract.py b/src/qibo/hamiltonians/abstract.py index 749ad0b21..bf19341b7 100644 --- a/src/qibo/hamiltonians/abstract.py +++ b/src/qibo/hamiltonians/abstract.py @@ -57,11 +57,10 @@ def ground_state(self): @abstractmethod def exp(self, a): # pragma: no cover - """Computes a tensor corresponding to exp(-1j * a * H). + """Computes a tensor corresponding to :math:`\\exp(-i \\, a \\, H)`. Args: - a (complex): Complex number to multiply Hamiltonian before - exponentiation. + a (complex): Complex number to multiply Hamiltonian before exponentiation. """ raise_error(NotImplementedError) @@ -70,27 +69,31 @@ def expectation(self, state, normalize=False): # pragma: no cover """Computes the real expectation value for a given state. Args: - state (array): the expectation state. - normalize (bool): If ``True`` the expectation value is divided - with the state's norm squared. + state (ndarray): state in which to calculate the expectation value. + normalize (bool, optional): If ``True``, the expectation value + :math:`\\ell_{2}`-normalized. Defaults to ``False``. Returns: - Real number corresponding to the expectation value. + float: real number corresponding to the expectation value. """ raise_error(NotImplementedError) @abstractmethod def expectation_from_samples(self, freq, qubit_map=None): # pragma: no cover - """Computes the real expectation value of a diagonal observable given the frequencies when measuring in the computational basis. + """Computes the expectation value of a diagonal observable, + given computational-basis measurement frequencies. Args: freq (collections.Counter): the keys are the observed values in binary form - and the values the corresponding frequencies, that is the number - of times each measured value/bitstring appears. - qubit_map (tuple): Mapping between frequencies and qubits. If None, [1,...,len(key)] + and the values the corresponding frequencies, that is the number + of times each measured value/bitstring appears. + qubit_map (tuple): Mapping between frequencies and qubits. + If ``None``, then defaults to + :math:`[1, \\, 2, \\, \\cdots, \\, \\mathrm{len}(\\mathrm{key})]`. + Defaults to ``None``. Returns: - Real number corresponding to the expectation value. + float: real number corresponding to the expectation value. """ raise_error(NotImplementedError) diff --git a/src/qibo/hamiltonians/hamiltonians.py b/src/qibo/hamiltonians/hamiltonians.py index 98434ed32..49ff52c6f 100644 --- a/src/qibo/hamiltonians/hamiltonians.py +++ b/src/qibo/hamiltonians/hamiltonians.py @@ -17,14 +17,16 @@ class Hamiltonian(AbstractHamiltonian): Args: nqubits (int): number of quantum bits. - matrix (np.ndarray): Matrix representation of the Hamiltonian in the - computational basis as an array of shape ``(2 ** nqubits, 2 ** nqubits)``. - Sparse matrices based on ``scipy.sparse`` for numpy/qibojit backends - or on ``tf.sparse`` for the tensorflow backend are also - supported. + matrix (ndarray): Matrix representation of the Hamiltonian in the + computational basis as an array of shape :math:`2^{n} \\times 2^{n}`. + Sparse matrices based on ``scipy.sparse`` for ``numpy`` / ``qibojit`` backends + (or on ``tf.sparse`` for the ``tensorflow`` backend) are also supported. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ - def __init__(self, nqubits, matrix=None, backend=None): + def __init__(self, nqubits, matrix, backend=None): from qibo.backends import _check_backend self.backend = _check_backend(backend) @@ -50,7 +52,7 @@ def __init__(self, nqubits, matrix=None, backend=None): def matrix(self): """Returns the full matrix representation. - Can be a dense ``(2 ** nqubits, 2 ** nqubits)`` array or a sparse + For :math:`n` qubits, can be a dense :math:`2^{n} \\times 2^{n}` array or a sparse matrix, depending on how the Hamiltonian was created. """ return self._matrix @@ -68,22 +70,22 @@ def matrix(self, mat): @classmethod def from_symbolic(cls, symbolic_hamiltonian, symbol_map, backend=None): - """Creates a ``Hamiltonian`` from a symbolic Hamiltonian. + """Creates a :class:`qibo.hamiltonian.Hamiltonian` from a symbolic Hamiltonian. - We refer to the - :ref:`How to define custom Hamiltonians using symbols? ` - example for more details. + We refer to :ref:`How to define custom Hamiltonians using symbols? ` + for more details. Args: - symbolic_hamiltonian (sympy.Expr): The full Hamiltonian written - with symbols. + symbolic_hamiltonian (sympy.Expr): full Hamiltonian written with ``sympy`` symbols. symbol_map (dict): Dictionary that maps each symbol that appears in - the Hamiltonian to a pair of (target, matrix). + the Hamiltonian to a pair ``(target, matrix)``. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. Returns: - A :class:`qibo.hamiltonians.SymbolicHamiltonian` object - that implements the Hamiltonian represented by the given symbolic - expression. + :class:`qibo.hamiltonians.SymbolicHamiltonian`: object that implements the + Hamiltonian represented by the given symbolic expression. """ log.warning( "`Hamiltonian.from_symbolic` and the use of symbol maps is " @@ -175,15 +177,16 @@ def energy_fluctuation(self, state): Evaluate energy fluctuation: .. math:: - \\Xi_{k}(\\mu) = \\sqrt{\\langle\\mu|\\hat{H}^2|\\mu\\rangle - \\langle\\mu|\\hat{H}|\\mu\\rangle^2} \\, + \\Xi_{k}(\\mu) = \\sqrt{\\bra{\\mu} \\, H^{2} \\, \\ket{\\mu} + - \\bra{\\mu} \\, H \\, \\ket{\\mu}^2} \\, . - for a given state :math:`|\\mu\\rangle`. + for a given state :math:`\\ket{\\mu}`. Args: - state (np.ndarray): quantum state to be used to compute the energy fluctuation. + state (ndarray): quantum state to be used to compute the energy fluctuation. - Return: - Energy fluctuation value (float). + Returns: + float: Energy fluctuation value. """ state = self.backend.cast(state) energy = self.expectation(state) @@ -311,6 +314,9 @@ class SymbolicHamiltonian(AbstractHamiltonian): The symbol_map can also be used to pass non-quantum operator arguments to the symbolic Hamiltonian, such as the parameters in the :meth:`qibo.hamiltonians.models.MaxCut` Hamiltonian. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ def __init__(self, form=None, nqubits=None, symbol_map={}, backend=None): @@ -419,7 +425,7 @@ def terms(self, terms): def matrix(self): """Returns the full matrix representation. - Consisting of ``(2 ** nqubits, 2 ** nqubits)`` elements. + Consisting of :math:`2^{n} \\times 2^{n}`` elements. """ return self.dense.matrix @@ -449,8 +455,8 @@ def _get_symbol_matrix(self, term): term (sympy.Expr): Symbolic expression containing local operators. Returns: - Numerical matrix corresponding to the given expression as a numpy - array of size ``(2 ** self.nqubits, 2 ** self.nqubits). + ndarray: matrix corresponding to the given expression as an array + of shape ``(2 ** self.nqubits, 2 ** self.nqubits)``. """ if isinstance(term, sympy.Add): # symbolic op for addition @@ -698,7 +704,7 @@ def apply_gates(self, state, density_matrix=False): Gates are applied to the given state. - Helper method for ``__matmul__``. + Helper method for :meth:`qibo.hamiltonians.SymbolicHamiltonian.__matmul__`. """ total = 0 for term in self.terms: @@ -760,7 +766,8 @@ def circuit(self, dt, accelerators=None): Args: dt (float): Time step used for Trotterization. - accelerators (dict): Dictionary with accelerators for distributed circuits. + accelerators (dict, optional): Dictionary with accelerators for distributed circuits. + Defaults to ``None``. """ from qibo import Circuit # pylint: disable=import-outside-toplevel from qibo.hamiltonians.terms import ( # pylint: disable=import-outside-toplevel diff --git a/src/qibo/hamiltonians/models.py b/src/qibo/hamiltonians/models.py index 1fa030fac..f6413b984 100644 --- a/src/qibo/hamiltonians/models.py +++ b/src/qibo/hamiltonians/models.py @@ -1,48 +1,52 @@ +from functools import reduce + from qibo.backends import matrices from qibo.config import raise_error from qibo.hamiltonians.hamiltonians import Hamiltonian, SymbolicHamiltonian from qibo.hamiltonians.terms import HamiltonianTerm -def multikron(matrix_list): +def _multikron(matrix_list): """Calculates Kronecker product of a list of matrices. Args: - matrices (list): List of matrices as ``np.ndarray``s. + matrix_list (list): List of matrices as ``ndarray``. Returns: - ``np.ndarray`` of the Kronecker product of all ``matrices``. + ndarray: Kronecker product of all matrices in ``matrix_list``. """ import numpy as np - h = 1 - for m in matrix_list: - # TODO: check if we observe GPU deterioration - h = np.kron(h, m) - return h + return reduce(np.kron, matrix_list) def _build_spin_model(nqubits, matrix, condition): """Helper method for building nearest-neighbor spin model Hamiltonians.""" h = sum( - multikron(matrix if condition(i, j) else matrices.I for j in range(nqubits)) + _multikron(matrix if condition(i, j) else matrices.I for j in range(nqubits)) for i in range(nqubits) ) return h -def XXZ(nqubits, delta=0.5, dense=True, backend=None): - """Heisenberg XXZ model with periodic boundary conditions. +def XXZ(nqubits, delta=0.5, dense: bool = True, backend=None): + """Heisenberg :math:`\\mathrm{XXZ}` model with periodic boundary conditions. .. math:: - H = \\sum _{i=0}^N \\left ( X_iX_{i + 1} + Y_iY_{i + 1} + \\delta Z_iZ_{i + 1} \\right ). + H = \\sum _{k=0}^N \\, \\left( X_{k} \\, X_{k + 1} + Y_{k} \\, Y_{k + 1} + + \\delta Z_{k} \\, Z_{k + 1} \\right) \\, . Args: - nqubits (int): number of quantum bits. - delta (float): coefficient for the Z component (default 0.5). - dense (bool): If ``True`` it creates the Hamiltonian as a + nqubits (int): number of qubits. + delta (float, optional): coefficient for the :math:`Z` component. + Defaults to :math:`0.5`. + dense (bool, optional): If ``True``, creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + Defaults to ``True``. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. Example: .. testcode:: @@ -60,9 +64,9 @@ def XXZ(nqubits, delta=0.5, dense=True, backend=None): matrix = hx + hy + delta * hz return Hamiltonian(nqubits, matrix, backend=backend) - hx = multikron([matrices.X, matrices.X]) - hy = multikron([matrices.Y, matrices.Y]) - hz = multikron([matrices.Z, matrices.Z]) + hx = _multikron([matrices.X, matrices.X]) + hy = _multikron([matrices.Y, matrices.Y]) + hz = _multikron([matrices.Z, matrices.Z]) matrix = hx + hy + delta * hz terms = [HamiltonianTerm(matrix, i, i + 1) for i in range(nqubits - 1)] terms.append(HamiltonianTerm(matrix, nqubits - 1, 0)) @@ -71,8 +75,8 @@ def XXZ(nqubits, delta=0.5, dense=True, backend=None): return ham -def _OneBodyPauli(nqubits, matrix, dense=True, backend=None): - """Helper method for constracting non-interacting X, Y, Z Hamiltonians.""" +def _OneBodyPauli(nqubits, matrix, dense: bool = True, backend=None): + """Helper method for constracting non-interacting :math:`X`, :math:`Y`, and :math:`Z` Hamiltonians.""" if dense: condition = lambda i, j: i == j % nqubits ham = -_build_spin_model(nqubits, matrix, condition) @@ -85,63 +89,74 @@ def _OneBodyPauli(nqubits, matrix, dense=True, backend=None): return ham -def X(nqubits, dense=True, backend=None): - """Non-interacting Pauli-X Hamiltonian. +def X(nqubits, dense: bool = True, backend=None): + """Non-interacting Pauli-:math:`X` Hamiltonian. .. math:: - H = - \\sum _{i=0}^N X_i. + H = - \\sum _{k=0}^N \\, X_{k} \\, . Args: - nqubits (int): number of quantum bits. - dense (bool): If ``True`` it creates the Hamiltonian as a + nqubits (int): number of qubits. + dense (bool, optional): If ``True`` it creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + Defaults to ``True``. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ return _OneBodyPauli(nqubits, matrices.X, dense, backend=backend) -def Y(nqubits, dense=True, backend=None): - """Non-interacting Pauli-Y Hamiltonian. +def Y(nqubits, dense: bool = True, backend=None): + """Non-interacting Pauli-:math:`Y` Hamiltonian. .. math:: - H = - \\sum _{i=0}^N Y_i. + H = - \\sum _{k=0}^{N} \\, Y_{k} \\, . Args: - nqubits (int): number of quantum bits. + nqubits (int): number of qubits. dense (bool): If ``True`` it creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ return _OneBodyPauli(nqubits, matrices.Y, dense, backend=backend) -def Z(nqubits, dense=True, backend=None): - """Non-interacting Pauli-Z Hamiltonian. +def Z(nqubits, dense: bool = True, backend=None): + """Non-interacting Pauli-:math:`Z` Hamiltonian. .. math:: - H = - \\sum _{i=0}^N Z_i. + H = - \\sum _{k=0}^{N} \\, Z_{k} \\, . Args: - nqubits (int): number of quantum bits. + nqubits (int): number of qubits. dense (bool): If ``True`` it creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ return _OneBodyPauli(nqubits, matrices.Z, dense, backend=backend) -def TFIM(nqubits, h=0.0, dense=True, backend=None): +def TFIM(nqubits, h: float = 0.0, dense: bool = True, backend=None): """Transverse field Ising model with periodic boundary conditions. .. math:: - H = - \\sum _{i=0}^N \\left ( Z_i Z_{i + 1} + h X_i \\right ). + H = - \\sum _{k=0}^{N} \\, \\left(Z_{k} \\, Z_{k + 1} + h \\, X_{k}\\right) \\, . Args: - nqubits (int): number of quantum bits. - h (float): value of the transverse field. - dense (bool): If ``True`` it creates the Hamiltonian as a + nqubits (int): number of qubits. + h (float, optional): value of the transverse field. Defaults to :math:`0.0`. + dense (bool, optional): If ``True`` it creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + Defaults to ``True``. """ if nqubits < 2: raise_error(ValueError, "Number of qubits must be larger than one.") @@ -154,7 +169,7 @@ def TFIM(nqubits, h=0.0, dense=True, backend=None): return Hamiltonian(nqubits, ham, backend=backend) matrix = -( - multikron([matrices.Z, matrices.Z]) + h * multikron([matrices.X, matrices.I]) + _multikron([matrices.Z, matrices.Z]) + h * _multikron([matrices.X, matrices.I]) ) terms = [HamiltonianTerm(matrix, i, i + 1) for i in range(nqubits - 1)] terms.append(HamiltonianTerm(matrix, nqubits - 1, 0)) @@ -163,17 +178,20 @@ def TFIM(nqubits, h=0.0, dense=True, backend=None): return ham -def MaxCut(nqubits, dense=True, backend=None): +def MaxCut(nqubits, dense: bool = True, backend=None): """Max Cut Hamiltonian. .. math:: - H = - \\sum _{i,j=0}^N \\frac{1 - Z_i Z_j}{2}. + H = -\\frac{1}{2} \\, \\sum _{j, k = 0}^{N} \\, \\left(1 - Z_{j} \\, Z_{k}\\right) \\, . Args: - nqubits (int): number of quantum bits. + nqubits (int): number of qubits. dense (bool): If ``True`` it creates the Hamiltonian as a :class:`qibo.core.hamiltonians.Hamiltonian`, otherwise it creates a :class:`qibo.core.hamiltonians.SymbolicHamiltonian`. + backend (:class:`qibo.backends.abstract.Backend`, optional): backend to be used + in the execution. If ``None``, it uses :class:`qibo.backends.GlobalBackend`. + Defaults to ``None``. """ import sympy as sp from numpy import ones diff --git a/src/qibo/measurements.py b/src/qibo/measurements.py index 75732f1fa..df06004f5 100644 --- a/src/qibo/measurements.py +++ b/src/qibo/measurements.py @@ -7,6 +7,13 @@ from qibo.config import raise_error +def _check_backend(backend): + """This is only needed due to the circular import with qibo.backends.""" + from qibo.backends import _check_backend + + return _check_backend(backend) + + def frequencies_to_binary(frequencies, nqubits): return collections.Counter( {"{:b}".format(k).zfill(nqubits): v for k, v in frequencies.items()} @@ -79,10 +86,8 @@ class MeasurementResult: to use for calculations. """ - def __init__(self, gate, nshots=0, backend=None): + def __init__(self, gate): self.measurement_gate = gate - self.backend = backend - self.nshots = nshots self.circuit = None self._samples = None @@ -96,15 +101,27 @@ def __repr__(self): nshots = self.nshots return f"MeasurementResult(qubits={qubits}, nshots={nshots})" - def add_shot(self, probs): + @property + def raw(self) -> dict: + samples = self._samples.tolist() if self.has_samples() else self._samples + return {"samples": samples} + + @property + def nshots(self) -> int: + if self.has_samples(): + return len(self._samples) + elif self._frequencies is not None: + return sum(self._frequencies.values()) + + def add_shot(self, probs, backend=None): + backend = _check_backend(backend) qubits = sorted(self.measurement_gate.target_qubits) - shot = self.backend.sample_shots(probs, 1) - bshot = self.backend.samples_to_binary(shot, len(qubits)) + shot = backend.sample_shots(probs, 1) + bshot = backend.samples_to_binary(shot, len(qubits)) if self._samples: self._samples.append(bshot[0]) else: self._samples = [bshot[0]] - self.nshots += 1 return shot def add_shot_from_sample(self, sample): @@ -112,20 +129,18 @@ def add_shot_from_sample(self, sample): self._samples.append(sample) else: self._samples = [sample] - self.nshots += 1 def has_samples(self): return self._samples is not None - def register_samples(self, samples, backend=None): + def register_samples(self, samples): """Register samples array to the ``MeasurementResult`` object.""" self._samples = samples - self.nshots = samples.shape[0] # len(samples) + self.nshots = samples.shape[0] - def register_frequencies(self, frequencies, backend=None): + def register_frequencies(self, frequencies): """Register frequencies to the ``MeasurementResult`` object.""" self._frequencies = frequencies - self.nshots = sum(frequencies.values()) def reset(self): """Remove all registered samples and frequencies.""" @@ -144,7 +159,7 @@ def symbols(self): return self._symbols - def samples(self, binary=True, registers=False): + def samples(self, binary=True, registers=False, backend=None): """Returns raw measurement samples. Args: @@ -159,6 +174,7 @@ def samples(self, binary=True, registers=False): samples are returned in decimal form as a tensor of shape `(nshots,)`. """ + backend = _check_backend(backend) if self._samples is None: if self.circuit is None: raise_error( @@ -172,9 +188,9 @@ def samples(self, binary=True, registers=False): return self._samples qubits = self.measurement_gate.target_qubits - return self.backend.samples_to_decimal(self._samples, len(qubits)) + return backend.samples_to_decimal(self._samples, len(qubits)) - def frequencies(self, binary=True, registers=False): + def frequencies(self, binary=True, registers=False, backend=None): """Returns the frequencies of measured samples. Args: @@ -192,8 +208,9 @@ def frequencies(self, binary=True, registers=False): If `binary` is `False` the keys of the `Counter` are integers. """ + backend = _check_backend(backend) if self._frequencies is None: - self._frequencies = self.backend.calculate_frequencies( + self._frequencies = backend.calculate_frequencies( self.samples(binary=False) ) if binary: diff --git a/src/qibo/models/error_mitigation.py b/src/qibo/models/error_mitigation.py index a5ee0f674..07d3777ce 100644 --- a/src/qibo/models/error_mitigation.py +++ b/src/qibo/models/error_mitigation.py @@ -52,51 +52,77 @@ def get_gammas(noise_levels, analytical: bool = True): return zne_coefficients -def get_noisy_circuit(circuit, num_insertions: int, insertion_gate: str = "CNOT"): +def get_noisy_circuit( + circuit, num_insertions: int, global_unitary_folding=True, insertion_gate=None +): """Standalone function to generate the noisy circuit with the inverse gate pairs insertions. Args: circuit (:class:`qibo.models.circuit.Circuit`): circuit to modify. - num_insertions (int): number of insertion gate pairs to add. - insertion_gate (str, optional): gate to be used in the insertion. - If ``"RX"``, the gate used is :math:``RX(\\pi / 2)``. - Default is ``"CNOT"``. + num_insertions (int): number of insertion gate pairs / global unitary folds to add. + global_unitary_folding (bool): If ``True``, noise is increased by global unitary folding. + If ``False``, local unitary folding is used. Defaults to ``True``. + insertion_gate (str, optional): gate to be folded in the local unitary folding. + If ``RX``, the gate used is :math:``RX(\\pi / 2)``. Otherwise, it is the ``CNOT`` gate. Returns: - :class:`qibo.models.Circuit`: circuit with the inserted gate pairs. + :class:`qibo.models.Circuit`: circuit with the inserted gate pairs or with global folding. """ - if insertion_gate not in ("CNOT", "RX"): # pragma: no cover - raise_error( - ValueError, - "Invalid insertion gate specification. Please select between 'CNOT' and 'RX'.", - ) - if insertion_gate == "CNOT" and circuit.nqubits < 2: # pragma: no cover - raise_error( - ValueError, - "Provide a circuit with at least 2 qubits when using the 'CNOT' insertion gate. " - + "Alternatively, try with the 'RX' insertion gate instead.", - ) - i_gate = gates.CNOT if insertion_gate == "CNOT" else gates.RX + from qibo import Circuit # pylint: disable=import-outside-toplevel + + if global_unitary_folding: + + copy_c = Circuit(**circuit.init_kwargs) + for g in circuit.queue: + if not isinstance(g, gates.M): + copy_c.add(g) + + noisy_circuit = copy_c - theta = np.pi / 2 - noisy_circuit = circuit.__class__(**circuit.init_kwargs) + for _ in range(num_insertions): + noisy_circuit += copy_c.invert() + copy_c - for gate in circuit.queue: - noisy_circuit.add(gate) + for m in circuit.measurements: + noisy_circuit.add(m) - if isinstance(gate, i_gate): - if insertion_gate == "CNOT": - control = gate.control_qubits[0] - target = gate.target_qubits[0] - for _ in range(num_insertions): - noisy_circuit.add(gates.CNOT(control, target)) - noisy_circuit.add(gates.CNOT(control, target)) - elif gate.init_kwargs["theta"] == theta: - qubit = gate.qubits[0] - for _ in range(num_insertions): - noisy_circuit.add(gates.RX(qubit, theta=theta)) - noisy_circuit.add(gates.RX(qubit, theta=-theta)) + else: + if insertion_gate is None or insertion_gate not in ( + "CNOT", + "RX", + ): # pragma: no cover + raise_error( + ValueError, + "Invalid insertion gate specification. Please select between 'CNOT' and 'RX'.", + ) + if insertion_gate == "CNOT" and circuit.nqubits < 2: # pragma: no cover + raise_error( + ValueError, + "Provide a circuit with at least 2 qubits when using the 'CNOT' insertion gate. " + + "Alternatively, try with the 'RX' insertion gate instead.", + ) + + i_gate = gates.CNOT if insertion_gate == "CNOT" else gates.RX + + theta = np.pi / 2 + noisy_circuit = Circuit(**circuit.init_kwargs) + + for gate in circuit.queue: + noisy_circuit.add(gate) + + if isinstance(gate, i_gate): + if insertion_gate == "CNOT": + control = gate.control_qubits[0] + target = gate.target_qubits[0] + for _ in range(num_insertions): + noisy_circuit.add(gates.CNOT(control, target)) + noisy_circuit.add(gates.CNOT(control, target)) + elif insertion_gate == "RX": + qubit = gate.qubits[0] + theta = gate.init_kwargs["theta"] + for _ in range(num_insertions): + noisy_circuit.add(gates.RX(qubit, theta=theta)) + noisy_circuit.add(gates.RX(qubit, theta=-theta)) return noisy_circuit @@ -108,6 +134,7 @@ def ZNE( noise_model=None, nshots=10000, solve_for_gammas=False, + global_unitary_folding=True, insertion_gate="CNOT", readout=None, qubit_map=None, @@ -129,9 +156,10 @@ def ZNE( nshots (int, optional): Number of shots. Defaults to :math:`10000`. solve_for_gammas (bool, optional): If ``True``, explicitly solve the equations to obtain the ``gamma`` coefficients. Default is ``False``. - insertion_gate (str, optional): gate to be used in the insertion. - If ``"RX"``, the gate used is :math:``RX(\\pi / 2)``. - Defaults to ``"CNOT"``. + global_unitary_folding (bool, optional): If ``True``, noise is increased by global unitary folding. + If ``False``, local unitary folding is used. Defaults to ``True``. + insertion_gate (str, optional): gate to be folded in the local unitary folding. + If ``RX``, the gate used is :math:``RX(\\pi / 2)``. Otherwise, it is the ``CNOT`` gate. readout (dict, optional): a dictionary that may contain the following keys: * ncircuits: int, specifies the number of random circuits to use for the randomized method of readout error mitigation. @@ -162,7 +190,10 @@ def ZNE( expected_values = [] for num_insertions in noise_levels: noisy_circuit = get_noisy_circuit( - circuit, num_insertions, insertion_gate=insertion_gate + circuit, + num_insertions, + global_unitary_folding, + insertion_gate=insertion_gate, ) val = get_expectation_val_with_readout_mitigation( noisy_circuit, diff --git a/src/qibo/quantum_info/clifford.py b/src/qibo/quantum_info/clifford.py index 11d1b4e9e..000aa6bcd 100644 --- a/src/qibo/quantum_info/clifford.py +++ b/src/qibo/quantum_info/clifford.py @@ -269,7 +269,7 @@ def samples(self, binary: bool = True, registers: bool = False): self._samples = self._backend.cast(samples, dtype="int32") for gate in self.measurements: rqubits = tuple(qubit_map.get(q) for q in gate.target_qubits) - gate.result.register_samples(self._samples[:, rqubits], self._backend) + gate.result.register_samples(self._samples[:, rqubits]) if registers: return { diff --git a/src/qibo/result.py b/src/qibo/result.py index f9b101ac9..b2fa8a95f 100644 --- a/src/qibo/result.py +++ b/src/qibo/result.py @@ -244,7 +244,7 @@ def frequencies(self, binary: bool = True, registers: bool = False): if int(bitstring[qubit_map.get(q)]): idx += 2 ** (len(rqubits) - i - 1) rfreqs[idx] += freq - gate.result.register_frequencies(rfreqs, self.backend) + gate.result.register_frequencies(rfreqs) else: self._frequencies = self.backend.calculate_frequencies( self.samples(binary=False) @@ -356,9 +356,7 @@ def samples(self, binary: bool = True, registers: bool = False): self._samples = samples for gate in self.measurements: rqubits = tuple(qubit_map.get(q) for q in gate.target_qubits) - gate.result.register_samples( - self._samples[:, rqubits], self.backend - ) + gate.result.register_samples(self._samples[:, rqubits]) if registers: return { diff --git a/src/qibo/symbols.py b/src/qibo/symbols.py index 9aa12a1dc..edb03eb67 100644 --- a/src/qibo/symbols.py +++ b/src/qibo/symbols.py @@ -99,13 +99,13 @@ def full_matrix(self, nqubits): Matrix of dimension (2^nqubits, 2^nqubits) composed of the Kronecker product between identities and the symbol's single-qubit matrix. """ - from qibo.hamiltonians.models import multikron + from qibo.hamiltonians.models import _multikron matrix_list = self.target_qubit * [matrices.I] matrix_list.append(self.matrix) n = nqubits - self.target_qubit - 1 matrix_list.extend(matrices.I for _ in range(n)) - return multikron(matrix_list) + return _multikron(matrix_list) class PauliSymbol(Symbol): diff --git a/src/qibo/transpiler/decompositions.py b/src/qibo/transpiler/decompositions.py index 780aa42c9..29d691402 100644 --- a/src/qibo/transpiler/decompositions.py +++ b/src/qibo/transpiler/decompositions.py @@ -387,6 +387,12 @@ def _u3_to_gpi2(t, p, l): lambda gate: two_qubit_decomposition(0, 1, gate.matrix(backend), backend=backend), ) +# temporary CNOT decompositions for CNOT, CZ, SWAP +cnot_dec_temp = GateDecompositions() +cnot_dec_temp.add(gates.CNOT, [gates.CNOT(0, 1)]) +cnot_dec_temp.add(gates.CZ, [gates.H(1), gates.CNOT(0, 1), gates.H(1)]) +cnot_dec_temp.add(gates.SWAP, [gates.CNOT(0, 1), gates.CNOT(1, 0), gates.CNOT(0, 1)]) + # register other optimized gate decompositions opt_dec = GateDecompositions() opt_dec.add( diff --git a/src/qibo/transpiler/unroller.py b/src/qibo/transpiler/unroller.py index a14aca382..9032e5e30 100644 --- a/src/qibo/transpiler/unroller.py +++ b/src/qibo/transpiler/unroller.py @@ -4,7 +4,14 @@ from qibo.config import raise_error from qibo.models import Circuit from qibo.transpiler._exceptions import DecompositionError -from qibo.transpiler.decompositions import cz_dec, gpi2_dec, iswap_dec, opt_dec, u3_dec +from qibo.transpiler.decompositions import ( + cnot_dec_temp, + cz_dec, + gpi2_dec, + iswap_dec, + opt_dec, + u3_dec, +) class NativeGates(Flag): @@ -22,6 +29,7 @@ class NativeGates(Flag): - :class:`qibo.gates.gates.U3` - :class:`qibo.gates.gates.CZ` - :class:`qibo.gates.gates.iSWAP` + - :class:`qibo.gates.gates.CNOT` """ I = auto() @@ -32,6 +40,7 @@ class NativeGates(Flag): U3 = auto() CZ = auto() iSWAP = auto() + CNOT = auto() # For testing purposes @classmethod def default(cls): @@ -240,6 +249,13 @@ def _translate_two_qubit_gates(gate: gates.Gate, native_gates: NativeGates): iswap_decomposed.append(g_translated) return iswap_decomposed + # For testing purposes + # No CZ, iSWAP gates in the native gate set + # Decompose CNOT, CZ, SWAP gates into CNOT gates + if native_gates & NativeGates.CNOT: + return cnot_dec_temp(gate) + raise_error( - DecompositionError, "Use only CZ and/or iSWAP as native gates" + DecompositionError, + "Use only CZ and/or iSWAP as native gates. CNOT is allowed in circuits where the two-qubit gates are limited to CZ, CNOT, and SWAP.", ) # pragma: no cover diff --git a/src/qibo/ui/__init__.py b/src/qibo/ui/__init__.py new file mode 100644 index 000000000..34354b6b7 --- /dev/null +++ b/src/qibo/ui/__init__.py @@ -0,0 +1 @@ +from qibo.ui.mpldrawer import plot_circuit diff --git a/src/qibo/ui/drawer_utils.py b/src/qibo/ui/drawer_utils.py new file mode 100644 index 000000000..59e8fc2ab --- /dev/null +++ b/src/qibo/ui/drawer_utils.py @@ -0,0 +1,42 @@ +from qibo.gates.abstract import Gate + + +class FusedStartGateBarrier(Gate): + """ + :class:`qibo.ui.drawer_utils.FusedStartGateBarrier` gives room to fused group of gates. + Inherit from ``qibo.gates.abstract.Gate``. A special gate barrier gate to pin the starting point of fused gates. + """ + + def __init__(self, q_ctrl, q_trgt, nfused, equal_qbits=False): + + super().__init__() + self.name = ( + "FusedStartGateBarrier" + + str(nfused) + + ("" if not equal_qbits else "@EQUAL") + ) + self.draw_label = "" + self.control_qubits = (q_ctrl,) + self.target_qubits = (q_trgt,) if q_ctrl != q_trgt else () + self.init_args = [q_trgt, q_ctrl] if q_ctrl != q_trgt else [q_ctrl] + self.unitary = False + self.is_controlled_by = False + self.nfused = nfused + + +class FusedEndGateBarrier(Gate): + """ + :class:`qibo.ui.drawer_utils.FusedEndGateBarrier` gives room to fused group of gates. + Inherit from ``qibo.gates.abstract.Gate``. A special gate barrier gate to pin the ending point of fused gates. + """ + + def __init__(self, q_ctrl, q_trgt): + + super().__init__() + self.name = "FusedEndGateBarrier" + self.draw_label = "" + self.control_qubits = (q_ctrl,) + self.target_qubits = (q_trgt,) if q_ctrl != q_trgt else () + self.init_args = [q_trgt, q_ctrl] if q_ctrl != q_trgt else [q_ctrl] + self.unitary = False + self.is_controlled_by = False diff --git a/src/qibo/ui/mpldrawer.py b/src/qibo/ui/mpldrawer.py new file mode 100644 index 000000000..439541d38 --- /dev/null +++ b/src/qibo/ui/mpldrawer.py @@ -0,0 +1,735 @@ +# Some functions in MPLDrawer are from code provided by Rick Muller +# Simplified Plotting Routines for Quantum Circuits +# https://github.com/rpmuller/PlotQCircuit +# +import json +from pathlib import Path +from typing import Union + +import matplotlib +import numpy as np + +from qibo import gates + +from .drawer_utils import FusedEndGateBarrier, FusedStartGateBarrier + +UI = Path(__file__).parent +STYLE = json.loads((UI / "styles.json").read_text()) +SYMBOLS = json.loads((UI / "symbols.json").read_text()) + +PLOT_PARAMS = { + "scale": 1.0, + "fontsize": 14.0, + "linewidth": 1.0, + "control_radius": 0.05, + "not_radius": 0.15, + "swap_delta": 0.08, + "label_buffer": 0.0, + "facecolor": "w", + "edgecolor": "#000000", + "fillcolor": "#000000", + "linecolor": "k", + "textcolor": "k", + "gatecolor": "w", + "controlcolor": "#000000", +} + + +def _plot_quantum_schedule( + schedule, inits, plot_params, labels=[], plot_labels=True, **kwargs +): + """Use Matplotlib to plot a queue of quantum circuit. + + Args: + schedule (list): List of time steps, each containing a sequence of gates during that step. + Each gate is a tuple containing (name,target,control1,control2...). Targets and controls initially defined in terms of labels. + + inits (list): Initialization list of gates. + + plot_params (list): Style plot configuration. + + labels (list): List of qubit labels, optional. + + kwargs (list): Variadic list that can override plot parameters. + + Returns: + matplotlib.axes.Axes: An Axes object encapsulates all the plt elements of a plot in a figure. + """ + + return _plot_quantum_circuit( + schedule, + inits, + plot_params, + labels=labels, + plot_labels=plot_labels, + schedule=True, + **kwargs + ) + + +def _plot_quantum_circuit( + gates, inits, plot_params, labels=[], plot_labels=True, schedule=False, **kwargs +): + """Use Matplotlib to plot a quantum circuit. + + Args: + gates (list): List of tuples for each gate in the quantum circuit. (name,target,control1,control2...). + Targets and controls initially defined in terms of labels. + + inits (list): Initialization list of gates. + + plot_params (list): Style plot configuration. + + labels (list): List of qubit labels. (optional). + + kwargs (list): Variadic list that can override plot parameters. + + Returns: + matplotlib.axes.Axes: An Axes object encapsulates all the plt elements of a plot in a figure. + """ + + plot_params.update(kwargs) + scale = plot_params["scale"] + + # Create labels from gates. This will become slow if there are a lot + # of gates, in which case move to an ordered dictionary + if not labels: + labels = [] + for i, gate in _enumerate_gates(gates, schedule=schedule): + for label in gate[1:]: + if label not in labels: + labels.append(label) + + nq = len(labels) + ng = len(gates) + + wire_grid = np.arange(0.0, nq * scale, scale, dtype=float) + + gate_grid = np.arange(0.0, (nq if ng == 0 else ng) * scale, scale, dtype=float) + ax, _ = _setup_figure( + nq, (nq if ng == 0 else ng), gate_grid, wire_grid, plot_params + ) + + measured = None if ng == 0 else _measured_wires(gates, labels, schedule=schedule) + _draw_wires(ax, nq, gate_grid, wire_grid, plot_params, measured) + + if plot_labels: + _draw_labels(ax, labels, inits, gate_grid, wire_grid, plot_params) + + if ng > 0: + _draw_gates( + ax, + gates, + labels, + gate_grid, + wire_grid, + plot_params, + measured, + schedule=schedule, + ) + + return ax + + +def _enumerate_gates(gates_plot, schedule=False): + """Enumerate the gates in a way that can take l as either a list of gates or a schedule + + Args: + gates_plot (list): List of gates to plot. + + schedule (bool): Check whether process single gate or array of gates at a time. + + Returns: + int: Index of gate or list of gates. + + list: Processed list of gates ready to plot. + """ + + if schedule: + for i, gates in enumerate(gates_plot): + for gate in gates: + yield i, gate + else: + for i, gate in enumerate(gates_plot): + yield i, gate + + +def _measured_wires(gates_plot, labels, schedule=False): + measured = {} + for i, gate in _enumerate_gates(gates_plot, schedule=schedule): + name, target = gate[:2] + j = _get_flipped_index(target, labels) + if name.startswith("M"): + measured[j] = i + return measured + + +def _draw_gates( + ax, + gates_plot, + labels, + gate_grid, + wire_grid, + plot_params, + measured={}, + schedule=False, +): + for i, gate in _enumerate_gates(gates_plot, schedule=schedule): + _draw_target(ax, i, gate, labels, gate_grid, wire_grid, plot_params) + if len(gate) > 2: # Controlled + _draw_controls( + ax, i, gate, labels, gate_grid, wire_grid, plot_params, measured + ) + + +def _draw_controls(ax, i, gate, labels, gate_grid, wire_grid, plot_params, measured={}): + + name, target = gate[:2] + + if "FUSEDENDGATEBARRIER" in name: + return + + linewidth = plot_params["linewidth"] + scale = plot_params["scale"] + control_radius = plot_params["control_radius"] + + target_index = _get_flipped_index(target, labels) + controls = gate[2:] + control_indices = _get_flipped_indices(controls, labels) + gate_indices = control_indices + [target_index] + min_wire = min(gate_indices) + max_wire = max(gate_indices) + + if "FUSEDSTARTGATEBARRIER" in name: + equal_qbits = False + if "@EQUAL" in name: + name = name.replace("@EQUAL", "") + equal_qbits = True + nfused = int(name.replace("FUSEDSTARTGATEBARRIER", "")) + dx_right = 0.30 + dx_left = 0.30 + dy = 0.25 + _rectangle( + ax, + gate_grid[i + 1] - dx_left, + gate_grid[i + nfused] + dx_right, + wire_grid[min_wire] - dy - (0 if not equal_qbits else -0.9 * scale), + wire_grid[max_wire] + dy, + plot_params, + ) + else: + + _line( + ax, + gate_grid[i], + gate_grid[i], + wire_grid[min_wire], + wire_grid[max_wire], + plot_params, + ) + + for ci in control_indices: + x = gate_grid[i] + y = wire_grid[ci] + + is_dagger = False + if name[-2:] == "DG": + name = name.replace("DG", "") + is_dagger = True + + if name == "SWAP": + _swapx(ax, x, y, plot_params) + elif name in [ + "ISWAP", + "SISWAP", + "FSWAP", + "FSIM", + "SYC", + "GENERALIZEDFSIM", + "RXX", + "RYY", + "RZZ", + "RZX", + "RXXYY", + "G", + "RBS", + "ECR", + "MS", + ]: + + symbol = SYMBOLS.get(name, name) + + if is_dagger: + symbol += r"$\rm{^{\dagger}}$" + + _text(ax, x, y, symbol, plot_params, box=True) + + else: + _cdot(ax, x, y, plot_params) + + +def _draw_target(ax, i, gate, labels, gate_grid, wire_grid, plot_params): + name, target = gate[:2] + + if "FUSEDSTARTGATEBARRIER" in name or "FUSEDENDGATEBARRIER" in name: + return + + is_dagger = False + if name[-2:] == "DG": + name = name.replace("DG", "") + is_dagger = True + + symbol = SYMBOLS.get(name, name) # override name with symbols + + if is_dagger: + symbol += r"$\rm{^{\dagger}}$" + + x = gate_grid[i] + target_index = _get_flipped_index(target, labels) + y = wire_grid[target_index] + if name in ["CNOT", "TOFFOLI"]: + _oplus(ax, x, y, plot_params) + elif name == "SWAP": + _swapx(ax, x, y, plot_params) + else: + if name == "ALIGN": + symbol = "A({})".format(target[2:]) + _text(ax, x, y, symbol, plot_params, box=True) + + +def _line(ax, x1, x2, y1, y2, plot_params): + Line2D = matplotlib.lines.Line2D + line = Line2D( + (x1, x2), (y1, y2), color=plot_params["linecolor"], lw=plot_params["linewidth"] + ) + ax.add_line(line) + + +def _text(ax, x, y, textstr, plot_params, box=False): + linewidth = plot_params["linewidth"] + fontsize = ( + 12.0 + if _check_list_str(["dagger", "sqrt"], textstr) + else plot_params["fontsize"] + ) + + if box: + bbox = dict( + ec=plot_params["edgecolor"], + fc=plot_params["gatecolor"], + fill=True, + lw=linewidth, + ) + else: + bbox = dict(fill=False, lw=0) + ax.text( + x, + y, + textstr, + color=plot_params["textcolor"], + ha="center", + va="center", + bbox=bbox, + size=fontsize, + ) + + +def _oplus(ax, x, y, plot_params): + Line2D = matplotlib.lines.Line2D + Circle = matplotlib.patches.Circle + not_radius = plot_params["not_radius"] + linewidth = plot_params["linewidth"] + c = Circle( + (x, y), + not_radius, + ec=plot_params["edgecolor"], + fc=plot_params["gatecolor"], + fill=True, + lw=linewidth, + ) + ax.add_patch(c) + _line(ax, x, x, y - not_radius, y + not_radius, plot_params) + + +def _cdot(ax, x, y, plot_params): + Circle = matplotlib.patches.Circle + control_radius = plot_params["control_radius"] + scale = plot_params["scale"] + linewidth = plot_params["linewidth"] + c = Circle( + (x, y), + control_radius * scale, + ec=plot_params["edgecolor"], + fc=plot_params["controlcolor"], + fill=True, + lw=linewidth, + ) + ax.add_patch(c) + + +def _swapx(ax, x, y, plot_params): + d = plot_params["swap_delta"] + linewidth = plot_params["linewidth"] + _line(ax, x - d, x + d, y - d, y + d, plot_params) + _line(ax, x - d, x + d, y + d, y - d, plot_params) + + +def _setup_figure(nq, ng, gate_grid, wire_grid, plot_params): + scale = plot_params["scale"] + fig = matplotlib.pyplot.figure( + figsize=(ng * scale, nq * scale), + facecolor=plot_params["facecolor"], + edgecolor=plot_params["edgecolor"], + ) + ax = fig.add_subplot(1, 1, 1, frameon=True) + ax.set_axis_off() + offset = 0.5 * scale + ax.set_xlim(gate_grid[0] - offset, gate_grid[-1] + offset) + ax.set_ylim(wire_grid[0] - offset, wire_grid[-1] + offset) + ax.set_aspect("equal") + return ax, fig + + +def _draw_wires(ax, nq, gate_grid, wire_grid, plot_params, measured={}): + scale = plot_params["scale"] + linewidth = plot_params["linewidth"] + xdata = (gate_grid[0] - scale, gate_grid[-1] + scale) + for i in range(nq): + _line( + ax, + gate_grid[0] - scale, + gate_grid[-1] + scale, + wire_grid[i], + wire_grid[i], + plot_params, + ) + + +def _draw_labels(ax, labels, inits, gate_grid, wire_grid, plot_params): + scale = plot_params["scale"] + label_buffer = plot_params["label_buffer"] + fontsize = plot_params["fontsize"] + nq = len(labels) + xdata = (gate_grid[0] - scale, gate_grid[-1] + scale) + for i in range(nq): + j = _get_flipped_index(labels[i], labels) + _text( + ax, + xdata[0] - label_buffer, + wire_grid[j], + _render_label(labels[i], inits), + plot_params, + ) + + +def _get_min_max_qbits(gates): + def _get_all_tuple_items(iterable): + t = [] + for each in iterable: + t.extend(list(each) if isinstance(each, tuple) else [each]) + return tuple(t) + + all_qbits = [] + c_qbits = [t._control_qubits for t in gates.gates] + t_qbits = [t._target_qubits for t in gates.gates] + c_qbits = _get_all_tuple_items(c_qbits) + t_qbits = _get_all_tuple_items(t_qbits) + all_qbits.append(c_qbits + t_qbits) + + flatten_arr = _get_all_tuple_items(all_qbits) + return min(flatten_arr), max(flatten_arr) + + +def _get_flipped_index(target, labels): + nq = len(labels) + i = labels.index(target) + return nq - i - 1 + + +def _rectangle(ax, x1, x2, y1, y2, plot_style): + Rectangle = matplotlib.patches.Rectangle + x = min(x1, x2) + y = min(y1, y2) + w = abs(x2 - x1) + h = abs(y2 - y1) + xm = x + w / 2.0 + ym = y + h / 2.0 + + rect = Rectangle( + (x, y), + w, + h, + ec=plot_style["edgecolor"], + fc=plot_style["fillcolor"], + fill=False, + lw=plot_style["linewidth"], + label="", + ) + ax.add_patch(rect) + + +def _get_flipped_indices(targets, labels): + return [_get_flipped_index(t, labels) for t in targets] + + +def _render_label(label, inits={}): + if label in inits: + s = inits[label] + if s is None: + return "" + else: + return r"$|%s\rangle$" % inits[label] + return r"$|%s\rangle$" % label + + +def _check_list_str(substrings, string): + return any(item in string for item in substrings) + + +def _make_cluster_gates(gates_items): + """ + Given a list of gates from a Qibo circuit, this fucntion gathers all gates to reduce the depth of the circuit making the circuit more user-friendly to avoid very large circuits printed on screen. + + Args: + gates_items (list): List of gates to gather for circuit depth reduction. + + Returns: + list: List of gathered gates. + """ + + temp_gates = [] + temp_mgates = [] + cluster_gates = [] + + for item in gates_items: + if len(item) == 2: # single qubit gates + if item[0] == "MEASURE": + temp_mgates.append(item) + else: + if len(temp_gates) > 0: + if item[1] in [tup[1] for tup in temp_gates]: + cluster_gates.append(temp_gates) + temp_gates = [] + temp_gates.append(item) + else: + temp_gates.append(item) + else: + temp_gates.append(item) + else: + if len(temp_gates) > 0: + cluster_gates.append(temp_gates) + temp_gates = [] + + if len(temp_mgates) > 0: + cluster_gates.append(temp_mgates) + temp_mgates = [] + + cluster_gates.append([item]) + + if len(temp_gates) > 0: + cluster_gates.append(temp_gates) + + if len(temp_mgates) > 0: + cluster_gates.append(temp_mgates) + + return cluster_gates + + +def _process_gates(array_gates, nqubits): + """ + Transforms the list of gates given by the Qibo circuit into a list of gates with a suitable structre to print on screen with matplotlib. + + Args: + array_gates (list): List of gates provided by the Qibo circuit. + nqubits (int): Number of circuit qubits + + Returns: + list: List of suitable gates to plot with matplotlib. + """ + + if len(array_gates) == 0: + return [] + + gates_plot = [] + + for gate in array_gates: + init_label = gate.name.upper() + + if init_label == "CCX": + init_label = "TOFFOLI" + elif init_label == "CX": + init_label = "CNOT" + elif _check_list_str(["SX", "CSX"], init_label): + is_dagger = init_label[-2:] == "DG" + init_label = ( + r"$\rm{\sqrt{X}}^{\dagger}$" if is_dagger else r"$\rm{\sqrt{X}}$" + ) + elif ( + len(gate._control_qubits) > 0 + and "C" in init_label[0] + and "CNOT" != init_label + ): + init_label = gate.draw_label.upper() + + if init_label in [ + "ID", + "MEASURE", + "KRAUSCHANNEL", + "UNITARYCHANNEL", + "DEPOLARIZINGCHANNEL", + "READOUTERRORCHANNEL", + ]: + for qbit in gate._target_qubits: + item = (init_label,) + item += ("q_" + str(qbit),) + gates_plot.append(item) + elif init_label == "ENTANGLEMENTENTROPY": + for qbit in list(range(nqubits)): + item = (init_label,) + item += ("q_" + str(qbit),) + gates_plot.append(item) + else: + item = () + item += (init_label,) + + for qbit in gate._target_qubits: + if type(qbit) is tuple: + item += ("q_" + str(qbit[0]),) + else: + item += ("q_" + str(qbit),) + + for qbit in gate._control_qubits: + item_add = ( + ("q_" + str(qbit[0]),) + if isinstance(qbit, tuple) + else ("q_" + str(qbit),) + ) + item += item_add + + gates_plot.append(item) + + return gates_plot + + +def _plot_params(style: Union[dict, str, None]) -> dict: + """ + Given a style name, the function gets the style configuration, if the style is not available, it return the default style. It is allowed to give a custom dictionary to give the circuit a style. + + Args: + style (Union[dict, str, None]): Name of the style. + + Returns: + dict: Style configuration. + """ + if not isinstance(style, dict): + style = ( + STYLE.get(style) + if (style is not None and style in STYLE.keys()) + else STYLE["default"] + ) + + return style + + +def plot_circuit(circuit, scale=0.6, cluster_gates=True, style=None): + """Main matplotlib plot function for Qibo circuit + + Args: + circuit (qibo.models.circuit.Circuit): A Qibo circuit to plot. + + scale (float): Scaling factor for matplotlib output drawing. + + cluster_gates (boolean): Group (or not) circuit gates on drawing. + + style (Union[dict, str, None]): Style applied to the circuit, it can a built-in sytle or custom + (built-in styles: garnacha, fardelejo, quantumspain, color-blind, cachirulo or custom dictionary). + + Returns: + matplotlib.axes.Axes: Axes object that encapsulates all the elements of an individual plot in a figure. + + matplotlib.figure.Figure: A matplotlib figure object. + + Example: + + .. testcode:: + + import matplotlib.pyplot as plt + import qibo + from qibo import gates, models + from qibo.models import QFT + + # new plot function based on matplotlib + from qibo.ui import plot_circuit + + %matplotlib inline + + # create a 5-qubits QFT circuit + c = QFT(5) + c.add(gates.M(qubit) for qubit in range(2)) + + # print circuit with default options (default black & white style, scale factor of 0.6 and clustered gates) + plot_circuit(c); + + # print the circuit with built-int style "garnacha", clustering gates and a custom scale factor + # built-in styles: "garnacha", "fardelejo", "quantumspain", "color-blind", "cachirulo" or custom dictionary + plot_circuit(c, scale = 0.8, cluster_gates = True, style="garnacha"); + + # plot the Qibo circuit with a custom style + custom_style = { + "facecolor" : "#6497bf", + "edgecolor" : "#01016f", + "linecolor" : "#01016f", + "textcolor" : "#01016f", + "fillcolor" : "#ffb9b9", + "gatecolor" : "#d8031c", + "controlcolor" : "#360000" + } + + plot_circuit(c, scale = 0.8, cluster_gates = True, style=custom_style); + """ + + params = PLOT_PARAMS.copy() + params.update(_plot_params(style)) + inits = list(range(circuit.nqubits)) + + labels = [] + for i in range(circuit.nqubits): + labels.append("q_" + str(i)) + + all_gates = [] + for gate in circuit.queue: + if isinstance(gate, gates.FusedGate): + min_q, max_q = _get_min_max_qbits(gate) + + fgates = None + + if cluster_gates: + fgates = _make_cluster_gates( + _process_gates(gate.gates, circuit.nqubits) + ) + else: + fgates = _process_gates(gate.gates, circuit.nqubits) + + l_gates = len(gate.gates) + equal_qbits = False + if min_q != max_q: + l_gates = len(fgates) + else: + max_q += 1 + equal_qbits = True + + all_gates.append(FusedStartGateBarrier(min_q, max_q, l_gates, equal_qbits)) + all_gates += gate.gates + all_gates.append(FusedEndGateBarrier(min_q, max_q)) + else: + all_gates.append(gate) + + gates_plot = _process_gates(all_gates, circuit.nqubits) + + if cluster_gates and len(gates_plot) > 0: + gates_cluster = _make_cluster_gates(gates_plot) + ax = _plot_quantum_schedule(gates_cluster, inits, params, labels, scale=scale) + return ax, ax.figure + + ax = _plot_quantum_circuit(gates_plot, inits, params, labels, scale=scale) + return ax, ax.figure diff --git a/src/qibo/ui/styles.json b/src/qibo/ui/styles.json new file mode 100644 index 000000000..24a3d4578 --- /dev/null +++ b/src/qibo/ui/styles.json @@ -0,0 +1,56 @@ +{ + "garnacha": { + "facecolor": "#5e2129", + "edgecolor": "#ffffff", + "linecolor": "#ffffff", + "textcolor": "#ffffff", + "fillcolor": "#ffffff", + "gatecolor": "#5e2129", + "controlcolor": "#ffffff" + }, + "fardelejo": { + "facecolor": "#e17a02", + "edgecolor": "#fef1e2", + "linecolor": "#fef1e2", + "textcolor": "#FFFFFF", + "fillcolor": "#fef1e2", + "gatecolor": "#8b4513", + "controlcolor": "#fef1e2" + }, + "quantumspain": { + "facecolor": "#EDEDF4", + "edgecolor": "#092D4E", + "linecolor": "#092D4E", + "textcolor": "#8561C3", + "fillcolor": "#092D4E", + "gatecolor": "#53E7CA", + "controlcolor": "#092D4E" + }, + "color-blind": { + "facecolor": "#d55e00", + "edgecolor": "#f0e442", + "linecolor": "#f0e442", + "textcolor": "#f0e442", + "fillcolor": "#cc79a7", + "gatecolor": "#d55e00", + "controlcolor": "#f0e442" + }, + "cachirulo": { + "facecolor": "#ffffff", + "edgecolor": "#800000", + "linecolor": "#800000", + "textcolor": "#000000", + "fillcolor": "#ffffff", + "gatecolor": "#ffffff", + "controlcolor": "#800000" + }, + "default": { + "facecolor": "w", + "edgecolor": "#000000", + "linecolor": "k", + "textcolor": "k", + "fillcolor": "#000000", + "gatecolor": "w", + "controlcolor": "#000000" + } +} diff --git a/src/qibo/ui/symbols.json b/src/qibo/ui/symbols.json new file mode 100644 index 000000000..8d455bfcb --- /dev/null +++ b/src/qibo/ui/symbols.json @@ -0,0 +1,26 @@ +{ + "NOP": "", + "CPHASE": "Z", + "ID": "I", + "CX": "X", + "CZ": "Z", + "FSIM": "F", + "SYC": "SYC", + "GENERALIZEDFSIM": "GF", + "DEUTSCH": "DE", + "UNITARY": "U", + "MEASURE": "M", + "ISWAP": "I", + "SISWAP": "SI", + "FSWAP": "FX", + "KRAUSCHANNEL": "K", + "UNITARYCHANNEL": "U", + "PAULINOISECHANNEL": "PN", + "DEPOLARIZINGCHANNEL": "D", + "THERMALRELAXATIONCHANNEL": "TR", + "AMPLITUDEDAMPINGCHANNEL": "AD", + "PHASEDAMPINGCHANNEL": "PD", + "READOUTERRORCHANNEL": "RE", + "RESETCHANNEL": "R", + "ENTANGLEMENTENTROPY": "EE" +} diff --git a/tests/conftest.py b/tests/conftest.py index 87ac46a01..538ed7a1e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -43,13 +43,13 @@ def get_backend(backend_name): AVAILABLE_BACKENDS.append(backend_name) if _backend.supports_multigpu: # pragma: no cover MULTIGPU_BACKENDS.append(backend_name) - except (ModuleNotFoundError, ImportError): + except ImportError: pass try: get_backend("qulacs") QULACS_INSTALLED = True -except ModuleNotFoundError: +except ImportError: QULACS_INSTALLED = False diff --git a/tests/test_measurements.py b/tests/test_measurements.py index 050d2c197..979cb843b 100644 --- a/tests/test_measurements.py +++ b/tests/test_measurements.py @@ -1,11 +1,13 @@ """Test circuit result measurements and measurement gate and as part of circuit.""" +import json import pickle import numpy as np import pytest from qibo import gates, models +from qibo.measurements import MeasurementResult def assert_result( @@ -473,3 +475,41 @@ def test_measurementsymbol_pickling(backend): assert symbol.index == new_symbol.index assert symbol.name == new_symbol.name backend.assert_allclose(symbol.result.samples(), new_symbol.result.samples()) + + +def test_measurementresult_nshots(backend): + gate = gates.M(*range(3)) + result = MeasurementResult(gate) + # nshots starting from samples + nshots = 10 + samples = backend.cast( + [[i % 2, i % 2, i % 2] for i in range(nshots)], backend.np.int64 + ) + result.register_samples(samples) + assert result.nshots == nshots + # nshots starting from frequencies + result = MeasurementResult(gate) + states, counts = np.unique(samples, axis=0, return_counts=True) + to_str = lambda x: [str(item) for item in x] + states = ["".join(to_str(s)) for s in states.tolist()] + freq = dict(zip(states, counts.tolist())) + result.register_frequencies(freq) + assert result.nshots == nshots + + +def test_measurement_serialization(backend): + kwargs = { + "register_name": "test", + "collapse": False, + "basis": ["Z", "X", "Y"], + "p0": 0.1, + "p1": 0.2, + } + gate = gates.M(*range(3), **kwargs) + samples = backend.cast(np.random.randint(2, size=(100, 3)), backend.np.int64) + gate.result.register_samples(samples) + dump = gate.to_json() + load = gates.M.from_dict(json.loads(dump)) + for k, v in kwargs.items(): + assert load.init_kwargs[k] == v + backend.assert_allclose(samples, load.result.samples()) diff --git a/tests/test_models_error_mitigation.py b/tests/test_models_error_mitigation.py index 613e2c47f..8e003993c 100644 --- a/tests/test_models_error_mitigation.py +++ b/tests/test_models_error_mitigation.py @@ -95,7 +95,8 @@ def get_circuit(nqubits, nmeas=None): ], ) @pytest.mark.parametrize("solve", [False, True]) -def test_zne(backend, nqubits, noise, solve, insertion_gate, readout): +@pytest.mark.parametrize("GUF", [False, True]) +def test_zne(backend, nqubits, noise, solve, GUF, insertion_gate, readout): """Test that ZNE reduces the noise.""" if backend.name == "tensorflow": import tensorflow as tf @@ -128,6 +129,7 @@ def test_zne(backend, nqubits, noise, solve, insertion_gate, readout): noise_model=noise, nshots=10000, solve_for_gammas=solve, + global_unitary_folding=GUF, insertion_gate=insertion_gate, readout=readout, backend=backend, diff --git a/tests/test_states.py b/tests/test_states.py index fc0cd512d..9ce556485 100644 --- a/tests/test_states.py +++ b/tests/test_states.py @@ -8,12 +8,12 @@ def test_measurement_result_repr(): - result = MeasurementResult(gates.M(0), nshots=10) - assert str(result) == "MeasurementResult(qubits=(0,), nshots=10)" + result = MeasurementResult(gates.M(0)) + assert str(result) == "MeasurementResult(qubits=(0,), nshots=None)" def test_measurement_result_error(): - result = MeasurementResult(gates.M(0), nshots=10) + result = MeasurementResult(gates.M(0)) with pytest.raises(RuntimeError): samples = result.samples() diff --git a/tests/test_transpiler_unroller.py b/tests/test_transpiler_unroller.py index 61e2c11fc..474d2c50a 100644 --- a/tests/test_transpiler_unroller.py +++ b/tests/test_transpiler_unroller.py @@ -121,3 +121,36 @@ def test_measurements_non_comp_basis(): assert isinstance(transpiled_circuit.queue[2], gates.M) # After transpiling the measurement gate should be in the computational basis assert transpiled_circuit.queue[2].basis == [] + + +def test_temp_cnot_decomposition(): + from qibo.transpiler.pipeline import Passes + + circ = Circuit(2) + circ.add(gates.H(0)) + circ.add(gates.CNOT(0, 1)) + circ.add(gates.SWAP(0, 1)) + circ.add(gates.CZ(0, 1)) + circ.add(gates.M(0, 1)) + + glist = [gates.GPI2, gates.RZ, gates.Z, gates.M, gates.CNOT] + native_gates = NativeGates(0).from_gatelist(glist) + + custom_pipeline = Passes([Unroller(native_gates=native_gates)]) + transpiled_circuit, _ = custom_pipeline(circ) + + # H + assert transpiled_circuit.queue[0].name == "z" + assert transpiled_circuit.queue[1].name == "gpi2" + # CNOT + assert transpiled_circuit.queue[2].name == "cx" + # SWAP + assert transpiled_circuit.queue[3].name == "cx" + assert transpiled_circuit.queue[4].name == "cx" + assert transpiled_circuit.queue[5].name == "cx" + # CZ + assert transpiled_circuit.queue[6].name == "z" + assert transpiled_circuit.queue[7].name == "gpi2" + assert transpiled_circuit.queue[8].name == "cx" + assert transpiled_circuit.queue[9].name == "z" + assert transpiled_circuit.queue[10].name == "gpi2"