{ "cells": [ { "cell_type": "markdown", "id": "prep-00", "metadata": {}, "source": [ "# Uniform state preparation\n", "\n", "**Download Notebook** - {nb-download}`state_preparation.ipynb`\n", "\n", "`uniform_state(L)` prepares equal amplitudes on the first $L$ basis states:\n", "\n", "$$\n", "|u_L\\rangle=\\frac{1}{\\sqrt L}\\sum_{j=0}^{L-1}|j\\rangle,\n", "\\qquad n=\\lceil\\log_2L\\rceil.\n", "$$\n", "\n", "The same interface works whether or not $L$ is a power of two. This notebook compares $L=4$ and $L=6$, checks their statevectors, and shows the resulting probabilities.\n", "\n", "Run from a source checkout with the development dependencies installed. The repository default is little endian." ] }, { "cell_type": "code", "execution_count": 1, "id": "prep-01", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "import numpy as np\n", "from matplotlib import pyplot as plt\n", "from guppylang import guppy\n", "from guppylang.std.quantum import discard_array\n", "from guppylang.std.debug import state_output\n", "from selene_sim import Quest\n", "\n", "from guppyalgos.primitives.state_preparation import uniform_state\n", "from guppyalgos.primitives.arithmetic.comparator import comparator_ripple_cuccaro\n", "from guppyalgos.primitives.gate_decompositions.cnx.cnx import cnx\n", "from guppyalgos.utils import qarray\n", "from guppyalgos.tests.helpers import assert_allclose_ignorephase, switch_endianness" ] }, { "cell_type": "markdown", "id": "prep-02", "metadata": {}, "source": [ "## 1. Four states: Hadamards are enough\n", "\n", "For $L=4$, two qubits span exactly the required states:\n", "\n", "$$\n", "|u_4\\rangle=H^{\\otimes2}|00\\rangle\n", "=\\tfrac12(|00\\rangle+|01\\rangle+|10\\rangle+|11\\rangle).\n", "$$\n", "\n", "The factory chooses the Hadamard implementation. Start `qreg` at zero and pass it to the returned function." ] }, { "cell_type": "code", "execution_count": 2, "id": "prep-03", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All four amplitudes match 1/2, up to global phase.\n" ] } ], "source": [ "prepare_four = uniform_state(4)\n", "\n", "\n", "@guppy\n", "def four_states() -> None:\n", " qreg = qarray(2)\n", " prepare_four(qreg)\n", " state_output(\"result_state\", qreg)\n", " discard_array(qreg)\n", "\n", "\n", "result = four_states.emulator(2).with_seed(42).run()\n", "state = Quest.extract_states_dict(result.results[0].entries)[\"result_state\"]\n", "amplitudes_four = switch_endianness(state.get_single_state())\n", "assert_allclose_ignorephase(amplitudes_four, np.ones(4) / 2)\n", "print(\"All four amplitudes match 1/2, up to global phase.\")" ] }, { "cell_type": "markdown", "id": "prep-04", "metadata": {}, "source": [ "## 2. Six states: exclude unused addresses\n", "\n", "For $L=6$, three qubits provide eight addresses, but the last two must have zero amplitude:\n", "\n", "$$\n", "|u_6\\rangle=\\frac1{\\sqrt6}\\sum_{j=0}^{5}|j\\rangle,\n", "\\qquad \\Pr(j)=\\begin{cases}1/6&j<6,\\\\0&j\\geq6.\\end{cases}\n", "$$\n", "\n", "The factory uses a comparator to identify valid addresses and amplitude amplification to prepare the state. The optional `cnx_box` and `comparator_box` arguments select the underlying implementations; omitting them uses these same defaults." ] }, { "cell_type": "code", "execution_count": 3, "id": "prep-05", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The first six amplitudes match 1/sqrt(6); the remaining two are zero.\n" ] } ], "source": [ "L = 6\n", "n = int(np.ceil(np.log2(L)))\n", "prepare_six = uniform_state(\n", " L, cnx_box=cnx, comparator_box=comparator_ripple_cuccaro,\n", ")\n", "\n", "\n", "@guppy\n", "def six_states() -> None:\n", " qreg = qarray(n)\n", " prepare_six(qreg)\n", " state_output(\"result_state\", qreg)\n", " discard_array(qreg)\n", "\n", "\n", "# Reserve simulator qubits for the comparator and amplification workspace.\n", "result = six_states.emulator(2 * n + 5).with_seed(42).run()\n", "state = Quest.extract_states_dict(result.results[0].entries)[\"result_state\"]\n", "amplitudes_six = switch_endianness(state.get_single_state())\n", "expected = np.zeros(2**n)\n", "expected[:L] = 1 / np.sqrt(L)\n", "assert_allclose_ignorephase(amplitudes_six, expected)\n", "print(\"The first six amplitudes match 1/sqrt(6); the remaining two are zero.\")" ] }, { "cell_type": "markdown", "id": "prep-06", "metadata": {}, "source": [ "## Compare the probabilities\n", "\n", "The assertions check the complex amplitudes, including their relative phases. The bars show their squared magnitudes, $\\Pr(j)=|\\langle j|u_L\\rangle|^2$. These are exact simulator probabilities, rather than finite-shot estimates." ] }, { "cell_type": "code", "execution_count": 4, "id": "prep-07", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA48AAAE3CAYAAAAKb3Q+AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUFBJREFUeJzt3Qm4jPX///G3XcieyL4U2SMifAtpU1Jpk1BIlnYlqVBEUokWlSiSNkkRlSgV2VKRXUQlIdnJMv/r9fld9/znHHPOPWfOHOfMOc/Hdc11Zu657/t85nbc73l/1myBQCBgAAAAAAAkI3tybwIAAAAAQPIIAAAAAIgILY8AAAAAAF8kjwAAAAAAXySPAAAAAABfJI8AAAAAAF8kjwAAAAAAXySPAAAAAABfJI9AEvr27WtDhgw5Yfv69evtoYceshtvvNG6devG9QMAxJUvvvjC2rVrZ//880+C7f/995+98MILdtttt7n3ly5dmm5lBJAxkTwirinADRgwIOx727dvd8HvjTfeiOrcX375pX3zzTcJtv3xxx9Wt25d++233+zqq6+2q666KqpzI3n6AtOlSxf376d/h1jw/h70pSk9zwEAkZg0aZK73/z1119h33/88cftlltuiepibtiwwaZMmWIHDhxIsL19+/Y2YsQIa9q0qasgLV26NP9YMfT333/bc889Z7feeqvdeeedNmvWrJidW38PqvRO73Mg88uZ3gUAUuPjjz+2mjVrhn1v//79LjiWKVMmqnMPHz7ccufOnWDbBx984M778ssvW+HChaM6L/ypQmDChAl29OhRu/TSS2Nyyby/h4suushatWqVbucAgEgsX77c3W+GDRsW9v158+bZ999/H9XFvPjii+3999+3YsWKBbft27fP/b6nn37aVcwitj777DO74YYbrGXLlta6dWvLli2bvfjii/b111/b0KFDU31+/T38+++/6X4OZH4kj0ASWrRoccK2LVu2WI4cOUgc09D8+fPdl5f777/fJfAAgNiqVKmSe4T6/fff3c/ixYtzuWNMw12uvfZa16r36KOPBrerBTKplmUgoyJ5RJaibiIVKlRwP8eOHetqbYsWLepqWWvXrp1gX93kCxYsaP3797fjx4/b9ddfbz/99JN7rq5Eom16yMaNG11r2bp16yxfvnzWrFkz1+0nV65cJ/z+Xr162bhx42zhwoX2v//9zy677DK76667rHfv3laxYkUbM2aM/fnnn+49BZfs2bO7rrKvvPKKbd682erXr+/OkbhlNCmq2fzoo49s27Ztdvrpp7sutzq37N2713URveKKK6xjx44nHNu9e3crX768Pfzww8FtK1eutMmTJ9uvv/5qBQoUcLXY11xzjatJFZXd+zxVqlSxV1991dauXevGiqrbb3IteyqDPnPz5s1TlDyqG9bEiRNt06ZN7t/tvPPOc9dfyf4vv/xiDzzwgNtPZZk9e7Z7rs/cuXNn99z7NxVd17Jly7pg37BhQ7ctknNEcm38ygoA0dA9/q233nJx6Mcff3T3GHVLVUuXureG3oPU9V7xRPcyxUC1gE2bNs29p+fTp093rZLaxxtK8Pbbb9u3335rhw4dsqpVq7r7nu6T4X7/Dz/84O6Du3btcsd5CZN6lSj2fffdd1aqVCm7++673c8jR47Ym2++6c6vXj09e/a0s846K6LPreRr/Pjx7t6reNuoUSP3eU855RT3viojdf/WPqHXQN59913Xo0ifU9fBi0P6HIsWLbLDhw+73k1du3ZNkFR7n2fgwIHu86rFTvup0jOcJ5980n0vUAxMrGTJkr6f8eDBg+46agyqnuv6K1aeccYZwe8WaqnWdfRimT6//gZE3ym8mKXvE0WKFLHzzz/fbrrppuD3CL9zRHpt/MqK+MeYR2QpM2fOdEGrQ4cOLuBccMEFtmzZMvflfcWKFUmOeVTA0Zd73QS953p4XWZnzJhh1atXd0makrJy5cq5oKhxI+oKFPr7FRx1Y1aCpcRk69attmfPHtddaM6cOS6RU1fbatWquQRMCYuCYqdOndzNt1atWi5w6YYdifvuu88lYrqJq7ulvkxceOGF9uCDD7r3Tz31VDcOY9CgQRYIBBIcq+RaXy6UcHo0mYISbSXJap1VMnz77bfbdddd5xJr8T6PrqHG0ChQVa5c2f0ev7KqfBpzkxK6prr+q1evdv+mev7555/blVde6d4vUaJE8HmDBg2C/37nnHNO8BzeNj10nVTWxo0bB8fMRnKOSK6NX1kBIBq6p+i+qy/7zz77rJ177rnuvqXKuNDKv3BjHhUDVYnpPde9zRvTr26MSsj69OnjWitVMark8+yzz04w/tv7/a+99po988wzrqJQiabMnTvXPRTfVBGqcyje6R6rSXtuvvlmVyZtV9zR71Nlp58FCxa4WDl16lR3Lj1XLFMFq3e8klMlpvp9iQ0ePNi1uHqJo+7diusqv+7Nukeru2mNGjVs1apVweO8z6O4rO8OumbJlVfJuL4b6PuG4pzioiqoleT7UZKmY1WZeuaZZ7rYou8Viuu65qJusIrTirVebFLlpyc0ZqnyWGNZ+/Xr5yo3vdjkd45Irk0kZUUmEADiWLFixQIXXHBB2Pc2btyoTChw9913B7dVrlw5cMoppwTmzp0b3HbgwIFA0aJFA7fcckuC4+vXrx+45JJLEmzTuXLkyJFg2969e93x//vf/wJHjx4Nbv/hhx8C2bJlC9xzzz0Jfn/evHkDs2bNCm47ePBgYNWqVa6sen/fvn3B95566qlArly5XDn27NkT3D5ixIhA9uzZA7/++muy1+fzzz935x06dGiC7YMHD3bbZ8+e7V5PnDjRvZ4zZ06C/bp16xYoUKCA+4yyePFi93v79++fYL+lS5e6zzpu3Dj32vs8ZcuWDezatSvBZ03KjBkz3DFTp051r2fOnOlev/baawE/+rerVq3aCdu3bt16wt/Dyy+/HIiU/u0KFy4cOH78uO85Ir02kZQVAPr27evuN+vWrQt7MVq2bBnInz9/8LXu89pf9+1Qd955p4t7ofdi3cO075YtW4Lbli9f7raNHz8+wfE9e/Z0cU/ve44cORJo1KhRoESJEi6Ghv7+0Fjq3fObNGniYt/7778ffO+vv/4K5MyZM3DuuecGJk+eHNz+999/u7j36KOPJvtHoHhbsWLFQPXq1QOHDh0Kbtd9Wr/rxhtvDJZB9/H27dsnOH7hwoUnxJh69eoFKlWqlCAOHzt2LNCwYcPA+eefH9zmfZ433njjhM+a2M6dO93vKVeunPv3euSRRwJjx44NXH755S5m+MW4r7/+2h3/7bffJtiu67579+4Efw/63hKpFStWuPOG/pskd45Irk2kZUV8o+URWY5qTtXy5lG3jCZNmkRUAxiOal5Vc6ouH6HdDtUipdo2dd0JpRq/Sy65JPg6b968wedqocqfP3/wtWrw1IVErY1qIfSoxk+1hT///HOyZXvnnXdcmVS2UGoVVdcVr2yqXVRXoddffz24j2qkdby65ar7pajbj1onVQMdql69eu6h7j+h1F0zdGKh0M8aaufOna5GWp+/bdu2llI6r2bCVS10SrsDedRaqq49ainUZ1brsFqpVeuusa5+Ir02sSgrACQl8WQ36kmhnicaOhANde3UOUInp8uZM6frGaMeGolnxA79/aH3fMWw0JYstXKpN4+6+GsiGc9pp53mWrbUSpccdZ3UcJEePXpYnjx5gtvV40OxR62RaglTGdTS9+GHHyaYDEbxTvHW+936fepuqyEhoXFYsVKttxqPr55CHv1OtZiG+6yhvNZdDTlRq/ATTzzh4p1aI9Uyp/icXKuld15NEKjPE/rdRcMeIqVuq4pPuhaKb+pCrM/m9z0iJdcmVmVFxsaYR8S1xOMXItkn8SQBXrCKdtY6jVsTddFITGM21FVGgdsbf6Hum0nReMdQ3kx4SW3369ajsqnLTujNXpQMqgusAq+obAooSoB2795thQoVcjPxeeMhPWvWrHHjI+644w73WsmS91A33NBg4fdZQykgaUzN6NGjLRrqkqVkTGM49O+rpFuztOqLir7k+FG3JXV50nXR2AyN8dTnVDfkxYsXu8TST6TXJrVlBZA1RBPfwsU4xTeJZmIWxQBV7iUV38SLI373fSV1icurWKb7ZrjtkcQ3Sapsuufq3qv4qWEeL730khuLp/GUoZWjXsWs7uHe2E0lpt79W1Th5yWAiqmiOBHJPds7v+KLuox69JkVb5TU6XuCxh+Go+EtStQ1dlOfQcNhlHRq/0hnk9fn11hFrU2tigCVSb9fnzXS+BbJtVH33dSWFRkf31QQ15QUhY4pDOXdEL1WM0+4SWZ0E/X6/aeUdz4liIlpcLnOHTppTmgLYlLnCi1Xctv9yqzjwpXLK1tobW1ocFVNrmplNaZFSY5Hn0OD/kMnl/Go9jZxzWJynzWUEne1UCqJ9HhfHNQaqLWwRo0aleSAe30pUe3pkiVL7KuvvnJjUVQjrLEZmsggqRphz8iRI93vU82q90XLmyEvUpFem9SWFUDW4FX6JRfjEse31MSLaOKbhMaR5O77ScXeaGNySsqmnkDqAaK4puRRPUF0/ULnDvDitBIe7ZvYvffe6yaA8/uciakyVmNPw93bvYpgv+Uxnn/+eTfZjno6ady85gVQy+Gnn36aoCdVOBprqM+thC60Z8yOHTvs2LFjEX2GlFyb1JQV8YHkEXFNk5Ooy4wG5Se+MXtdXhLPohpr3oQpmjlVg/w9qpVTq5W6nKZXi5LKpsRLExGE1gZr4LtmwQud7EXP9VCQUc2kJgtKPHGNPp/Op5pQTQoUK1o30wv2HnUjVuDRQH/NFugXqPVlQ/vqoUmGdE59SVDXUx3v/RuE+0KimlN1oQpNHCXxBAvJnSMl18avrADgxS5VaiWepVoxT5OUhFbupQUlX6pEVGtTYop5EhpHTibvmqgciYc7aJvu6aEVjupFowpKzZquOKfJdUKvn+7dXmVvuErA1NBQFQ0TUUVAaMLvtehF0ktHLZ5qqdTjqaeecnFGs8R6CZniU1LxTfRdJFS4CYSSOkdKr41fWRHfGPOIuKbuEap11MyhWlDeo240mhpbN+Q2bdqkaRkUfHRjVa2ekjSPZrtTjZ9mVksv6qKi1rB77rknOOudrpfGPCqAaXxfKNXCanpt1SIqSGi681BKcDQ2T2Mctm/fnuA9fbnQzGvR0Cx/CkihD9VwimbN0+vkkkdN/e6tUebxklFvCnGVW4FRM/0lpi8/6t6kZN+j6de9blGe5M4R6bWJpKwAoPuiul/qy7fGBXoU6xTzlIjoXp3WFD+0hIOW8AhNetRbQrOjqhIsPSi+a5Zq9U5RQuiZNGmS68WR+Nqoh4eGaGjogCpHQ4dkiJYdUcxUpal6hIRS1131zImW/r2UfD3yyCMJunuq14vGd4ZbV9qj8YTeMhsexXG1GobGDJVfsSVxa6JmQ1U895Zi8bqYalbc0F5RyZ0j0msTaVkR32h5RFxTC5m+5GttJU0RrgH9GqOhVislHVpmIXGXmrSggfjq01+nTh2XSCp5UJdHJbCayju9aKyHAobW49I4GNU86kuAJtHRgHaN2QilcY/q1qKlRzThgLrahFLLnLpaakIEnU81v0pO1ZKpmkZ9mUgPqilVjaa+GKhbqAbu6/orode/iSjp05eg5557zrVKqxupt0ajKiGU3OmLkMYgqgurvphoKvXQbk3JnSPSaxNJWQFAX+zVm0EVUoptuqeoEk1rFmqMuMaoa7x0WlMloyrXFGe1dJO6Wno9bTTMIT1pCQ5VcmqsnR6qiNOwAMUxb13e0O6jGluusX+6tuHWNdZyS7qvX3755a4bplrM9NmVIKmCMFr691NXWSWs+jfVeVWpqAmDNCFRcr2TtHSGlh/R34FaS5WEaqiHJs7TOpMeDTfRv4fiiM6r+KMJelSpqa6kSqbVu0VJnBJEJdleJa3fOSK9NpGWFfEtm6ZcTe9CAKmlGUlV86gbmYKCblqJJ5kR3bQ1ti60e6motU3Hhq61py4dGlMRenPV71DrohKrcNTSqGRBiYFqYxWsIvn9SniVvOiY0IROgVBrQ2q9LiUaHg321/gBjT0INwFQuOujz6ikSF15lFgnrnH0KAHSWAi1xiXXlUY14ap91nlUOx7aVTOpz5MSKqtqhxN/9qSoZlPduNRaqC836vKVeKIg799Isw7qy5cmWghN2PTvq6Cqa6quWqqdVYDXWlih4zmTO4fftUlJWQFA1NtB9wzdc1QZpXtO4rGCuueoclDrM4be3zUbuOKZesl43Th1j1J3WK3t503mpjGAWnM2qfu2hjporLZ6sei+puQikt/vxRVJ3G1Rk5KpQk0zk4fSvV9xK7kWuVD6PFoPWb9X8S2pVi5dR/UwURxW5XNSFMN0ffRT9299pwi93kl9Hj+axEeJt8Y46jtK4q6kyVFFoyoOlJAp7oQbHuH9G+nfUpXEod15NWGSEmtVqOs7iH5qRlrFu9AYltw5Irk2kZYV8YvkEQAAAADgizGPAAAAAID4SR69yTwipW4OoROkxOq8AADEkuJQSkeIqHtiWpwXAIC4Th619ov6nmvmR/WL1piw5Ki/tsabaZyQxghpliot9Jra8wIAEEuanEJjmhSHNNGJJqxIbl01jSF64okn3HgzjbEtWrRocEHz1JwXAIBMkTyOHj3aTVM8ffp0Fxw1O5MG5ia3MLfWyfFm/tJkIgqsmiFSg3tTc14AAGJFk1NoVkI9tKSCJgDRLI+PP/54ksdoXVNNYqHZCdWqqGM083Howt7RnBcAgEwxYY5mclRSFzq9v2ZV1JpuiRcnT677qoKtFh/VFPmxOi8AANEaOnSoizeaNdibhl+tipoyX9s0i2EkVFm6YsUKt35aLM8LAEBctTxqKQBNrax11UJpjTVNY5wcjXXUNMeaRv+xxx5zUzJ7ax2l5rwAAMSC4k3jxo0TrN+mtc60JppfLxhNka+1YrVsgtZj1TqisTgvAACplfSqpGns77//dj8Tr8WjRcn9kjytC6SFXjU+RONCtNCpt3ZRtOfV2jt6hLZoam0kja3UOjUAgKxNHXUUdxRvsmdPvu5VsUhr4SWOQ957idfIC6XkUJWg6rrarVu3YK+aaM9LfAMAxCrGpVvyGJqkJW5V9EvWWrZs6VoeNRvda6+95rqofvHFF672NdrzqivQoEGDov4cAICsYcuWLVamTBnf/cLFIfGLcVpcW3788Ue77rrrXAI5fvz4qM9LfAMAxCrGpVvy6LUUaoxGKNWceu/5yZ07t/Xq1csmTpzoHkoeoz1vv3797L777gu+3r17t5UrV85dQLVuAgCyNnUnLVu2rJvh1E/p0qXDxiGJNMbVrVvX+vbtaz169LBXX33VcuXKFdV5iW8AgFjFuHRLHrWMRs2aNe3LL790NatebeqcOXPcBAGegwcPulrV5D6ImliVSKbkvIlp0h09ElPiSPIIAPBEMpShadOm9sgjj7iup3nz5nXb1ENGCV7FihXday2vofil+JbURDcK5hrf6HUhiuS8xDcAQFrFuHRdquPhhx92XXE0ZlHjO9SKqLEZqmX13HnnnW78h2hpjlatWtns2bPdUh0rV650S3VokoDQMSGRnBcAgLSiSW6UFHbt2tXFqKlTp9qoUaNcK6AXmBcvXmxFihRxP0XrNWrm8DVr1rheL1qaavDgwa7i00suIzkvAABpJV3HPN50002uZfGpp55y3XC06LFaCEuVKhXcJ1++fMGWv/z589uAAQNs+PDhtmzZMvf6nHPOcWti6WdKzgsAQFopVKiQzZ071+6//37XWli0aFEbMmSI9e7dO7iPWhS1nzdzav/+/W3YsGEuGVSLo1oSn3766QSzrUZyXgAAMuU6jxmZAreCtMY+0m0VAJBZ4kJm+RwAgJMfG9K12yoAAAAAID6QPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfJE8AgAAAAB8kTwCAAAAAHyRPAIAAAAAfOW0DGDjxo22bds2q1q1qhUpUsR3/yNHjtjq1astZ86cVrlyZcudO3eC99euXWt//vlngm358+e3Bg0axLzsAAAkZe/evbZy5UorWrSonXnmmRFdqD/++MO2bt1qlSpVcsclPt/SpUtPOKZevXpWsGBB/iEAAJk3eTx48KDdeOON9uWXX1rFihVt/fr19uSTT9q9994bdv9AIGCPP/64vfTSS3b66afbgQMH3OPll1+2q666Krjfs88+a1OmTLEaNWoEt+n848ePPymfCwCAN954w3r37m3ly5e333//3SV4H330kRUqVCjsxfnqq6/sgQcecJWfpUqVslWrVlmHDh1czMuRI4fbZ82aNda8eXNr0qSJq0D1aJ/q1atz0QEAmTd5HDhwoC1btsw2bNjgksFPPvnE2rRpY40bN7ZGjRqFTR71UPAsXLiw2/bEE0/YTTfd5M6hYOu54IIL7IMPPjipnwcAAFHvmK5du7pKy1tuucX+/fdfO++88+z++++3sWPHhr1Iv/32m40ZM8bq168fPIdioVos+/Tpk2Df6dOnB+MgAABZYsyjamUVXJU4ypVXXmm1a9dOsoUwe/bsLuEMDZi33367a8FUEhpK2xYtWuQSzaNHj6bxJwEA4P+bMGGCnXHGGS5xFMUttUJOnjzZDh8+HPZSderUKZg4SrVq1axZs2Y2f/78E/ZVYrlkyRLbs2cPlx0AkPmTR43p+PvvvxMEStHrxIlgcpQgSpUqVRJsnz17tt1xxx2ue4+6DKlVMzkK5grCoQ8AAKKhOBYuvmmohSo1I6G49NNPP4UdK9m+fXu79dZbrXjx4i4p1VwAyZ2H+AYAiOtuq7t27XI/E08GoEDovedHyaeCprqtnnXWWcHtl19+uQ0ZMsSKFStmx48ft0ceecRuuOGGJIOwDB061AYNGmSxVuGhGTE/Z2a1aVjrmJ2L637yrzvX/ORfc657+l13P4pjoePuvfjmvRcJdVXdt2+f3XnnncFtipkaG6mhGaLJc1RJetppp9mAAQNOanwDAGQ96dby6M2Qqu6loVQrm3j21HAUfC+99FIrU6aMvfbaawne07hJJY5eV1eNi8yTJ0+yrY/9+vWz3bt3Bx9btmyJ8pMBALI6xbFw8c17z48qQMeNG2dTp051cc6jGVi9xNFrzdTwj3fffTfJcxHfAABx3/KoYKjETt1XQ+m1upkmRxMPXHzxxZY3b16bNWuWW4YjOZqlTrW1iZfvCKXkUg8AAFJLcWzz5s0Jtnnxzi/GDRs2zCWPmhQnNFFMilodiW8AgEzd8pgvXz431fjHH38c3KbuORqr2KpVq+A2jQ1ZvHhx8LVaBZU4aopyJY6nnnpqgvNqNtb9+/cn2KZzbNq0yWrVqpWmnwkAAFEcW7BggW3fvj14QbRMh5bT0EQ6onGI6oIaOsZ++PDhbkkq9ZRp0aLFCRdT6zwm9tlnnxHfAACZf6kO1ay2bNnSrWul5TleeOEFK1mypHXr1i24z9NPP23ff/+9rVixwk0IoK6qms5cXVV/+OGH4H5Vq1Z1S3VonwYNGljnzp3deBPV/KoWt2HDhm5sJAAAaU3xZuTIkW4WcY1dXL58uZtJXN1QPStXrnTjFZVkakkOrVnct29fe/TRR12PGSWWUrBgQbdGpGgMv7rDKnaqEvWtt95yFaxKIAEAyNTJo6Ygnzdvnlvc+JVXXnHB8Z133rECBQokSAqPHTsWHC+irqVnn322PfvsswnOpQS0devWbizJ3Llz7cUXX3TrZRUpUsQFW81KF7qgMgAAaSVXrlwuFqkCVOs6aujE559/nqA1UUmhuqXqp9etVa8VF/XwqLVScVKee+45e/vtt12vHfWy0XIeo0ePTjAuEgCAtJItoH6eOIG6ERUqVMh1k/UCezSYgTJyzECZPphtNX6vuXCPOXnXPVZxIb1lls8BADj5sSHdxjwCAAAAAOIHySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwBfJIwAAAADAF8kjAAAAAMAXySMAAAAAwFdOS2cHDhywGTNm2LZt26xWrVp2wQUX+B6zevVqW7BggeXMmdMaN25sVapUicl5AQCIpe+//96WLl1qRYsWtdatW1vBggWT3X/37t321Vdf2datW+3MM8+0Fi1aWLZs2VJ9XgAA4r7lUcGxTp06NmTIEBcEr7vuOuvQoUOS+wcCAbvyyivt2muvtW+++cYlh0oMdXxqzgsAQKzdfffddtlll9miRYts5MiRVr16dVu/fn2S+7/xxhsudo0bN85+/PFH69q1qzVs2NAllKk5LwAAmaLlsW/fvnbqqae6VsQ8efLYihUrXOBs166dtW3bNmzy2L17d7viiiuC295//327/vrrXYJ41llnRXVeAABiSRWco0aNsu+++87OP/98O3bsmGtFvOeee2z69Olhj6lYsaL99NNPVqhQIfd6z549VqNGDXvyySftqaeeivq8AADEfcujAt6HH35onTp1cgme1KxZ05o2bWrvvfde2GOyZ8+eIHEUrzuqV+sazXkBAIglxRvFHiV4kiNHDteSOGvWLJcUhqN45iWOoq6o55xzjq1bty5V5wUAIO6Txy1bttj+/futatWqCbZXq1bNVq1aFfF5lChq7KMCbGrOe/jwYRd4Qx8AAERD8SZcHFIFZ2gymJwdO3bYvHnzXNfV1JyX+AYAiPvkce/eve5n4cKFE2zXa+89P+re88ADD9jDDz9spUqVStV5hw4d6mp8vUfZsmVT/JkAAPBiUbg4FBqnknPkyBFr3769lSxZ0nr37p2q8xLfAADpmjzWrl3bDdJXrWi08uXL534mbuHTxAD58+f3PV61rxdffLHdcMMNNnDgwFSft1+/fm4f76EWTAAAoqFYFC4OiV+MUyvizTffbGvWrHHdUQsUKJCq8xLfAADpmjxqxtMRI0ZY6dKl3SQ0M2fOdMEuJcqXL+/GJG7YsCHBdr3W9OTJUUDVBAGanvzVV19NMI15tOfVMRpfEvoAACAa6loaLg4pXoVbXipx4qilOObOnWsVKlRI9XmJbwCAdE0etQTG5s2b7aOPPnIBSzOYKmnr379/xNOFa5yikr9JkybZ8ePH3bZNmzbZ119/bVdffXVwv88//9xNX+5Zu3atNW/e3E1TPnbsWDeJTjTnBQAgrVx11VW2bNkyN9u3580333ST4hQpUiS4rJQqYvXTSxxvueUWmz9/vkscK1WqFNV5AQDIcEt1KGlTAqfHzp077ZVXXrFBgwa5KcUVxO69914X5JIzfPhwN2Ocup9qQoB33nnHJYY33nhjgpnlVAPbuXNnO3jwoGtxVIDVBAHPPvtscL9LLrnErfkY6XkBAEgrio1aRkqxSQmhkj0lharI9Pz2229u3L5mA9e4fXUvnTx5svXo0cOmTp0a3O+MM85w4x8jPS8AABl2nUcFLS1orCRPA/tvvfVW+/vvv61Dhw5222232fPPP5/ksZUrV3aBT8Fy27ZtLvHUeo2aetyjAHn22WcH13n0EkD9jlBKLFNyXgAA0pJi0LRp02zJkiWu4lOVrBruEZoU3n///e6nVK9e3b2Wv/76K7ift+xUpOcFACCtZAsoI0shBbUJEya4pPHXX391YyC7devmWvq8bqQrV660Bg0auGUz4pEmJNCsq5qIIDXjHys8NCOm5crMNg1rHbNzcd1P/nXnmp/8a851P7nXPVZxIb1lls8BADj5sSGqlscyZcq4gfldunSxTp06WYkSJU7YRzWoSh4BAAAAAFl0wpzBgwfb6tWr3ViNxInj9OnTg8+/+uqr1JcQAAAAABCfyaMG9SdFXVgBAAAAAJlLVMljUnbs2OH6ygIAAAAAMpcUjXm84oorwj4Xram4atUqa9asWexKBwAAAACIv+RRk+SEey65cuWy1q1bu3WnAAAAAABZOHkcOXKk+1m8eHF75JFH0qpMAAAAAIDMMOaRxBEAAAAAspaIWx4vvfRS93PWrFnB50nRPgAAAACALJg81qxZM+xzAAAAAEDmF3HyOGLEiLDPAQAAAACZX0zXeQQAAAAAZE4pHvMYCcY8AgAAAEDmEtWYRwAAAABA1hLVmEcAAAAAQNbCmEcAAAAAgC/WeQQAAAAA+GKdRwAAAACAL9Z5BAAAUanw0IwMdeU2DWsdd2WO13LHY5njtdzxWOZIy41MnDyGs2fPHlu/fr17XqVKFStYsGCsygUAAAAAiPcJc/bv32933HGHFS9e3OrXr+8eet6zZ087cOBA7EsJAAAAAIi/5FFJ4pw5c+y9996z33//3T30fPbs2darV6/YlxIAAAAAEH/dVqdMmWLz58+32rVrB7eVLl3aKlasaE2bNrXx48fHsowAAAAAgHhseSxUqJBLFhPTNr0HAAAAAMhcokoe27RpYwMGDLAjR44Et+n5wIED3XsAAAAAgCzabbVdu3bB55oUZ+bMmfbBBx9YnTp1LBAI2M8//2zbtm2zyy67LK3KCgAAAADI6MmjZlMN1b179wSvK1WqFFUBNmzYYOPGjXOJZ61atez222+3U045Jdljtm7daq+//rqtXr3a+vfvb2effXaC9zXm8ssvv0ywrWzZsjZ06NCoyggAQEqpR47i25IlS6xo0aLWqVMnq169uu8x06ZNs+nTp9t5551nPXr0SPD+xo0b7dFHHz3huEGDBlnlypX5RwIAZIzkccyYMTH/5Wqt1AQ7rVu3tkaNGrkgO2nSJPv2228td+7cYY8ZOXKkPfvss+4Y7du1a9cTkseFCxfa2rVr7a677gpuK1y4cMzLDwBAOOqRc/nll9vmzZvd0lYrVqywevXquVnJFffC2bRpk/3vf/+zBg0a2KpVq+zo0aMnJI87d+50se+VV16xfPnyBbcz3wAAIMPOthorDz30kDVu3NgmT57sXt90001Wvnx5e/PNN61bt25hj7niiivcciBqqUwuoS1Xrpx16NAhzcoOAEBSpk6d6pa0Uu+aChUquG379u2z+++/31VwhlOkSBH3XqlSpezSSy9N9uJef/31VIoCAOInedy1a5fNnTvX1aqqdjRUnz59fI//77//XA3syy+/HNxWokQJa9Giheuuk1TyWKVKlYjKt3LlStcFVrWxzZo1YyIfAMBJozjWsGHDYOIoN954o11zzTW2fft2O+200044RvEq0hbEhx9+2I4fP+563nTu3JmWRwBAxk0eVTOqbqMFChSw3377zapWrerGYSghrFGjRkTJo5JOje1QS2Movf7mm28sNbJnz+7GT9atW9f++OMP69ixo5vIx2vhDOfw4cPu4dmzZ0+qygAAyLp+/fXXsPHNey9c8hgpxdkyZcpY/vz5XVzTeP7vvvsuyTGPxDcAQLomj0oO1fWmX79+li1bNjdxjWpS1U1UYzoicfDgQfdTCWioU089NfhetDRxQGhgbtu2rZt44Oabb3bdXsNR8NVxAACkluJYuPjmvRets846y3744YfgvAC9e/d28U0x+aOPPgp7DPENAJCu6zz+9NNPwUH8auVTraaSNY1BnDBhQkTn8LrmqPtrqH/++SfV3W8S1+hq8gGNgVy0aFGSxygR3r17d/CxZcuWVJUBAJB1KY6Fi2/ee9EqWLBgggnlcuTI4SpIiW8AgAybPO7duzc4UF/jFNUF1Rvs7wVHP1o6Q+fQDHShli9f7rqcxtr+/fuTfT9PnjwuKIc+AACIhuKY4lkovc6VK5drPYwl4hsAIEMnj6GaN29uDzzwgM2aNct1n6lTp05Ex6m7qyYP0HqNSkZl/vz5rva0ffv2wf30vloFI6VxlFOmTEmw7YUXXrAdO3a4cZoAAKQ1zR6+bt06mzlzpnt96NAh1ztHrYQaqyiaiVXDPfQzUjpf6Jh8zTugZa6SGpIBAEC6J49PP/108Pnw4cNdN8+rr77atSJq7alIPfnkk24MSM2aNd16WJdcconde++9dvHFFwf3WbBggX3yySfB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qoDV0lehC37rHqMvsRl1ApqlS5fa5Zdfbi1atHDLjHj3RGnSpEmGHRumZLdly5auAlCtefqyrUrwzz//PL2Lluno/6ISRXX5VOI4evRo938yIy/nliNHDrdUh77T5syZ0ypWrOi+12rinx49elhG9/rrr7v4WKZMGYs32TTlanoXAifHjh073H809QlX4qKxSQokSDsvvviiTZ48+YTtgwcPtgsvvJBLnwY0WF7j7BLT33pGHSeTGegLqtaRVcuAujvpi6rWOfPGpQCJqVuzvqQqGVC3M42zyuhrnWmGx3vuueeE7eoOquQ3I3r//fddhVo4Gg+eUceYqlVGazp+9913LsFV5Z+Sgow8YU5iGvOorrYjR460c8891zIqVbRqTU11bda1VuWO5gzQ2o8ZndZyVpdgTaqkvxENWcnofyP//POPtW3b1q35GG/jHYXkEQAAAADgizGPAAAAAABfJI8AAAAAAF8kjwAAAAAAXySPAAAAAABfJI8AAAAAAF8kjwAAAAAAXySPAAAAAABfJI9ABrd48WJbsGCBZUax+mzLli2zb7/9NiZlAgCcHDt27LB33nnHjh8/nukueaw+27///uvOc+TIkZiVDUiNbIFAIJCqMwBZ1I8//mirV692z7Nly2aFChWyGjVqWNmyZWP6e7p27Wr79u1zwSPWFi5caLoFNGrU6KQcl1af7Z577rFNmzbZRx99lKrzAADMdu/ebTNnzgxeijx58rjYVr9+fRfvYkWVfs2aNbODBw9a3rx5Y3rp//77b5szZ47dcMMNKSpztMel1WfTd41zzjnHdu3aZYULF476PECs5IzZmYAs5q233rKxY8fapZde6l7v3LnTvvnmG+vVq5c988wzMfs9DRs2tEOHDllaePnll+3o0aMpTgKjPe5kfjYAQHS2bNliN910k1188cVWpEgRO3z4sC1atMiKFStmX3zxhZ1++ukxubSnnXaaS9Jy5MgR83+qlStXus/Qrl07y5kzZ5ofdzI/G5CeSB6BVChTpkyCVrMpU6a4gNO9e3c766yz3Lbly5fbL7/84p6r1rB27dp2xhlnnHCujRs3uv1KlCjhahlz5crltuu5ErVI9k1KuP1Vm6nt6lLjfYaLLrrItm7dmmx5kzquePHi7vlPP/3k3i9XrpzVrVvXsmdPund84s+mLqwK1tWrV3ddUQ8cOGDnnXeea9UNpYTz66+/tty5c7tzJCWpsvz666+uy+xVV10VrBHWOadNm2YNGjSwSpUqJXs9ASArGDJkiJ177rnuuXqJnHnmmfb888/bk08+Gdw2ffp091z348qVK7uYkbjFTvsp+VTXS7VeevFCyWjbtm0TJFhJ7ZuUcPur5VSth/Lee++5e7/KdvbZZydb3qSOU1zwWiX1u/Lly2f16tVLtiUw8Wf766+/bN68eXb99de7GKvYVK1aNatSpcoJxyr+/fHHH668SUmqLMeOHXPfRfS5dH6PYqbibcuWLZO9noAfkkcghsqXLx8MZp5Vq1YFu1OqdXL+/PkuIKurpefRRx+1UaNGuS4uGt+gbi4ffvihO98rr7zizte4cWPffcNJan8Fr82bN7vup175lIj5lTep45SQXnvttbZu3TqrU6eOO4+C+CeffJJk8E/82fSlZP369bZ3716XwP3+++/BFl0FcPntt9+sefPmLqgr6KqWWMltyZIlg+fVF4DkyqIa4Ycffth9Nv1OefDBB23GjBkuOQYAJFSgQAGXEIXGt/379wfjgNc6qQTz008/dUmNLFmyxPXQ0f1a91/FkMcff9xuueUWN/RDrXxKslSRl9y+4SS1v2KENw5elYJKDlu0aOEqEpMrr2JPuOOUPKpH0RNPPOEqNP/77z/7+eef7Y033rArr7wybNkSfzbFFr2eMGGCS/yKFi1qc+fOdeft3bt38LguXbq4xLVJkya2du3aBAmgJ7myKFnVdXnggQdcBaqSSn3OVq1a2dSpU/mzRuppzCOAlLv//vsDZcqUCUyePNk9XnzxxUDt2rUD7dq1Cxw/fjzJ477//vtA7ty5A1u2bHGv9+/fH8iRI0dg3rx5wX1WrlwZWLVqlXvepUuXwA033BDRvon57d+pU6fAzTffnOznTFzepI7r2LFjoG3btoH//vvPvT569GigdevWrvxJCf1soucFChQIrFu3zr0+duxYoEmTJoGePXsG97nuuusCzZs3Dxw+fNi9XrJkifuMV111VYrKsmDBgkCuXLkCn376aWDGjBnuubYBQFa3fPlyzYcRGDJkiItvb7zxRqBz586BsmXLuhiSlIMHDwbOOeecwLBhw4LbbrzxxsBtt92WYB/dd+Wbb75xv0fb/PYNJ7n9586d68595MiRFJU33HFffvlloEiRIoG1a9cGt73z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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(1, 2, figsize=(9, 3), layout=\"constrained\")\n", "for axis, (length, amplitudes) in zip(axes, [(4, amplitudes_four), (6, amplitudes_six)]):\n", " axis.bar(np.arange(len(amplitudes)), np.abs(amplitudes)**2)\n", " axis.set(title=f\"Uniform over {length} states\", xlabel=\"Basis-state index\",\n", " xticks=np.arange(len(amplitudes)), ylim=(0, 0.3))\n", "axes[0].set_ylabel(\"Probability\")\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "prep-08", "metadata": {}, "source": [ "To reverse a preparation, build its inverse with `uniform_state(L, dagger=True)`. Additional workspace is internal to the preparation routine; the calling circuit keeps the same `qreg` interface." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.13" } }, "nbformat": 4, "nbformat_minor": 5 }