diff --git a/algorithms/swap_test/swap_test.ipynb b/algorithms/swap_test/swap_test.ipynb index ddf14e44..bf22cd22 100644 --- a/algorithms/swap_test/swap_test.ipynb +++ b/algorithms/swap_test/swap_test.ipynb @@ -7,20 +7,20 @@ "source": [ "# The Swap Test Algorithm\n", "\n", - "The swap test is a quantum function that checks the overlap between two quantum states: the inputs of the function are two quantum registers of the same size, $|\\psi_1\\rangle, \\,|\\psi_2\\rangle$, and it returns as an output a single \"test\" qubit whose state encodes the overlap between the two inputs: $|q\\rangle_{\\rm test} = \\alpha|0\\rangle + \\sqrt{1-\\alpha^2}|1\\rangle$, with\n", + "The Swap test is a quantum function that checks the overlap between two quantum states: the inputs of the function are two quantum registers of the same size, $|\\psi_1\\rangle, \\,|\\psi_2\\rangle$, and it returns as an output a single test qubit whose state encodes the overlap between the two inputs: $|q\\rangle_{\\rm test} = \\alpha|0\\rangle + \\sqrt{1-\\alpha^2}|1\\rangle$, with\n", "$$\n", "\\alpha^2 = \\frac{1}{2}\\left(1+|\\langle \\psi_1 |\\psi_2 \\rangle |^2\\right).\n", "$$\n", "Thus, the probability of measuring the test qubit at state $|0\\rangle$ is $1$ if the states are identical (up to a global phase) and 0.5 if the states are orthogonal to each other.\n", "\n", - "The quantum model starts with an H gate on the test qubit, followed by swapping between the two states controlled on the test qubit (a controlled-SWAP gate for each of the qubits in the two states), and a final H gate on the test qubit:\n", + "The quantum model starts with an $H$ gate on the test qubit, followed by swapping between the two states controlled on the test qubit (a controlled-SWAP gate for each of the qubits in the two states), and a final $H$ gate on the test qubit\n", + "\n", + "A general scheme of the Swap test algorithm:\n", "\n", "
\n", - "\n", - "
\n", - " \n", - "
\n", - "
Closed (left panel) and opened (right panel) visualization of the swap test algorithm
\n", + "
\n", + " \"Swap_Test_blocks\"\n", + "
\n", "
" ] }, @@ -34,16 +34,9 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "id": "3172465a-c12d-4636-8092-430c8506622f", - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T14:30:58.002513Z", - "iopub.status.busy": "2024-05-07T14:30:58.002260Z", - "iopub.status.idle": "2024-05-07T14:30:58.132861Z", - "shell.execute_reply": "2024-05-07T14:30:58.132021Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", @@ -69,17 +62,18 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "id": "eb3efd6a-ed62-4607-a297-f903f2415c93", - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T14:30:58.138930Z", - "iopub.status.busy": "2024-05-07T14:30:58.137654Z", - "iopub.status.idle": "2024-05-07T14:31:03.338893Z", - "shell.execute_reply": "2024-05-07T14:31:03.337995Z" + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Opening: https://platform.classiq.io/circuit/2sDZTfkLYOewJWOLqSzQB7pgqMW?version=0.66.0\n" + ] } - }, - "outputs": [], + ], "source": [ "from classiq import *\n", "\n", @@ -105,9 +99,9 @@ "id": "eeaa11bb-4a3a-4172-bc29-1bb8860f232a", "metadata": {}, "source": [ - "## swap test - qmod implementations\n", - "The swap test is defined as a library function in the qmod language (definition can be found on our [public github](https://github.com/Classiq/classiq-library/blob/main/functions/open_library_definitions/swap_test.qmod ) ).\n", - "Users can easily add their own functions" + "## Swap Test - Qmod Implementations\n", + "The Swap test is defined as a library function in the qmod language (definition can be found on our [public github](https://github.com/Classiq/classiq-library/blob/main/functions/open_library_definitions/swap_test.qmod)).\n", + "Users can easily add their own functions." ] }, { @@ -120,16 +114,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "id": "deea6297-699c-44c2-9d39-52cf44010a15", - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T14:31:03.534246Z", - "iopub.status.busy": "2024-05-07T14:31:03.533227Z", - "iopub.status.idle": "2024-05-07T14:31:04.983428Z", - "shell.execute_reply": "2024-05-07T14:31:04.982620Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "result = execute(qprog).result_value()" @@ -140,28 +127,21 @@ "id": "959995ad-aa6b-4b31-a25b-95396f8ffa7f", "metadata": {}, "source": [ - "## Comparing the measured overlap with the exact overlap\n", + "## Comparing Measured and Exact Overlap\n", "Using the expected probability of measuring the state $|0\\rangle$ as defined above:\n", "$$\n", "\\alpha^2 = \\frac{1}{2}\\left(1+|\\langle \\psi_1 |\\psi_2 \\rangle |^2\\right).\n", "$$\n", - "we extract the overlap $|\\langle \\psi_1 |\\psi_2 \\rangle |^2=\\sqrt{2 P\\left(q_{\\text{test}}=|0\\rangle\\right)-1}$ \n", + "we extract the overlap $|\\langle \\psi_1 |\\psi_2 \\rangle |=\\sqrt{2 P\\left(q_{\\text{test}}=|0\\rangle\\right)-1}$ \n", "The exact overlap is computed with the dot product of the two state-vectors.\n", "Note that for the sake of this demonstration we execute this circuit $100,000$ times to improve the precision of the probability estimate. This is usually not required in actual programs." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "id": "c95fc7a8-c609-4734-95cb-55054d593dbb", - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T14:31:04.988036Z", - "iopub.status.busy": "2024-05-07T14:31:04.986986Z", - "iopub.status.idle": "2024-05-07T14:31:04.992140Z", - "shell.execute_reply": "2024-05-07T14:31:04.991431Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "overlap_from_swap_test = np.sqrt(\n", @@ -199,16 +179,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "27a9308b-5840-44c5-b7b7-7299d8d6175a", - "metadata": { - "execution": { - "iopub.execute_input": "2024-05-07T14:31:05.006570Z", - "iopub.status.busy": "2024-05-07T14:31:05.005418Z", - "iopub.status.idle": "2024-05-07T14:31:05.011253Z", - "shell.execute_reply": "2024-05-07T14:31:05.010541Z" - } - }, + "metadata": {}, "outputs": [], "source": [ "RTOL = 0.05\n", @@ -217,6 +190,14 @@ "), f\"\"\"\n", "The quantum result is too far than classical one, by a relative tolerance of {RTOL}. Please verify your parameters\"\"\"" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d39ccb95-5989-460f-8a49-2b2392cb4c9f", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -235,7 +216,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/algorithms/swap_test/swap_test.synthesis_options.json b/algorithms/swap_test/swap_test.synthesis_options.json index 0967ef42..bee3a9c2 100644 --- a/algorithms/swap_test/swap_test.synthesis_options.json +++ b/algorithms/swap_test/swap_test.synthesis_options.json @@ -1 +1,46 @@ -{} +{ + "constraints": { + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "custom_hardware_settings": { + "basis_gates": [ + "cx", + "r", + "u2", + "rx", + "x", + "z", + "sx", + "id", + "h", + "ry", + "t", + "s", + "rz", + "p", + "u1", + "sdg", + "y", + "cy", + "tdg", + "cz", + "sxdg", + "u" + ], + "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": 1860637157 + } +} \ No newline at end of file diff --git a/tutorials/advanced_tutorials/linear_combination_of_unitaries/linear_combination_of_unitaries.ipynb b/tutorials/advanced_tutorials/linear_combination_of_unitaries/linear_combination_of_unitaries.ipynb index 088b0011..ae593f04 100644 --- a/tutorials/advanced_tutorials/linear_combination_of_unitaries/linear_combination_of_unitaries.ipynb +++ b/tutorials/advanced_tutorials/linear_combination_of_unitaries/linear_combination_of_unitaries.ipynb @@ -55,7 +55,7 @@ "\n", "Therefore, the action of the sequence of operations over the target qubit will be the non-unitary operation $A$, up to a normalization factor. \n", "\n", - "Detailed mathematical description of the algorithm can be seen [below](#mathematical-description) and in refernce [[1](#childs_paper)]. It is also important to notice that the projection onto the $|0\\rangle$ state depends on a success probability, detailed in [[1]](https://arxiv.org/abs/1202.5822).\n", + "A detailed mathematical description of the algorithm can be seen [below](#mathematical-description) and in reference [[1](#childs_paper)]. It is also important to notice that the projection onto the $|0\\rangle$ state depends on a success probability, detailed in [[1]](https://arxiv.org/abs/1202.5822).\n", "\n", "Overall, a scheme of the algorithm looks like:" ] @@ -65,9 +65,11 @@ "id": "24bce818", "metadata": {}, "source": [ - "
\n", - " \n", - "
" + "
\n", + "
\n", + " \"LCU_blocks\"\n", + "
\n", + "
" ] }, { @@ -89,14 +91,11 @@ "\n", "\n", "\n", - "
\n", - "How does the Within-Apply function work?\n", + "
\n", + " How does the Within-Apply function work?\n", "\n", - "The Within-Apply maps unitary operations of the kind $V = U^{-1} W U$ into the quantum circuit, given $U$ and $W$. \n", + "The Within-Apply maps unitary operations of the kind $V = U^{-1}WU$ into the quantum circuit, given $U$ and $W$. \n", "\n", - "For example, if the W operator is the mcx gate and U is the Quantum Fourier Transform, the Within-Apply function would look like this on [Classiq's IDE](https://platform.classiq.io/):\n", - "\n", - "![Within_Apply_Gif](https://docs.classiq.io/resources/Within_apply_gif.gif)\n", "\n", "
\n", "\n", @@ -127,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 10, "id": "58e277dd", "metadata": {}, "outputs": [], @@ -136,7 +135,7 @@ "\n", "\n", "@qfunc\n", - "def lcu_controllers(controller: QNum, psi: QNum):\n", + "def select(controller: QNum, psi: QNum):\n", " control(ctrl=controller == 0, stmt_block=lambda: apply_to_all(IDENTITY, psi))\n", "\n", " control(ctrl=controller == 1, stmt_block=lambda: qft(psi))\n", @@ -157,7 +156,7 @@ "id": "6c007f00", "metadata": {}, "source": [ - "![LCU_controllers_gif](https://docs.classiq.io/resources/LCU_Controllers_gif.gif)" + "![select.gif](https://docs.classiq.io/resources/Select_function_final.gif)" ] }, { @@ -165,7 +164,30 @@ "id": "3a05a9eb", "metadata": {}, "source": [ - "With the SELECT function defined, we are able to apply the V operator, by using the Within-Apply function. For this, it is necessary to build the PREPARE operator, which will be done using the inplace_prepare_state() function, that requires the probability distribution $\\alpha$, the maximum error in the decomposition of the operator and the target qubits, which are the controllers. Thus, the sequence of operations we will define in our quantum program is:\n", + "With the SELECT function defined, we are able to apply the V operator, by using the Within-Apply function. For this, it is necessary to build the PREPARE operator, which will be done using the inplace_prepare_state() function, that requires the probability distribution $\\alpha$, the maximum error in the decomposition of the operator and the target qubits, which are the controllers.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "1fe3de0d-c13c-42cc-babd-77c577372874", + "metadata": {}, + "outputs": [], + "source": [ + "@qfunc\n", + "def prepare(controller: QNum):\n", + " # Defining the error bound and probability distribution\n", + " error_bound = 0.01\n", + " controller_probabilities = [0.5, 0.25, 0.25, 0]\n", + " inplace_prepare_state(controller_probabilities, error_bound, controller)" + ] + }, + { + "cell_type": "markdown", + "id": "e3124075-48bd-4a15-b402-f3ceb81070b6", + "metadata": {}, + "source": [ + "Thus, the sequence of operations we will define in our quantum program is:\n", "* Define the error bound in the decomposition, and define the probability distribution $\\alpha$\n", "* Allocate target and control qubits\n", "* Execute the Within-Apply function, using the PREPARE and SELECT functions" @@ -173,31 +195,22 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 12, "id": "82854a21", "metadata": {}, "outputs": [], "source": [ "@qfunc\n", "def main(controller: Output[QNum], psi: Output[QNum]):\n", - "\n", - " # Defining the error bound and probability distribution\n", - " error_bound = 0.01\n", - " controller_probabilities = [0.5, 0.25, 0.25, 0]\n", - "\n", " # Allocating the target and control qubits, respectively\n", " allocate(2, psi)\n", " allocate(2, controller)\n", - "\n", - " # Executing the Within-Apply function, the SELECT function is defined by lcu_controllers and the PREPARE function is defined by the inplace_prepare_state function.\n", + " # Executing the Within-Apply function with the select and the prepare functions.\n", " within_apply(\n", - " within=lambda: inplace_prepare_state(\n", - " probabilities=controller_probabilities, bound=error_bound, target=controller\n", - " ),\n", - " apply=lambda: lcu_controllers(controller, psi),\n", + " within=lambda: prepare(controller),\n", + " apply=lambda: select(controller, psi),\n", " )\n", "\n", - "\n", "quantum_model = create_model(main)\n", "quantum_program = synthesize(quantum_model)" ] @@ -212,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 13, "id": "262dd6f5", "metadata": {}, "outputs": [ @@ -220,7 +233,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Opening: https://platform.classiq.io/circuit/48abc366-3b53-4c29-8bd1-dbe70430bbc8?version=0.42.2\n" + "Opening: https://platform.classiq.io/circuit/2sDTrI2KmNNYeCfOTeSOrt4W0sC?version=0.66.0\n" ] } ], @@ -228,16 +241,6 @@ "show(quantum_program)" ] }, - { - "cell_type": "markdown", - "id": "51d3c022", - "metadata": {}, - "source": [ - "In the IDE, this quantum algorithm would look like this:\n", - "\n", - "![LCU_circuit_gif](https://docs.classiq.io/resources/LCU_circuit_gif.gif)" - ] - }, { "cell_type": "markdown", "id": "c39fe07d", @@ -282,14 +285,12 @@ "id": "9ebe4500", "metadata": {}, "source": [ - "## The complete code\n", - "\n", - "You can see the complete Python version of this code below:" + "## All the Code Together\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 14, "id": "03804a1a", "metadata": {}, "outputs": [ @@ -297,7 +298,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Opening: https://platform.classiq.io/circuit/98ac673a-a411-44b6-b114-fad6b5eb8f37?version=0.42.2\n" + "Opening: https://platform.classiq.io/circuit/2sDUbWQbPKHeoBcPvYjOS9PajN8?version=0.66.0\n" ] } ], @@ -306,7 +307,7 @@ "\n", "\n", "@qfunc\n", - "def lcu_controllers(controller: QNum, psi: QNum):\n", + "def select(controller: QNum, psi: QNum):\n", " control(ctrl=controller == 0, stmt_block=lambda: apply_to_all(IDENTITY, psi))\n", "\n", " control(ctrl=controller == 1, stmt_block=lambda: qft(psi))\n", @@ -315,23 +316,23 @@ "\n", "\n", "@qfunc\n", - "def main(controller: Output[QNum], psi: Output[QNum]):\n", + "def prepare(controller: QNum):\n", " # Defining the error bound and probability distribution\n", " error_bound = 0.01\n", " controller_probabilities = [0.5, 0.25, 0.25, 0]\n", + " inplace_prepare_state(controller_probabilities, error_bound, controller)\n", + " \n", + "@qfunc\n", + "def main(controller: Output[QNum], psi: Output[QNum]):\n", " # Allocating the target and control qubits, respectively\n", " allocate(2, psi)\n", - "\n", " allocate(2, controller)\n", - " # Executing the Within-Apply function, the SELECT function is defined by lcu_controllers and the PREPARE function is defined by the inplace_prepare_state function.\n", + " # Executing the Within-Apply function with the select and the prepare functions.\n", " within_apply(\n", - " within=lambda: inplace_prepare_state(\n", - " probabilities=controller_probabilities, bound=error_bound, target=controller\n", - " ),\n", - " apply=lambda: lcu_controllers(controller, psi),\n", + " within=lambda: prepare(controller),\n", + " apply=lambda: select(controller, psi),\n", " )\n", "\n", - "\n", "quantum_model = create_model(main)\n", "quantum_program = synthesize(quantum_model)\n", "\n", @@ -364,7 +365,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.11.7 ('classiq')", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/tutorials/documentation_materials/classiq_101/hadamard_test/hadamard_test.ipynb b/tutorials/documentation_materials/classiq_101/hadamard_test/hadamard_test.ipynb index 046b2407..0cb30a27 100644 --- a/tutorials/documentation_materials/classiq_101/hadamard_test/hadamard_test.ipynb +++ b/tutorials/documentation_materials/classiq_101/hadamard_test/hadamard_test.ipynb @@ -367,13 +367,13 @@ "\n", " NOTE: Precision of the Results (read only after completing the exercise) \n", "Increasing the `tot_num_shots` parameter in the execution preferences will enhance the precision of the expectation value estimation. \n", - "This improvement arises from the statistical nature of the measurements; each measurement represents a sample from a distribution modeled by a classical random variable, with the expectation value corresponding to the mean of this distribution. As a result, the law of large numbers applies, and the standard error of the sample mean $ \\langle U \\rangle$ is inversely proportional to the square root of the sample size: \n", + "This improvement arises from the statistical nature of the measurements; each measurement represents a sample from a distribution modeled by a classical random variable, with the expectation value corresponding to the mean of this distribution. As a result, the law of large numbers applies, and the standard error of the sample mean $\\langle U\\rangle$ is inversely proportional to the square root of the sample size: \n", "\n", "$$\n", "\\sigma_{\\langle U\\rangle}=\\frac{\\sigma}{\\sqrt{n}}\n", "$$\n", "\n", - "Where $\\sigma $ is the standard deviation of the random variable modeling the measurements, and $ n $ represents the total number of measurements (`tot_num_shots`). This formula demonstrates that increasing the number of measurements reduces the statistical error of the estimated mean, resulting in a more reliable estimation of $ \\langle U \\rangle$ \n", + "Where $\\sigma$ is the standard deviation of the random variable modeling the measurements, and $n$ represents the total number of measurements (`tot_num_shots`). This formula demonstrates that increasing the number of measurements reduces the statistical error of the estimated mean, resulting in a more reliable estimation of $\\langle U\\rangle$ \n", "
" ] }, 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 39c03194..290d8813 100644 --- a/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb +++ b/tutorials/documentation_materials/classiq_101/phase_kickback/phase_kickback.ipynb @@ -552,7 +552,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.11.7" }, "vscode": { "interpreter": {