{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# QUANTUM PHASE ESTIMATION" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Use Braket SDK Cost Tracking to estimate the cost to run this example\n", "from braket.tracking import Tracker\n", "t = Tracker().start()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial provides a detailed implementation of the Quantum Phase Estimation (QPE) algorithm using the Amazon Braket SDK.\n", "The QPE algorithm is designed to estimate the eigenvalues of a unitary operator $U$ [1, 2]; \n", "it is a very important subroutine to many quantum algorithms, most famously Shor's algorithm for factoring and the HHL algorithm (named after the physicists Harrow, Hassidim and Lloyd) for solving linear systems of equations on a quantum computer [1, 2]. \n", "Moreover, eigenvalue problems can be found across many disciplines and application areas, including (for example) principal component analysis (PCA) as used in machine learning or the solution of differential equations as relevant across mathematics, physics, engineering and chemistry. \n", "We first review the basics of the QPE algorithm.\n", "We then implement the QPE algorithm in code using the Amazon Braket SDK, and we illustrate the application thereof with simple examples. \n", "This notebook also showcases the Amazon Braket `circuit.subroutine` functionality, which allows us to use custom-built gates as if they were any other built-in gates. \n", "This tutorial is set up to run either on the local simulator or the on-demand simulators; changing between these devices merely requires changing one line of code as demonstrated as follows in cell [4]. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## TECHNICAL BACKGROUND OF QPE " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Introduction__: A unitary matrix is a complex, square matrix whose adjoint (or conjugate transpose) is equal to its inverse. Unitary matrices have many nice properties, including the fact that their eigenvalues are always roots of unity (that is, phases). Given a unitary matrix $U$ (satisfying $U^{\\dagger}U=\\mathbb{1}=UU^{\\dagger}$) and an eigenstate $|\\psi \\rangle$ with $U|\\psi \\rangle = e^{2\\pi i\\varphi}|\\psi \\rangle$, the Quantum Phase Estimation (QPE) algorithm provides an estimate $\\tilde{\\varphi} \\approx \\varphi$ for the phase $\\varphi$ (with $\\varphi \\in [0,1]$ since the eigenvalues $\\lambda = \\exp(2\\pi i\\varphi)$ of a unitary have modulus one). \n", "The QPE works with high probability within an additive error $\\varepsilon$ using $O(\\log(1/\\varepsilon))$ qubits (without counting the qubits used to encode the eigenstate) and $O(1/\\varepsilon)$ controlled-$U$ operations [1].\n", "\n", "__Quantum Phase Estimation Algorithm__: \n", "The QPE algorithm takes a unitary $U$ as input. For the sake of simplicity (we will generalize the discussion below), suppose that the algorithm also takes as input an eigenstate $|\\psi \\rangle$ fulfilling \n", "\n", "$$U|\\psi \\rangle = \\lambda |\\psi \\rangle,$$\n", "\n", "with $\\lambda = \\exp(2\\pi i\\varphi)$. \n", "\n", "QPE uses two registers of qubits: we refer to the first register as *precision* qubits (as the number of qubits $n$ in the first register sets the achievable precision of our results) and the second register as *query* qubits (as the second register hosts the eigenstate $|\\psi \\rangle$). \n", "Suppose we have prepared this second register in $|\\psi \\rangle$. We then prepare a uniform superposition of all basis vectors in the first register using a series of Hadamard gates. \n", "\n", "Next, we apply a series of controlled-unitaries $C-U^{2^{k}}$ for different powers of $k=0,1,\\dots, n-1$ (as illustrated in the circuit diagram that follows). \n", "For example, for $k=1$ we get\n", "\\begin{equation} \n", "\\begin{split}\n", "(|0 \\rangle + |1 \\rangle) |\\psi \\rangle & \\rightarrow |0 \\rangle |\\psi \\rangle + |1 \\rangle U|\\psi \\rangle \\\\\n", "& = (|0 \\rangle + e^{2\\pi i \\varphi}|1 \\rangle) |\\psi \\rangle.\n", "\\end{split}\n", "\\end{equation}\n", "\n", "Note that the second register remains unaffected as it stays in the eigenstate $|\\psi \\rangle$. \n", "However, we managed to transfer information about the phase of the eigenvalue of $U$ (that is, $\\varphi$) into the first *precision* register by encoding it as a relative phase in the state of the qubits in the first register. \n", "\n", "Similarly, for $k=2$ we obtain\n", "\\begin{equation} \n", "\\begin{split}\n", "(|0 \\rangle + |1 \\rangle) |\\psi \\rangle & \\rightarrow |0 \\rangle |\\psi \\rangle + |1 \\rangle U^{2}|\\psi \\rangle \\\\\n", "& = (|0 \\rangle + e^{2\\pi i 2\\varphi}|1 \\rangle) |\\psi \\rangle,\n", "\\end{split}\n", "\\end{equation}\n", "\n", "where this time we wrote $2\\varphi$ into the precision register. The process is similar for all $k>2$.\n", "\n", "Introducing the following notation for binary fractions\n", "$$[0. \\varphi_{l}\\varphi_{l+1}\\dots \\varphi_{m}] = \\frac{\\varphi_{l}}{2^{1}} + \\frac{\\varphi_{l+1}}{2^{2}} + \\frac{\\varphi_{m}}{2^{m-l+1}},$$ \n", "\n", "one can show that the application of a controlled unitary $C-U^{2^{k}}$ leads to the following transformation\n", "\n", "\\begin{equation} \n", "\\begin{split}\n", "(|0 \\rangle + |1 \\rangle) |\\psi \\rangle & \\rightarrow |0 \\rangle |\\psi \\rangle + |1 \\rangle U^{2^{k}}|\\psi \\rangle \\\\\n", "& = (|0 \\rangle + e^{2\\pi i 2^{k}\\varphi}|1 \\rangle) |\\psi \\rangle \\\\\n", "& = (|0 \\rangle + e^{2\\pi i [0.\\varphi_{k+1}\\dots \\varphi_{n}]}|1 \\rangle) |\\psi \\rangle,\n", "\\end{split}\n", "\\end{equation}\n", "\n", "where the first $k$ bits of precision in the binary expansion (that is, those bits to the left of the decimal) can be dropped, because $e^{2\\pi i \\theta} = 1$ for any whole number $\\theta$.\n", "\n", "The QPE algorithm implements a series of these transformations for $k=0, 1, \\dots, n-1$, using $n$ qubits in the precision register. \n", "In its entirety, this sequence of controlled unitaries leads to the transformation\n", "\n", "$$ |0, \\dots, 0 \\rangle \\otimes |\\psi \\rangle \\longrightarrow \n", "(|0 \\rangle + e^{2\\pi i [0.\\varphi_{n}]}|1 \\rangle) \n", "\\otimes (|0 \\rangle + e^{2\\pi i [0.\\varphi_{n-1}\\varphi_{n}]}|1 \\rangle)\n", "\\otimes \\dots\n", "\\otimes (|0 \\rangle + e^{2\\pi i [0.\\varphi_{1}\\dots\\varphi_{n}]}|1 \\rangle) \n", "\\otimes |\\psi \\rangle.\n", "$$\n", "\n", "By inspection, one can see that the state of the register qubits above corresponds to a quantum Fourier transform of the state $|\\varphi_1,\\dots,\\varphi_n\\rangle$. Thus, the final step of the QPE algorithm is to run the *inverse* Quantum Fourier Transform (QFT) algorithm on the precision register to extract the phase information from this state. The resulting state is\n", "$$|\\varphi_{1}, \\varphi_{2}, \\dots, \\varphi_{n} \\rangle \\otimes |\\psi\\rangle.$$\n", "\n", "Measuring the precision qubits in the computational basis then gives the classical bitstring $\\varphi_{1}, \\varphi_{2}, \\dots, \\varphi_{n}$, from which we can readily infer the phase estimate $\\tilde{\\varphi} = 0.\\varphi_{1} \\dots \\varphi_{n}$ with the corresponding eigenvalue $\\tilde{\\lambda} = \\exp(2\\pi i \\tilde{\\varphi})$.\n", " \n", "__Simple example for illustration__: For concreteness, consider a simple example with the unitary given by the Pauli $X$ gate, $U=X$, for which $|\\Psi \\rangle = |+\\rangle = (|0 \\rangle + |1 \\rangle)/\\sqrt{2}$ is an eigenstate with eigenvalue $\\lambda = 1$, i.e., $\\varphi=0$. \n", "This state can be prepared with a Hadamard gate as $|\\Psi \\rangle = H|0 \\rangle$. \n", "We take a precision register consisting of just two qubits ($n=2$). \n", "\n", "Thus, after the first layer of Hadamard gates, the quantum state is\n", "$$|0,0,0 \\rangle \\rightarrow |+,+,+\\rangle.$$\n", "\n", "Next, the applications of the controlled-$U$ gates (equal to $C-X$ operations, or CNOT gates in this example) leave this state untouched, because $|+\\rangle$ is an eigenstate of $X$ with eigenvalue $+1$. \n", "Finally, applying the inverse QFT leads to \n", "\n", "$$\\mathrm{QFT}^{\\dagger}|+++\\rangle=\\mathrm{QFT}^\\dagger\\frac{|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle}{4}\\otimes |+\\rangle = |00\\rangle \\otimes |+\\rangle,$$\n", "\n", "from which we deduce $\\varphi = [0.00]=0$ and therefore $\\lambda=1$, as expected. \n", "Here, in the last step we have used $|00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle = (|0\\rangle + e^{2\\pi i[0.0]}|1\\rangle)(|0\\rangle + e^{2\\pi i[0.00]}|1\\rangle)$, which makes the effect of the inverse QFT more apparent. \n", "\n", "__Initial state of query register__: So far, we have assumed that the query register is prepared in an eigenstate $|\\Psi\\rangle$ of $U$. What happens if this is not the case? Let's reconsider the simple example given previously.\n", "\n", "Suppose now that the query register is instead prepared in the state $|\\Psi\\rangle = |1\\rangle$. \n", "We can always express this state in the eigenbasis of $U$, that is, $|1\\rangle = \\frac{1}{\\sqrt{2}}(|+\\rangle - |-\\rangle)$. \n", "By linearity, application of the QPE algorithm then gives (up to normalization)\n", "\n", "\\begin{equation} \n", "\\begin{split}\n", "\\mathrm{QPE}(|0,0,\\dots\\rangle \\otimes |1\\rangle) & = \\mathrm{QPE}(|0,0,\\dots\\rangle \\otimes |+\\rangle)\n", "- \\mathrm{QPE}(|0,0,\\dots\\rangle \\otimes |-\\rangle) \\\\\n", "& = |\\varphi_{+}\\rangle \\otimes |+\\rangle - |\\varphi_{-}\\rangle \\otimes |-\\rangle. \\\\\n", "\\end{split}\n", "\\end{equation}\n", "\n", "When we measure the precision qubits in this state, 50% of the time we will observe the eigenphase $\\varphi_{+}$ and 50% of the time we will measure $\\varphi_{-}$. We illustrate this example numerically as follows.\n", "\n", "This example motivates the general case: we can pass a state that is not an eigenstate of $U$ to the QPE algorithm, but we may need to repeat our measurements several times in order to obtain an estimate of the desired phase." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CIRCUIT IMPLEMENTATION OF QPE" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The QPE circuit can be implemented using Hadamard gates, controlled-$U$ unitaries, and the inverse QFT (denoted as $\\mathrm{QFT}^{-1}$). \n", "The details of the calculation can be found in a number of resources (such as, [1]); we omit them here.\n", "Following the previous discussion, the circuit that implements the QPE algorithm reads as below, where m is the size of lower query register and n is the size of upper precision register." ] }, { "attachments": { "image.png": { "image/png": "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edY5V3RudVklktu6W3fddYPB/+jRo43MnKy00kpBXq+++mqb/YbbCRMmmL59+xqtrq44Hn/88UCIF7/NN9/c7LbbbqZfv35GNzHXXXXVVWappZaqaJPipgeSaqcHlb333juIw7YDu1W8Ylr90wxC18VJzw2nfR+8LG+bb7u1ori+HhBDvfDRdamf2onEMNVLrRcR1fnkPwQg0JWAXtDY601bXWM+nRYf++c//9kwyrz2IT761rT3v2pwPli5ccYVieP6TzN2cPNp9/Vyfqeddgrud7IDrgVwNPtW94Nhw4YZzXpolags4VHp2usnjdkHvWzWGChLpxe1Nq/a/v73v/eW3F//+teKuI8//vgucbd6LJe07fm+ZtUeNcbRWFDj51GjRgUvc3RMY2qNrTXxo57z0Q+lGeMpXz76nVaM85KOueux5zgEIFBOAq6oLN3EvZffd999sQv9xBNPmH322ScIh6gcGx8BOpSAz/UhciMqa0av26G4A299krj66qubww47zOht1ueffx6p6h955BFz+eWXB6KXBF0bZy1RWbOZNeg799xzzcCBA0O/9URl5UOfXaoDs/Fqq4d3PSjooctd0Vtv3TQL2H6iqIcXDXSjOOVL+VhllVVqLmSombxKWwKsBr/VTnnV7GYJgTavYi131FFHBcLqN998Y1zbhDpvZ6G2sqzKg8opQVczg2s5zTZWOfTJuD5ZredkG1Gi50svvVTTi95qHnzwwUFc1aKybnYS/zXz2J1FKBbVbvbs2eaGG24If6p/y1kLELjn7L5mq7guTnpuOF+8dK2oPUsgdq8Vicr6kmDllVc2N998s5t08DZYsyBVVs0Q0+wUHAQgEI+Au8iWriX14610ee5DfPStae9/bl34YuXGGVckjuM/7djBzae+ZjrttNMCEW7ttdcOv/SxfrRg3vjx482gQYOCWbL2Hjh8+HDrxfv23//+d3ivVXq17s9RE9UMp6ztKVdf61qh3pfTZ7+Wubbbb799l6hbOZZL0/Z8XrN6yaGFEfVSvNbLb13TGv9p4oXGw2rH1c5HP5R0jKe8+Op3sh7npRlzVzPnPwQgUG4C6hP1vGmdvki29zBpKHGdJndJWJZDVI5LD/+dSEAvq632aicRpuGQG1FZhZD4V2u2sO1k7FYzCzQjRp/hR3XuTOhaorIbjwahmimt9OqJyq5/10aeKmeXXXap++mGhGYrLOvTR3V8jZwVjDXg1SeEtZwGwZoBrfxuttlmtbyEx/74xz8G/pRPDTC10qo1JzFx4sSwQ9d5ezwMbEwwI8nWg++ySkTWDUYirmYUN3KWi2YA1xKWJYQqruOOO65RNMGMcbGrFpXdQIrDlrnWTGXXr/Zd8T7JRRo1PZ+83DJYoV1l1uyd/v37B8Ky68fuuzOvtHooDgIQiEfAvd51zW277bbxIkjhu2h9SNq+Nc39LytWcURiVXVU//Ye6WPsILMN66yzTnAf1FZjpHpOC+JobGDvmVmKyvpay6ajbVJ7yhINNXmh0WzVeuWNc1yzh938ahzry1177bUVcTd7OVWUcWuaa1ZsNTtXzxWaiV6v3Wp2ra0XXTfNXNp+yO3zm40ps+p3fI/zfI65m/HnPAQgUHwC1aKynpdtPyydJ879XCYv9GJYk8XkEJWL3z4oQbYENHHUXc8niV5VncNcicrKnOzcbrPNNmHHYjuYelvNLI7iZI7CxtFMVFZ8EnzlP4qobKeOy78G6prR08hNnjw5zItMMNhOsDqM7B/bWaPHHHNM9emK/1pcxpavni09BdBMVPnTQ9/GG28c2JOzESnfamASWOuZl8iqrJq5K9MWytt5551ns9Rwax82NAOl2tnFezRTvZnTjJpGovI111wTsm32AKC00j5wREnPNy+XkWa127ak2U4yj1LPyeSKHsblX+0JBwEIxCNQ/bXLfvvtFy+ChL6L2Iek7VuT3v+yZBVVJLbVHMW/77GDBDn18RLnar3EtXmzW/cekqWorBf49l6ll59JnURFvcyOals3aToaq9j8aqv26Mtp/Qk37hVWWKFh1FmN5Xy3vaTXrC28Jh5YLpqJXM/JBIb8qR1o9k4jl7YfijLGU/pZ9jvuNepjnOdzzN2IPecgAIFyEKgWlVUqfelk++s4E5X0HK+vdazzISonWQvApu9u9QW5tIOktvxtXGlt1We1vlgW6x+kYR91zQCZ15V1AXFp5GSuVC93tc6aXl4kda0oU9T1rnysD1GLQ+5EZZvJp59+2sg+nh4UbAdTb3vCCSfYYHW37meHUURlOxCNIiq7b/wbCbpu5vRGzZZHtn5rOX0aaf1oFkAjp9nKdpZ3o08qbV41eymJPT8bXvnyWVbXHqA+aY3ixo0bF/LRBe86+xAse9bNnGZWNRKVozzEu2mkfeCIkp5vXm7+3dlfernSbMEE2+6aPcS6abAPAQj8j8DIkSPDfkz9qr6qaYUrYh+Stm+196+4978sWUXp7932EMW/z7GD7vP2xWEtO71u3uy+xm927JKVqKyX8e6M6KiLUdo8uluZudpqq63cQ5nsy/605aLt0KFDvaWjh2o3br2kb+TstaAwPsdyPtue8m/zGfeaVVi1EY1LLJdGIr77NaMWwG7k0vZDUa5hpZ9lv+N7nOdzzN2IPecgAIFyEKglKrtf3MgUZlSnL3PctYrSiMpJ1wKozmtaW/5ufGls1dezpV9LC0uyvpjuzfYeq63GZdY1W7PL+rPbNOzrldPOwK23NpR0Pk3uqRaX77333sC0p9qWxm76ql1WDLQOl9aqieraUSa9HNd4p9rkl4/1IRqVO7eisptp2VDWBaVBSz2RuZm5BHcAVetCctPTftai8k033RRehLoAq2crS+i0F+lyyy1Xnb2a/7fbbrsgjHtBV3u0A3TFrdnbcZ0bPuqDSLOy6kK35kbiLFL10UcfhYxk29d17qBddpYaza7SbBC1j3rOjSuKzcasHziy4OWW3b1Wojxoq32qPfXs2dONhn0IQCACgTPOOCPsx3QdRXkRFiHahl6K2oek7Vvd+1fU+1/WrOLeX5r59z12kD19OxZpJrbZRvevf/0rDJOVqOzTnrJs7rqznGw5fG9PPvnkkIuYbrHFFt6S0Fd7tp603WCDDRrG7V4LvsZyvtueCuDmM+o16xZ87NixwaQBPRDah0v3vN235mLETjOYGrm0/VCza1hpZ93v+B7nuWVKO+ZuxJ5zEIBAOQjUEpUlgkkQs/eyKGMO2ZzfYYcdKqAkFZXTrAXgZsCHLX8bX1pb9VmvL5ZmzS5bRm3Tsk+7ZsBaa60Vrg117LHHGlkSqF6n7LbbbgsnWdT7oj9PZape78rH+hBu+ar3CyEqV2daA0N3UKfOZ/3116/2VvHfHUDlQVSWbWXbaWqrhQpdd91114Xno5oV0EKGNs6vvvrKjS7cdwfod955Z3g86o4bPuqDSLOy3nXXXWG+JYxHdfrkws6g0tZ9y6S3bRI5LQ+ZEVHcl1xyidEsqlr2ouul6w6W8yAqZ8HLLbt7rWimTDNnX8BoIICDAATiEXA/hVZ/pa9YsnZF7UPc+34jgageP/f+FfX+lzWruPeXZv59jh2mTp0a3kPVNmVbOYprhajs3qeUt6gLH1fnX5MWFD5re8pKtzrPSb4Wq86//a+HIJXD/nbeeWd7qubWvRZ8jeV8tj2baTefUa9ZG9Zuqydt2OPuVp9aW3aaCNHIpe2Hml3DSjvrfsdtiz7GeT7H3I3Ycw4CECgHgVqiskomE3C2L45iDk5ftVfPHE0iKtsXi5p5m3YNK1+2/H3bqne/yGmmhcVdX8yaJNXExrhrdvlkrzbkjhvirA11yy23BOL2XnvtZaQx1XJau0ztU5qHqztV+81LmRqZkUk7lqkucyFFZVuII444Iux4VMESC+s5dwDV7EJSHFYoy8r8hWuLVnnXTGzXuQKxRAaJoc1+eqtiO+J6D9zuhSb7MHGdGz7qg0izsrqzd/bYY49YWXLfaFbX/3333Res6G2ZuNullloqmCV0//33N00vygOAG0nai7RZelnxsmVwrxXtN3NxrpVmcXEeAp1GQJ9GuX1TI1M8SdhIbKs2n1TUPiRt3+rev6Le/7Jm1ay/r67zZv59jh1GjRoVtk3dM6O6ZqKyhFytnxHlV+8FudsWVl111ahZ6+JP4p3GEVnbU1bCmnXlXuu1vlLrksGIB1weSkP2Gxs591rwNZbz2fZs3t18Rr1mbdhaW5nz0qLg//jHP4zWKtHDo74OsV9cid0NN9xQK2h4zGVdb6wdeq6x0+waVpCs+50sxnm+xtw1kHEIAhAoGYF6orJ7n9S9+Ztvvqlbcr3o1hfs1WYa44rKvtcCsM/Fup+kseXv21Z9luuLJV3/wDd7NZakawasvfbagXmLRl+3a90vO47TPa+Wy1OZGk1MTTuWqS57LkRlfboQZ5VPWwgtLCfbJrZyNXW+nnMHUHkQlZVPt9M55ZRTKrKuRmDL9Yc//MFoNlvUn9601Fss0B2gV8+OrshAnT9u+KgPIs3K+qc//Sksq+zWxHESYCynWvWqh1v79sz6q95qRo8ecuu5KA8Abti0F2mz9LLkpXJkea24nNiHAAT+R8C1+6n+adasWd7QaABUPROtqH1I2r7VvX9Fvf9lzapZf1/dEJr59zl2cIWtOC87monKss1cfR+u918v02s5996vek3q9CCkOm6F04OvXYPAlldfcvlwLg/FLeG0kXOvBV9jOZ9tz+bdzWfUa9aGdbcffvhhICJrnQh92aY611orEjDef/99Y2cViV0eROWs+52sxnk+xtxuvbEPAQiUk0A9UVmllT1le4/UFzD1nPSOE088scvpuKKyz7UAfNry922rvhXri8Vd/8Ane9sQ3PtbnLWh1OaamdnS+MC2TU28qOXyVKZG612lfaaqLnsuRGVNx9eDUhIne2m2cjVLop5zG1gt8bE6nBV8s5qprPRcIUGzrl230UYbheXaf//93VOp9t0B+gcffBA7Ljd8nAeRRmWVEXRbhzKWHsdppo8N26gj0OcPZ599ttlmm22MOhgbxm7Fu54Q3+whvjq/aS/SZullzSvLa6WaFf8hAAFj3Bl+6pMaDaLj8tp6662NBt6uK2ofkrZvde9fUe9/WbNq1t+79ab9Zv59jh3OPPPM8F4ZZ72DrEVlLchj793aNjNXUM3Q/tfnnZoJpdnKrXLDhg2ryPuYMWNSJ/3xxx9XxCmBuZnJB/da8DWW89n2LBQ3n1GvWRtWW43rJBhrpr3aimxN1/q02TV/kQdROet+J+txXpoxt1t/7EMAAuUk0EhUvvDCC8N7muzh13MyRSABudrFEZWzWAvAly1/d7znw1Z9lv2+e69upMe4dZUFe8XvljPO2lAaIzz66KNuFrvsy66yHX9qLYtql7cyNVrvKu0zVXXZcyEq77bbbqZWxVRnttZ/d7E2idP1nNvA8iAq//DDD6E9YDXO6kVitCq4bbQ77bRTvWLFPu5e9EkG6G74qA8izcq64447hmXdZZddYpXJPiiIlWz4WNfsgUqfg5900kkVs4auuOIKG7xi63bqPmwqq81ef/31FWm4f5qllwUvN/0srxU3HfYhAIH/EdAMvMUXXzzsB3WN+3CaGakBxbRp0yqiK2of0mwA1Kxvde9fUe9/WbNq1t9XVFwEUdnn2EF2Cu04pNHAtDqPzURl1ZNMGUT51Zq1r6/bbL60bTYrtzp/9r9WJtcEgupPZ+35LLYqs5v3uCa/auXJtWWsuLWwTzPnXgu+xnI+257Nv5vPqNesDbtw4UKj5wvLWzPv640NfYrKzfqhKNd81v2O73FePa62LuKMuW0YthCAQHkJNBKVZbbNHRPXMjMk4XjTTTetCSiOqOzePxuZCnATcieC1DPR1axPVHzufafWy3Hftup99/suE/deHXX9g6zYu+Ws/lLTzbPdtxNJNVZoZjnBFZX1wrra5a1MmjhRzzV7pqoXrt7x3IjKKlgSJ0PaWoRNDaGRMO3aBowiKttPFLOaqfzGG2+EA13l/bHHHqsovvuJgs/FXNyLPu4AXRl0w0d9EGlWVnc2VL0bRAWc///nu+++q2Do2sCRrbwo9awblbWlp1k2tVyUBwA3XLOL9Iknnmi4Mnuz9LLg5ebf7YyjMLSdcZRrxU2HfQhA4FcChxxySCaftWQAACAASURBVNif6WVZ9arDv/qMviexTQOK6gUnitqHpO1b3ftX1Ptf1qya9ffVtd3Mv8+xwyeffBK2SY1TotodbiYqV5cp7v+ZM2dW5GvOnDlxozASHFdaaaUuL/RjR5QggL4eEE/9NH5t9hDTLAmtWm7j09dbjRaPsXG514KvsZzPtlcrn1GvWRtW4rrlIjNyqvN6zn24d2cqq++s7j/T9kPNrmHlMet+x/c4z+eYu14dcRwCECgPgUaiskqpCXW2/z766KO7FFwTwzQjuJaLIyq7ArHPNazcfOnFdVJb/j5t1fvu990yumOKqOsfZMXeLaf2mzmrY2g81sy5ovIZZ5zRxXveytRIm2k2lulSuCYHciMq68E3yYPB7Nmzw07n3nvvrVtcdxDXTCizq4GrM2tUGTYx90KKOjjX58i2s9RDQPXDmmy8yS6N/OhtnWb7RnWaul9vlXY3r3EH6ErfDe+rrLqxWBYSU+rlvbr8kyZNCsP95je/qTitFWP1WUwUJ1vcSr+ezUi37fiYqfz444+bDTfcsG7WmqWXBS83M25n3OxaUTjbGUe5Vtx02IcABH4loJkZrl1ULSCV1h1++OHm2GOP7RJNUfuQZgOgZn2re/+Kev/LmlWz/r668pr59z12cM1F6ZP2KC5rUVl5cPOVZOwoAVSTB9yX0VHK5sOPFue0kyE09qg12yVqOu6iRopLC9BFce614Gss57vtqRxuPqNeswq3YMEC45pH08v8Rk4ChR2HuqKyFlmS4Oy6tP1Qs2tYaWXd7/ge5/kcc7us2YcABMpJQH1cIxFPYqrtk9WXq0+3TiKtFuirpxfEEZWzWAvA5tOXLX+NqdKuD6U8+e73bTm1de/VUdc/yIp9luVsJioXqUzNxjJu/UbZz42orI4jyid71YXSYFhhJbzW+kzS+r/99tvDzqmemQPrV4NP25FFEcrcC2ny5Mk2mrpbfRLhziy5+eaba/qVGGDzEfVTAj1c6UGp3swXN69xBug2g254n2Xdd999w7LWW03T5sFurQF7MVL9uk4D3B49eph6n6W4fvUgpDjWWWcd93C4H+UBIPRsjLEroCrOl19+2T0V7E+YMMFst912XY7bA1HS883Lpq1tlp2xmw77EIBAJYGnn366QmxqJoRUhq78p5duffr0Mfqio5YrYh+Stm91719x7n9ZsorS37v1F8W/z7HDtddeG96bdc+N4iTu27HL8OHDowSJ7cddyOzZZ5+NFf7uu+8OrjPXZFasCDx4vvrqq0NGmlQR9SHMTVr2gt2xZBxTGu614HMs57PtqaxuPuNcs2+++WbIVxM0ms3elt1F22abicpp+6Eo17DKnmW/43uc53PM7bZx9iEAgXISaCYqSzh2J1q4OogmEerrvnoujqicxVoAWdjyV1nT2qr33e+7/JPcq7NgrzxlWc5monKRylRqUVlvrKJOmbcNeeeddw4GglpNvJF79913wwHjeeed18irEWQ7i0RidTPnXki1ZoVVh9cDjR28NrKdqdnJdgVUCZ7Vs5mr49V/LUYnG3L1nJtXialxnRveZ1klhtvF/KLM0NMMdWu2Qnb8qp0GuGIcZQbQv//978BvvQUR3QeAavG6Ol39Vx3Y+q21AJBmSB166KG1ggbHoqTnm5ebmbidsa2HKC9g3HTYhwAEuhIYPXp0+JWKXhDKfmxcp1nPmsnZ6AVdEfuQtH2re/+Kc//LklWU/t6t/yj+fY4d9BJcZql0T9MDXhT7w7qX2nvgn//8Zzf73vZdsfvyyy+PHK8WaZOIe80110QOk5XHAw88MOQk8wz1Fguul75WvbecBw4c2FQ4deNxrwWfYzmfbU/5dfMZ55qVLUrLRqJyvZdrSkPc3Znvrqh80EEHGb0AcF3afijKNaz0sux3fI/zfI65XdbsQwAC5STQTFRWqd0vSNwF13bYYYeak7YsqTiisu+1AHza8m9mlzmurfq4/X6cL5Hde3XUF8C+2dv6z7KczUTlIpWpmajcbH0Iy9tuczVT2T60aLZWFKfZFQojMbLRgNHGteqqqwb+BbGe0wPH5ptvbjTAtwNSPaA3cu6FpE80br311rreNSiWHT9b1nozim0EmoFjF6NTQ230QKdZ23roaxTn7rvvHpZLK1TGdVmWVbOGrGH+008/vW7W9LmLVvAWQwmaX3zxRRe/doArobPZg8ipp54avETQzJZaTov52LbgPmzU8qtjVqRWGD2QVDt9wvLAAw9UHw7/R03PJ68w8SpbflFEeT2gq6yaGe5+nuTGyT4EIBCdgMRgLYym60r3lEb9RXWsstu25pprGtm4bOaK1oek7VvT3P+yYuX291FMF0T173PsoAc0u87EPvvs08XGrNvO9OWVbbtqv1EXvnHjiLKvhy07W1mCYDMzFvKvBXJ1PUW5NqLkIa0f5ckVhrfZZhszf/78SNFqcoT46jd48GDzzTffRApnPWU5lvPZ9tJcs+uuu27ISF+I1XOy16nryj5Au+NPCRn69Nh1afsh9xpuNqbMqt9xbTb7GOf5HHO7rNmHAATKSSCKqOyKw927dzda5+HTTz+t+2WxJeWG0z2ykd7hey0An7b8fduqb9X6YlFFZd/sbf23U1QuUpmaicrN1gCzvO02V6KyPmU45ZRTgllaGuRJIa/n9HAgwVAialQRWmKvOheFq2VDToM3zQxWZ1RtE0UDP80wnjt3bpcsuYNzzWiQ0KlZNNVOphDspxzDhg1r+hBkw0+bNs3YwbGEZdl8dp2EPA0QZVe4lrmFJ5980uhTEdmFU9ntg8jaa68d2N/TYPvBBx+MJMxnXVbZGpQgojzqYevrr792ixqYOJHpCJ3fc88965q3sAPcFVdcMXhQqPUZuRZf0axACdkXXnhhRTp6aJCwo3q0M6iVpmw4qe3dc889XfLmRiDj7fIvodW9mckms+KoXvglaXq+eCkelVeihm2jyr/21aZ1Tn7kNBNJn9ar3bifgcq/ZqVpNrfO17pWXEbsQwAC9QloEVHZXtd1pZ/6Ow3C6zl93i37nxLNGgko1eGL1ofE7Vt93v98sarX3+servuL+tu33norrKq4/m3AtGMHG4+2H3/8cTgu0gzb6lm1ui9I6NRLU403bLvVVmM73ReqFyR240+y79oh32STTYzsF9ZyU6dODa4lic+aZZI3N2bMmND+rxZm1ouhek6TBvQ1l7hq7KKVzavrol5Y93jWY7k0bc/XNatnAzsDWWMZ9amu09j5nHPOMdtuu23wJaDEVXGVX30houcEjddqCf1x+6F613CUMaWvfkfxZDXOSzvmduuFfQhAoPwEoojKoqB7ux1PSOu44IILjMTRRi6OqKyJZ77WsNI9RWNwm99a2oObb3cmtvuC0dryV7/qa30opet+JdNszaQ064tFFZV9sne5tlNULlKZmonKzdapcZlrPzeisoRYK0LpwUOCp95K6aFaF5cavwQ+PZxY0XHIkCFdBNbqAlb/l00eCY0ajGuWiwbkehMk0VYPQ+qI5FxR2XYO2tYa7LuDcw1C9fAl8VcDU83qURqye6c0tY3zwG/zrxnKGvxqlrNmLm+55ZbmL3/5i5H5DM0gUsOoZz9Yq5lqNqk6OuVJ5ZetTW3FXcclNushoJlrRVn1gKQBu/Kojl4PWfqcVjPIVQ595tmMocTOfv36BbOYH3744eBlwfrrrx98SqkHB3XUq622mhkwYIDRA0y1GzFiRAUz5UWzWPSAollYMo/yz3/+szpYxf+TTz458Kt2rM+HNePlt7/9bfCmtcKjMSZNej54yRZjrTai9qL2oXN6ESKnlz0qv9qdeKgNiY/Ed/3XcZ2vda1Ul5v/EIBAYwK6Z62++urhIFX3EC3Ap0G1fiNHjjSDBg0K7gu6X+r+E9cVrQ+J07f6vP+Jqw9Wtfp79Z+2v9U9/ogjjgirMa7/MKAxwddNSccObjza12edEo779u0b9Psy46RZnVtssUVwn9Cq1xLg3IX63PGTxi++nV48a1yosYLuUxJc/+///i+Year7moR63YM1hqg3RvKdpyTxqRwa62p8obJsvfXWRg+ZEkZ1L9WYR2XQeb2s1tjv7bffTpJUEKYVY7mk41af16xmtullt9qGxuAaK0uYUL+pMaBM5+malpO5CT1X2DarfDQaF8fph2pdw3HGlD76nSzHeWnH3IkbMgEhAIFCEtDLXj0rNnO33HJL2CfrWVPj4eoJZ9VxxBGVFdbXWgC+bflLq/C1PpTKqZf79v6W5fpiUUVln+zdNtBOUblIZXInBtaalKpxZ6M1wFzm2s+FqKyB2f3331+dt2CmgB5YNItAIrMeSFQ42TOTUNjM1kyXCP//AYVTZ6ZZo1dddZUZO3ZsF7uVAjlu3Djz0EMPBQN6CWn1Pi+sHpzbdDWY1ayA6667LnjI0kweH072hDWzWLNKNXtan4K0yrWjrDJzotlbzz//fDBLNkpZNTvY5aI6V3jVqV5O6O2Lez5KnEn8qM1MnDgxmO0re+FR7GInSceGUdtIwsuGZwsBCOSTgGynaYaGbOZLPNbg+ne/+13wskrCiPtFRJoSFKUPaXXfWotpUVjZvPscO8jslMZtsk2se44EOes0g1j3bN379PL1jTfeCO63WZpH0ixMjQ1lLkFiocydySyEjtUzbWXzm6etxoka12nSgPKvmawSxjXpQYK5xpOqx7SuHWO5do1bxUpcNe6TQKGxs9psPZMpssesNhvlGaMd/VAe+528jLnTXheEhwAEWkNA+ooETnfsUCtlmby05rfkP8o6DXFFZd0ffKxh5duWv/0CJIqJIn0NIz56+VzPtWp9sWZmR938+WLvxhlXVNbkOLHTBMtmrplNZYUvSpnSrg9RzSoXonJ1por2v97gvGjliJLfTiprFB74gQAEIAABCEAAAkUiwFiuSLVFXiEAAQiUh4CEYn29KyHvuOOOa/oCT18jya9+tcyXVpOp/lpKLxGbOV9rAVhzpcpro6+qo9jyt6KyxM5mQm2z9aFs+bNaXyzN+ge+2Nsy6msk216iCPL6ksn6V9ts5Fy71LJEUM/lpUyN1ruyLyJU9iRrgFWXHVG5mkiC/500OO+ksiZoCgSBAAQgAAEIQAACuSbAWC7X1UPmIAABCJSKgEwi6AtxzY6UCS0r4mkr85Ra4EwibC3TFjIBJX/6aqfWFyT6Mlxfwii8zKVaM6k2DQmpl19+ubnrrruCha/rmWdIsxaArSyftvytqJx0fSibJ3frc30xX+sfKH9p2ftaM0BmomR20F0bSl+7yfKAvsBTG7TtSuZBL7vssmAdEX0NX+3yUqZG613FXR+iuozuf0Rll0bC/U4anHdSWRM2B4JBAAIQgAAEIACB3BJgLJfbqiFjEIAABEpH4OKLLw7MC8iUhdaPkE15mXGT6QF3PZ5a6xwJxjbbbBOYLK0FRiaNtN6A4lG8EmFlMtX+lI6OK12lf/7559eKJjiWdC0AN0JftvyzslXva30xn+sfiF8a9lmuGaD1QrTWiV2bTGugqE3ZdVA001nmymq5vJbJzWuc9SHccNX7iMrVRBL876TBeSeVNUFTIAgEIAABCEAAAhDINQHGcrmuHjIHAQhAAAJtJpB2HYq0tvyztFXve30x31WVlr3v/PiIL89l8rE+BKKyh1aityN2Knwj+zkekmp7FJ1U1rbDJgMQgAAEIAABCEDAMwHGcp6BEh0EIAABCEAAAhDoUAKIygkr/pVXXglWkr766quNa+B70KBBgU0frXiuVUDL4DqprGWoL8oAAQhAAAIQgAAEXAKM5Vwa7EMAAhCAAAQgAAEI+CCAqJyQ4oABA4LZyUsssURgx0d2VmSnRwLzYostFpyLsuJkwuRbGqyTytpSsCQGAQhAAAIQgAAEWkCAsVwLIJMEBCAAAQhAAAIQ6DACiMoJK3z+/Plm0aJFdUP/9NNPRr8yuE4qaxnqizJAAAIQgAAEIAABlwBjOZcG+xCAAAQgAAEIQAACPgggKvugSBwQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABDqEAKJyh1Q0xYQABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQg4IMAorIPisQBAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQKBDCCAqd0hFU0wIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAj4IICr7oEgcEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQ6hACicodUNMWEAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIOCDAKKyD4rEAQEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgQwggKndIRVNMCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAI+CCAq+6BIHBCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEOoQAonKHVDTFhAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCDggwCisg+KxAEBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAoEMIICp3SEVTTAhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACPgggKvugSBwQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABDqEAKJyh1Q0xYQABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQg4IMAorIPisQBAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQKBDCCAqd0hFU0wIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAj4IICr7oEgcEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQ6hACicodUNMWEAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIOCDAKKyD4rEAQEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgQwggKndIRVNMCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAI+CCAq+6BIHBCAAAQgAAEIQAACEIAABCAAAQhAAAIQyIDAiy++aN5++21+TRi8+eabZtq0aRnUAFHWIoCoXIsKxyAAAQhAAAIQgAAEIAABCEAAAhCAAAQg0GYCN954o+nWrRu/GAzmzJnT5lrrjOQRlTujniklBCAAAQhAAAIQgAAEIAABCEAAAhCAQMEITJw4MRCUhw4das455xx+DRisv/76Aasvv/yyYLVczOwiKhez3hLl+rXXXjPLLrus2WijjczgwYM76rfOOuuYPn36mG+++SYROwJBAAIQgAAEIAABCEAAAhCAAAQgAIFWE5g0aVIglI4fP77VSRcuvSOOOAJRuYW1hqjcQtjtTur6668PLq5evXqZ3r17d9Rv6aWXDso+derUdlcD6UMAAhCAAAQgAAEIQAACEIAABCAAgUgEEJUjYQo8ISpHZ+XDJ6KyD4oFieOBBx4IhNVx48YVJMf+snn66acHZZ8+fbq/SIkJAhCAAAQgAAEIQAACEIAABCAAAQhkSABROTpcROXorHz4RFT2QbEgcSAqdzOIygVprGQTAhCAAAQgAAEIQAACEIAABCAAAYOoHL0RICpHZ+XDJ6KyD4oFiQNRGVG5IE2VbEIAAhCAAAQgAAEIQAACEIAABCBgDKJyjFaAqBwDlgeviMoeIBYlCkRlROWitFXyCQEIQAACEIAABCAAAQhAAAIQgACicpw2gKgch1Z6v4jK6RkWJgZEZUTlwjRWMgoBCEAAAhCAAAQgAAEIQAACEIBAx8xU/vzzz82GG25oHn/88cS1jqicGF2igN5E5QULFiTKQNpAixYtMj/88EPaaDoiPKIyonJHNHQKCQEIQAACEIAABCAAAQhAAAIQKAmBTrGpfNBBB5lu3bqZhx9+OHHNISonRpcooDdReYUVVjBXXnllokykCXTIIYeYfv36mZ9++ilNNB0RFlEZUbkjGjqFhAAEIAABCEAAAhCAAARaRuDtt982yyyzjFljjTXM+uuvzw8GhWoD0rI22WSTll0vSRLqBFH5rbfeMj169DCDBw9OgigMg6gcomjJjhdR+dtvvw3eJkjgbbW75JJLgrQnTpzY6qQLlx6iMqJy4RotGYYABCAAAQhAAAIQgAAEck1gwoQJwTO5hOXf/OY3/GBQqDawxBJLmF69euX6GusEUXnbbbc13bt3N1OnTk1VF4jKqfDFDuxFVJ47d25wEzn44INjZyBtANlcWXzxxc12222XNqrSh0dURlQufSOngBCAAAQgAAEIQAACEIBASwn885//DPSAa6+9tqXpkhgEfBD4/e9/b1ZddVUfUWUWR9lF5cceeyzoQ/bff//UDBGVUyOMFUHbReWvv/7a3HDDDeaEE04wBxxwgDn55JPN5MmTzc8//xy5IDvttFMwTf6zzz6LHKYTPSIqIyp3YrunzBCAAAQgAAEIQAACEIBAdgQQlbNjS8zZE0BUzp5xoxS0TtrAgQPN0ksvbWbOnNnIa6RziMqRMHnz1DZRef78+eawww4zSy21VGAzZcyYMea+++4zF154oVlxxRVN7969zV133RWpoPfee2/wVuOiiy6K5L9TPSEqIyp3atun3BCAAAQgAAEIQAACEIBANgQQlbPhSqytIYCo3BrO9VKRFqjF+U477bR6XmIdR1SOhSu157aIyjJZscEGGwQNR7OUq92PP/5ohg4dGpw//PDDq093+a9F+pZddlnTv3//Luc48CuBLETlWbNmmTvvvNPIprU+yXj00UfNU089ZZ599tlgq/86rvN33HGHmT179q8ZMsbMmTMneHkgO1z333+/eeSRR8yTTz4ZhH/66aeNPoNQvu++++4gnY8++qgifNQ/p59+etCepk+fHjUI/iAAAQhAAAIQgAAEIAABCECgCQFE5SaAOJ1rAojK7aueefPmmeWXXz7Q87RWmw+HqOyDYvQ42iIqb7311oHAJ1MX9ZxmMg8aNKiu8Fwd7rjjjgv8Pvfcc9Wn+P//CWQhKl9++eXBSr8ybq+3S/V++pRBq6pKKHadZplrVrpmrNcLq+M6rxcHt956qxs88j6icmRUeIQABCAAAQhAAAIQgAAEIBCZAKJyZFR4zCEBROX2Vcq5554b6EDXXXedt0wgKntDGSmilovKt99+e9BotLrmd9991zCT48ePD/z27NnTfPjhhw39vvXWW4HfkSNHNvTXySezEJVdnpqB3rdv36AeJARLSNYsZc0kj+I0a3mzzTYLw2vlz5tuusn88MMPUYI39IOo3BAPJyEAAQhAAAIQgAAEIAABCCQigKicCBuBckIAUbk9FSH9SFrfgAEDzMKFC71lAlHZG8pIEbVUVFZDWW655QLRcM8992yaQU2FVyOTQKlF/Jq59ddf30isVjhcVwJZi8q//PJLMGvZzjjeb7/9umaiyZENN9wwFJU32mijJr6jn0ZUjs4KnxCAAAQgAAEIQAACEIAABKISQFSOSgp/eSSAqNyeWjnooIMC7Uc6lU+HqOyTZvO4WioqP/TQQ6FgeOWVVzbPnTFmyJAhQZgoYrGmzEvQvOWWWyLF3WmeshaV33jjjbB+VQ/jxo2Lhfj77783iy++eBjHGWecESt8I8+Iyo3ocA4CEIAABCAAAQhAAAIQgEAyAojKybgRKh8EEJVbXw+yNNCjRw8zePBg74kjKntH2jDClorKI0aMCAVDLbwWxQ0fPjwMo8XcGrm5c+cGJhdkQgHXlUDWovKoUaPCupKoPHPmzK6ZaHBEi/rZWc7aPv744w18xzuFqByPF74hAAEIQAACEIAABCAAAQhEIYCoHIUSfvJKAFG59TWz7bbbGpk7nTp1qvfEEZW9I20YYUtF5f79+4ei4VNPPdUwY/bk8ccfH4bRfjO3zz77BI2zmQ3mZvGU8XzWovLQoUPDulp55ZVjIzzttNPC8Fr4z4ctZZsJRGVLgi0EIAABCEAAAhCAQCcS+Pbbb43Ev5tvvtm88sor5scff+xEDJQ5AwKIyhlAJcqWEUBUbhnqIKHHHnss0H3233//TBJGVM4Ea91IWyYqa1E+vYmwM1GnTZtWN1Puib/97W9hmCgzkDW7VWn4NJ3g5qfI+1mKyrKn3Lt377CukiyY+Mc//jEMv8kmm3hFjajsFSeRQQACEIAABCAAAQgUhIAWzl599dUrnsX0vKRJHFtttZWZPn16QUpCNvNKAFE5rzVDvqIQQFSOQsmPn0WLFpmBAwcGFgbiftkeNQeIylFJ+fHXMlH5vffeCwVDDWI+/fTTSCW44YYbwnCrrLJK0zASN/v27Wv69Olj1GBxvxLIUlSutqc8fvz4XxOOsKdZyRrY2pcOvl8KICpHqAS8QAACEIAABCAAAQiUhsA333xjDjzwwHB8bcfZ1dull17aaL0bPUfhIJCEAKJyEmqEyQsBROXW1cSYMWOCe5K+Us/KISpnRbZ2vC0TlV9++eWKAc3nn39eO0dVR2+66aYw3LLLLlt1tvbfs88+OwgjG724XwlkKSpfddVVYT1poDpr1qxfE46w98QTT1SE92lPWckjKkeoBLxAAAIQgAAEIAABCJSGgGxWVgvIjf5rfRQcBJIQQFROQo0weSGAqNyampg3b55ZfvnljXQ9mWPKyh188MHBvU/ruElXyutP/eb333+fFYaWxdsyUdmapbADmdmzZ0cq5NixY8PB0FJLLRUpzCeffBJ83rXXXntF8t8pnrIUlXfbbbewnqLMKK9mftZZZ4XhfdtTVlqIytXE+Q8BCEAAAhCAAAQgUFYCo0ePDsfW9vmr2VYzlvV1KQ4CcQkgKsclhv88EUBUbk1tnHvuucF96dprr800wUGDBsW+/zW7P2Z1/tRTT82URSsib5mofM8991RU7Ndffx2pfOPGjasIF3VBiS233NJIhJ4zZ06kdDrBU1aicrU95YMOOig2zs033zysZ9/2lJUZROXYVUIACEAAAhCAQK4IfPnll+byyy83+hItzWf6eYsnV5DJTCkI6PmnV69e4dg6zsPwuFcJCAAAIABJREFUkCFDSsGAQrSWAKJya3mTml8CiMp+edaKTZYKevbsaQYMGGAWLlxYy4u3YyNGjAjuf5dddpm5/vrrc/u78cYbI5sF9gYng4haJirfeuutFQObqGLvbbfdVhFODwJRnA13zTXXRPHeEX6yEpXffPPNijoS+zhuwYIFwQsAO+D1bU9ZeUFUjlMj+IUABCAAAQjki8D8+fMrFgSWqbMkLm/xJCkDYSDQjMBDDz1UMTa3Y+wo2yWXXNL89NNPzZLgPAQqCCAqV+DgT8EIICpnX2HWJIU0qawdNpWzJlwZf8tE5QkTJlQMbqKKytVidFTbK1r4TW/oNfW9FU4zqGVHOM8/a0pEs799ump7yvqsIc4bISv42oGub3vKKqtN4+mnn851HeW5/ZQhb++//76ZMWMGbSDnfVUZ2lonl0GfTndy+Sn7rGDWhe/FkmUXz44TtP3tb3+baCiTt3iaFUK29mhT+R5f57F+TjjhhIrrxb12ouxPnjyZdsdYKVYbsM/6WX/W3qzP5DwEkhAYOHCg+c1vfhOrzbe677dazvjx45MU0XsY6W2yPvDf//7XfPHFF8F+vReSb731lunRo4cZPHiw93zUihBRuRaV7I61TFR+5JFHKgY3X331VaRS2dUhNQBabLHFYn3ueOihhwZpaiZt1m777bevKF+UAVu7/Jx88slecbj2lDW7YcUVV4z1k/02yyILe8oqbNyFSmx+2HYL6wYWsKAN0AZoA7SBqG3At404PbBojGDTT2JqS+OBvMXTbECmxWxsmdly/dEGaAN5bwOHHXZYs26N8xDIHYGk5oLacT36Hl81qozp06cbvTDSl+R77rmn2WCDDYKF9qT51Cu7tB0J9JtuuqnZb7/9zIUXXmjWWWedwP/UqVMbJeftHKKyN5SRImqZqPzCCy9UNLzPPvssUgZlZ8Q2WF3scdyUKVOCsOeff36cYIn8Pvjgg+a4447L9W/XXXcNePh8g1xtT1lCfly32WabhXWchT1l5efwww8P0jjwwANzXUd5b0NFz5/sBA4fPpw2kPO+qujtrJPzf8ABBxj16X/961+5zjr4Ojv++ONNFg8OsqW8yy67mNNOO81EXfC51pgkb/HUyqM9dt1113EtdfC1lPR+st5664Vja/scFWc7bNgw2h3tLlYbUJtRG7v44ott98UWAoUh0K9fP7PMMsvEavNJ++ek4TT+0TWmcUFWTl/1/uMf/zA777xzhckxpasJniussILZaKONzE477WRkt1gvkY455hhz9NFHB/t6ztZky3XXXdfUeinep0+fQGi+5ZZbUo3jmpUfUbkZIb/nWyYqv/POOxWDm08++SRSSSSA2kGQZsDGcbK3p7ASl3HGZGFTudqe8p133hkLtWwbum+6srCnrAxZ8xd624aDAAQgAAEIQAACEIBAWQlYUwT2GSrOVsJBVHODZeVHueITwKZyfGaEyA+BTrap/PHHHxuZL11zzTVD3U1fhkk81iSR22+/3UjzkbnXuO6bb74xq666avCl2d577x2k0b179yAd3Ws0oVBroMmMhk+HqOyTZvO4WiYqa7VHd0AT1STFeeedF4aTrZuoTjNo+/btG/zSrBAeNb0i+MtCVNabLLdeZVMnjrMDEBtHFvaUlR9E5Ti1gl8IQAACEIAABCAAgaIS0OQd++Bux9hRtxIWcBCIS8A+0/n8IjZuHvAPgaQEOk1U1roXWmNCNo7tvUIziw855BAzadIk89133yVFWRHu5ptvDrQifWFmncyQyS70HnvsYXr27Bmcl4i91157meeee856S7VFVE6FL3bglonKypk7Bf7ZZ5+NlFlrtkADIU2nj+qs6YuzzjorapDS+8tCVN59991DUbl///6xGZ555plh+KzsKStTiMqxq4YAEIAABCAAAQhAAAIFJaDPkaMKya6/hx9+uKAlJtvtJICo3E76pJ2WQKeIypptfP311wc2j9Xv64txibkyC+Z7geV58+YF9pelAdb7+kV+brvtNiMTlVbc3nDDDQNhO02dbr755sH9T/ad8/yTqF6GF3EtFZVlm8UOWvRZVhRn7QAr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xu3bkYeipImojKhclLZKPiEAAQhAAAIQgAAE/BNAVPbPlBiNscLstddemwkOLezmirRnnHGGt3Rs3m38q666asO4q0XloUOHGuXH/jSLepdddjHLL798mGdE5YZI234SUbntVRBm4OSTTw6umwkTJoTH4u4gKsclls6/N1FZb/SuvPLKdLlJEPqQQw4x/fr1Mz/99FOC0J0VBFEZUbmzWjylhQAEIAABCEAAAhBwCSAquzTY90XACrNZicpWaLLC71FHHeUr6+b+++8PxV/Fv9122zWMu1pUvvPOO2v6nzdvnrFiOKJyTUS5OYionI+qmDFjRjDLf+211zaaPJrUISonJZcsnBdRWVPU1QFL4G21u+SSS4K0J06c2OqkC5ceojKicuEaLRmGAAQgAAEIQAACEPBGAFHZG0oicghkLSr//e9/rxB+ZQ7Dlxs/fnxF3EcffXTDqKOKyorkyy+/NEsssQTmLxoSbf9JROX214FyMHz48OBanDJlSqoMISqnwhc7sBdRee7cuUHlH3zwwbEzkDbA559/bhZffPGmbxTTplOG8IjKiMplaMeUAQIQgAAEIAABCEAgGQFE5WTcCNWYQNai8tNPP10h/G6xxRaNMxTj7Omnn14Rd7Ovr+OIysqGFv5jpnKMCmmDV0TlNkCvSlI2lLt372623377qjPx/yIqx2eWJkTbReWvv/7a3HDDDeaEE04wBxxwgNGnLZMnTzY///xz5HLttNNOpkePHuazzz6LHKYTPSIqIyp3YrunzBCAAAQgAAEIQAAC/yOAqExLyIJA1qKytIFlllkmFH979eplfvnlFy9FkbkLa1ZD22eeeaZhvHFF5cGDByMqNyTa/pOIyu2vA70okqY3bdq01JlBVE6NMFYEbROV58+fbw477DCz1FJLGXW0Y8aMMffdd5+58MILzYorrmh69+5t7rrrrkiFuffee4MbwUUXXRTJf6d6QlRGVO7Utk+5IQABCEAAAhCAAASMQVSmFWRBIGtRWXkeNmxYhfj73nvveSnKsssuG8a71lprNY0zrqj8xBNPmI8//rhpvEk89OnTJ8y77NDikhFAVE7GzVcoa9f80EMP9RIlorIXjJEjaYuoLJMVG2ywQdABapZytfvxxx+NVlHVm8LDDz+8+nSX/1qkTzeD/v37dznHgV8JICojKv/aGtiDAAQgAAEIQAAC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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## IMPORTS and SETUP" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# general imports\n", "import numpy as np\n", "import math\n", "import matplotlib.pyplot as plt\n", "# magic word for producing visualizations in notebook\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# AWS imports: Import Amazon Braket SDK modules\n", "from braket.circuits import Circuit, circuit\n", "from braket.devices import LocalSimulator\n", "from braket.aws import AwsDevice" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# local imports\n", "from utils_qpe import qpe, run_qpe\n", "\n", "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# set up device: local simulator or the on-demand simulator\n", "device = LocalSimulator()\n", "# device = AwsDevice(\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pauli Matrices:\n", "In some of our examples, we choose the unitary $U$ to be given by the **Pauli Matrices**, which we thus define as follows:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Define Pauli matrices\n", "Id = np.eye(2) # Identity matrix\n", "X = np.array([[0., 1.],\n", " [1., 0.]]) # Pauli X\n", "Y = np.array([[0., -1.j],\n", " [1.j, 0.]]) # Pauli Y\n", "Z = np.array([[1., 0.],\n", " [0., -1.]]) # Pauli Z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## IMPLEMENTATION OF THE QPE CIRCUIT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In ```utils_qpe.py``` we provide simple helper functions to implement the quantum circuit for the QPE algorithm. \n", "Specifically, we demonstrate that such modular building blocks can be registered as subroutines, using ```@circuit.subroutine(register=True)```. \n", "Moreover, we provide a helper function (called ```get_qpe_phases```) to perform postprocessing based on the measurement results to extract the phase. The details of ```utils_qpe.py``` are shown in the Appendix.\n", "\n", "To implement the unitary $C-U^{2^k}$, one can use the fact that $C-U^{2} = (C-U)(C-U)$, so that $C-U^{2^{k}}$ can be constructed by repeatedly applying the core building block $C-U$. \n", "However, the circuit generated using this approach will have a significantly larger depth. In our implementation, we instead define the matrix $U^{2^k}$ and create the controlled $C-(U^{2^k})$ gate from that." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## VISUALIZATION OF THE QFT CIRCUIT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check our implementation of the QPE circuit, we visualize this circuit for a small number of qubits. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QPE CIRCUIT:\n", "T : |0|1|2| 3 |4| 5 |6|\n", " \n", "q0 : -H---U-SWAP---PHASE(-1.57)-H-\n", " | | | \n", "q1 : -H-U-|-SWAP-H-C--------------\n", " | | \n", "q2 : -H-U-U-----------------------\n", "\n", "T : |0|1|2| 3 |4| 5 |6|\n" ] } ], "source": [ "# set total number of qubits\n", "precision_qubits = [0, 1]\n", "query_qubits = [2]\n", "\n", "# prepare query register\n", "my_qpe_circ = Circuit().h(query_qubits)\n", "\n", "# set unitary\n", "unitary = X\n", "\n", "# show small QPE example circuit\n", "my_qpe_circ = my_qpe_circ.qpe(precision_qubits, query_qubits, unitary)\n", "print('QPE CIRCUIT:')\n", "print(my_qpe_circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As shown in the following code, the two registers can be distributed anywhere across the circuit, with arbitrary indices for the precision and the query registers. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QPE CIRCUIT:\n", "T : |0|1|2|3| 4 |5| 6 |7|\n", " \n", "q0 : -I-----------------------------\n", " \n", "q1 : -I-H---U-SWAP---PHASE(-1.57)-H-\n", " | | | \n", "q2 : -I-----|-|------|--------------\n", " | | | \n", "q3 : -I-H-U-|-SWAP-H-C--------------\n", " | | \n", "q4 : -I---|-|-----------------------\n", " | | \n", "q5 : -I-H-U-U-----------------------\n", " \n", "q6 : -I-----------------------------\n", "\n", "T : |0|1|2|3| 4 |5| 6 |7|\n" ] } ], "source": [ "# set qubits\n", "precision_qubits = [1, 3]\n", "query_qubits = [5]\n", "\n", "# prepare query register\n", "my_qpe_circ = Circuit().i(range(7))\n", "my_qpe_circ.h(query_qubits)\n", "\n", "# set unitary\n", "unitary = X\n", "\n", "# show small QPE example circuit\n", "my_qpe_circ = my_qpe_circ.qpe(precision_qubits, query_qubits, unitary)\n", "print('QPE CIRCUIT:')\n", "print(my_qpe_circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As follows, we set up the same circuit, this time implementing the unitary $C-U^{2^k}$, by repeatedly applying the core building block $C-U$. \n", "This operation can be done by setting the parameter ```control_unitary=False``` (default is ```True```). " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QPE CIRCUIT:\n", "T : |0|1|2|3|4| 5 |6| 7 |8|\n", " \n", "q0 : -I-------------------------------\n", " \n", "q1 : -I-H---U-U-SWAP---PHASE(-1.57)-H-\n", " | | | | \n", "q2 : -I-----|-|-|------|--------------\n", " | | | | \n", "q3 : -I-H-U-|-|-SWAP-H-C--------------\n", " | | | \n", "q4 : -I---|-|-|-----------------------\n", " | | | \n", "q5 : -I-H-U-U-U-----------------------\n", " \n", "q6 : -I-------------------------------\n", "\n", "T : |0|1|2|3|4| 5 |6| 7 |8|\n" ] } ], "source": [ "# set qubits\n", "precision_qubits = [1, 3]\n", "query_qubits = [5]\n", "\n", "# prepare query register\n", "my_qpe_circ = Circuit().i(range(7))\n", "my_qpe_circ.h(query_qubits)\n", "\n", "# set unitary\n", "unitary = X\n", "\n", "# show small QPE example circuit\n", "my_qpe_circ = my_qpe_circ.qpe(precision_qubits, query_qubits, unitary, control_unitary=False)\n", "print('QPE CIRCUIT:')\n", "print(my_qpe_circ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the circuit diagram, we can visually infer the exponents for $k=0,1$, at the expense of a larger circuit depth. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NUMERICAL TEST EXPERIMENTS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the following section, we verify that our QFT implementation works as expected with a few test examples:\n", "1. We run QPE with $U=X$ and prepare the eigenstate $|\\Psi\\rangle = |+\\rangle = H|0\\rangle$ with phase $\\varphi=0$ and eigenvalue $\\lambda=1$. \n", "2. We run QPE with $U=X$ and prepare the eigenstate $|\\Psi\\rangle = |-\\rangle = HX|0\\rangle$ with phase $\\varphi=0.5$ and eigenvalue $\\lambda=-1$. \n", "3. We run QPE with $U=X$ and prepare $|\\Psi\\rangle = |1\\rangle = X|0\\rangle$ which is *not* an eigenstate of $U$. \n", "Because $|1\\rangle = (|+\\rangle - |-\\rangle)/\\sqrt{2}$, we expect to measure both $\\varphi=0$ and $\\varphi=0.5$ associated with the two eigenstates $|\\pm\\rangle$. \n", "4. We run QPE with unitary $U=X \\otimes Z$, and prepare the query register in the eigenstate $|\\Psi\\rangle = |+\\rangle \\otimes |1\\rangle = H|0\\rangle \\otimes Z|0\\rangle$. \n", "Here, we expect to measure the phase $\\varphi=0.5$ (giving the corresponding eigenvalue $\\lambda=-1$). \n", "5. We run QPE with a _random_ two qubit unitary, diagonal in the computational basis, and prepare the query register in the eigenstate $|11\\rangle$.\n", "In this case, we should be able to read off the eigenvalue and phase from $U$ and verify QPE gives the right answer (with high probability) up to a small error (that depends on the number of qubits in the precision register)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## HELPER FUNCTIONS FOR NUMERICAL TESTS\n", "Because we will run the same code repeatedly, let's first create a helper function we can use to keep the notebook clean." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def postprocess_qpe_results(out):\n", " \"\"\"\n", " Function to postprocess dictionary returned by run_qpe\n", "\n", " Args:\n", " out: dictionary containing results/information associated with QPE run as produced by run_qpe\n", " \"\"\"\n", " \n", " # unpack results\n", " circ = out['circuit']\n", " measurement_counts = out['measurement_counts']\n", " bitstring_keys = out['bitstring_keys']\n", " probs_values = out['probs_values']\n", " precision_results_dic = out['precision_results_dic']\n", " phases_decimal = out['phases_decimal']\n", " eigenvalues = out['eigenvalues']\n", " \n", " # print the circuit \n", " print('Printing circuit:')\n", " print(circ)\n", " \n", " # print measurement results\n", " print('Measurement counts:', measurement_counts)\n", " \n", " # plot probabalities\n", " plt.bar(bitstring_keys, probs_values);\n", " plt.xlabel('bitstrings');\n", " plt.ylabel('probability');\n", " plt.xticks(rotation=90);\n", "\n", " # print results\n", " print('Results in precision register:', precision_results_dic)\n", " print('QPE phase estimates:', phases_decimal)\n", " print('QPE eigenvalue estimates:', np.round(eigenvalues, 5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### NUMERICAL TEST EXAMPLE 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, apply the QPE algorithm to the simple single-qubit unitary $U=X$, with eigenstate $|\\Psi\\rangle = |+\\rangle = H|0\\rangle$. Here, we expect to measure the phase $\\varphi=0$ (giving the corresponding eigenvalue $\\lambda=1$). \n", "We show that this result stays the same as we increase the number of qubits $n$ for the top register. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", " \n", "q0 : -H---U-SWAP---PHASE(-1.57)-H-Probability--\n", " | | | | \n", "q1 : -H-U-|-SWAP-H-C--------------Probability--\n", " | | | \n", "q2 : -H-U-U-----------------------Probability--\n", "\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", "Measurement counts: Counter({'000': 504, '001': 496})\n", "Results in precision register: {'00': 1000}\n", "QPE phase estimates: [0.0]\n", "QPE eigenvalue estimates: [1.+0.j]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits: 2\n", "number_precision_qubits = 2\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits]\n", "\n", "# State preparation for eigenstate of U=X\n", "query = Circuit().h(query_qubits)\n", "\n", "# Run the test with U=X\n", "out = run_qpe(X, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, check that we get the same result for a larger precision (top) register. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2|3| 4 |5| 6 | 7 | 8 |9|Result Types|\n", " \n", "q0 : -H-----U-SWAP------------------PHASE(-0.785)-PHASE(-1.57)-H-Probability--\n", " | | | | | \n", "q1 : -H---U-|-|------PHASE(-1.57)-H-|-------------C--------------Probability--\n", " | | | | | | \n", "q2 : -H-U-|-|-SWAP-H-C--------------C----------------------------Probability--\n", " | | | | \n", "q3 : -H-U-U-U----------------------------------------------------Probability--\n", "\n", "T : |0|1|2|3| 4 |5| 6 | 7 | 8 |9|Result Types|\n", "Measurement counts: Counter({'0000': 504, '0001': 496})\n", "Results in precision register: {'000': 1000}\n", "QPE phase estimates: [0.0]\n", "QPE eigenvalue estimates: [1.+0.j]\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEWCAYAAABrDZDcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAXw0lEQVR4nO3de7RkdXnm8e8DiBdEgtKioWmbiXghGm8t6lrxDrGJK0CijoAukeiQGWWUZbK0TUYyIklAE0dNMNrxRrwEiM4kHW0FTVDHccBuLorAtPSwUJok2sZLdIwX5J0/qg4W1XXOqTqn9jnV/L6ftWqd2pd691vY1lO192/vnapCktSufVa7AUnS6jIIJKlxBoEkNc4gkKTGGQSS1DiDQJIat99qNzCpQw45pNavX7/abUjSXuXKK6/8ZlWtGbVsrwuC9evXs3379tVuQ5L2Kkm+Ot8ydw1JUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxnUaBEk2JtmRZGeSTSOWvzjJ7iTX9B8v7bIfSdKeOjuPIMm+wPnAscAuYFuSLVV1/dCqF1XVGV31IUlaWJcnlB0N7KyqmwCSXAicAAwHwYpZv+ljy3r9zec+e0qdSNLs6HLX0GHALQPTu/rzhj0nyZeSfDjJ4R32I0kaYbUPFv8dsL6qfgn4JHDBqJWSnJ5ke5Ltu3fvXtEGJemurssguBUY/Ia/tj/vDlX1L1X1o/7ku4DHjSpUVZurakNVbVizZuQ1kyRJS9TlMYJtwJFJjqAXACcBpwyukOSBVfVP/cnjgRs67GfqlnPMweMNkmZFZ0FQVbclOQO4BNgXeE9VXZfkbGB7VW0BXpHkeOA24FvAi7vqR5I0WqeXoa6qrcDWoXlnDTx/LfDaLnuQJC1stQ8WS5JWmUEgSY0zCCSpcQaBJDXOIJCkxhkEktQ4g0CSGmcQSFLjDAJJapxBIEmNMwgkqXEGgSQ1ziCQpMYZBJLUOINAkhpnEEhS4wwCSWqcQSBJjTMIJKlxBoEkNc4gkKTGGQSS1DiDQJIaZxBIUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxhkEktQ4g0CSGmcQSFLjOg2CJBuT7EiyM8mmBdZ7TpJKsqHLfiRJe+osCJLsC5wPHAccBZyc5KgR6x0IvBK4oqteJEnz6/IXwdHAzqq6qap+DFwInDBivTcA5wE/7LAXSdI8ugyCw4BbBqZ39efdIcljgcOr6mMd9iFJWsCqHSxOsg/wZuC3x1j39CTbk2zfvXt3981JUkO6DIJbgcMHptf25805EHgE8OkkNwNPBLaMOmBcVZurakNVbVizZk2HLUtSe7oMgm3AkUmOSLI/cBKwZW5hVX23qg6pqvVVtR64HDi+qrZ32JMkaUhnQVBVtwFnAJcANwAXV9V1Sc5OcnxX25UkTWa/LotX1VZg69C8s+ZZ92ld9iJJGs0ziyWpcQaBJDXOIJCkxhkEktQ4g0CSGmcQSFLjDAJJapxBIEmNMwgkqXEGgSQ1ziCQpMYZBJLUOINAkhpnEEhS4wwCSWqcQSBJjTMIJKlxBoEkNc4gkKTGGQSS1DiDQJIaZxBIUuMMAklqnEEgSY0zCCSpcQaBJDVurCBI8t+TPDuJwSFJdzHjfrC/HTgFuDHJuUke2mFPkqQVNFYQVNWnquoFwGOBm4FPJfl8ktOS3K3LBiVJ3Rp7V0+S+wEvBl4KXA28lV4wfLKTziRJK2K/cVZK8j+AhwLvB36tqv6pv+iiJNu7ak6S1L2xggD4i6raOjgjyd2r6kdVtaGDviRJK2TcXUPnjJj3vxd7UZKNSXYk2Zlk04jl/zHJtUmuSfK5JEeN2Y8kaUoW/EWQ5AHAYcA9kzwGSH/RfYB7LfLafYHzgWOBXcC2JFuq6vqB1T5UVe/or3888GZg41LeiCRpaRbbNfQsegeI19L7kJ7zPeB3F3nt0cDOqroJIMmFwAnAHUFQVf86sP4BQI3VtSRpahYMgqq6ALggyXOq6iMT1j4MuGVgehfwhOGVkrwceBWwP/CMCbchSVqmxXYNvbCqPgCsT/Kq4eVV9eYRL5tIVZ0PnJ/kFOC/AKeO6ON04HSAdevWLXeTkqQBix0sPqD/997AgSMeC7kVOHxgem1/3nwuBE4ctaCqNlfVhqrasGbNmkU2K0maxGK7ht7Z//v6JdTeBhyZ5Ah6AXASvctU3CHJkVV1Y3/y2cCNSJJW1GK7ht620PKqesUCy25LcgZwCbAv8J6qui7J2cD2qtoCnJHkGOAnwLcZsVtIktStxUYNXbmc4v2T0LYOzTtr4Pkrl1NfkrR844wakiTdhS22a+gtVXVmkr9jxBj/qjq+s84kSStisV1D7+///eOuG5EkrY7Fdg1d2f/7mST7Aw+j98tgR1X9eAX6kyR1bNzLUD8beAfwf+ldb+iIJL9VVR/vsjlJUvfGvQz1nwBPr6qdAEl+AfgYYBBI0l5u3MtQf28uBPpuonfhOUnSXm6xUUO/0X+6PclW4GJ6xwieR+/MYUnSXm6xXUO/NvD868BT+893A/fspCNJ0opabNTQaSvViCRpdYw7augewEuAXwTuMTe/qn6zo74kSStk3IPF7wceQO+OZZ+hd0lpDxZL0l3AuEHw4Kp6HfD/+tcfejYj7jYmSdr7jBsEP+n//U6SRwAHAffvpiVJ0koa94SyzUkOBl4HbKF3x7LXddaVJGnFjBUEVfWu/tPPAP+uu3YkSSttrF1DSe6X5E+TXJXkyiRvSXK/rpuTJHVv3GMEFwLfAJ4DPBf4JnBRV01JklbOuMcIHlhVbxiYPifJ87toSJK0ssb9RXBpkpOS7NN//Ht6N6WXJO3lFrvo3PfoXWQuwJnAB/qL9gG+D/xOp91Jkjq32LWGDlypRiRJq2PcYwQkOR54Sn/y01X10W5akiStpHGHj54LvBK4vv94ZZI/6rIxSdLKGPcXwa8Cj66q2wGSXABcDby2q8YkSStj3FFDAD838PygaTciSVod4/4i+EPg6iSX0RtB9BRgU2ddSZJWzKJBkGQf4HbgicDj+7NfU1X/3GVjkqSVsWgQVNXtSV5dVRfTu/KoJOkuZNxjBJ9K8jtJDk9y37lHp51JklbEuMcInk/vDOOXDc33ktSStJcbNwiOohcCv0wvEP4n8I6umpIkrZxxdw1dADwceBvwp/SC4YLFXpRkY5IdSXYm2WOUUZJXJbk+yZeS/H2SB03SvCRp+cb9RfCIqjpqYPqyJNcv9IIk+wLnA8cCu4BtSbZU1eDrrgY2VNUPkvwn4I30dkNJklbIuL8IrkryxLmJJE8Ati/ymqOBnVV1U1X9mN7NbU4YXKGqLquqH/QnLwfWjtmPJGlKxv1F8Djg80m+1p9eB+xIci1QVfVLI15zGHDLwPQu4AkLbOMlwMfH7EeSNCXjBsHGLptI8kJgA/DUeZafDpwOsG7dui5bkaTmjBUEVfXVJdS+FTh8YHptf96dJDkG+D3gqVX1o3m2vxnYDLBhw4ZaQi+SpHlMctG5SW0DjkxyRJL9gZMYOjM5yWOAdwLHV9U3OuxFkjSPzoKgqm4DzqB3b+MbgIur6rokZ/dvcgPwJuDewF8nuSaJl7CQpBU29h3KlqKqtgJbh+adNfD8mC63L0laXJe7hiRJewGDQJIaZxBIUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxhkEktQ4g0CSGmcQSFLjDAJJapxBIEmNMwgkqXEGgSQ1ziCQpMYZBJLUOINAkhpnEEhS4wwCSWqcQSBJjTMIJKlxBoEkNc4gkKTGGQSS1DiDQJIaZxBIUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxhkEktS4ToMgycYkO5LsTLJpxPKnJLkqyW1JnttlL5Kk0ToLgiT7AucDxwFHAScnOWpota8BLwY+1FUfkqSF7ddh7aOBnVV1E0CSC4ETgOvnVqiqm/vLbu+wD0nSArrcNXQYcMvA9K7+vIklOT3J9iTbd+/ePZXmJEk9e8XB4qraXFUbqmrDmjVrVrsdSbpL6TIIbgUOH5he258nSZohXQbBNuDIJEck2R84CdjS4fYkSUvQWRBU1W3AGcAlwA3AxVV1XZKzkxwPkOTxSXYBzwPemeS6rvqRJI3W5aghqmorsHVo3lkDz7fR22UkSVole8XBYklSdwwCSWqcQSBJjTMIJKlxBoEkNc4gkKTGGQSS1DiDQJIaZxBIUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxhkEktQ4g0CSGmcQSFLjDAJJapxBIEmNMwgkqXEGgSQ1ziCQpMYZBJLUOINAkhpnEEhS4wwCSWqcQSBJjTMIJKlxBoEkNc4gkKTGGQSS1DiDQJIa12kQJNmYZEeSnUk2jVh+9yQX9ZdfkWR9l/1IkvbUWRAk2Rc4HzgOOAo4OclRQ6u9BPh2VT0Y+G/AeV31I0karctfBEcDO6vqpqr6MXAhcMLQOicAF/Sffxh4ZpJ02JMkach+HdY+DLhlYHoX8IT51qmq25J8F7gf8M3BlZKcDpzen/x+kh2ddAyHDG/7Tn1M9ntlmrUWrWetzuu1UGva9VqoNe160+5t0IPmW9BlEExNVW0GNne9nSTbq2rDrNWadr0Wak27Xgu1pl2vhVrTrjft3sbV5a6hW4HDB6bX9ueNXCfJfsBBwL902JMkaUiXQbANODLJEUn2B04CtgytswU4tf/8ucA/VFV12JMkaUhnu4b6+/zPAC4B9gXeU1XXJTkb2F5VW4B3A+9PshP4Fr2wWE3T3P007V1Zs9rbrNaadr0Wak27Xgu1pl2v813go8Qv4JLUNs8slqTGGQSS1DiDQJIaZxBIUuP2ihPKutK/nMXR9M5wht55DV+Y5hDWJA+rqv8z4WsOAjYO9XVJVX1nin0dW1WfXMLrZrK3JA+jd8mSwb62VNUNU+zrtKp677TqSbOi2VFDSX4FeDtwIz870W0t8GDgZVV16ZS287WqWjfB+i8Cfh+4dKivY4HXV9VfrkZfs9xbktcAJ9O7ntWugb5OAi6sqnNXo6+B181kePZfN5MBuhJ9LaO3ZwEnDvX2t1X1iSn2dVZVnT2teotur+EguAE4rqpuHpp/BLC1qh4+Qa23zbcIOLWq7jNBrR3AE4Y/JJIcDFxRVQ+ZoNbwCXyDfT2jqg4Yt9Ys95bkK8AvVtVPhubvD1xXVUdOUOtLC/T1kKq6+7i1+vVmMjz7r5nJAF2pvpbY21uAhwB/OdTbi4Abq+qVq9HXcrW8a2g/fvY/5KBbgbtNWOs04LeBH41YdvKEtQKMSufb+8sm8WTghcD3R2zj6Alrzb1uFnu7Hfh54KtD8x/YXzaJQ4FnAd8e0dfnJ6wF8HvA4+YLT3ofKGNZJDzvt4TeXsLoAH0zcB0w9gfuIgF66Gr11UFvvzrqC0+Si4CvAGMHQZJ/XaCve07Y17K0HATvAbYluZCfXSX1cHrfOt49Ya1twJerao8PiiT/dcJafwBcleTSgb7W0fsG+YYJa10O/KCqPjOir6VcwXVWezsT+PskNw719WDgjAlrfRS4d1VdM6KvT09YC2Y3POd6mMUAnWZf0+7th0keX1XbhuY/HvjhhLW+Azy+qr4+vCDJLSPW70yzu4YA+jfKOZ4990NeP2Gd+wI/rKofTKmvg+n9wx3epzz8D3nFzWpvSfZhzwP/26rqp6vXFSQ5FTiL3q6hPcKzqt43Qa2PA2+sqstGLPtsVT1lwt42An9G7zjZHgE6yT7vJO8G3ltVnxux7ENVdcpq9NVBb48F/hw4kJ/tUTgc+C7w8qq6coJa59D7vPnCiGXnVdVrxq21XE0HwZz+BzlV9a1ZqjWrkhzKwAfuqG80q1Frnvr3rqrhb9ArWmtWwxNmOkBnsq85SR7Anf/d/vNq9rNczQZBknXAG4Fn0EvzAPcB/gHYNHwQecxaz6T3c2/JtRbZzrVV9cjVqpXk0cA76F0ufBe997mW3nt+WVVdNUGtx9D7ZnUQdz6IOnGtRbYztYNuy6m1N4VnfxurGqDTHto9q0PFV6LWOFo+RnAR8BbgBXPfMtK7z/Lz6I1WeOJq1EryG/MtAh4wQU9TrdX3PuC3quqKoe08EXgv8KgJar13WrWSvGq+RcC9J+hpqrX69UaGZ5KphedSao3henq7Y1a81kJDu5NMPLR72vUWcCnT+282zVqLajkIDqmqiwZn9D/EL0wy6YHPada6CPggow8w3mMVawEcMPzBDVBVlyeZaCjqlGv9IfAm4LYRyyY9e36atWBGw7P/ulkN0LcCx8w3tBsYe2j3tOstMlT85yZpapq1lqvlILgyyduBC7jzqKFTgatXsdaXgD+uqi8PL0hyzCrWAvh4ko/RG/I4+D5fBEx6Ms00a10F/M2oA3VJXrqKtWB2wxNmN0CnObR72vWmOVR8mrWWpeUgeBG98cqvZ2jUEJMPH51mrTOB+cYX//oq1qKqXpHkOPY84/P8qtq6WrXo/R9qvlucTnr/12nWgtkNT5jdAJ3m0O5p15vmUPFp1lqWZg8WSytlnsDbsoTAm3athwLfqqrdI5YdOslB6GnW6r/m4Yx+nxMN7Z52vWkOFZ/2sPNl9dJqECTZj963+D2uGQK8e/isxlWo9ev0TqqZiVpjbGtzVZ1uLWnv03IQ/BW9oYoXcOdrhpwK3Leqnm+tPerdd75FwBeraq219qh3EPBaet9GD6V34P4b9ML43OFLT6xUraF6JwL3n1Jvy661yHY+XlXHTaPWtOvNaq1xtHyM4HG15zVDdgGXp3cRM2vtaTe90/4HL41Q/en7W2uki+mdT/L0uZOO+icjvbi/7FdWqdZgvacN1Tt1Gb0tu1b/7N2Ri4BHT9DT1OvNaq3lajkIvpXkecBHqup2uONsxuex5zVJrNVzE/DMqvra8IJMfm2UFmoBrK+q8wZn9D8oz01y2irWWqjeeUl+cxVrbQM+w53DeM5ShlVOs96s1lqeqmryAaynN87+G/SuGviV/vOLgCOsNbLey4FHzbPsP1tr5GsuBV4NHDow71DgNcCnVqvWLPcGfBk4cp5ltyzhfU6t3qzWWu6j2WMEMO9Igr+tJdz8ooVa/XpTu2FII7UOBjb1683tWvo6vaHF59YE1xuaZq1Z7i3Jc4Frq2qPq9AmObGq/mbcWtOuN6u1lqvZexand/OLD9Hb/3tF/wHwV0k2WWtkvVfTu2RGgC/0H1lib3f5WgBV9e2qek1VPayq7tt/PLx6V5Y8cbVqzXJvVfXhUR+OfQdPUmva9Wa11rKt5M+PWXrQ201ytxHz96d3pyFr7SW9zWqtMbb1tVmsNcu9+T67ebR8sHiaN79oodYs9zartcgU7441zVrTrjertaZdb1ZrLVfLQTDNu1q1UGuWe5vVWjDdu2NN+zaas9qb73Np73PJmg2CqvpEkocwhZtftFBrlnub1Vp907z15bRvozmrvfk+l/Y+l6zpUUOSpIZHDUmSegwCSWqcQaDmJFmfZNTNet6V5Kj+898do86ZSe61wPI76kmzzGMEak6S9cBHq+oRC6zz/apa8BaLSW4GNlTVN0cs23eJB5elFecvArVqvyQfTHJDkg8nuVeSTyfZkORc4J5Jrumvc0CSjyX5YpIvJ3l+klfQO9/gsiSXQS88kvxJki8CT5qrN7DsD/o1Lk9yaH/+L/Snr01yTpLv9+c/MMln+z18OcmTV+c/k1pgEKhVDwXeXlUPp3c7z5fNLaiqTcC/VdWjq+oFwEbgH6vqUf1fEZ+oqrcB/0jvktBP77/0AOCK/nqfG9reAcDlVfUo4LPAf+jPfyvw1qp6JHe+r+4pwCVV9Wh6N6XfY4ihNC0GgVp1S1X9r/7zDwC/vMC61wLHJjkvyZOr6rvzrPdT4CPzLPsxvXHjAFfSuzIswJOAv+4//9DA+tuA09K7d+0jq+p7C/QnLYtBoFYNHxyb92BZVX0FeCy9QDgnyVnzrPrDBY4L/KR+dkDupyxyMmdVfRZ4Cr2T2d6X5EULrS8th0GgVq1L8qT+81OA4V05P0lyN4AkPw/8oKo+ALyJXigAfA84cJl9XA48p//8pLmZSR4EfL2q/gJ418A2pakzCNSqHcDLk9xA75K/fz60fDPwpSQfBB4JfCHJNcDvA+cMrPOJuYPFS3Qm8Kr+BcgeDMztdnoa8MUkVwPPp3csQeqEw0elVdQ/D+HfqqqSnAScXFUnrHZfakuzF52TZsTjgD9LEuA7wKT395WWzV8EktQ4jxFIUuMMAklqnEEgSY0zCCSpcQaBJDXOIJCkxv1/ld9w/GlRytgAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits: 3\n", "number_precision_qubits = 3\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits]\n", "\n", "# State preparation for eigenstate of U=X\n", "query = Circuit().h(query_qubits)\n", "\n", "# Run the test with U=X\n", "out = run_qpe(X, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### NUMERICAL TEST EXAMPLE 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, apply the QPE algorithm to the simple single-qubit unitary $U=X$, with eigenstate $|\\Psi\\rangle = |-\\rangle = HX|0\\rangle$. \n", "Here, we expect to measure the phase $\\varphi=0.5$ (giving the corresponding eigenvalue $\\lambda=-1$). " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2|3| 4 |5| 6 |7|Result Types|\n", " \n", "q0 : -H-----U-SWAP---PHASE(-1.57)-H-Probability--\n", " | | | | \n", "q1 : -H---U-|-SWAP-H-C--------------Probability--\n", " | | | \n", "q2 : -X-H-U-U-----------------------Probability--\n", "\n", "T : |0|1|2|3| 4 |5| 6 |7|Result Types|\n", "Measurement counts: Counter({'100': 516, '101': 484})\n", "Results in precision register: {'10': 1000}\n", "QPE phase estimates: [0.5]\n", "QPE eigenvalue estimates: [-1.+0.j]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits: 2\n", "number_precision_qubits = 2\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits]\n", "\n", "# State preparation for eigenstate of U=X\n", "query = Circuit().x(query_qubits).h(query_qubits)\n", "\n", "# Run the test with U=X\n", "out = run_qpe(X, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### NUMERICAL TEST EXAMPLE 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, apply the QPE algorithm again to the simple single-qubit unitary $U=X$, but we initialize the query register in the state $|\\Psi\\rangle = |1\\rangle$ which is *not* an eigenstate of $U$. \n", "Here, following the previous discussion, we expect to measure the phases $\\varphi=0, 0.5$ (giving the corresponding eigenvalue $\\lambda=\\pm 1$). Accordingly, here we set ```items_to_keep=2```. " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", " \n", "q0 : -H---U-SWAP---PHASE(-1.57)-H-Probability--\n", " | | | | \n", "q1 : -H-U-|-SWAP-H-C--------------Probability--\n", " | | | \n", "q2 : -X-U-U-----------------------Probability--\n", "\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", "Measurement counts: Counter({'000': 261, '100': 256, '101': 242, '001': 241})\n", "Results in precision register: {'10': 498, '00': 502}\n", "QPE phase estimates: [0.0, 0.5]\n", "QPE eigenvalue estimates: [ 1.+0.j -1.+0.j]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits: 2\n", "number_precision_qubits = 2\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits]\n", "\n", "# State preparation for |1>, which is not an eigenstate of U=X\n", "query = Circuit().x(query_qubits)\n", "\n", "# Run the test with U=X\n", "out = run_qpe(X, precision_qubits, query_qubits, query, device, items_to_keep=2)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### NUMERICAL TEST EXAMPLE 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, apply the QPE algorithm to the two-qubit unitary $U=X \\otimes Z$, and prepare the query register in the eigenstate $|\\Psi\\rangle = |+\\rangle \\otimes |1\\rangle = H|0\\rangle \\otimes X|0\\rangle$. \n", "Here, we expect to measure the phase $\\varphi=0.5$ (giving the corresponding eigenvalue $\\lambda=-1$). " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Two-qubit unitary (XZ):\n", " [[ 0. 0. 1. 0.]\n", " [ 0. 0. 0. -1.]\n", " [ 1. 0. 0. 0.]\n", " [ 0. -1. 0. 0.]]\n", "Eigenvalues: [ 1. -1. 1. -1.]\n" ] } ], "source": [ "# set unitary matrix U\n", "u1 = np.kron(X, Id) \n", "u2 = np.kron(Id, Z)\n", "unitary = np.dot(u1, u2)\n", "print('Two-qubit unitary (XZ):\\n', unitary)\n", "\n", "# get example eigensystem \n", "eig_values, eig_vectors = np.linalg.eig(unitary)\n", "print('Eigenvalues:', eig_values)\n", "# print('Eigenvectors:', eig_vectors)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", " \n", "q0 : -H---U-SWAP---PHASE(-1.57)-H-Probability--\n", " | | | | \n", "q1 : -H-U-|-SWAP-H-C--------------Probability--\n", " | | | \n", "q2 : -H-U-U-----------------------Probability--\n", " | | | \n", "q3 : -X-U-U-----------------------Probability--\n", "\n", "T : |0|1|2| 3 |4| 5 |6|Result Types|\n", "Measurement counts: Counter({'1011': 503, '1001': 497})\n", "Results in precision register: {'10': 1000}\n", "QPE phase estimates: [0.5]\n", "QPE eigenvalue estimates: [-1.+0.j]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits: 2\n", "number_precision_qubits = 2\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits, number_precision_qubits+1]\n", "\n", "# State preparation for eigenstate |+,1> of U=X \\otimes Z\n", "query = Circuit().h(query_qubits[0]).x(query_qubits[1])\n", "\n", "# Run the test with U=X\n", "out = run_qpe(unitary, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### NUMERICAL TEST EXAMPLE 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this example, we choose the unitary to be a _random_ two-qubit unitary, diagonal in the computational basis. We initialize the query register to be in the eigenstate $|11\\rangle$ of $U$, which we can prepare using that $|11\\rangle = X\\otimes X|00\\rangle$.\n", "In this case we should be able to read off the eigenvalue and phase from $U$ and verify that QPE gives the right answer." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Two-qubit random unitary:\n", " [[-0.078+0.997j 0. +0.j 0. +0.j 0. +0.j ]\n", " [ 0. +0.j -0.987-0.159j 0. +0.j 0. +0.j ]\n", " [ 0. +0.j 0. +0.j 0.192-0.981j 0. +0.j ]\n", " [ 0. +0.j 0. +0.j 0. +0.j 0.747-0.665j]]\n", "Check for unitarity: True\n", "Eigenvalues: [-0.078+0.997j -0.987-0.159j 0.192-0.981j 0.747-0.665j]\n" ] } ], "source": [ "# Generate a random 2 qubit unitary matrix:\n", "from scipy.stats import unitary_group\n", "\n", "# Fix random seed for reproducibility\n", "np.random.seed(seed=42)\n", "\n", "# Get random two-qubit unitary\n", "random_unitary = unitary_group.rvs(2**2)\n", "\n", "# Let's diagonalize this\n", "evals = np.linalg.eig(random_unitary)[0]\n", "\n", "# Since we want to be able to read off the eigenvalues of the unitary in question\n", "# let's choose our unitary to be diagonal in this basis\n", "unitary = np.diag(evals)\n", "\n", "# Check that this is indeed unitary, and print it out:\n", "print('Two-qubit random unitary:\\n', np.round(unitary, 3))\n", "print('Check for unitarity: ', np.allclose(np.eye(len(unitary)), unitary.dot(unitary.T.conj())))\n", "\n", "# Print eigenvalues\n", "print('Eigenvalues:', np.round(evals, 3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When we execute the QPE circuit, we expect the following (approximate) result for the eigenvalue estimate: " ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Target eigenvalue: (0.747-0.665j)\n" ] } ], "source": [ "print('Target eigenvalue:', np.round(evals[-1], 3))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Printing circuit:\n", "T : |0|1|2|3| 4 |5| 6 | 7 | 8 |9|Result Types|\n", " \n", "q0 : -H-----U-SWAP------------------PHASE(-0.785)-PHASE(-1.57)-H-Probability--\n", " | | | | | \n", "q1 : -H---U-|-|------PHASE(-1.57)-H-|-------------C--------------Probability--\n", " | | | | | | \n", "q2 : -H-U-|-|-SWAP-H-C--------------C----------------------------Probability--\n", " | | | | \n", "q3 : -X-U-U-U----------------------------------------------------Probability--\n", " | | | | \n", "q4 : -X-U-U-U----------------------------------------------------Probability--\n", "\n", "T : |0|1|2|3| 4 |5| 6 | 7 | 8 |9|Result Types|\n", "Measurement counts: Counter({'11111': 986, '11011': 8, '00011': 3, '01011': 1, '10011': 1, '10111': 1})\n", "Results in precision register: {'100': 1, '101': 1, '111': 986, '000': 3, '010': 1, '110': 8}\n", "QPE phase estimates: [0.875]\n", "QPE eigenvalue estimates: [0.70711-0.70711j]\n", "Target eigenvalue: (0.747-0.665j)\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Set total number of precision qubits\n", "number_precision_qubits = 3\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits, number_precision_qubits+1]\n", "\n", "# State preparation for eigenstate |1,1> of diagonal U\n", "query = Circuit().x(query_qubits[0]).x(query_qubits[1])\n", "\n", "# Run the test with U=X\n", "out = run_qpe(unitary, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "postprocess_qpe_results(out)\n", "\n", "# compare output to exact target values\n", "print('Target eigenvalue:', np.round(evals[-1], 3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can easily improve the precision of our parameter estimate by increasing the number of qubits in the precision register, as shown in the following example. " ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "QPE eigenvalue estimates: [0.74506-0.667j]\n", "Target eigenvalue: (0.74699-0.66484j)\n" ] } ], "source": [ "# Set total number of precision qubits\n", "number_precision_qubits = 10\n", "\n", "# Define the set of precision qubits\n", "precision_qubits = range(number_precision_qubits)\n", "\n", "# Define the query qubits. We'll have them start after the precision qubits\n", "query_qubits = [number_precision_qubits, number_precision_qubits+1]\n", "\n", "# State preparation for eigenstate |1,1> of diagonal U\n", "query = Circuit().x(query_qubits[0]).x(query_qubits[1])\n", "\n", "# Run the test with U=X\n", "out = run_qpe(unitary, precision_qubits, query_qubits, query, device)\n", "\n", "# Postprocess results\n", "eigenvalues = out['eigenvalues']\n", "print('QPE eigenvalue estimates:', np.round(eigenvalues, 5))\n", "\n", "# compare output to exact target values\n", "print('Target eigenvalue:', np.round(evals[-1], 5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## APPENDIX" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Version: 0.6.0\r\n" ] } ], "source": [ "# Check SDK version\n", "# alternative: braket.__version__\n", "!pip show amazon-braket-sdk | grep Version" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Details of the ```utiles_qpe.py``` module" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Imports, including inverse QFT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# general imports\n", "import numpy as np\n", "import math\n", "from collections import Counter\n", "from datetime import datetime\n", "import pickle\n", "\n", "# AWS imports: Import Braket SDK modules\n", "from braket.circuits import Circuit, circuit\n", "\n", "# local imports\n", "from utils_qft import inverse_qft\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### QPE Subroutine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "@circuit.subroutine(register=True)\n", "def controlled_unitary(control, target_qubits, unitary):\n", " \"\"\"\n", " Construct a circuit object corresponding to the controlled unitary\n", "\n", " Args:\n", " control: The qubit on which to control the gate\n", "\n", " target_qubits: List of qubits on which the unitary U acts\n", "\n", " unitary: matrix representation of the unitary we wish to implement in a controlled way\n", " \"\"\"\n", "\n", " # Define projectors onto the computational basis\n", " p0 = np.array([[1., 0.],\n", " [0., 0.]])\n", "\n", " p1 = np.array([[0., 0.],\n", " [0., 1.]])\n", "\n", " # Instantiate circuit object\n", " circ = Circuit()\n", "\n", " # Construct numpy matrix\n", " id_matrix = np.eye(len(unitary))\n", " controlled_matrix = np.kron(p0, id_matrix) + np.kron(p1, unitary)\n", "\n", " # Set all target qubits\n", " targets = [control] + target_qubits\n", "\n", " # Add controlled unitary\n", " circ.unitary(matrix=controlled_matrix, targets=targets)\n", "\n", " return circ\n", "\n", "\n", "@circuit.subroutine(register=True)\n", "def qpe(precision_qubits, query_qubits, unitary, control_unitary=True):\n", " \"\"\"\n", " Function to implement the QPE algorithm using two registers for precision (read-out) and query.\n", " Register qubits need not be contiguous.\n", "\n", " Args:\n", " precision_qubits: list of qubits defining the precision register\n", "\n", " query_qubits: list of qubits defining the query register\n", "\n", " unitary: Matrix representation of the unitary whose eigenvalues we wish to estimate\n", "\n", " control_unitary: Optional boolean flag for controlled unitaries,\n", " with C-(U^{2^k}) by default (default is True),\n", " or C-U controlled-unitary (2**power) times\n", " \"\"\"\n", " qpe_circ = Circuit()\n", "\n", " # Get number of qubits\n", " num_precision_qubits = len(precision_qubits)\n", " num_query_qubits = len(query_qubits)\n", "\n", " # Apply Hadamard across precision register\n", " qpe_circ.h(precision_qubits)\n", "\n", " # Apply controlled unitaries. Start with the last precision_qubit, and end with the first\n", " for ii, qubit in enumerate(reversed(precision_qubits)):\n", " # Set power exponent for unitary\n", " power = ii\n", "\n", " # Alterantive 1: Implement C-(U^{2^k})\n", " if control_unitary:\n", " # Define the matrix U^{2^k}\n", " Uexp = np.linalg.matrix_power(unitary,2**power)\n", "\n", " # Apply the controlled unitary C-(U^{2^k})\n", " qpe_circ.controlled_unitary(qubit, query_qubits, Uexp)\n", " # Alterantive 2: One can instead apply controlled-unitary (2**power) times to get C-U^{2^power}\n", " else:\n", " for _ in range(2**power):\n", " qpe_circ.controlled_unitary(qubit, query_qubits, unitary)\n", "\n", " # Apply inverse qft to the precision_qubits\n", " qpe_circ.inverse_qft(precision_qubits)\n", "\n", " return qpe_circ\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### QPE postprocessing helper functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "# helper function to remove query bits from bitstrings\n", "def substring(key, precision_qubits):\n", " \"\"\"\n", " Helper function to get substring from keys for dedicated string positions as given by precision_qubits.\n", " This function is necessary to allow for arbitrary qubit mappings in the precision and query registers\n", " (that is, so that the register qubits need not be contiguous.)\n", "\n", " Args:\n", " key: string from which we want to extract the substring supported only on the precision qubits\n", "\n", " precision_qubits: List of qubits corresponding to precision_qubits.\n", " Currently assumed to be a list of integers corresponding to the indices of the qubits\n", " \"\"\"\n", " short_key = ''\n", " for idx in precision_qubits:\n", " short_key = short_key + key[idx]\n", "\n", " return short_key\n", "\n", "\n", "# helper function to convert binary fractional to decimal\n", "# reference: https://www.geeksforgeeks.org/convert-binary-fraction-decimal/\n", "def binaryToDecimal(binary):\n", " \"\"\"\n", " Helper function to convert binary string (example: '01001') to decimal\n", "\n", " Args:\n", " binary: string which to convert to decimal fraction\n", " \"\"\"\n", "\n", " length = len(binary)\n", " fracDecimal = 0\n", "\n", " # Convert fractional part of binary to decimal equivalent\n", " twos = 2\n", "\n", " for ii in range(length):\n", " fracDecimal += ((ord(binary[ii]) - ord('0')) / twos);\n", " twos *= 2.0\n", "\n", " # return fractional part\n", " return fracDecimal\n", "\n", "\n", "# helper function for postprocessing based on measurement shots\n", "def get_qpe_phases(measurement_counts, precision_qubits, items_to_keep=1):\n", " \"\"\"\n", " Get QPE phase estimate from measurement_counts for given number of precision qubits\n", "\n", " Args:\n", " measurement_counts: measurement results from a device run\n", "\n", " precision_qubits: List of qubits corresponding to precision_qubits.\n", " Currently assumed to be a list of integers corresponding to the indices of the qubits\n", "\n", " items_to_keep: number of items to return (topmost measurement counts for precision register)\n", " \"\"\"\n", "\n", " # Aggregate the results (that is, ignore the query register qubits):\n", "\n", " # First get bitstrings with corresponding counts for precision qubits only\n", " bitstrings_precision_register = [substring(key, precision_qubits) for key in measurement_counts.keys()]\n", " # Then keep only the unique strings\n", " bitstrings_precision_register_set = set(bitstrings_precision_register)\n", " # Cast as a list for later use\n", " bitstrings_precision_register_list = list(bitstrings_precision_register_set)\n", "\n", " # Now create a new dict to collect measurement results on the precision_qubits.\n", " # Keys are given by the measurement count substrings on the register qubits. Initialize the counts to zero.\n", " precision_results_dic = {key: 0 for key in bitstrings_precision_register_list}\n", "\n", " # Loop over all measurement outcomes\n", " for key in measurement_counts.keys():\n", " # Save the measurement count for this outcome\n", " counts = measurement_counts[key]\n", " # Generate the corresponding shortened key (supported only on the precision_qubits register)\n", " count_key = substring(key, precision_qubits)\n", " # Add these measurement counts to the corresponding key in our new dict\n", " precision_results_dic[count_key] += counts\n", "\n", " # Get topmost values only\n", " c = Counter(precision_results_dic)\n", " topmost= c.most_common(items_to_keep)\n", " # get decimal phases from bitstrings for topmost bitstrings\n", " phases_decimal = [binaryToDecimal(item[0]) for item in topmost]\n", "\n", " # Get decimal phases from bitstrings for all bitstrings\n", " # number_precision_qubits = len(precision_qubits)\n", " # Generate binary decimal expansion\n", " # phases_decimal = [int(key, 2)/(2**number_precision_qubits) for key in precision_results_dic]\n", " # phases_decimal = [binaryToDecimal(key) for key in precision_results_dic]\n", "\n", " return phases_decimal, precision_results_dic\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Run QPE experiments:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "def run_qpe(unitary, precision_qubits, query_qubits, query_circuit,\n", " device, items_to_keep=1, shots=1000, save_to_pck=False):\n", " \"\"\"\n", " Function to run QPE algorithm end-to-end and return measurement counts.\n", "\n", " Args:\n", " precision_qubits: list of qubits defining the precision register\n", "\n", " query_qubits: list of qubits defining the query register\n", "\n", " unitary: Matrix representation of the unitary whose eigenvalues we wish to estimate\n", "\n", " query_circuit: query circuit for state preparation of query register\n", "\n", " items_to_keep: (optional) number of items to return (topmost measurement counts for precision register)\n", "\n", " device: Braket device backend\n", "\n", " shots: (optional) number of measurement shots (default is 1000)\n", "\n", " save_to_pck: (optional) save results to pickle file if True (default is False)\n", " \"\"\"\n", "\n", " # get size of precision register and total number of qubits\n", " number_precision_qubits = len(precision_qubits)\n", " num_qubits = len(precision_qubits) + len(query_qubits)\n", "\n", " # Define the circuit. Start by copying the query_circuit, then add the QPE:\n", " circ = query_circuit\n", " circ.qpe(precision_qubits, query_qubits, unitary)\n", "\n", " # Add desired results_types\n", " circ.probability()\n", "\n", " # Run the circuit with all zeros input.\n", " # The query_circuit subcircuit generates the desired input from all zeros.\n", " # The following code executes the correct device.run call, depending on whether the backend is local or on-demand\n", " task = device.run(circ, shots=shots)\n", "\n", " # get result for this task\n", " result = task.result()\n", "\n", " # get metadata\n", " metadata = result.task_metadata\n", "\n", " # get output probabilities (see result_types above)\n", " probs_values = result.values[0]\n", "\n", " # get measurement results\n", " measurements = result.measurements\n", " measured_qubits = result.measured_qubits\n", " measurement_counts = result.measurement_counts\n", " measurement_probabilities = result.measurement_probabilities\n", "\n", " # bitstrings\n", " format_bitstring = '{0:0' + str(num_qubits) + 'b}'\n", " bitstring_keys = [format_bitstring.format(ii) for ii in range(2**num_qubits)]\n", "\n", " # QPE postprocessing\n", " phases_decimal, precision_results_dic = get_qpe_phases(measurement_counts, precision_qubits, items_to_keep)\n", " eigenvalues = [np.exp(2*np.pi*1j*phase) for phase in phases_decimal]\n", "\n", " # aggregate results\n", " out = {'circuit': circ,\n", " 'task_metadata': metadata,\n", " 'measurements': measurements,\n", " 'measured_qubits': measured_qubits,\n", " 'measurement_counts': measurement_counts,\n", " 'measurement_probabilities': measurement_probabilities,\n", " 'probs_values': probs_values,\n", " 'bitstring_keys': bitstring_keys,\n", " 'precision_results_dic': precision_results_dic,\n", " 'phases_decimal': phases_decimal,\n", " 'eigenvalues': eigenvalues}\n", "\n", " if save_to_pck:\n", " # store results: dump output to pickle with timestamp in filename\n", " time_now = datetime.strftime(datetime.now(), '%Y%m%d%H%M%S')\n", " results_file = 'results-'+time_now+'.pck'\n", " pickle.dump(out, open(results_file, \"wb\"))\n", " # you can load results as follows\n", " # out = pickle.load(open(results_file, \"rb\"))\n", "\n", " return out\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## REFERENCES\n", "\n", "[1] Wikipedia: https://en.wikipedia.org/wiki/Quantum_phase_estimation_algorithm\n", "\n", "[2] Nielsen, Michael A., Chuang, Isaac L. (2010). Quantum Computation and Quantum Information (2nd ed.). Cambridge: Cambridge University Press." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Task Summary\n", "{}\n", "Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).\n", "Estimated cost to run this example: 0.00 USD\n" ] } ], "source": [ "print(\"Task Summary\")\n", "print(t.quantum_tasks_statistics())\n", "print('Note: Charges shown are estimates based on your Amazon Braket simulator and quantum processing unit (QPU) task usage. Estimated charges shown may differ from your actual charges. Estimated charges do not factor in any discounts or credits, and you may experience additional charges based on your use of other services such as Amazon Elastic Compute Cloud (Amazon EC2).')\n", "print(f\"Estimated cost to run this example: {t.qpu_tasks_cost() + t.simulator_tasks_cost():.2f} USD\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.10 ('venv': venv)", "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.8.10" }, "vscode": { "interpreter": { "hash": "590fab68195cf107911461461f81d5c472d3d6127f579badfcfad30f03e5cab2" } } }, "nbformat": 4, "nbformat_minor": 4 }