diff --git a/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb b/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb index 290d8813..ba4bd546 100644 --- a/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb +++ b/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb @@ -11,27 +11,29 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Phase kickback [[1](#childs),[2](#LinLin),[3](#Wolf)] is an important and highly used primitive in quantum computing. It deals with kicking the result of a function to the phase of a quantum state so it can be smartly manipulated with constructive and destructive interferences to achieve the desired result. Every quantum algortihm can be decomposed into these steps: 1) Encoding the data; 2) Manipulating the data; and 3) Extracting the result. The phase kickback primitive is a key step in the manipulation of the data that enables extracting the result. See the [Deutsch-Jozsa](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb) and [Simon's](https://github.com/Classiq/classiq-library/blob/main/algorithms/simon/simon.ipynb) algorithms for concrete examples.\n", + "Phase kickback [[1](#childs),[2](#LinLin),[3](#Wolf)] is an important and highly used primitive in quantum computing. The algorithm deals with \"kicking\" the result of a function to the phase of a quantum state so it can be wisely manipulated with interferences to achieve the desired result. Every quantum algorithm can be decomposed into these steps: 1) Encoding the data, 2) Manipulating the data, and 3) Extracting the result. The phase kickback primitive is a key step in manipulating the data, enabling the extraction of the result. See the [Deutsch-Jozsa](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb) and [Simon's](https://github.com/Classiq/classiq-library/blob/main/algorithms/simon/simon.ipynb) algorithms for concrete examples.\n", "\n", - "The standard way [[4](#NielsenChuang)] to apply a classical function $f:\\{0,1\\}^n \\rightarrow \\{0,1\\}$ on quantum states is with the oracle model: \n", - "$\\begin{equation}\n", + "The standard way [[4](#NielsenChuang)] of applying a classical function $f:\\{0,1\\}^n \\rightarrow \\{0,1\\}$ on quantum states is by utilizing the oracle model \n", + "$$\n", "O_f (|x \\rangle_n|y \\rangle_1) = |x \\rangle_n|y \\oplus f(x) \\rangle_1\n", - "\\end{equation}$\n", - "with $|x \\rangle$ and $|y \\rangle$ as the argument and target quantum states, respectively, and $\\oplus$ as the addition modolu $2$ or the XOR operation. The phase kickback primitive takes the oracle $O_f$ as input, and performs this operation:\n", + "$$\n", + "where $|x \\rangle$ and $|y \\rangle$ are the argument and target quantum states, respectively, and $\\oplus$ is the addition modulo $2$ or the XOR operation. \n", + "\n", + "The phase kickback primitive takes the oracle $O_f$ as input, and performs the operation\n", "$\\begin{equation}\n", "|x \\rangle\\rightarrow (-1)^{f(x)}|x \\rangle\n", - "\\end{equation}$\n", - "This can be applied on a superposition of state:\n", + "\\end{equation}$. \n", + "This can be applied to a superposition of states \n", "$\\begin{equation}\n", "\\sum_{i=0}^{2^n-1}\\alpha_i|x_i \\rangle\\rightarrow (-1)^{f(x_i)}\\alpha_i|x_i \\rangle\n", "\\end{equation}$\n", - "with $\\alpha_i$ as the amplitude of the $|x_i \\rangle$ state.\n", + "as well, where $\\alpha_i$ are the amplitudes of the $|x_i \\rangle$ state. \n", "\n", - "How does this happen? Its beauty lies in its simplicity: applying the oracle $O_f$ to the state target quantum state $|- \\rangle=\\frac{1}{\\sqrt{2}}|0 \\rangle-\\frac{1}{\\sqrt{2}}|1 \\rangle$:\n", - "$\\begin{equation}\n", + "The operation is achieved by simply applying the oracle $O_f$ to the state target quantum state $|- \\rangle=\\frac{1}{\\sqrt{2}}|0 \\rangle-\\frac{1}{\\sqrt{2}}|1 \\rangle$:\n", + "$$\n", "O_f|x \\rangle |- \\rangle = (-1)^{f(x)}|x \\rangle |- \\rangle\n", - "\\end{equation}$\n", - "then effectively achieving the desired transformation $|x \\rangle\\rightarrow (-1)^{f(x)}|x \\rangle$. " + "$$\n", + "and then arriving at the desired transformation $|x \\rangle\\rightarrow (-1)^{f(x)}|x \\rangle$. " ] }, { @@ -39,7 +41,7 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Phase\n", "
" ] }, @@ -76,7 +78,7 @@ "\\end{equation}$\n", "\n", "This useful trick is not the same as the Phase Kickback described in the literature [[1](#childs),[2](#LinLin),[3](#Wolf)]\n", - "." + "" ] }, { @@ -90,7 +92,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "When using the Classiq system (as for any development platform), it is recommended to design your code at the functional level in terms of functions. The above figure indicates which functional building blocks you need, so you can now implement them, one function at a time, and then connect them." + "When using the Classiq platform (as for any development platform), it is recommended to design your code at the functional level in terms of functions. The above figure indicates which functional building blocks you need, so you can now implement them, one function at a time, and then connect them." ] }, { @@ -105,24 +107,17 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Prepare\n", "
" ] }, { "cell_type": "code", - "execution_count": 1, - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T13:28:40.509980Z", - "iopub.status.busy": "2024-05-07T13:28:40.509504Z", - "iopub.status.idle": "2024-05-07T13:28:43.317981Z", - "shell.execute_reply": "2024-05-07T13:28:43.317192Z" - } - }, + "execution_count": 4, + "metadata": {}, "outputs": [], "source": [ - "from classiq import H, Output, QBit, X, allocate, qfunc\n", + "from classiq import *\n", "\n", "\n", "@qfunc\n", @@ -147,7 +142,7 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Oracle\n", "
" ] }, @@ -160,20 +155,10 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T13:28:43.324621Z", - "iopub.status.busy": "2024-05-07T13:28:43.323957Z", - "iopub.status.idle": "2024-05-07T13:28:43.327908Z", - "shell.execute_reply": "2024-05-07T13:28:43.327270Z" - } - }, + "execution_count": 5, + "metadata": {}, "outputs": [], "source": [ - "from classiq import QNum\n", - "\n", - "\n", "@qfunc\n", "def oracle_function(target: QBit, x: QNum):\n", " target ^= x == 0" @@ -191,26 +176,16 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"compute\n", "
" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T13:28:43.332422Z", - "iopub.status.busy": "2024-05-07T13:28:43.331903Z", - "iopub.status.idle": "2024-05-07T13:28:43.341870Z", - "shell.execute_reply": "2024-05-07T13:28:43.341160Z" - } - }, + "execution_count": 6, + "metadata": {}, "outputs": [], "source": [ - "from classiq import within_apply\n", - "\n", - "\n", "@qfunc\n", "def oracle_phase_kickback(x: QNum):\n", " target = QBit(\"target\")\n", @@ -254,7 +229,7 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Hadamard\n", "
" ] }, @@ -263,7 +238,7 @@ "metadata": {}, "source": [ "\n", - "Therefore, the phase kickback primitive is constructed of this:\n", + "Therefore, the phase kickback primitive is constructed by the following steps:\n", "\n", "1. Initializing the `qnum` type with $4$ qubits using the `allocate` function such that $| x \\rangle=|0\\rangle$.\n", "2. Applying the Hadamard transform using the `hadamard_transform` function such that $| x \\rangle = \\frac{1}{\\sqrt{2^n}}\\sum_{i=0}^{2^n-1}| i \\rangle_n$.\n", @@ -272,28 +247,18 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T13:28:43.345452Z", - "iopub.status.busy": "2024-05-07T13:28:43.344967Z", - "iopub.status.idle": "2024-05-07T13:28:45.966322Z", - "shell.execute_reply": "2024-05-07T13:28:45.965655Z" - } - }, + "execution_count": 7, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Opening: https://platform.classiq.io/circuit/51cc75df-75d3-4f91-ba4c-fc48e41784bc?version=0.41.0.dev39%2B79c8fd0855\n" + "Opening: https://platform.classiq.io/circuit/2tFx2LvEKS1hHC1H4zqM7swXcnb?version=0.66.1\n" ] } ], "source": [ - "from classiq import create_model, hadamard_transform, show, synthesize\n", - "\n", - "\n", "@qfunc\n", "def main(x: Output[QNum]):\n", " allocate(num_qubits=4, out=x)\n", @@ -311,7 +276,7 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Phase\n", "
" ] }, @@ -319,7 +284,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Verify that the quantum program actually operates as expected; receiving a $(-)$ phase only for the state $|0\\rangle$, that is:\n", + "Verify that the quantum program actually operates as expected; receiving a minus $(-)$ phase only for the state $|0\\rangle$, that is:\n", "$\\begin{equation}\n", "| x \\rangle = \\frac{1}{\\sqrt{2^4}}(|1\\rangle+| 2 \\rangle+\\dots +| 15 \\rangle-|0\\rangle)\n", "\\end{equation}$\n", @@ -331,7 +296,7 @@ "metadata": {}, "source": [ "
\n", - " \"Phase\n", + " \"Execution\n", "
" ] }, @@ -339,7 +304,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Indeed, see that you receive the $(-)$ phase only for the zero state, as expected.\n", + "Indeed, we receive the minus $(-)$ phase only for the zero state, as expected.\n", "The result shows bit strings of five bits rather than just four. This includes the `target` qubit measurement that always results in 0.\n", "\n", "To see how this phase kickback is actually implemented in practice see the [Deutsch-Josza example](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb) and [Simon's example](https://github.com/Classiq/classiq-library/blob/main/algorithms/simon/simon.ipynb)." @@ -405,40 +370,19 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T13:28:46.004172Z", - "iopub.status.busy": "2024-05-07T13:28:46.003615Z", - "iopub.status.idle": "2024-05-07T13:28:48.262514Z", - "shell.execute_reply": "2024-05-07T13:28:48.261873Z" - } - }, + "execution_count": 8, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Opening: https://platform.classiq.io/circuit/4915ffcd-0613-479c-b93e-14bdaa8c5d27?version=0.41.0.dev39%2B79c8fd0855\n" + "Opening: https://platform.classiq.io/circuit/2tFx8UpAVEPQkNGfpEWm73lVWkH?version=0.66.1\n" ] } ], "source": [ - "from classiq import (\n", - " H,\n", - " Output,\n", - " QBit,\n", - " QNum,\n", - " X,\n", - " allocate,\n", - " create_model,\n", - " hadamard_transform,\n", - " qfunc,\n", - " show,\n", - " synthesize,\n", - " within_apply,\n", - " write_qmod,\n", - ")\n", + "from classiq import *\n", "\n", "\n", "@qfunc\n", @@ -470,46 +414,16 @@ "\n", "qmod = create_model(main)\n", "qprog = synthesize(qmod)\n", - "show(qprog)\n", - "\n", - "write_qmod(qmod, \"phase_kickback\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Native QMOD version:" + "show(qprog)" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 9, "metadata": {}, + "outputs": [], "source": [ - "```\n", - "// Phase Kickback\n", - "\n", - "qfunc prepare_minus(output target:qbit){\n", - " allocate(1, target);\n", - " X(target);\n", - " H(target);\n", - "}\n", - "\n", - "qfunc oracle_function(x: qnum, target: qbit){\n", - " target ^= x==0;\n", - "}\n", - "\n", - "qfunc oracle_phase_kickback(x:qnum){\n", - " target:qbit;\n", - " within{prepare_minus(target);} apply{oracle_function(x,target);}\n", - "}\n", - "\n", - "qfunc main(output x:qnum){\n", - " allocate(4, x);\n", - " hadamard_transform(x);\n", - " oracle_phase_kickback(x);\n", - "}\n", - "```" + "write_qmod(qmod, \"phase_kickback\")" ] }, { diff --git a/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.synthesis_options.json b/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.synthesis_options.json index 0967ef42..3252bb51 100644 --- a/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.synthesis_options.json +++ b/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.synthesis_options.json @@ -1 +1,46 @@ -{} +{ + "constraints": { + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "custom_hardware_settings": { + "basis_gates": [ + "r", + "ry", + "rx", + "u1", + "u2", + "t", + "sdg", + "h", + "cx", + "sx", + "sxdg", + "x", + "tdg", + "u", + "cy", + "z", + "rz", + "cz", + "p", + "id", + "y", + "s" + ], + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "synthesize_all_separately": false, + "optimization_level": 3, + "output_format": [ + "qasm" + ], + "pretty_qasm": true, + "transpilation_option": "auto optimize", + "timeout_seconds": 300, + "random_seed": 906707084 + } +} \ No newline at end of file