{ "cells": [ { "cell_type": "markdown", "id": "c4e97d94-9f03-4956-bb03-2f1753d8afa5", "metadata": {}, "source": [ "# Adaptive QPE\n", "\n", "**Download this notebook - {nb-download}`adaptive-qpe.ipynb`**\n", "\n", "This example illustrates a possible implementation of a quantum algorithm in Guppy, showcasing the possible integration, usage and pitfalls of features including:\n", "- [Control flow](https://docs.quantinuum.com/guppy/language_guide/control_flow.html)\n", "- [Compile time expressions](https://docs.quantinuum.com/guppy/language_guide/comptime.html), especially for referencing global constants\n", "\n", "The implemented algorithm is the basic adaptive random walk phase estimation algorithm found at [arXiv:2208.04526](https://arxiv.org/abs/2208.04526) (Alg. 1 with sampling circuit from Fig. 1), with an example Hamiltonian and numbers taken from [arXiv:2206.12950](https://arxiv.org/abs/2206.12950) (Section V.B)." ] }, { "cell_type": "markdown", "id": "df0a6b3278335d52", "metadata": {}, "source": [ "## Setup\n", "\n", "We begin by specifying the example Hamiltonian in use, in this case $H = 0.5 * Z$, in two variants:\n", "1. The unitary oracle $U(t) = R_Z[-0.5t]$ generated by the Hamiltonian, *and*\n", "2. An eigenstate $\\ket{0}$ of the Hamiltonian.\n", "\n", "Although this may seem redundant, we will need both for executing the algorithm." ] }, { "cell_type": "code", "execution_count": 1, "id": "d77268ee-b737-41cf-86a8-6abfb10b9b89", "metadata": { "ExecuteTime": { "end_time": "2025-12-08T17:47:00.347536Z", "start_time": "2025-12-08T17:46:59.783948Z" } }, "outputs": [], "source": [ "from guppylang import guppy\n", "from guppylang.std.quantum import qubit, crz\n", "\n", "\n", "@guppy\n", "def oracle(ctrl: qubit, q: qubit, t: float) -> None:\n", " \"\"\"Applies a controlled e^-iπHt/2 gate for the example Hamiltonian H = 0.5 * Z.\"\"\"\n", " crz(ctrl, q, angle(0.5 * t))\n", "\n", "\n", "@guppy\n", "def eigenstate() -> qubit:\n", " \"\"\"Prepares eigenstate of the example Hamiltonian H = 0.5 * Z.\"\"\"\n", " q = qubit()\n", " x(q)\n", " return q" ] }, { "cell_type": "markdown", "id": "19fcf6eef9268158", "metadata": {}, "source": [ "## Algorithm\n", "\n", "The algorithm roughly performs the following steps on each iteration, which are outlined below:\n", "1. Sample from a distribution generated by a circuit involving the eigenstate, an iteration-specific ancilla and the oracle (see Fig. 1 of [arXiv:2208.04526](https://arxiv.org/abs/2208.04526)).\n", "2. Based on the outcome, step the phase estimate up or down by a fixed amount.\n", "3. Decrease the step size by a fixed amount.\n", "\n", "Following [arXiv:2206.12950](https://arxiv.org/abs/2206.12950) (Fig. 4), we use 24 such iterations, and finally record the phase estimate using `result`.\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "f4b1a3fe-5586-44a4-b891-7af85c28013e", "metadata": { "ExecuteTime": { "end_time": "2025-12-08T17:47:00.374670Z", "start_time": "2025-12-08T17:47:00.355445Z" } }, "outputs": [], "source": [ "import math\n", "from guppylang.std.angles import angle\n", "from guppylang.std.builtins import output\n", "from guppylang.std.quantum import discard, measure, h, rz, x\n", "\n", "sqrt_e = math.sqrt(math.e)\n", "sqrt_e_div = math.sqrt((math.e - 1) / math.e)\n", "\n", "\n", "@guppy\n", "def main() -> None:\n", " # Pick initial estimate of phase mean and stdv\n", " # and prepare eigenstate\n", " mu, sigma = sqrt_e_div, 1 / sqrt_e\n", " tgt = eigenstate()\n", "\n", " for _ in range(24):\n", " t = 1 / sigma\n", "\n", " # Sample from the phase estimate distribution\n", " aux = qubit()\n", " h(aux)\n", " rz(aux, angle((sigma - mu) * t))\n", " oracle(aux, tgt, t)\n", " h(aux)\n", " outcome = measure(aux)\n", "\n", " # Adjust estimate and step size\n", " if outcome:\n", " mu += sigma / sqrt_e\n", " else:\n", " mu -= sigma / sqrt_e\n", " sigma *= sqrt_e_div\n", "\n", " discard(tgt)\n", " output(\"eigenvalue\", 2 * mu)\n", "\n", "main.check()" ] }, { "cell_type": "markdown", "id": "971da15f27c8fca8", "metadata": {}, "source": [ "Note that the implementation uses [`comptime`](https://docs.quantinuum.com/guppy/language_guide/comptime.html) expressions to reference the constants `sqrt_e` and `sqrt_e_div` since they are defined outside the function annotated with `@guppy`.\n", "\n", "One may ask why expressions involving `sigma` and these constants are not entirely wrapped in [`comptime`](https://docs.quantinuum.com/guppy/language_guide/comptime.html). This uncovers a subtlety of such wrapping: [`comptime`](https://docs.quantinuum.com/guppy/language_guide/comptime.html) expressions are only evaluated *once* during compile time, and thus cannot react to changing variables such as `sigma`." ] }, { "cell_type": "markdown", "id": "ff9db1b761f2faff", "metadata": {}, "source": [ "## Testing and Evaluation\n", "\n", "We test the implementation by creating an emulator and allocating the maximum number of qubits: One holding the eigenstate and one ancilla that will be reused. Running the emulator once yields an example result:" ] }, { "cell_type": "code", "execution_count": 3, "id": "4a51f004-53aa-41d0-884b-cdfd7c6efab5", "metadata": { "ExecuteTime": { "end_time": "2025-12-08T17:47:01.325159Z", "start_time": "2025-12-08T17:47:00.378285Z" } }, "outputs": [ { "data": { "text/plain": [ "EmulatorResult(results=[QsysShot(entries=[('eigenvalue', 2.3679925580437398)])])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "emulator = main.emulator(n_qubits=2).with_seed(2)\n", "emulator.run()" ] }, { "cell_type": "markdown", "id": "90c22ecc1a52005e", "metadata": {}, "source": [ "However, this is not guaranteed to be the actual phase of our example Hamiltonian, as it is only one example drawn from a distribution. We thus run a larger number of shots, extract the recorded phase from each and visualize them using `matplotlib`. Doing this reveals the expected phase of the Hamiltonian as the highest peak in the histogram." ] }, { "cell_type": "code", "execution_count": 4, "id": "526d9fad-1a5a-4adb-bf11-41729e03c3cf", "metadata": { "jupyter": { "is_executing": true } }, "outputs": [ { "data": { "image/png": "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xbBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyxrBDREREssawQ0RERLLGsENERESyZtCwc/ToUXTo0AFubm5QKBTYsmWL1nIhBCZMmABXV1dYWVkhICAA8fHxWn0eP36M0NBQ2NnZwd7eHuHh4cjIyCjBURAREZExM2jYyczMRJ06dbB48eJ8l8+cORMLFy7EsmXLcPr0aVhbWyMwMBDPnz+X+oSGhuLKlSvYt28fduzYgaNHj2LgwIElNQQiIiIycmaGfPF27dqhXbt2+S4TQmD+/Pn49ttv0bFjRwDAzz//DGdnZ2zZsgUhISG4evUq9uzZg9jYWDRo0AAAsGjRIgQFBWH27Nlwc3MrsbEQERGRcTLaa3YSEhKQnJyMgIAAqU2lUsHPzw8xMTEAgJiYGNjb20tBBwACAgJgYmKC06dPl3jNREREZHwMOrPzNsnJyQAAZ2dnrXZnZ2dpWXJyMpycnLSWm5mZwcHBQeqTn6ysLGRlZUnP09PT9VU2ERERGRmjndkpTpGRkVCpVNLD3d3d0CURERFRMTHasOPi4gIASElJ0WpPSUmRlrm4uCA1NVVr+cuXL/H48WOpT37GjRsHtVotPZKSkvRcPRERERkLow07np6ecHFxwYEDB6S29PR0nD59Gv7+/gAAf39/pKWlIS4uTupz8OBBaDQa+Pn5FbhtpVIJOzs7rQcRERHJk0Gv2cnIyMCNGzek5wkJCTh//jwcHBzg4eGB4cOHY+rUqahSpQo8PT0xfvx4uLm5ITg4GABQrVo1tG3bFgMGDMCyZcvw4sULREREICQkhHdiEREREQADh50zZ86gZcuW0vORI0cCAMLCwhAdHY1vvvkGmZmZGDhwINLS0tCkSRPs2bMHlpaW0jpr1qxBREQEWrduDRMTE3Tp0gULFy4s8bEQERGRcVIIIYShizC09PR0qFQqqNVqntIiek2lsTvztCVOb2+ASoiI8irs72+jvWaHiIiISB8YdoiIiEjWGHaIiIhI1nQKO7du3dJ3HURERETFQqewU7lyZbRs2RK//PKL1jeQExERERkbncLO2bNnUbt2bYwcORIuLi4YNGgQfv/9d33XRkRERFRkOoWdunXrYsGCBbh//z5++uknPHjwAE2aNEHNmjUxd+5cPHz4UN91EhEREemkSBcom5mZoXPnztiwYQNmzJiBGzduYNSoUXB3d0fv3r3x4MEDfdVJREREpJMihZ0zZ87gq6++gqurK+bOnYtRo0bh5s2b2LdvH+7fv4+OHTvqq04iIiIinej0dRFz585FVFQUrl27hqCgIPz8888ICgqCicmr7OTp6Yno6GhUqlRJn7USERERvTedws7SpUvRr18/9OnTB66urvn2cXJywsqVK4tUHBEREVFR6RR24uPj39nHwsICYWFhumyeiIiISG90umYnKioKGzZsyNO+YcMGrFq1qshFEREREemLTmEnMjIS5cuXz9Pu5OSEadOmFbkoIiIiIn3RKezcuXMHnp6eedorVqyIO3fuFLkoIiIiIn3RKew4OTnh4sWLedovXLiAcuXKFbkoIiIiIn3RKez06NEDQ4cOxaFDh5CTk4OcnBwcPHgQw4YNQ0hIiL5rJCIiItKZTndjTZkyBYmJiWjdujXMzF5tQqPRoHfv3rxmh4iIiIyKTmHHwsIC69evx5QpU3DhwgVYWVmhVq1aqFixor7rIyIiIioSncJOLm9vb3h7e+urFiIiIiK90yns5OTkIDo6GgcOHEBqaio0Go3W8oMHD+qlOCIiIqKi0insDBs2DNHR0Wjfvj1q1qwJhUKh77qIiIiI9EKnsLNu3Tr873//Q1BQkL7rISIiItIrnW49t7CwQOXKlfVdCxEREZHe6RR2vv76ayxYsABCCH3XQ0RERKRXOp3GOn78OA4dOoTdu3ejRo0aMDc311q+adMmvRRHREREVFQ6hR17e3t06tRJ37UQERER6Z1OYScqKkrfdRAREREVC52u2QGAly9fYv/+/Vi+fDmePn0KALh//z4yMjL0VhwRERFRUek0s3P79m20bdsWd+7cQVZWFj7++GPY2tpixowZyMrKwrJly/RdJxEREZFOdJrZGTZsGBo0aIAnT57AyspKau/UqRMOHDigt+KIiIiIikqnmZ1jx47h5MmTsLCw0GqvVKkS7t27p5fCiIiIiPRBp5kdjUaDnJycPO13796Fra1tkYsiIiIi0hedwk6bNm0wf/586blCoUBGRgYmTpzIr5AgIiIio6LTaaw5c+YgMDAQ1atXx/Pnz9GzZ0/Ex8ejfPny+PXXX/VdIxEREZHOdJrZqVChAi5cuIB///vfGDFiBOrVq4fp06fj3LlzcHJy0ltxOTk5GD9+PDw9PWFlZQUvLy9MmTJF62sqhBCYMGECXF1dYWVlhYCAAMTHx+utBiIiIirddJrZAQAzMzN8/vnn+qwljxkzZmDp0qVYtWoVatSogTNnzqBv375QqVQYOnQoAGDmzJlYuHAhVq1aBU9PT4wfPx6BgYH4448/YGlpWaz1ERERkfHTKez8/PPPb13eu3dvnYp508mTJ9GxY0e0b98ewKu7vX799Vf8/vvvAF7N6syfPx/ffvstOnbsKNXm7OyMLVu2ICQkRC91EBERUemlU9gZNmyY1vMXL17g2bNnsLCwQJkyZfQWdho1aoQVK1bg+vXr8Pb2xoULF3D8+HHMnTsXAJCQkIDk5GQEBARI66hUKvj5+SEmJqbAsJOVlYWsrCzpeXp6ul7qJSIiIuOjU9h58uRJnrb4+Hh8+eWXGD16dJGLyjV27Fikp6fDx8cHpqamyMnJwffff4/Q0FAAQHJyMgDA2dlZaz1nZ2dpWX4iIyMxadIkvdVJRERExkvn78Z6U5UqVTB9+vQ8sz5F8b///Q9r1qzB2rVrcfbsWaxatQqzZ8/GqlWrirTdcePGQa1WS4+kpCQ9VUxERETGRucLlPPdmJkZ7t+/r7ftjR49GmPHjpVOR9WqVQu3b99GZGQkwsLC4OLiAgBISUmBq6urtF5KSgrq1q1b4HaVSiWUSqXe6iQiIiLjpVPY2bZtm9ZzIQQePHiAH374AY0bN9ZLYQDw7NkzmJhoTz6ZmppCo9EAADw9PeHi4oIDBw5I4SY9PR2nT5/Gl19+qbc6iIiIqPTSKewEBwdrPVcoFHB0dESrVq0wZ84cfdQFAOjQoQO+//57eHh4oEaNGjh37hzmzp2Lfv36Sa87fPhwTJ06FVWqVJFuPXdzc8tTIxEREf0z6RR2cmdWituiRYswfvx4fPXVV0hNTYWbmxsGDRqECRMmSH2++eYbZGZmYuDAgUhLS0OTJk2wZ88efsYOERERAQAU4vWPI/6HSk9Ph0qlglqthp2dnaHLITIalcbuzNOWOL29ASohIsqrsL+/dZrZGTlyZKH75n4mDhEREZEh6BR2zp07h3PnzuHFixeoWrUqAOD69eswNTVF/fr1pX4KhUI/VRIRERHpSKew06FDB9ja2mLVqlUoW7YsgFcfNNi3b180bdoUX3/9tV6LJCIiItKVTh8qOGfOHERGRkpBBwDKli2LqVOn6vVuLCIiIqKi0inspKen4+HDh3naHz58iKdPnxa5KCIiIiJ90SnsdOrUCX379sWmTZtw9+5d3L17Fxs3bkR4eDg6d+6s7xqJiIiIdKbTNTvLli3DqFGj0LNnT7x48eLVhszMEB4ejlmzZum1QCIiIqKi0CnslClTBkuWLMGsWbNw8+ZNAICXlxesra31WhwRERFRURXpW88fPHiABw8eoEqVKrC2tgY/n5CIiIiMjU5h56+//kLr1q3h7e2NoKAgPHjwAAAQHh7O286JiIjIqOgUdkaMGAFzc3PcuXMHZcqUkdq7d++OPXv26K04IiIioqLS6Zqd3377DXv37kWFChW02qtUqYLbt2/rpTAiIiIifdBpZiczM1NrRifX48ePoVQqi1wUERERkb7oFHaaNm2Kn3/+WXquUCig0Wgwc+ZMtGzZUm/FERERERWVTqexZs6cidatW+PMmTPIzs7GN998gytXruDx48c4ceKEvmskIiIi0plOMzs1a9bE9evX0aRJE3Ts2BGZmZno3Lkzzp07By8vL33XSERERKSz957ZefHiBdq2bYtly5bhP//5T3HURERERKQ37z2zY25ujosXLxZHLURERER6p9NprM8//xwrV67Udy1EREREeqfTBcovX77ETz/9hP3798PX1zfPd2LNnTtXL8URERERFdV7hZ1bt26hUqVKuHz5MurXrw8AuH79ulYfhUKhv+qIiIiIiui9wk6VKlXw4MEDHDp0CMCrr4dYuHAhnJ2di6U4IiIioqJ6r2t23vxW8927dyMzM1OvBRERERHpk04XKOd6M/wQERERGZv3CjsKhSLPNTm8RoeIiIiM2XtdsyOEQJ8+faQv+3z+/Dm++OKLPHdjbdq0SX8VEhERERXBe4WdsLAwreeff/65XoshIiIi0rf3CjtRUVHFVQcRERFRsSjSBcpERERExo5hh4iIiGSNYYeIiIhkjWGHiIiIZI1hh4iIiGSNYYeIiIhkzejDzr179/D555+jXLlysLKyQq1atXDmzBlpuRACEyZMgKurK6ysrBAQEID4+HgDVkxERETGxKjDzpMnT9C4cWOYm5tj9+7d+OOPPzBnzhyULVtW6jNz5kwsXLgQy5Ytw+nTp2FtbY3AwEA8f/7cgJUTERGRsXivDxUsaTNmzIC7u7vWhxl6enpK/xZCYP78+fj222/RsWNHAMDPP/8MZ2dnbNmyBSEhISVeMxERERkXo57Z2bZtGxo0aICuXbvCyckJ9erVw48//igtT0hIQHJyMgICAqQ2lUoFPz8/xMTEFLjdrKwspKenaz2IiIhInow67Ny6dQtLly5FlSpVsHfvXnz55ZcYOnQoVq1aBQBITk4GADg7O2ut5+zsLC3LT2RkJFQqlfRwd3cvvkEQERGRQRl12NFoNKhfvz6mTZuGevXqYeDAgRgwYACWLVtWpO2OGzcOarVaeiQlJempYiIiIjI2Rh12XF1dUb16da22atWq4c6dOwAAFxcXAEBKSopWn5SUFGlZfpRKJezs7LQeREREJE9GHXYaN26Ma9euabVdv34dFStWBPDqYmUXFxccOHBAWp6eno7Tp0/D39+/RGslIiIi42TUd2ONGDECjRo1wrRp09CtWzf8/vvvWLFiBVasWAEAUCgUGD58OKZOnYoqVarA09MT48ePh5ubG4KDgw1bPBERERkFow47H374ITZv3oxx48Zh8uTJ8PT0xPz58xEaGir1+eabb5CZmYmBAwciLS0NTZo0wZ49e2BpaWnAyomIiMhYKIQQwtBFGFp6ejpUKhXUajWv3yF6TaWxO/O0JU5vb4BKiIjyKuzvb6O+ZoeIiIioqBh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWGHaIiIhI1hh2iIiISNYYdoiIiEjWjPrrIojI+Lz5qcr8RGUiMnac2SEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZY9ghIiIiWWPYISIiIllj2CEiIiJZK1VhZ/r06VAoFBg+fLjU9vz5cwwePBjlypWDjY0NunTpgpSUFMMVSUREREal1ISd2NhYLF++HLVr19ZqHzFiBLZv344NGzbgyJEjuH//Pjp37mygKomIiMjYlIqwk5GRgdDQUPz4448oW7as1K5Wq7Fy5UrMnTsXrVq1gq+vL6KionDy5EmcOnXKgBUTERGRsSgVYWfw4MFo3749AgICtNrj4uLw4sULrXYfHx94eHggJiamwO1lZWUhPT1d60FERETyZGboAt5l3bp1OHv2LGJjY/MsS05OhoWFBezt7bXanZ2dkZycXOA2IyMjMWnSJH2XSkREREbIqGd2kpKSMGzYMKxZswaWlpZ62+64ceOgVqulR1JSkt62TURERMbFqMNOXFwcUlNTUb9+fZiZmcHMzAxHjhzBwoULYWZmBmdnZ2RnZyMtLU1rvZSUFLi4uBS4XaVSCTs7O60HERERyZNRn8Zq3bo1Ll26pNXWt29f+Pj4YMyYMXB3d4e5uTkOHDiALl26AACuXbuGO3fuwN/f3xAlExERkZEx6rBja2uLmjVrarVZW1ujXLlyUnt4eDhGjhwJBwcH2NnZYciQIfD398dHH31kiJKJiIjIyBh12CmMefPmwcTEBF26dEFWVhYCAwOxZMkSQ5dFRERERkIhhBCGLsLQ0tPToVKpoFaref0O0Wsqjd35zj6J09uXQCVERHkV9ve3UV+gTERERFRUDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrDDtEREQka2aGLoCISrdKY3fmaUuc3t4AlRAR5Y8zO0RERCRrDDtEREQkaww7REREJGsMO0RERCRrRh92IiMj8eGHH8LW1hZOTk4IDg7GtWvXtPo8f/4cgwcPRrly5WBjY4MuXbogJSXFQBUTERGRMTH6sHPkyBEMHjwYp06dwr59+/DixQu0adMGmZmZUp8RI0Zg+/bt2LBhA44cOYL79++jc+fOBqyaiIiI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TZsW6vXq16+P5ORkmJmZoVKlSgX28/b2hre3N0aMGIEePXogKioKnTp1goWFBXJycnQe79ucOHECffr0kUJVRkYGEhMTtfrk9/r169fHH3/8UaTjQESv8DQWEeldlSpVsHr1aly9ehWnT59GaGgorKyspOXR0dFYuXIlLl++jFu3buGXX36BlZUVKlasCG9vb4SGhqJ3797YtGkTEhIS8PvvvyMyMhI7d+7M9/UCAgLg7++P4OBg/Pbbb0hMTMTJkyfxn//8B2fOnMHff/+NiIgIHD58GLdv38aJEycQGxuLatWqAXh111VGRgYOHDiAR48e4dmzZ3rdF5s2bcL58+dx4cIF9OzZU5r1yVWpUiUcPXoU9+7dk0LhmDFjcPLkSUREROD8+fOIj4/H1q1beYEykQ4YdohI71auXIknT56gfv366NWrF4YOHQonJydpub29PX788Uc0btwYtWvXxv79+7F9+3aUK1cOABAVFYXevXvj66+/RtWqVREcHIzY2NgCT98oFArs2rULzZo1Q9++feHt7Y2QkBDcvn0bzs7OMDU1xV9//YXevXvD29sb3bp1Q7t27TBp0iQAQKNGjfDFF1+ge/fucHR0xMyZM/W2L+bOnYuyZcuiUaNG6NChAwIDA1G/fn2tPpMnT0ZiYiK8vLykz/apXbs2jhw5guvXr6Np06aoV68eJkyYADc3N73VRvRPoRCvn2gnIiIikhnO7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkawx7BAREZGsMewQERGRrDHsEBERkaz9P8+fWIpLKTwZAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Ensure that matplotlib does not print warnings. Added to avoid failing on CI.\n", "import matplotlib; matplotlib.set_loglevel(\"critical\")\n", "import matplotlib.pyplot as plt\n", "import matplotlib.ticker as ticker\n", "\n", "shots = emulator.with_shots(500).run()\n", "\n", "fig, ax = plt.subplots(1, 1)\n", "ax.hist([shot.as_dict()[\"eigenvalue\"] for shot in shots], bins=100)\n", "ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))\n", "ax.set_title(\"Phase estimate [frequency / phase]\")\n", "ax.set_xlabel(\"Phase estimate\")\n", "ax.set_ylabel(\"Frequency\")\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "guppylang (3.13.11)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }