From 18dffbd10bc8b6245767f7ee22c8aa0a611ca66c Mon Sep 17 00:00:00 2001 From: Amir Naveh Date: Tue, 15 Oct 2024 10:47:58 +0000 Subject: [PATCH] Updates for 0.53.0 --- CONTRIBUTING.md | 4 +- README.md | 20 +- .../bernstein_vazirani.ipynb | 38 +- .../grover_max_cut/grover_max_cut.ipynb | 38 +- algorithms/hhl/hhl/hhl.ipynb | 2 +- algorithms/hhl/hhl/hhl_exact.qmod | 48 +- .../hhl/hhl/hhl_exact.synthesis_options.json | 51 +- .../hhl/hhl_trotter.synthesis_options.json | 51 +- .../oblivious_amplitude_amplification.ipynb | 3 +- .../oblivious_amplitude_amplification.qmod | 8 +- ...itude_amplification.synthesis_options.json | 51 +- .../hybrid_qnn_for_subset_majority.ipynb | 630 ++++++++++++++++++ algorithms/qml/hybrid_qnn/neural_network.png | Bin 0 -> 43744 bytes algorithms/qml/hybrid_qnn/trained_model.pth | Bin 0 -> 2626 bytes .../option_pricing/option_pricing.ipynb | 3 +- .../option_pricing/option_pricing.qmod | 68 +- .../option_pricing.synthesis_options.json | 47 +- .../facility_location/facility_location.ipynb | 28 +- .../Submissions/HW3/Samyak_Jain_HW3_VQE.ipynb | 2 +- .../function_declarations/core_lib_decls.qmod | 18 +- .../function_declarations/open_lib_decls.qmod | 2 + .../encode_in_angle.qmod | 6 + .../encode_on_bloch.qmod | 9 + .../encode_in_angle.metadata.json | 6 + .../encode_in_angle.qmod | 3 + .../encode_in_angle.synthesis_options.json | 50 ++ .../encode_on_bloch.metadata.json | 6 + .../encode_on_bloch.qmod | 3 + .../encode_on_bloch.synthesis_options.json | 50 ++ .../figures/angle_encoding_circuit.png | Bin 0 -> 29714 bytes .../figures/dense_angle_encoding_circuit.png | Bin 0 -> 115171 bytes .../variational_data_encoding.ipynb | 193 ++++++ research/README.md | 2 +- .../glued_trees/figures/10_qubits.png | Bin .../glued_trees/figures/20_qubits.png | Bin .../glued_trees/figures/A_matrix.png | Bin .../figures/glued_trees_diagram.png | Bin .../glued_trees/glued_trees.ipynb | 0 .../glued_trees/glued_trees_cache.json | 0 .../glued_trees_example.metadata.json | 0 .../glued_trees/glued_trees_example.qmod | 0 ...glued_trees_example.synthesis_options.json | 0 .../glued_trees/results/10-qubits/2n+0.json | 0 .../glued_trees/results/10-qubits/2n+10.json | 0 .../glued_trees/results/10-qubits/2n+12.json | 0 .../glued_trees/results/10-qubits/2n+2.json | 0 .../glued_trees/results/10-qubits/2n+4.json | 0 .../glued_trees/results/10-qubits/2n+6.json | 0 .../glued_trees/results/10-qubits/2n+8.json | 0 .../glued_trees/results/10-qubits/2n-10.json | 0 .../glued_trees/results/10-qubits/2n-12.json | 0 .../glued_trees/results/10-qubits/2n-2.json | 0 .../glued_trees/results/10-qubits/2n-4.json | 0 .../glued_trees/results/10-qubits/2n-6.json | 0 .../glued_trees/results/10-qubits/2n-8.json | 0 .../glued_trees/results/20-qubits/2n+0.json | 0 .../glued_trees/results/20-qubits/2n+10.json | 0 .../glued_trees/results/20-qubits/2n+12.json | 0 .../glued_trees/results/20-qubits/2n+2.json | 0 .../glued_trees/results/20-qubits/2n+4.json | 0 .../glued_trees/results/20-qubits/2n+6.json | 0 .../glued_trees/results/20-qubits/2n+8.json | 0 .../glued_trees/results/20-qubits/2n-10.json | 0 .../glued_trees/results/20-qubits/2n-12.json | 0 .../glued_trees/results/20-qubits/2n-2.json | 0 .../glued_trees/results/20-qubits/2n-4.json | 0 .../glued_trees/results/20-qubits/2n-6.json | 0 .../glued_trees/results/20-qubits/2n-8.json | 0 .../getting_started/part4_ghz_state.ipynb | 2 +- .../QMOD_workshop/QMOD_Workshop_Part_1.ipynb | 118 ++-- .../QMOD_workshop/QMOD_Workshop_Part_2.ipynb | 340 ++++++---- 71 files changed, 1557 insertions(+), 343 deletions(-) create mode 100644 algorithms/qml/hybrid_qnn/hybrid_qnn_for_subset_majority.ipynb create mode 100644 algorithms/qml/hybrid_qnn/neural_network.png create mode 100644 algorithms/qml/hybrid_qnn/trained_model.pth create mode 100644 functions/open_library_definitions/encode_in_angle.qmod create mode 100644 functions/open_library_definitions/encode_on_bloch.qmod create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.metadata.json create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.qmod create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.synthesis_options.json create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.metadata.json create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.qmod create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.synthesis_options.json create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/angle_encoding_circuit.png create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/dense_angle_encoding_circuit.png create mode 100644 functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb rename {algorithms => research}/glued_trees/figures/10_qubits.png (100%) rename {algorithms => research}/glued_trees/figures/20_qubits.png (100%) rename {algorithms => research}/glued_trees/figures/A_matrix.png (100%) rename {algorithms => research}/glued_trees/figures/glued_trees_diagram.png (100%) rename {algorithms => research}/glued_trees/glued_trees.ipynb (100%) rename {algorithms => research}/glued_trees/glued_trees_cache.json (100%) rename {algorithms => research}/glued_trees/glued_trees_example.metadata.json (100%) rename {algorithms => research}/glued_trees/glued_trees_example.qmod (100%) rename {algorithms => research}/glued_trees/glued_trees_example.synthesis_options.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+0.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+10.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+12.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+2.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+4.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+6.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n+8.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-10.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-12.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-2.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-4.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-6.json (100%) rename {algorithms => research}/glued_trees/results/10-qubits/2n-8.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+0.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+10.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+12.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+2.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+4.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+6.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n+8.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-10.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-12.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-2.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-4.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-6.json (100%) rename {algorithms => research}/glued_trees/results/20-qubits/2n-8.json (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0c36a572..4fba4bcc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,9 +24,9 @@ Pull requests are the best way to propose changes to the codebase. We actively w In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://opensource.org/licenses/MIT) that covers the project. Feel free to contact the maintainers if that's a concern. -## Report bugs using GitHub's [issues](https://github.com/Classiq/classiq-library/issues) +## Report bugs using GitHub's [issues](https://github.com/[YourRepo]/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/Classiq/classiq-library/issues/new); it's that easy! +We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/[YourRepo]/issues/new); it's that easy! Write bug reports with detail, background, and sample code diff --git a/README.md b/README.md index bf7134eb..0bd8d351 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ -# Classiq: High-Level Quantum Modeling Language +# Classiq -Classiq provides a powerful platform for **designing, optimizing, analyzing, and executing** quantum programs. This repository hosts a comprehensive collection of quantum functions, algorithms, applications, and tutorials built using the Classiq SDK and our native Qmod language. +Your entry-point for creating & running quantum programs. -Whether you're a researcher, developer, or student, Classiq helps you simplify complex quantum workflows and seamlessly transform quantum logic into optimized circuits by leveraging our **high-level functional design** approach. A user-friendly interface allows you to model, simulate, visualize, and execute quantum programs across various quantum hardware platforms. +This repository holds a wide collection of quantum functions, algorithms, applications and tutorials built with Classiq.

@@ -32,7 +32,7 @@ Whether you're a researcher, developer, or student, Classiq helps you simplify c Working with Classiq's latest GUI requires no installations! Just head over to [Classiq's platform](https://platform.classiq.io/) and follow the examples below over there :) -If you'd rather work programmatically using Python, Classiq also provides an SDK, which can be installed as follows: +If you'd rather work programmatically, using Python, Classiq also provides an SDK, which can be installed as follows: ```bash pip install classiq @@ -51,9 +51,9 @@ The `.ipynb` files are intended to be viewed inside [JupyterLab](https://jupyter # Create Quantum Programs with Classiq -The simplest quantum circuit has 1 qubit and has a single `X` gate. +The simplest quantum circuit has 1 qubit, and has a single `X` gate. -Using Classiq's SDK, it would look like this: +Using Classiq's SDK, it would like like so: ```python from classiq import * @@ -115,7 +115,7 @@ def prep_minus(out: Output[QBit]) -> None: H(out) ``` -A part of the Deutsch Jozsa algorithm (see the full algorithm [here](/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb)) +A part of the Deutsch Jozsa algorithm (see the full algorithm [here](/algorithms/deutsch_josza/deutsch_jozsa.ipynb)) ```python @qfunc @@ -258,7 +258,7 @@ print(result[0].value.parsed_counts) The examples found in this repository can be accessed via [Classiq's platform](https://platform.classiq.io/), in the [`model`](https://platform.classiq.io/dsl-synthesis) tab, under the same folder structure. -Additionally, one may write their own model in the model editor (highlighted in green) or upload his own model (highlighted in red) +Additionally, one may write his own model in the model editor (highlighted in green) or upload his own model (highlighted in red) ![writing_models.png](README_resources/writing_models.png) @@ -302,14 +302,14 @@ qfunc main(output res: qnum){ -4. Press Run: +3. Press Run:
![Execution_Screenshot_3_plus_5.png](README_resources/Execution_Screenshot_3_plus_5.png)
-5. View Results: +4. View Results:
![Jobs_Screenshot_3_plus_5.png](README_resources/Jobs_Screenshot_3_plus_5.png) diff --git a/algorithms/bernstein_vazirani/bernstein_vazirani.ipynb b/algorithms/bernstein_vazirani/bernstein_vazirani.ipynb index f11b5417..b0d77952 100644 --- a/algorithms/bernstein_vazirani/bernstein_vazirani.ipynb +++ b/algorithms/bernstein_vazirani/bernstein_vazirani.ipynb @@ -13,7 +13,7 @@ "id": "22ec3e91-cc89-43be-88d0-1a36639e5e4e", "metadata": {}, "source": [ - "The Bernstein-Vazirani (BV) algorithm [[1](#BVWiki)], named after Ethan Bernstein and Umesh Vazirani, is a basic quantum algorithm. It gives a linear speed-up with respect to its classical counterpart, in the oracle complexity setting.\n", + "The Bernstein-Vazirani (BV) algorithm [[1](#BVWiki)], named after Ethan Bernstein and Umesh Vazirani, is a basic quantum algorithm. It gives a linear speedup compared to its classical counterpart, in the oracle complexity setting.\n", "\n", "The algorithm treats the following problem:\n", "\n", @@ -21,14 +21,14 @@ "$$\n", "f(x)\\equiv (x\\cdot a) \\,\\,\\mod 2,\n", "$$\n", - "where the $ \\cdot$ refers to a bitwise dot operation, and $a$ is some binary string of length $n$.\n", + "where the $ \\cdot$ refers to a bitwise dot operation, and $a$ is a binary string of length $n$.\n", "\n", - "* **Output:** Returns the secret string $a$ with the minimal inquries of the function.\n", + "* **Output:** Returns the secret string $a$ with minimum inquiries of the function.\n", "\n", "\n", "Comments:\n", "* This problem is a special case of the [hidden-shift problem](https://github.com/Classiq/classiq-library/blob/main/algorithms/algebraic/hidden_shift/hidden_shift.ipynb), where the goal is to find a secret string satisfing $f(x)=f(x\\oplus a)$, with $\\oplus$ indicating bitwise addition.\n", - "* The problem can be considered as a restricted version of the [Duetsch-Jozsa algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb). In particular, the functional quantum circuit is identical for both problems.\n", + "* The problem is a restricted version of the [Deutsch-Jozsa algorithm](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb). In particular, the functional quantum circuit is identical for both problems.\n", "\n", "***" ] @@ -40,7 +40,7 @@ "jp-MarkdownHeadingCollapsed": true }, "source": [ - "Problem Hardness: Classically, the minimal inquiries of the function $f$ for determining the secret string is $n$: $f$ is called with the strings \n", + "Problem hardness: Classically, the minimum inquiries of the function $f$ for determining the secret string is $n$: $f$ is called with these strings: \n", "$$\n", "\\begin{eqnarray}\n", "f(100\\dots0) &=& a_0, \\\\\n", @@ -49,7 +49,7 @@ "f(00\\dots01)&=& a_{n-1},\n", "\\end{eqnarray}\n", "$$\n", - "which reveals the secret string, one bit at a time. **The BV algorithm finds the secret string using one function call (oracle inquiry); thus, providing a linear speed-up with respect to the classical solution.**" + "which reveals the secret string, one bit at a time. **The BV algorithm finds the secret string using one function call (oracle inquiry), thereby providing a linear speedup with respect to the classical solution.**" ] }, { @@ -71,7 +71,7 @@ "source": [ "## How to Build the Algorithm with Classiq\n", "\n", - "The BV algorithm contains three function blocks: an oracle for the predicate $f$, \"sandwiched\" between two Hadamard transforms. The resulting state corresponds to the secret string. The full [mathematical derivation](#Technical-Notes) is given at the end of this notebook." + "The BV algorithm contains three function blocks: an oracle for the predicate $f$, \"sandwiched\" between two Hadamard transforms. The resulting state corresponds to the secret string. The full [mathematical derivation](#Technical-Notes) is at the end of this notebook." ] }, { @@ -81,7 +81,7 @@ "source": [ "### Implementing the BV Predicate\n", "\n", - "A simple quantum implementation of the binary function $f(x)$ is by applying a series of controlled-X operations: starting with the state $|f\\rangle=|0\\rangle$, we apply an X gate on it, controlled on the $|x_i\\rangle$ state, for all $i$ such that $a_i=1$:\n", + "A simple quantum implementation of the binary function $f(x)$ applies a series of controlled-X operations: starting with the state $|f\\rangle=|0\\rangle$, we apply an X gate, controlled on the $|x_i\\rangle$ state, for all $i$ such that $a_i=1$:\n", "$$\n", " |x_0\\dots x_{n-1}\\rangle |0\\rangle_f \\rightarrow \\Pi_{i: a_i=1} {\\rm CX}(x_i,f) |x_0\\dots x_{n-1}\\rangle |0\\rangle_f = |x_0\\dots x_{n-1}\\rangle X^{a\\cdot x}|0\\rangle_f=|x_0\\dots x_{n-1}\\rangle |a\\cdot x \\left(\\text{ mod } 2\\right)\\rangle_f.\n", "$$" @@ -123,8 +123,8 @@ "source": [ "
\n", "\n", - "
Figure 1. The Bernstein Vazirani Predicate $f(x)$ for a secret string $a=01101$, on $n$ qubits.\n", - "The quantum variable $x$ is stored on the 5 upper qubits and the resulting value of $f$ is on the lower-most qubit.
\n", + "
Figure 1. The Bernstein-Vazirani predicate $f(x)$ for a secret string $a=01101$, on $n$ qubits.\n", + "The quantum variable $x$ is stored on the five upper qubits and the resulting value of $f$ is on the lowermost qubit.
\n", "
" ] }, @@ -135,7 +135,7 @@ "source": [ "### Implementing the BV Quantum Function\n", "\n", - "The quantum part of the BV algorithm is essentially identical to the Deutch-Jozsa one, see `deutsch_jozsa` function in [Deutsch-Jozsa notebook](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb). However, in contrast to the latter, the predicate function implementation is fixed, depending solely on the secret string $a$. Hereafter we refer to the secret string as a secret integer, defined as an integer argument for the `bv_function`:" + "The quantum part of the BV algorithm is essentially identical to the `deutsch_jozsa` function in the [Deutsch-Jozsa notebook](https://github.com/Classiq/classiq-library/blob/main/algorithms/deutsch_jozsa/deutsch_jozsa.ipynb). However, in contrast to the latter, the predicate function implementation is fixed, depending solely on the secret string $a$. Hereafter, we refer to the secret string as a secret integer, defined as an integer argument for the `bv_function`:" ] }, { @@ -160,13 +160,13 @@ "id": "134ef74c-180b-4b60-9b35-c64ee626c2db", "metadata": {}, "source": [ - "## An Example on 5 Qbits\n", + "## An Example on Five Qubits\n", "\n", "We construct a model for a specific example, setting the secret integer to $a=13$ and $n=5$.\n", "\n", - "We can essentially set the number of shots to 1. This is because that under the assumption of noiseless execution, the resulting state is just the secret integer (see last equation Eq. ([1](#mjx-eqn-1)) below). In particular, the idea of using solely 1 shot was used to demonstrate algorithmic speedup in Ref. [[2](#ssBV)], where the authors considered a modified version of the BV algorithm in which the secret integer changes after every inquiry.\n", + "We can essentially set the number of shots to 1. This is because that under the assumption of noiseless execution, the resulting state is just the secret integer (see the last Eq. ([1](#mjx-eqn-1)) below). In particular, the idea of using solely one shot demonstrated algorithmic speedup in Ref. [[2](#ssBV)], where the authors considered a modified version of the BV algorithm in which the secret integer changes after every inquiry.\n", "\n", - "In our example, we take `num_shots=1000` to highlight the fact that the resulting state is purely the secret string." + "In this example, we take `num_shots=1000` to highlight the fact that the resulting state is purely the secret string." ] }, { @@ -207,7 +207,7 @@ "id": "2e210edf-f2ce-478a-9118-655d1d64f0cc", "metadata": {}, "source": [ - "We can now visualize the circuit" + "We can now visualize the circuit:" ] }, { @@ -286,11 +286,11 @@ "id": "c8c52c24-f49b-424a-bd42-c881146b5921", "metadata": {}, "source": [ - "A brief summary of the linear algebra behind the Bernstein-Vazirani algorithm. The first Hadamard transformation generates an equal super-position over all the standard basis elements:\n", + "Here is a brief summary of the linear algebra behind the Bernstein-Vazirani algorithm. The first Hadamard transformation generates an equal superposition over all the standard basis elements:\n", "$$\n", "|0\\rangle_n \\xrightarrow[H^{\\otimes n}]{} \\frac{1}{2^{n/2}}\\sum^{2^n-1}_{j=0}|j\\rangle_n.\n", "$$\n", - "The oracle gets the boolean Bernstein-Vazirani predicate and adds an $e^{\\pi i}=-1$ phase to all states for which the function returns True:\n", + "The oracle gets the Boolean Bernstein-Vazirani predicate and adds an $e^{\\pi i}=-1$ phase to all states for which the function returns true:\n", "$$\n", "\\frac{1}{2^{n/2}}\\sum^{2^n-1}_{j=0}|j\\rangle_n \\xrightarrow[\\text{Oracle}(f(j))]{}\\frac{1}{2^{n/2}}\\sum^{2^n-1}_{j=0}(-1)^{a\\cdot j}|j\\rangle_n.\n", "$$\n", @@ -299,14 +299,14 @@ "\\frac{1}{2^{n/2}}\\sum^{2^n-1}_{j=0}(-1)^{a\\cdot j}|j\\rangle \\xrightarrow[H^{\\otimes n}]{} \n", "\\sum^{2^n-1}_{k=0} \\left(\\frac{1}{2^{n}}\\sum^{2^n-1}_{j=0}(-1)^{j\\cdot \\left(k\\oplus a \\right)} \\right) |k\\rangle.\n", "$$\n", - "The final expression represents a super-position over all basis states $|k\\rangle$; however, one can verify that the amplitude of the state $|k\\rangle=|a\\rangle$ is simply 1, as $a\\oplus a =0$:\n", + "The final expression represents a superposition over all basis states $|k\\rangle$; however, we can verify that the amplitude of the state $|k\\rangle=|a\\rangle$ is simply one, as $a\\oplus a =0$:\n", "$$\n", "\\begin{equation*}\n", "\\left(\\frac{1}{2^{n}}\\sum^{2^n-1}_{j=0}1 \\right) |a\\rangle + \\sum^{2^n-1}_{k\\neq a} 0 |k\\rangle = |a\\rangle.\n", "\\tag{1}\n", "\\end{equation*}\n", "$$\n", - "Therefore, the final state is simply the secret string." + "Therefore, the final state is the secret string." ] }, { diff --git a/algorithms/grover/grover_max_cut/grover_max_cut.ipynb b/algorithms/grover/grover_max_cut/grover_max_cut.ipynb index c4eadcda..2cc1c115 100644 --- a/algorithms/grover/grover_max_cut/grover_max_cut.ipynb +++ b/algorithms/grover/grover_max_cut/grover_max_cut.ipynb @@ -5,7 +5,7 @@ "id": "6a6a7ea3-e27b-43f3-a53c-9c8a4eb9ec7a", "metadata": {}, "source": [ - "# Graph Cut search problem with Grover Oracle" + "# Graph Cut Search Problem with Grover Oracle" ] }, { @@ -13,15 +13,13 @@ "id": "5193de81-389e-4a87-89dc-1acb2f2630e0", "metadata": {}, "source": [ - "## Introduction\n", - "\n", "The \"Maximum Cut Problem\" (MaxCut) [[1](#MaxCutWiki)] is an example of combinatorial optimization problem. It refers to finding a partition of a graph into two sets, such that the number of edges between the two sets is maximal.\n", "\n", - "## Mathematical formulation\n", + "## Mathematical Formulation\n", "\n", - "Given a graph $G=(V,E)$ with $|V|=n$ nodes and $E$ edges, a cut is defined as a partition of the graph into two complementary subsets of nodes. In the MaxCut problem we are looking for a cut where the number of edges between the two subsets is maximal. We can represent a cut of the graph by a binary vector $x$ of size $n$, where we assign 0 and 1 to nodes in the first and second subsets, respectively. The number of connecting edges for a given cut is simply given by summing over $x_i (1-x_j)+x_j (1-x_i)$ for every pair of connected nodes $(i,j)$.\n", + "Given a graph $G=(V,E)$ with $|V|=n$ nodes and $E$ edges, a cut is defined as a partition of the graph into two complementary subsets of nodes. In the MaxCut problem we look for a cut where the number of edges between the two subsets is maximal. We can represent a cut of the graph by a binary vector $x$ of size $n$, assigning 0 and 1 to nodes in the first and second subsets, respectively. The number of connecting edges for a given cut is simply given by summing over $x_i (1-x_j)+x_j (1-x_i)$ for every pair of connected nodes $(i,j)$.\n", "\n", - "# Solving with the Classiq platform\n" + "# Solving with the Classiq Platform\n" ] }, { @@ -29,7 +27,7 @@ "id": "311c3a03-cd25-4453-94ff-8743b0ba0e55", "metadata": {}, "source": [ - "In this tutorial we define a **search problem** instead: Given a graph and number of edges, check if there is a cut in the graph larger than a certain size. We will solve the problem using the grover algorithm." + "In this tutorial we define a **search problem** instead: Given a graph and number of edges, we check if there is a cut in the graph larger than a certain size. We solve the problem using the Grover algorithm." ] }, { @@ -54,7 +52,7 @@ "id": "6e32027b-edd3-47d2-bb68-233bbea58fc9", "metadata": {}, "source": [ - "### Define the cut search problem" + "### Define the Cut Search Problem" ] }, { @@ -62,7 +60,7 @@ "id": "a651a787-2c21-476d-8426-5a5f1be75e10", "metadata": {}, "source": [ - "We will use sympy in order to create an formula for the cut, later to be used within the quantum algorithm." + "We use SymPy to create an formula for the cut, for use later in the quantum algorithm." ] }, { @@ -92,7 +90,7 @@ "id": "39d882bc-56e8-4680-8803-14b1dd05d115", "metadata": {}, "source": [ - "### Define a speific problem input" + "### Define a Specific Problem Input" ] }, { @@ -100,7 +98,7 @@ "id": "759ca95a-67b2-4a35-832a-34af10d9910d", "metadata": {}, "source": [ - "We will initiate a specific graph, whose maximum cut is 5:" + "We initiate a specific graph whose maximum cut is 5:" ] }, { @@ -159,7 +157,7 @@ "id": "87c640ad-f91c-4b2d-bdf9-28a329c8107a", "metadata": {}, "source": [ - "## Creating quantum circuit from the problem formulation and solving it using the Classiq platform" + "## Creating a Quantum Circuit and Solving It Using the Classiq Platform" ] }, { @@ -167,10 +165,10 @@ "id": "4127c806-1a14-416b-bae8-07b951e662fe", "metadata": {}, "source": [ - "We use the `grover_search` function for the quantum circuit. The oracle function will be a `phase_oracle`, which applies a $(-1)$ phase to each state that the inner function delivered to `phase_oracle` returns 1 for. The `cut_oracle` is the inner function in this case - calculating whether a given graph partition`s cut is larger than some constant.\n", + "We use the `grover_search` function for the quantum circuit. The oracle function is a `phase_oracle`, which applies a $(-1)$ phase to each state for which the inner function delivered to `phase_oracle` returns 1. The `cut_oracle` is the inner function in this case, calculating whether a given graph partition`s cut is larger than some constant.\n", "\n", "\n", - "here we look for a cut of size 4 to the graph:" + "Here we look for a cut of size 4 to the graph:" ] }, { @@ -223,7 +221,7 @@ "source": [ "## Synthesizing the Circuit\n", "\n", - "We proceed by synthesizing the circuit using Classiq's synthesis engine. The synthesis should take approximately several seconds:" + "We synthesize the circuit using the Classiq synthesis engine. The synthesis takes several seconds:" ] }, { @@ -250,7 +248,7 @@ "source": [ "## Showing the Resulting Circuit\n", "\n", - "After Classiq's synthesis engine has finished the job, we can show the resulting circuit in the interactive GUI:" + "After the Classiq synthesis engine finishes the job, we display the resulting circuit in the interactive GUI:" ] }, { @@ -304,8 +302,8 @@ } }, "source": [ - "### Execute the problem on a simulator and try to find a valid solution\n", - "Lastly, we can execute the resulting circuit with Classiq's execute interface, using the `execute` function." + "### Execute on a Simulator to Find a Valid Solution\n", + "Lastly, we run the resulting circuit on the Classiq execute interface using the `execute` function." ] }, { @@ -332,7 +330,7 @@ } }, "source": [ - "Printing out the result, we see that our execution of Grover's algorithm successfully found the satisfying assignments for the input formula:" + "Upon printing the result, we see that our execution of Grover's algorithm successfully found the satisfying assignments for the input formula:" ] }, { @@ -394,7 +392,7 @@ "id": "66b05fd2-25ef-403b-b40b-45a2358acf52", "metadata": {}, "source": [ - "We can see that the satisfying assignments are ~6 times more probable than the unsatisfying assignments. Let's print one of them:" + "The satisfying assignments are ~6 times more probable than the unsatisfying assignments. We print one:" ] }, { diff --git a/algorithms/hhl/hhl/hhl.ipynb b/algorithms/hhl/hhl/hhl.ipynb index 5d70f191..210f5069 100644 --- a/algorithms/hhl/hhl/hhl.ipynb +++ b/algorithms/hhl/hhl/hhl.ipynb @@ -683,7 +683,7 @@ "from classiq import write_qmod\n", "\n", "# Save qmod file\n", - "write_qmod(qmod_hhl_exact, \"hhl_exact\", decimal_precision=10)" + "write_qmod(qmod_hhl_exact, \"hhl_exact\", decimal_precision=20)" ] }, { diff --git a/algorithms/hhl/hhl/hhl_exact.qmod b/algorithms/hhl/hhl/hhl_exact.qmod index 9344feb4..4d5d1f8a 100644 --- a/algorithms/hhl/hhl/hhl_exact.qmod +++ b/algorithms/hhl/hhl/hhl_exact.qmod @@ -16,10 +16,10 @@ qfunc simple_eig_inv(phase: qnum, output indicator: qbit) { qfunc hhl(rhs_vector: real[], bound: real, precision: int, hamiltonian_evolution_with_power: qfunc (int, qbit[]), output state: qbit[], output phase: qnum, output indicator: qbit) { allocate_num(precision, False, precision, phase); load_b([ - 0.1825741858, - 0.3651483717, - 0.7302967433, - 0.5477225575 + 0.18257418583505536, + 0.3651483716701107, + 0.7302967433402214, + 0.5477225575051661 ], state, bound); within { qpe_flexible(lambda(k) { @@ -32,35 +32,35 @@ qfunc hhl(rhs_vector: real[], bound: real, precision: int, hamiltonian_evolution qfunc main(output res: qnum, output phase: qnum, output indicator: qbit) { hhl([ - 0.1825741858, - 0.3651483717, - 0.7302967433, - 0.5477225575 + 0.18257418583505536, + 0.3651483716701107, + 0.7302967433402214, + 0.5477225575051661 ], 0, 4, lambda(arg0, arg1) { unitary_with_power_logic(arg0, [ [ - ((-0.0940624095) + 0.8149069223j), - (0.0352187195 - 0.0297635346j), - ((-0.018800717) - 0.161428798j), - (0.4376924593 + 0.3270555491j) + ((-0.09406240950199855) + 0.8149069223122056j), + (0.03521871946675125 - 0.029763534641642626j), + ((-0.018800717000078307) - 0.16142879795007103j), + (0.4376924593076474 + 0.32705554908759304j) ], [ - (0.0352187195 - 0.0297635346j), - ((-0.153472483) - 0.1727528247j), - (0.2311764446 + 0.8872069971j), - (0.2397182575 + 0.2154826792j) + (0.03521871946675127 - 0.029763534641642633j), + ((-0.15347248298890323) - 0.1727528247294824j), + (0.23117644455908545 + 0.8872069971297388j), + (0.2397182575488357 + 0.21548267921288924j) ], [ - ((-0.018800717) - 0.161428798j), - (0.2311764446 + 0.8872069971j), - ((-0.1219131721) + 0.1320013813j), - (0.295840691 + 0.1148893873j) + ((-0.018800717000078276) - 0.16142879795007103j), + (0.23117644455908537 + 0.8872069971297386j), + ((-0.12191317205164585) + 0.13200138126428376j), + (0.2958406910149558 + 0.11488938733473104j) ], [ - (0.4376924593 + 0.3270555491j), - (0.2397182575 + 0.2154826792j), - (0.295840691 + 0.1148893873j), - ((-0.656382795) + 0.2569098899j) + (0.43769245930764744 + 0.3270555490875932j), + (0.23971825754883574 + 0.21548267921288933j), + (0.2958406910149558 + 0.114889387334731j), + ((-0.6563827949579104) + 0.25690988991104674j) ] ], arg1); }, res, phase, indicator); diff --git a/algorithms/hhl/hhl/hhl_exact.synthesis_options.json b/algorithms/hhl/hhl/hhl_exact.synthesis_options.json index 0967ef42..2dc93f20 100644 --- a/algorithms/hhl/hhl/hhl_exact.synthesis_options.json +++ b/algorithms/hhl/hhl/hhl_exact.synthesis_options.json @@ -1 +1,50 @@ -{} +{ + "constraints": { + "max_width": null, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "cy", + "rz", + "z", + "sdg", + "t", + "s", + "h", + "u2", + "tdg", + "sx", + "ry", + "cz", + "u1", + "y", + "r", + "x", + "rx", + "sxdg", + "id", + "u", + "p", + "cx" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": -1 + } +} diff --git a/algorithms/hhl/hhl/hhl_trotter.synthesis_options.json b/algorithms/hhl/hhl/hhl_trotter.synthesis_options.json index 0967ef42..2dc93f20 100644 --- a/algorithms/hhl/hhl/hhl_trotter.synthesis_options.json +++ b/algorithms/hhl/hhl/hhl_trotter.synthesis_options.json @@ -1 +1,50 @@ -{} +{ + "constraints": { + "max_width": null, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "cy", + "rz", + "z", + "sdg", + "t", + "s", + "h", + "u2", + "tdg", + "sx", + "ry", + "cz", + "u1", + "y", + "r", + "x", + "rx", + "sxdg", + "id", + "u", + "p", + "cx" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": -1 + } +} diff --git a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.ipynb b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.ipynb index 4f5de501..067db62f 100644 --- a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.ipynb +++ b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.ipynb @@ -350,7 +350,8 @@ " )\n", "\n", "\n", - "qmod_2 = create_model(main, out_file=\"oblivious_amplitude_amplification\")\n", + "qmod_2 = create_model(main)\n", + "write_qmod(qmod_2, \"oblivious_amplitude_amplification\", decimal_precision=20)\n", "qprog_2 = synthesize(qmod_2)\n", "show(qprog_2)\n", "result_2 = execute(qprog_2).result_value()" diff --git a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.qmod b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.qmod index 9d49e9b5..154002cd 100644 --- a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.qmod +++ b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.qmod @@ -44,10 +44,10 @@ qfunc oblivious_amplitude_amplification(reps: int, block_encoding: qfunc (qnum, qfunc main(output data: qnum, output block: qnum) { allocate(2, block); prepare_amplitudes([ - 0.4709, - 0.8134, - 0.0001, - 0.3414 + 0.4709243714124557, + 0.8134303596981152, + 0.0001291583857834318, + 0.3414107052353368 ], 0, data); oblivious_amplitude_amplification(1, lambda(_block, _data) { block_encode([ diff --git a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.synthesis_options.json b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.synthesis_options.json index 0967ef42..3cb65326 100644 --- a/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.synthesis_options.json +++ b/algorithms/oblivious_amplitude_amplification/oblivious_amplitude_amplification.synthesis_options.json @@ -1 +1,50 @@ -{} +{ + "constraints": { + "max_width": null, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "t", + "s", + "u1", + "sx", + "ry", + "y", + "tdg", + "u2", + "sxdg", + "rx", + "rz", + "z", + "u", + "h", + "id", + "cx", + "x", + "p", + "sdg", + "cz", + "cy", + "r" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": -1 + } +} diff --git a/algorithms/qml/hybrid_qnn/hybrid_qnn_for_subset_majority.ipynb b/algorithms/qml/hybrid_qnn/hybrid_qnn_for_subset_majority.ipynb new file mode 100644 index 00000000..10e933d1 --- /dev/null +++ b/algorithms/qml/hybrid_qnn/hybrid_qnn_for_subset_majority.ipynb @@ -0,0 +1,630 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "73eef373-8478-4af6-9f90-e36970fc546b", + "metadata": {}, + "source": [ + "# Hybrid Classical-Quantum Neural Network" + ] + }, + { + "cell_type": "markdown", + "id": "d57cbeb5-a0d8-4e78-8510-c11080089241", + "metadata": {}, + "source": [ + "## Classical Neural Networks" + ] + }, + { + "cell_type": "markdown", + "id": "55d39605-9fa4-4aab-b709-23889e9771d0", + "metadata": {}, + "source": [ + "Neural networks is one of the major branches in machine learning, with wide usa in applications and research. A neural network, or more generally a deep neural network, is a parametric function of a specific structure (inspired from biological neural networks in biology), which is trained to capture specific functionality.\n", + "\n", + "In its most basic form, a neural network for learning a function $\\vec{f}: \\mathbb{R}^N\\rightarrow \\mathbb{R}^M$ looks as follows:\n", + "1. There is an input vector of size $N$ (red circles in Fig. 1).\n", + "2. Each entry of the input goes into a hidden layer of size $K$, where each neuron (blue circles in Fig. 1) is defined with some \"activation function\" $y^{k}(\\vec{w}^{(1)}; \\vec{x})$ for $k=1,\\dots,K$, and $\\vec{w}^{(1)}$ are parameters.\n", + "3. Finally, the output of the hidden layer is sent to the output layer (green circles in Fig. 1) $\\tilde{f}^{m}(\\vec{w}^{(2)};\\vec{y})$ for $m=1,\\dots,M$, and $\\vec{w}^{(2)}$ are parameters.\n", + "\n", + "The output $\\vec{\\tilde{f}}$ is thus a parametric function (in $\\vec{w}^{(1)},\\,\\vec{w}^{(2)}$), which can be trained to capture the target function $\\vec{f}$.\n", + "\n", + "\n", + "![png](neural_network.png)\n", + "\n", + "
\n", + "
Figure 1. A single layer classical neural network (taken from Wikipedia). Here the input size is $N=3$, the output size is $M=3$, and the hidden layer has $L=4$ neurons.
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "deed6b9a-de21-4eec-ba57-7f65987dd154", + "metadata": { + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "**Deep neural networks** - Deep neural networks are similar to the description above, having more than one hidden layer. This provides a more complex structure that can capture more complex functionalities." + ] + }, + { + "cell_type": "markdown", + "id": "9f9e946f-aaaa-4eb9-a9b7-8c6de430bbc8", + "metadata": { + "jp-MarkdownHeadingCollapsed": true + }, + "source": [ + "### Quantum Neural Networks\n", + "\n", + "The idea of a quantum neural network refers to combining parametric circuits as a replacement to all, or part of, classical layers in classical neural networks. The basic object in QNN is thus a **quantum layer**. A quantum layer has a classical input and it returns a classical output. The output is obtained by running a quantum program. A quantum layer is thus composed of three parts:\n", + "1. A quantum part that encodes the input: This is a parametric quantum function for representing the entries of a single data point. There are three canonical ways to encode a data vector of size $N$: [angle-encoding](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb) using $N$ qubits, [dense angle-encoding](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb) using $\\lceil N/2\\rceil$ qubits, and amplitude-encoding using $\\lceil\\log_2N\\rceil$ qubits.\n", + "2. A quantum ansatz part: This is a parametric quantum function, whose parameters are trained as the weights in classical layers.\n", + "3. A postprocess classical part, for returning an output classical vector.\n", + "\n", + "The integration of quantum layers in classical neural networks may offer reduction in resources for a given functionality, as the network (or part of it) is expressed via the Hilbert space, providing different expressibility compared to classical networks.\n", + "\n", + "This notebook demonstrates QNN by treating a specific function, the subset majority, for which we construct, train, and verify a hybrid classical-quantum neural network. The notebook assumes familiarity with Classiq and NN with PyTorch. See [QML guide with Classiq](https://github.com/Classiq/classiq-library/blob/main/tutorials/qml_with_classiq_guide/qml_with_classiq_guide.ipynb) ." + ] + }, + { + "cell_type": "markdown", + "id": "dd948132-0640-41fc-bf25-eaf370f36d00", + "metadata": {}, + "source": [ + "## Example: Hybrid Neural Network for the Subset Majority Function\n", + "\n", + "\n", + "For an integer $N$ and a given subset of indices $S \\subset \\{0,1,\\dots,N\\}$ we define the subset majority function, $M_{S}:\\{0,1\\}^{\\times N}\\rightarrow \\{0,1\\}$ that acts on binary strings of size $N$ as follows: it returns 1 if the number of ones within the a substring according to $S$ are larger than $|S|//2$, and 0 otherwise,\n", + "$$\n", + "M_S(\\vec{b}) = \\left\\{ \\begin{array}{l l }\n", + "1 & \\text{if } \\sum_{j\\in S} b_{j}>|S|//2, \\\\\n", + "0 & \\text{otherwise}\n", + "\\end{array}\n", + "\\right .\n", + "$$\n", + "\n", + "For example, we consider $N=7$ and $S=\\{0,1,4\\}$.\n", + "* The string 0101110 corresponds to the substring 011, for which the number of ones is 2(>1). Therefore, $M_S(0101110)=1$.\n", + "* The string 0011111 corresponds to the substring 001, for which the number of ones is 1(=1). Therefore, $M_S(0101110)=0$." + ] + }, + { + "cell_type": "markdown", + "id": "ce5f70ee-11d1-44f9-9f12-219515f1250e", + "metadata": {}, + "source": [ + "### Generating data for a specific example\n", + "\n", + "Let us consider a specific example for our demonstration. We choose $N=10$ and generate all possible data of $2^N$ bit strings. We also take a specific subset $S=\\{1, 3, 4, 6, 7, 9\\}$." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "33d68af9-6771-4bf4-b357-d3315d1029d8", + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "\n", + "import numpy as np\n", + "\n", + "np.random.seed(0)\n", + "random.seed(1)\n", + "\n", + "STRING_LEN = 10\n", + "majority_data = [\n", + " [int(d) for d in np.binary_repr(k, STRING_LEN)] for k in range(2**STRING_LEN)\n", + "]\n", + "random.shuffle(majority_data) # shuffling the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "de244fae-61a0-4f10-b759-ace3c084ab1a", + "metadata": {}, + "outputs": [], + "source": [ + "SUBSET_INDICES = [1, 3, 4, 6, 7, 9]\n", + "subset_indicator = np.zeros(STRING_LEN)\n", + "subset_indicator[SUBSET_INDICES] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6120ba11-3e30-4c1c-a777-d38d44ee2d99", + "metadata": {}, + "outputs": [], + "source": [ + "majority = (majority_data @ subset_indicator > len(SUBSET_INDICES) // 2) * 1\n", + "labels = [[l] for l in majority]" + ] + }, + { + "cell_type": "markdown", + "id": "b9f3bbb9-6d18-4455-af26-097b3403d28b", + "metadata": {}, + "source": [ + "We choose data for training and data for verification, and define the batch size for the corresponding data loaders:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "884e29ac-15f6-423f-a834-7949b5cc2dc3", + "metadata": {}, + "outputs": [], + "source": [ + "TRAINING_SIZE = 340\n", + "TEST_SIZE = 512\n", + "\n", + "training_data = majority_data[0:TRAINING_SIZE]\n", + "training_labels = labels[0:TRAINING_SIZE]\n", + "test_data = majority_data[TRAINING_SIZE : TRAINING_SIZE + TEST_SIZE]\n", + "test_labels = labels[TRAINING_SIZE : TRAINING_SIZE + TEST_SIZE]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a2c9cd12-c1e8-4f0c-be8e-b7bb02d5bf85", + "metadata": {}, + "outputs": [], + "source": [ + "BATCH_SIZE = 64" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "8d860e88-0796-4090-9688-358bc5ad6915", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import torch\n", + "from torch.utils.data import DataLoader, TensorDataset\n", + "\n", + "training_dataset = TensorDataset(\n", + " torch.Tensor(training_data), torch.Tensor(training_labels)\n", + ") # create dataset\n", + "training_dataloader = DataLoader(\n", + " training_dataset, batch_size=BATCH_SIZE, shuffle=True, drop_last=False\n", + ") # create dataloader\n", + "\n", + "test_dataset = TensorDataset(\n", + " torch.Tensor(test_data), torch.Tensor(test_labels)\n", + ") # create your dataset\n", + "test_dataloader = DataLoader(\n", + " test_dataset, batch_size=BATCH_SIZE, shuffle=True, drop_last=False\n", + ") # create your dataloader" + ] + }, + { + "cell_type": "markdown", + "id": "a5dd682a-73c5-4954-9fc2-934ae187b920", + "metadata": {}, + "source": [ + "### Constructing a hybrid network" + ] + }, + { + "cell_type": "markdown", + "id": "583a05af-fde0-4bc1-9d03-6574cd96cc8a", + "metadata": {}, + "source": [ + "We will build the following hybrid neural network:\n", + "\n", + "**Data flattening $\\rightarrow$ A classical linear layer of size 10 to 4 with `Tanh` activation $\\rightarrow$ A qlayer of size 4 to 2 $\\rightarrow$ a classical linear layer of size 2 to 1 with `ReLU` activation.**" + ] + }, + { + "cell_type": "markdown", + "id": "371cb77f-efac-4203-976a-94d426d9826c", + "metadata": {}, + "source": [ + "The classical layers can be defined with PyTorch built-in functions. The quantum layer is constructed with (1) a [dense angle-encoding](https://github.com/Classiq/classiq-library/blob/main/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb) function, (2) a simple ansatz with RY and RZZ rotations, and (3) a postprocess that is based on a measurement per qubit." + ] + }, + { + "cell_type": "markdown", + "id": "e8b2e803-7d75-474e-ae31-bfb4de049ae4", + "metadata": {}, + "source": [ + "#### The quantum layer" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "217da235-7483-491d-8395-f3ec306c60b9", + "metadata": {}, + "outputs": [], + "source": [ + "from classiq import *\n", + "from classiq.applications.qnn.types import SavedResult\n", + "from classiq.execution import ExecutionPreferences, execute_qnn\n", + "\n", + "\n", + "@qfunc\n", + "def my_ansatz(weights: CArray[CReal], qbv: QArray) -> None:\n", + " \"\"\"\n", + " Gets a quantum variable of $m$ qubits, and applies RY gate on each qubit and RZZ gate on each pair of qubits\n", + " in a linear connectivity. The classical array weights represents the $2m-1$ parametric rotations.\n", + " \"\"\"\n", + " repeat(\n", + " count=qbv.len,\n", + " iteration=lambda index: RY(weights[index], qbv[index]),\n", + " )\n", + " repeat(\n", + " count=qbv.len - 1,\n", + " iteration=lambda index: RZZ(weights[qbv.len + index], qbv[index : index + 2]),\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f3e96089-0e5d-4dc7-875d-3215eac3a98b", + "metadata": {}, + "outputs": [], + "source": [ + "QLAYER_SIZE = 4\n", + "num_qubits = int(np.ceil(QLAYER_SIZE / 2))\n", + "num_weights = 2 * num_qubits - 1\n", + "NUM_SHOTS = 4096\n", + "\n", + "\n", + "@qfunc\n", + "def main(\n", + " input: CArray[CReal, QLAYER_SIZE],\n", + " weight: CArray[CReal, num_weights],\n", + " result: Output[QArray[QBit]],\n", + ") -> None:\n", + " \"\"\"\n", + " The quantum part of the quantum layer.\n", + " The prefix for the data loading parameters must be set to `input_` or `i_`.\n", + " The prefix for the ansatz parameters must be set to `weights_` or `weight`\n", + " \"\"\"\n", + " encode_on_bloch(input, result)\n", + " my_ansatz(weights=weight, qbv=result)\n", + "\n", + "\n", + "qmod = create_model(\n", + " main, execution_preferences=ExecutionPreferences(num_shots=NUM_SHOTS)\n", + ")\n", + "qprog = synthesize(qmod)\n", + "show(qprog)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "75842461-b8d0-4e2a-a45a-bf3037e1ce48", + "metadata": {}, + "outputs": [], + "source": [ + "def my_post_process(result: SavedResult, num_qubits, num_shots) -> torch.Tensor:\n", + " \"\"\"\n", + " Classical postprocess function.\n", + " Gets the histogram after execution and returns a vector $\\vec{y}$,\n", + " where $y_i$ is the probability of measuring 1 on the $i$-th qubit.\n", + " \"\"\"\n", + " res = result.value\n", + " yvec = [\n", + " (res.counts_of_qubits(k)[\"1\"] if \"1\" in res.counts_of_qubits(k) else 0)\n", + " / num_shots\n", + " for k in range(num_qubits)\n", + " ]\n", + "\n", + " return torch.tensor(yvec)" + ] + }, + { + "cell_type": "markdown", + "id": "88b4321f-ccfe-4b99-b480-475720157356", + "metadata": {}, + "source": [ + "#### The full hybrid network" + ] + }, + { + "cell_type": "markdown", + "id": "fdd727cf-bd5e-4c60-b118-8c11581d3982", + "metadata": {}, + "source": [ + "Now, we can define the full network." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "00115f70-db1e-4d9c-9e16-4fe7fca53bbe", + "metadata": {}, + "outputs": [], + "source": [ + "import torch.nn as nn\n", + "\n", + "from classiq.applications.qnn import QLayer\n", + "\n", + "\n", + "def create_net(*args, **kwargs) -> nn.Module:\n", + " class Net(nn.Module):\n", + " def __init__(self, *args, **kwargs):\n", + " super().__init__()\n", + " self.flatten = nn.Flatten()\n", + " self.linear_1 = nn.Linear(STRING_LEN, 4)\n", + " self.activation_1 = nn.Tanh()\n", + " self.linear_2 = nn.Linear(2, 1)\n", + " self.activation_2 = nn.ReLU()\n", + "\n", + " self.qlayer = QLayer(\n", + " qprog,\n", + " execute_qnn,\n", + " post_process=lambda res: my_post_process(\n", + " res, num_qubits=num_qubits, num_shots=NUM_SHOTS\n", + " ),\n", + " *args,\n", + " **kwargs,\n", + " )\n", + "\n", + " def forward(self, x):\n", + " x = self.flatten(x)\n", + " x = self.linear_1(x)\n", + " x = self.activation_1(x)\n", + " x = self.qlayer(x) # 4 to 2\n", + " x = self.linear_2(x) # 2 to 1\n", + " x = self.activation_2(x)\n", + " return x\n", + "\n", + " return Net(*args, **kwargs)\n", + "\n", + "\n", + "my_network = create_net()" + ] + }, + { + "cell_type": "markdown", + "id": "d822e3b0-3ee7-49a7-86ac-86d2cd6fbc93", + "metadata": {}, + "source": [ + "### Training and verifying the networks" + ] + }, + { + "cell_type": "markdown", + "id": "fcfcb0fe-65f0-426a-a5b8-6c3ca56f33f2", + "metadata": {}, + "source": [ + "We define some hyperparameters such as loss function and optimization method, and a training function." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "7c81a0a8-8b43-4945-b584-64d1763144f1", + "metadata": {}, + "outputs": [], + "source": [ + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "\n", + "LEARNING_RATE = 0.05\n", + "\n", + "# choosing our loss function\n", + "loss_func = nn.MSELoss()\n", + "\n", + "# choosing our optimizer\n", + "optimizer = optim.SGD(my_network.parameters(), lr=LEARNING_RATE)" + ] + }, + { + "cell_type": "markdown", + "id": "79178da6-f30f-4e36-91ea-486cd09305f0", + "metadata": {}, + "source": [ + "Next, we define a `train` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "55be4fdc-5735-4f94-8907-0a6fdd5bb022", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import time as time\n", + "\n", + "from torch.utils.data import DataLoader\n", + "\n", + "\n", + "def train(\n", + " network: nn.Module,\n", + " data_loader: DataLoader,\n", + " loss_func: nn.modules.loss._Loss,\n", + " optimizer: optim.Optimizer,\n", + " epoch: int = 20,\n", + ") -> None:\n", + " for index in range(epoch):\n", + " start = time.time()\n", + " for data, label in data_loader:\n", + "\n", + " optimizer.zero_grad()\n", + " output = network(data)\n", + " loss = loss_func(output, label.type(output.dtype))\n", + " loss.backward()\n", + "\n", + " optimizer.step()\n", + "\n", + " print(index, f\"\\tloss = {loss.item()}\", \"time\", time.time() - start)" + ] + }, + { + "cell_type": "markdown", + "id": "607c0f6f-205c-45cf-8089-2137558bd809", + "metadata": {}, + "source": [ + "We also define a validation function, `check_accuracy`, which tests a trained network on new data: " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "4ad21e5e-4e90-48e0-9b76-e034f3618f84", + "metadata": {}, + "outputs": [], + "source": [ + "from torch import Tensor\n", + "\n", + "\n", + "def get_correctly_guessed_labels_function(\n", + " model: nn.Module, data: Tensor, labels: Tensor\n", + ") -> int:\n", + " predictions = model(data)\n", + " list_of_predictions = [\n", + " round(prediction.type(torch.float).item()) for prediction in predictions\n", + " ]\n", + " correct = sum(\n", + " [\n", + " list_of_predictions[k] == labels.flatten().tolist()[k]\n", + " for k in range(len(predictions))\n", + " ]\n", + " )\n", + " return correct\n", + "\n", + "\n", + "def _get_amount_of_labels(labels: Tensor) -> int:\n", + " # the first dimension of `labels` is `batch_size`\n", + " return labels.size(0)\n", + "\n", + "\n", + "def check_accuracy(\n", + " network: nn.Module,\n", + " data_loader: DataLoader,\n", + " should_print: bool = True,\n", + ") -> float:\n", + " num_correct = 0\n", + " total = 0\n", + "\n", + " network.eval()\n", + "\n", + " with torch.no_grad():\n", + " for data, labels in data_loader:\n", + " num_correct += get_correctly_guessed_labels_function(network, data, labels)\n", + " total += _get_amount_of_labels(labels)\n", + "\n", + " accuracy = float(num_correct) / float(total)\n", + "\n", + " if should_print:\n", + " print(f\"Test accuracy of the model: {accuracy*100:.2f}%\")\n", + " print(f\"num correct: {num_correct}, total: {total}\")\n", + "\n", + " return accuracy" + ] + }, + { + "cell_type": "markdown", + "id": "c7307920-333a-4fc1-8a26-b76e266925ec", + "metadata": {}, + "source": [ + "### Training and verifying the network" + ] + }, + { + "cell_type": "markdown", + "id": "6e772fc4-4b0a-4683-8483-3d5aeed0e89c", + "metadata": {}, + "source": [ + "For convenience, we load a pre-trained model and set the epoch size to 1. Training a network takes around 30 epochs." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a9d55b6a-5968-4f24-9940-50c54bfd8fa9", + "metadata": {}, + "outputs": [], + "source": [ + "import pathlib\n", + "\n", + "path = (\n", + " pathlib.Path(__file__).parent.resolve()\n", + " if \"__file__\" in locals()\n", + " else pathlib.Path(\".\")\n", + ")\n", + "\n", + "# comment out for training\n", + "my_network.load_state_dict(torch.load(path / \"trained_model.pth\"))\n", + "num_epoch = 1\n", + "# uncomment out for training\n", + "# epoch=30" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "29a16bc9-1b99-432a-b07d-cdea6307a224", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 \tloss = 0.06314731389284134 time 42.93171310424805\n" + ] + } + ], + "source": [ + "data_loader = training_dataloader\n", + "train(my_network, training_dataloader, loss_func, optimizer, epoch=num_epoch)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "2e79922f-bca0-4d0d-a5a5-2f98d5648960", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test accuracy of the model: 94.53%\n", + "num correct: 484, total: 512\n" + ] + } + ], + "source": [ + "accuracy = check_accuracy(my_network, test_dataloader)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/algorithms/qml/hybrid_qnn/neural_network.png b/algorithms/qml/hybrid_qnn/neural_network.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7b259124544f8a8780ef5e6b3442e4034bf03c GIT binary patch literal 43744 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 literal 0 HcmV?d00001 diff --git a/applications/finance/option_pricing/option_pricing.ipynb b/applications/finance/option_pricing/option_pricing.ipynb index 44249c76..2362ea37 100644 --- a/applications/finance/option_pricing/option_pricing.ipynb +++ b/applications/finance/option_pricing/option_pricing.ipynb @@ -445,7 +445,8 @@ " constraints=Constraints(max_width=20),\n", " classical_execution_function=cmain,\n", " out_file=\"option_pricing\",\n", - ")" + ")\n", + "write_qmod(qmod, \"option_pricing\", decimal_precision=10)" ] }, { diff --git a/applications/finance/option_pricing/option_pricing.qmod b/applications/finance/option_pricing/option_pricing.qmod index 9e42fa7f..64fb81c4 100644 --- a/applications/finance/option_pricing/option_pricing.qmod +++ b/applications/finance/option_pricing/option_pricing.qmod @@ -9,47 +9,47 @@ qfunc iqae_oracle(state: OptionPricingState) { qfunc load_distribution(asset: qnum) { inplace_prepare_state([ - 0.0001, - 0.0003, - 0.0008, - 0.0019, - 0.004, - 0.0074, - 0.0126, - 0.0198, - 0.0288, - 0.0392, - 0.0501, - 0.0605, - 0.0692, - 0.0755, - 0.0787, - 0.0788, - 0.0759, - 0.0705, - 0.0634, - 0.0553, - 0.0469, - 0.0387, - 0.0312, - 0.0246, - 0.0189, - 0.0143, - 0.0106, - 0.0077, - 0.0055, - 0.0039, - 0.0027, - 0.0019 + 0.0001096665, + 0.000325131, + 0.0008423406, + 0.0019330863, + 0.0039764136, + 0.0074083288, + 0.0126157287, + 0.019796302, + 0.0288308524, + 0.0392206066, + 0.0501234708, + 0.0604877711, + 0.0692466213, + 0.0755165222, + 0.0787466388, + 0.0787861125, + 0.0758647471, + 0.0705062166, + 0.0634057464, + 0.0553049808, + 0.046888762, + 0.0387167866, + 0.0311920107, + 0.0245598482, + 0.0189284118, + 0.0142996499, + 0.0106030118, + 0.0077259727, + 0.0055384217, + 0.0039100417, + 0.0027212013, + 0.0018685977 ], 0, asset); } qfunc payoff_linear(asset: qnum, ind: qbit) { - ind *= sqrt(abs((((asset * 0.0513) + 1.2355) - 1.9) / 0.9262)); + ind *= sqrt(abs((((asset * 0.0513152339) + 1.2354548887) - 1.9) / 0.9262271399)); } qfunc payoff(asset: qnum, ind: qbit) { - control (asset >= ceiling(12.9503)) { + control (asset >= ceiling(12.9502500662)) { payoff_linear(asset, ind); } } diff --git a/applications/finance/option_pricing/option_pricing.synthesis_options.json b/applications/finance/option_pricing/option_pricing.synthesis_options.json index a20de7f2..e8075090 100644 --- a/applications/finance/option_pricing/option_pricing.synthesis_options.json +++ b/applications/finance/option_pricing/option_pricing.synthesis_options.json @@ -1,5 +1,50 @@ { "constraints": { - "max_width": 20 + "max_width": 20, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "sx", + "rx", + "u", + "z", + "cz", + "y", + "s", + "u1", + "p", + "r", + "cy", + "ry", + "rz", + "x", + "h", + "t", + "sxdg", + "tdg", + "cx", + "id", + "u2", + "sdg" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": -1 } } diff --git a/applications/logistics/facility_location/facility_location.ipynb b/applications/logistics/facility_location/facility_location.ipynb index 474a5755..498a37f5 100644 --- a/applications/logistics/facility_location/facility_location.ipynb +++ b/applications/logistics/facility_location/facility_location.ipynb @@ -307,7 +307,7 @@ }, "outputs": [], "source": [ - "from classiq import construct_combinatorial_optimization_model\n", + "from classiq import *\n", "from classiq.applications.combinatorial_optimization import OptimizerConfig, QAOAConfig\n", "\n", "qaoa_config = QAOAConfig(num_layers=5, penalty_energy=10)" @@ -402,14 +402,11 @@ }, "outputs": [], "source": [ - "from classiq import set_execution_preferences\n", - "from classiq.execution import ClassiqBackendPreferences, ExecutionPreferences\n", + "from classiq.execution import ClassiqBackendPreferences\n", "\n", - "backend_preferences = ExecutionPreferences(\n", - " backend_preferences=ClassiqBackendPreferences(backend_name=\"simulator\")\n", - ")\n", - "\n", - "qmod = set_execution_preferences(qmod, backend_preferences)" + "qmod = set_execution_preferences(\n", + " qmod, backend_preferences=ClassiqBackendPreferences(backend_name=\"simulator\")\n", + ")" ] }, { @@ -426,8 +423,6 @@ }, "outputs": [], "source": [ - "from classiq import write_qmod\n", - "\n", "write_qmod(qmod, \"facility_location\")" ] }, @@ -567,8 +562,6 @@ } ], "source": [ - "from classiq import show, synthesize\n", - "\n", "qprog = synthesize(qmod)\n", "show(qprog)" ] @@ -596,9 +589,7 @@ }, "outputs": [], "source": [ - "from classiq import execute\n", - "\n", - "res = execute(qprog).result()" + "result = execute(qprog).result_value()" ] }, { @@ -637,10 +628,7 @@ } ], "source": [ - "from classiq.execution import VQESolverResult\n", - "\n", - "vqe_result = res[0].value\n", - "vqe_result.convergence_graph" + "result.convergence_graph" ] }, { @@ -754,7 +742,7 @@ ")\n", "\n", "solution = get_optimization_solution_from_pyo(\n", - " pmedian_model, vqe_result=vqe_result, penalty_energy=qaoa_config.penalty_energy\n", + " pmedian_model, vqe_result=result, penalty_energy=qaoa_config.penalty_energy\n", ")\n", "optimization_result = pd.DataFrame.from_records(solution)\n", "optimization_result.sort_values(by=\"cost\", ascending=True).head(5)" diff --git a/community/QClass_2024/Submissions/HW3/Samyak_Jain_HW3_VQE.ipynb b/community/QClass_2024/Submissions/HW3/Samyak_Jain_HW3_VQE.ipynb index 15bc864b..725bcd02 100644 --- a/community/QClass_2024/Submissions/HW3/Samyak_Jain_HW3_VQE.ipynb +++ b/community/QClass_2024/Submissions/HW3/Samyak_Jain_HW3_VQE.ipynb @@ -207,7 +207,7 @@ " # TODO: Create an ansatz which allows each qubit to have arbitrary rotation\n", " allocate(2, q)\n", " U(angles[0], angles[1], angles[2], 0, q[0])\n", - " CX(control=q[0], target=q[1])\n", + " CX(ctrl=q[0], target=q[1])\n", " U(angles[0], angles[1], angles[2], 0, q[1])\n", "\n", "\n", diff --git a/functions/function_declarations/core_lib_decls.qmod b/functions/function_declarations/core_lib_decls.qmod index b8db3559..25d961b6 100644 --- a/functions/function_declarations/core_lib_decls.qmod +++ b/functions/function_declarations/core_lib_decls.qmod @@ -26,14 +26,14 @@ qfunc R(theta: real, phi: real, target: qbit); qfunc RXX(theta: real, target: qbit[2]); qfunc RYY(theta: real, target: qbit[2]); qfunc RZZ(theta: real, target: qbit[2]); -qfunc CH(control: qbit, target: qbit); -qfunc CX(control: qbit, target: qbit); -qfunc CY(control: qbit, target: qbit); -qfunc CZ(control: qbit, target: qbit); -qfunc CRX(theta: real, control: qbit, target: qbit); -qfunc CRY(theta: real, control: qbit, target: qbit); -qfunc CRZ(theta: real, control: qbit, target: qbit); -qfunc CPHASE(theta: real, control: qbit, target: qbit); +qfunc CH(ctrl: qbit, target: qbit); +qfunc CX(ctrl: qbit, target: qbit); +qfunc CY(ctrl: qbit, target: qbit); +qfunc CZ(ctrl: qbit, target: qbit); +qfunc CRX(theta: real, ctrl: qbit, target: qbit); +qfunc CRY(theta: real, ctrl: qbit, target: qbit); +qfunc CRZ(theta: real, ctrl: qbit, target: qbit); +qfunc CPHASE(theta: real, ctrl: qbit, target: qbit); qfunc SWAP(qbit0: qbit, qbit1: qbit); qfunc IDENTITY(target: qbit[]); qfunc prepare_state(probabilities: real[], bound: real, output out: qbit[log(probabilities.len, 2)]); @@ -45,7 +45,7 @@ qfunc integer_xor(left: qbit[], right: qbit[]); qfunc modular_add_constant(left: real, right: qnum); qfunc real_xor_constant(left: real, right: qnum); qfunc U(theta: real, phi: real, lam: real, gam: real, target: qbit); -qfunc CCX(control: qbit[2], target: qbit); +qfunc CCX(ctrl: qbit[2], target: qbit); qfunc allocate(num_qubits: int, output out: qbit[num_qubits]); qfunc free(input in: qbit[]); qfunc randomized_benchmarking(num_of_cliffords: int, target: qbit[]); diff --git a/functions/function_declarations/open_lib_decls.qmod b/functions/function_declarations/open_lib_decls.qmod index 343f6b51..9772dd48 100644 --- a/functions/function_declarations/open_lib_decls.qmod +++ b/functions/function_declarations/open_lib_decls.qmod @@ -49,3 +49,5 @@ qfunc _prepare_uniform_trimmed_state_step(size_lsb: int, ctrl_val: int, lsbs_val qfunc _qct_d_operator(x: qnum, q: qbit); qfunc _qct_pi_operator(x: qbit[], q: qbit); qfunc _check_msb(ref: int, x: qbit[], aux: qbit); +qfunc encode_in_angle(data: real[], output qba: qbit[]); +qfunc encode_on_bloch(data: real[], output qba: qbit[]); diff --git a/functions/open_library_definitions/encode_in_angle.qmod b/functions/open_library_definitions/encode_in_angle.qmod new file mode 100644 index 00000000..d5b5e5c8 --- /dev/null +++ b/functions/open_library_definitions/encode_in_angle.qmod @@ -0,0 +1,6 @@ +qfunc encode_in_angle(data: real[], output qba: qbit[]) { + allocate(data.len, qba); + repeat (index: data.len) { + RY(pi * data[index], qba[index]); + } +} diff --git a/functions/open_library_definitions/encode_on_bloch.qmod b/functions/open_library_definitions/encode_on_bloch.qmod new file mode 100644 index 00000000..d4d6799e --- /dev/null +++ b/functions/open_library_definitions/encode_on_bloch.qmod @@ -0,0 +1,9 @@ +qfunc encode_on_bloch(data: real[], output qba: qbit[]) { + allocate(ceiling(data.len / 2), qba); + repeat (index: ceiling(data.len / 2)) { + RX(pi * data[2 * index], qba[index]); + } + repeat (index: floor(data.len / 2)) { + RZ(pi * data[(2 * index) + 1], qba[index]); + } +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.metadata.json b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.metadata.json new file mode 100644 index 00000000..77e5fd37 --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.metadata.json @@ -0,0 +1,6 @@ +{ + "friendly_name": "Encode in Angle", + "description": "Angle encoding of classical data", + "qmod_type": ["function"], + "level": ["demos", "basic"] +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.qmod b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.qmod new file mode 100644 index 00000000..3510209f --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.qmod @@ -0,0 +1,3 @@ +qfunc main(data: real[4], output x: qbit[]) { + encode_in_angle(data, x); +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.synthesis_options.json b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.synthesis_options.json new file mode 100644 index 00000000..a64dac4f --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_in_angle.synthesis_options.json @@ -0,0 +1,50 @@ +{ + "constraints": { + "max_width": null, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "r", + "p", + "rz", + "cz", + "sx", + "y", + "z", + "t", + "h", + "x", + "sxdg", + "u", + "rx", + "cy", + "u2", + "cx", + "tdg", + "sdg", + "ry", + "id", + "u1", + "s" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": 2425870057 + } +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.metadata.json b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.metadata.json new file mode 100644 index 00000000..5375227f --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.metadata.json @@ -0,0 +1,6 @@ +{ + "friendly_name": "Encode on Bloch", + "description": "Dense angle (Bloch sphere) encoding of classical data", + "qmod_type": ["function"], + "level": ["demos", "basic"] +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.qmod b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.qmod new file mode 100644 index 00000000..81e9d4a6 --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.qmod @@ -0,0 +1,3 @@ +qfunc main(data: real[7], output x: qbit[]) { + encode_on_bloch(data, x); +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.synthesis_options.json b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.synthesis_options.json new file mode 100644 index 00000000..60fc0ef9 --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/encode_on_bloch.synthesis_options.json @@ -0,0 +1,50 @@ +{ + "constraints": { + "max_width": null, + "max_depth": null, + "max_gate_count": {}, + "optimization_parameter": "no_opt" + }, + "preferences": { + "machine_precision": 8, + "backend_service_provider": null, + "backend_name": null, + "custom_hardware_settings": { + "basis_gates": [ + "r", + "p", + "rz", + "cz", + "sx", + "y", + "z", + "t", + "h", + "x", + "sxdg", + "u", + "rx", + "cy", + "u2", + "cx", + "tdg", + "sdg", + "ry", + "id", + "u1", + "s" + ], + "connectivity_map": null, + "is_symmetric_connectivity": true + }, + "debug_mode": true, + "output_format": ["qasm"], + "pretty_qasm": true, + "qasm3": null, + "transpilation_option": "auto optimize", + "solovay_kitaev_max_iterations": null, + "timeout_seconds": 300, + "optimization_timeout_seconds": null, + "random_seed": 2239067196 + } +} diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/angle_encoding_circuit.png b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/angle_encoding_circuit.png new file mode 100644 index 0000000000000000000000000000000000000000..36c42b61f4626eab87a367f48f2ef30b39f9d3a4 GIT binary patch literal 29714 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
KG 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 literal 0 HcmV?d00001 diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/dense_angle_encoding_circuit.png b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/figures/dense_angle_encoding_circuit.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8a55b32f79471c9d146725bb954f89ad9bbf38 GIT binary patch literal 115171 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�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%0DlxfE5 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ÎtDRzKr9pKU$J-S&LZ$qJV(#@d6={2oYq;>Bk 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 literal 0 HcmV?d00001 diff --git a/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb new file mode 100644 index 00000000..3f4a571c --- /dev/null +++ b/functions/qmod_library_reference/classiq_open_library/variational_data_encoding/variational_data_encoding.ipynb @@ -0,0 +1,193 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9eede0bd-bd8b-4f22-a03b-0d212334f026", + "metadata": {}, + "source": [ + "# Variational Data Encoding\n", + "\n", + "Encoding classical data on quantum states is an important subroutine in variational quantum circuits, such as Quantum Singular Vector Machine (QSVM) and Quantum Neural Networks (QNN). " + ] + }, + { + "cell_type": "markdown", + "id": "716790b4-d1d4-47ee-8b46-41d9c2c56c2d", + "metadata": {}, + "source": [ + "## Encode in angle\n", + "\n", + "This function encodes $n$ data points on $n$ qubits, mapping the data point $x_i$ to a RY rotation on the $i$-th qubit with a $\\pi x_i$ angle." + ] + }, + { + "cell_type": "markdown", + "id": "44009574-a515-4e08-a03a-71af6a973a68", + "metadata": {}, + "source": [ + "Function: `encode_in_angle`\n", + "\n", + "Arguments:\n", + "\n", + "- `data`: `CArray[Creal]`\n", + "- `qba`: `Output[QArray[QBit]]`\n", + "\n", + "The `qba` quantum argument is the quantum state on which we encode the classical array `data`." + ] + }, + { + "cell_type": "markdown", + "id": "4aaa84d1-36c5-4eb3-a713-593d9cc509b3", + "metadata": {}, + "source": [ + "## Example" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d67855d0-5461-4d8e-9f7d-1bc47ca80928", + "metadata": {}, + "outputs": [], + "source": [ + "from classiq import *\n", + "\n", + "\n", + "@qfunc\n", + "def main(data: CArray[CReal, 4], x: Output[QArray[QBit]]):\n", + " encode_in_angle(data, x)\n", + "\n", + "\n", + "qmod = create_model(main)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4e9bb384-4af0-4ab4-9e2e-2b8ba243ad5e", + "metadata": {}, + "outputs": [], + "source": [ + "from classiq import synthesize, write_qmod\n", + "\n", + "write_qmod(qmod, \"encode_in_angle\")\n", + "qprog = synthesize(qmod)" + ] + }, + { + "cell_type": "markdown", + "id": "2b15dc5a-17bc-4a05-baf2-0cb597e4b832", + "metadata": {}, + "source": [ + "![png](figures/angle_encoding_circuit.png)\n", + "
\n", + "
Angle encoding.
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "7bc356ad-e7f2-4f7c-8f10-5f7f38911853", + "metadata": {}, + "source": [ + "## Encode on Bloch\n", + "\n", + "This function encodes $n$ data points on $\\lceil n/2 \\rceil$, mapping pairs of data points $(x_{2i}, x_{2i+1})$ to the bloch sphere via RX rotation with an angle $\\pi x_{2i}$ followed by a RZ rotation with an angle $\\pi x_{2i+1}$. If the number of data points is odd then a single RX rotation is applied to the last qubit, with an angle of $2\\pi x_n$." + ] + }, + { + "cell_type": "markdown", + "id": "97515d2b-252d-4d0f-b19b-71deaca7b4b3", + "metadata": {}, + "source": [ + "Function: `encode_on_bloch`\n", + "\n", + "Arguments:\n", + "\n", + "- `data`: `CArray[Creal]`\n", + "- `qba`: `Output[QArray[QBit]]`\n", + "\n", + "The `qba` quantum argument is the quantum state on which we encode the classical array `data`." + ] + }, + { + "cell_type": "markdown", + "id": "7cd298b4-9066-480a-bf06-a3fec2349186", + "metadata": {}, + "source": [ + "## Example" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8950baf6-c12a-419a-8110-f4cf9b59d417", + "metadata": {}, + "outputs": [], + "source": [ + "from classiq import *\n", + "\n", + "\n", + "@qfunc\n", + "def main(data: CArray[CReal, 7], x: Output[QArray[QBit]]):\n", + " encode_on_bloch(data, x)\n", + "\n", + "\n", + "qmod = create_model(main)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d414992f-821c-4b16-930d-7fd864709340", + "metadata": {}, + "outputs": [], + "source": [ + "from classiq import synthesize, write_qmod\n", + "\n", + "write_qmod(qmod, \"encode_on_bloch\")\n", + "qprog = synthesize(qmod)" + ] + }, + { + "cell_type": "markdown", + "id": "e8b25648-fb42-4387-96ff-36c018290a55", + "metadata": {}, + "source": [ + "![png](figures/dense_angle_encoding_circuit.png)\n", + "
\n", + "
Dense angle (Bloch sphere) encoding.
\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c8bd4ef-5e91-4c20-95d8-adccd18d1f8f", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/research/README.md b/research/README.md index ee75c8bb..f115a4a5 100644 --- a/research/README.md +++ b/research/README.md @@ -56,7 +56,7 @@ in the table or to add new ones.
Exponential quantum speedup in simulating coupled classical oscillators - Glued Trees Implementation + Glued Trees Implementation Exponential speedup in solving system of coupled harmonic oscilators #quantum_speedup diff --git a/algorithms/glued_trees/figures/10_qubits.png b/research/glued_trees/figures/10_qubits.png similarity index 100% rename from algorithms/glued_trees/figures/10_qubits.png rename to research/glued_trees/figures/10_qubits.png diff --git a/algorithms/glued_trees/figures/20_qubits.png b/research/glued_trees/figures/20_qubits.png similarity index 100% rename from algorithms/glued_trees/figures/20_qubits.png rename to research/glued_trees/figures/20_qubits.png diff --git a/algorithms/glued_trees/figures/A_matrix.png b/research/glued_trees/figures/A_matrix.png similarity index 100% rename from algorithms/glued_trees/figures/A_matrix.png rename to research/glued_trees/figures/A_matrix.png diff --git a/algorithms/glued_trees/figures/glued_trees_diagram.png b/research/glued_trees/figures/glued_trees_diagram.png similarity index 100% rename from algorithms/glued_trees/figures/glued_trees_diagram.png rename to research/glued_trees/figures/glued_trees_diagram.png diff --git a/algorithms/glued_trees/glued_trees.ipynb b/research/glued_trees/glued_trees.ipynb similarity index 100% rename from algorithms/glued_trees/glued_trees.ipynb rename to research/glued_trees/glued_trees.ipynb diff --git a/algorithms/glued_trees/glued_trees_cache.json b/research/glued_trees/glued_trees_cache.json similarity index 100% rename from algorithms/glued_trees/glued_trees_cache.json rename to research/glued_trees/glued_trees_cache.json diff --git a/algorithms/glued_trees/glued_trees_example.metadata.json b/research/glued_trees/glued_trees_example.metadata.json similarity index 100% rename from algorithms/glued_trees/glued_trees_example.metadata.json rename to research/glued_trees/glued_trees_example.metadata.json diff --git a/algorithms/glued_trees/glued_trees_example.qmod b/research/glued_trees/glued_trees_example.qmod similarity index 100% rename from algorithms/glued_trees/glued_trees_example.qmod rename to research/glued_trees/glued_trees_example.qmod diff --git a/algorithms/glued_trees/glued_trees_example.synthesis_options.json b/research/glued_trees/glued_trees_example.synthesis_options.json similarity index 100% rename from algorithms/glued_trees/glued_trees_example.synthesis_options.json rename to research/glued_trees/glued_trees_example.synthesis_options.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+0.json b/research/glued_trees/results/10-qubits/2n+0.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+0.json rename to research/glued_trees/results/10-qubits/2n+0.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+10.json b/research/glued_trees/results/10-qubits/2n+10.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+10.json rename to research/glued_trees/results/10-qubits/2n+10.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+12.json b/research/glued_trees/results/10-qubits/2n+12.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+12.json rename to research/glued_trees/results/10-qubits/2n+12.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+2.json b/research/glued_trees/results/10-qubits/2n+2.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+2.json rename to research/glued_trees/results/10-qubits/2n+2.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+4.json b/research/glued_trees/results/10-qubits/2n+4.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+4.json rename to research/glued_trees/results/10-qubits/2n+4.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+6.json b/research/glued_trees/results/10-qubits/2n+6.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+6.json rename to research/glued_trees/results/10-qubits/2n+6.json diff --git a/algorithms/glued_trees/results/10-qubits/2n+8.json b/research/glued_trees/results/10-qubits/2n+8.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n+8.json rename to research/glued_trees/results/10-qubits/2n+8.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-10.json b/research/glued_trees/results/10-qubits/2n-10.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-10.json rename to research/glued_trees/results/10-qubits/2n-10.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-12.json b/research/glued_trees/results/10-qubits/2n-12.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-12.json rename to research/glued_trees/results/10-qubits/2n-12.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-2.json b/research/glued_trees/results/10-qubits/2n-2.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-2.json rename to research/glued_trees/results/10-qubits/2n-2.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-4.json b/research/glued_trees/results/10-qubits/2n-4.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-4.json rename to research/glued_trees/results/10-qubits/2n-4.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-6.json b/research/glued_trees/results/10-qubits/2n-6.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-6.json rename to research/glued_trees/results/10-qubits/2n-6.json diff --git a/algorithms/glued_trees/results/10-qubits/2n-8.json b/research/glued_trees/results/10-qubits/2n-8.json similarity index 100% rename from algorithms/glued_trees/results/10-qubits/2n-8.json rename to research/glued_trees/results/10-qubits/2n-8.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+0.json b/research/glued_trees/results/20-qubits/2n+0.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+0.json rename to research/glued_trees/results/20-qubits/2n+0.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+10.json b/research/glued_trees/results/20-qubits/2n+10.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+10.json rename to research/glued_trees/results/20-qubits/2n+10.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+12.json b/research/glued_trees/results/20-qubits/2n+12.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+12.json rename to research/glued_trees/results/20-qubits/2n+12.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+2.json b/research/glued_trees/results/20-qubits/2n+2.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+2.json rename to research/glued_trees/results/20-qubits/2n+2.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+4.json b/research/glued_trees/results/20-qubits/2n+4.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+4.json rename to research/glued_trees/results/20-qubits/2n+4.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+6.json b/research/glued_trees/results/20-qubits/2n+6.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+6.json rename to research/glued_trees/results/20-qubits/2n+6.json diff --git a/algorithms/glued_trees/results/20-qubits/2n+8.json b/research/glued_trees/results/20-qubits/2n+8.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n+8.json rename to research/glued_trees/results/20-qubits/2n+8.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-10.json b/research/glued_trees/results/20-qubits/2n-10.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-10.json rename to research/glued_trees/results/20-qubits/2n-10.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-12.json b/research/glued_trees/results/20-qubits/2n-12.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-12.json rename to research/glued_trees/results/20-qubits/2n-12.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-2.json b/research/glued_trees/results/20-qubits/2n-2.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-2.json rename to research/glued_trees/results/20-qubits/2n-2.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-4.json b/research/glued_trees/results/20-qubits/2n-4.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-4.json rename to research/glued_trees/results/20-qubits/2n-4.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-6.json b/research/glued_trees/results/20-qubits/2n-6.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-6.json rename to research/glued_trees/results/20-qubits/2n-6.json diff --git a/algorithms/glued_trees/results/20-qubits/2n-8.json b/research/glued_trees/results/20-qubits/2n-8.json similarity index 100% rename from algorithms/glued_trees/results/20-qubits/2n-8.json rename to research/glued_trees/results/20-qubits/2n-8.json diff --git a/tutorials/getting_started/part4_ghz_state.ipynb b/tutorials/getting_started/part4_ghz_state.ipynb index 6f1fd987..f8e4cf8a 100644 --- a/tutorials/getting_started/part4_ghz_state.ipynb +++ b/tutorials/getting_started/part4_ghz_state.ipynb @@ -94,7 +94,7 @@ " H(reg[0])\n", " repeat(\n", " count=reg.len - 1,\n", - " iteration=lambda index: CX(control=reg[index], target=reg[index + 1]),\n", + " iteration=lambda index: CX(ctrl=reg[index], target=reg[index + 1]),\n", " )\n", "\n", "\n", diff --git a/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_1.ipynb b/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_1.ipynb index c06de49a..b83ae1d4 100644 --- a/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_1.ipynb +++ b/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_1.ipynb @@ -4,44 +4,44 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# The Qmod Workshop - Part 1: Introduction\n", + "# Qmod Workshop - Part 1: Introduction\n", "\n", "The Classiq platform features a high-level quantum modeling language called Qmod. Qmod is compiled into concrete gate-level implementation using a powerful synthesis engine that optimizes and adapts the implementation to different target hardware/simulation environments.\n", "\n", - "In this workshop, we will learn how to write quantum models using Qmod. We will be using the Python embedding of Qmod, available as part of the Classiq Python SDK. We will learn basic concepts in the Qmod language, such as functions, operators, quantum variables, and quantum types. We will develop useful building blocks and small algorithms.\n", + "This workshop demonstrates how to write quantum models using Python embedding of Qmod, available as part of the Classiq Python SDK. You will learn basic concepts in the Qmod language such as functions, operators, quantum variables, and quantum types. You will develop useful building blocks and small algorithms.\n", "\n", - "The [QMOD language reference](https://docs.classiq.io/latest/qmod-reference/language-reference/) covers these concepts more systematically and includes more examples.\n", + "The [Qmod language reference](https://docs.classiq.io/latest/qmod-reference/language-reference/) covers these concepts more systematically and includes more examples.\n", "\n", "This workshop consists of step-by-step exercises. It is structured as follows:\n", "\n", "- Part 1: Language Fundamentals - Exercises 1-5\n", "- Part 2: Higher-Level Concepts - Exercises 6-10\n", - "- Part 3: Execution Flows - Exercises 11, 12\n", + "- Part 3: Execution Flows - Exercises 11-12\n", "\n", - "The introduction and Part 1 are included in this notebook. Part 2 and 3 are each in its own separate notebook. For each exercise you will find the solution to the exercises at the bottom of the same notebook.\n", + "The introduction and Part 1 are included in this notebook. Parts 2 and 3 are each in their own notebook. The solutions to the exercises are at the bottom of each notebook.\n", "\n", - "### Preparations\n", + "## Preparations\n", "\n", "Make sure you have a Python version of 3.8 through 3.12 installed.\n", "\n", - "Install Classiq’s Python SDK by following the instructions on this page: [Getting Started - Classiq](https://docs.classiq.io/latest/user-guide/synthesis/getting-started/).\n", + "Install the Classiq Python SDK using the instructions in [Getting Started - Classiq](https://docs.classiq.io/latest/user-guide/synthesis/getting-started/).\n", "\n", "### Python Qmod Exercises - General Instructions\n", "\n", - "In order to synthesize and execute your Qmod code, you should:\n", - "1. Make sure you define a `main` function that calls functions you create.\n", - "2. Use `create_model` by running `qmod = create_model(main)` to construct a representation of your model.\n", - "3. You can synthesize the model (using `qprog = synthesize(qmod)`) to obtain an implementation - a quantum program.\n", - "4. You can then visualize the quantum program (`show(qprog)`) or execute it (using `execute(qprog)`. See: [Execution - Classiq](https://docs.classiq.io/latest/classiq_101/classiq_concepts/execute/) ). You can also execute it with the IDE after visualizing the circuit.\n" + "To synthesize and execute your Qmod code:\n", + "1. Make sure you define a `main` function that calls the functions you create.\n", + "2. Construct a representation of your model using `create_model` by running `qmod = create_model(main)`.\n", + "3. Synthesize the model (using `qprog = synthesize(qmod)`) to obtain the implementation; i.e., a quantum program.\n", + "4. Visualize the quantum program (using `show(qprog)`) or execute it (using `execute(qprog)`. See: [Execution - Classiq](https://docs.classiq.io/latest/classiq_101/classiq_concepts/execute/) ). You can also execute it with the IDE after visualizing the circuit.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 0: From Model to Execution\n", + "### Preliminary Exercise: From Model to Execution\n", "\n", - "The following model defines a function that applies X and H gates on a single qubit, and subsequently calls it:" + "The following model defines a function that applies X and H gates on a single qubit and subsequently calls it:" ] }, { @@ -78,7 +78,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a model from it, and synthesize, visualize, and execute it.\n", + "Create a model from it, then synthesize, visualize, and execute it.\n", "\n", "Use the General Instructions above to do so.\n" ] @@ -105,18 +105,18 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In Qmod `QBit` is the simplest quantum type, and in this example, `q` is a quantum variable of type `QBit`. Quantum variables abstract away the mapping of quantum objects to qubits in the actual circuit.\n", + "In Qmod, `QBit` is the simplest quantum type. In this example, `q` is a quantum variable of type `QBit`. Quantum variables abstract away the mapping of quantum objects to qubits in the actual circuit.\n", "\n", - "See also [Quantum Variables](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-variables/).\n", + "See [quantum variables](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-variables/).\n", "\n", - "We will discuss other quantum types during the workshop.\n" + "You will encounter additional quantum types during the workshop.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# The Qmod Workshop - Part 1: Language Fundamentals\n", + "## Part 1: Language Fundamentals\n", "\n", "Follow exercises 1 through 5 for the first session of the workshop." ] @@ -125,12 +125,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Exercise 1 - Bell Pair\n", + "### Exercise 1 - Bell Pair\n", "\n", "Create a function that takes two single-qubit (`QBit`) quantum arguments and prepares the bell state on them ([Bell state](https://en.wikipedia.org/wiki/Bell_state)) by applying `H` on one variable and then using it as the control of a `CX` function with the second variable as the target.\n", "Create a main function that uses this function and has two single-qubit outputs, initialize them to the |0> state (using the `allocate` function), and apply your function to them.\n", "\n", - "See also [Functions](https://docs.classiq.io/latest/qmod-reference/language-reference/functions/#syntax)\n" + "See [functions](https://docs.classiq.io/latest/qmod-reference/language-reference/functions/#syntax).\n" ] }, { @@ -167,7 +167,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Use qubit array subscript (the syntax - _variable_ **[** _index-expression_ **]**) to change the function from subsection 1 to receive a single quantum variable, a qubit array (`QArray`) of size 2.\n", + "Use the qubit array subscript (the syntax - _variable_ **[** _index-expression_ **]**) to change the function from subsection 1 to receive a single quantum variable: a qubit array (`QArray`) of size 2.\n", "Change your main function to declare a single output (also an array of size 2).\n" ] }, @@ -205,13 +205,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Exercise 2 - Repeat\n", + "### Exercise 2 - Repeat\n", "\n", - "Use the built-in `repeat` operator to create your own Hadamard transform function (call it `my_hadamard_transform`). The Hadamard transform function is a function that takes as argument a qubit array of an unspecified size and applies `H` to each of its qubit.\n", + "Use the built-in `repeat` operator to create your own Hadamard transform function (and call it `my_hadamard_transform`). The Hadamard transform function takes a qubit array of an unspecified size as an argument and applies `H` to each of its qubits.\n", "\n", - "See also [Classical repeat](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/classical-control-flow/#classical-repeat).\n", + "See [classical repeat](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/classical-control-flow/#classical-repeat).\n", "\n", - "Set your main function to have a quantum array output of unspecified size, allocate 10 qubits, and then apply your Hadamard transform function.\n" + "Set your main function to have a quantum array output of unspecified size. Allocate 10 qubits and then apply your Hadamard transform function.\n" ] }, { @@ -248,11 +248,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Note: Quantum Variable Capture\n", + "Note: Quantum variable capture:\n", "The `repeat` operator invokes a statement block multiple times. The statement block is specified using a Python callable, typically a lambda expression. Inside the block you can refer to variables declared in the outer function scope.\n", - "This concept is called `quantum variable capture`, equivalent to [capture](https://en.wikipedia.org/wiki/Closure_(computer_programming)) in classical languages.\n", + "This concept is called `quantum variable capture`, and is equivalent to [capture](https://en.wikipedia.org/wiki/Closure_(computer_programming) in classical languages.\n", "\n", - "See also [Capturing context variables and parameters](https://docs.classiq.io/latest/qmod-reference/language-reference/operators/#capturing-context-variables-and-parameters)." + "See [capturing context variables and parameters](https://docs.classiq.io/latest/qmod-reference/language-reference/operators/#capturing-context-variables-and-parameters)." ] }, { @@ -260,13 +260,13 @@ "metadata": {}, "source": [ "### Exercise 3 - Power\n", - "Raising a quantum operation to a power appears in many known algorithms, for examples, in Grover search and Quantum Phase Estimation.\n", - "For most operations, it simply means repeating the same circuit multiple times.\n", + "Raising a quantum operation to a power appears in many known algorithms; for example, in Grover search and Quantum Phase Estimation.\n", + "For most operations, it means repeating the same circuit multiple times.\n", "\n", - "Sometimes, however, power can be simplified, thus saving computational resources.\n", - "The most trivial example is a quantum operation expressed as a single explicit unitary matrix (i.e., all n*n matrix terms are given) - raising the operation can be done by raising the matrix to that power via classical programming.\n", + "Sometimes, however, power can be simplified, thereby saving computational resources.\n", + "The most trivial example is a quantum operation expressed as a single explicit unitary matrix (i.e., all n*n matrix terms are given). Raising the operation can be done by raising the matrix to that power via classical programming.\n", "\n", - "See also [Power operator](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/power/#syntax).\n", + "See [power operator](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/power/#syntax).\n", "\n", "Use the following code to generate a 2-qubit (real) unitary matrix:" ] @@ -301,13 +301,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In order to reuse some classical value we can define a `QConstant` to store that value.\n", + "To reuse a classical value, define `QConstant` to store it.\n", "\n", - "1. Create a model that applies `unitary_matrix` on a 2 qubit variable.\n", - "2. Create another model that applies `unitary_matrix` raised to power 3 on a 2 qubit variable.\n", - "3. Compare the gate count via the Classiq’s IDE in both cases.\n", + "1. Create a model that applies `unitary_matrix` on a 2-qubit variable.\n", + "2. Create another model that applies `unitary_matrix` raised to the power of 3 on a 2-qubit variable.\n", + "3. Compare the gate count via the Classiq IDE in both cases.\n", "\n", - "Note - the signature of function `unitary` is:" + "The signature of function `unitary`:" ] }, { @@ -364,17 +364,17 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Exercise 4 - User-defined Operators\n", - "Create a function that applies a given single-qubit operation to all qubits in its quantum argument (Call your function `my_apply_to_all`). Such a function is also called an operator, i.e. a function that one of its arguments is another function (its operand).\n", + "### Exercise 4 - User-defined Operators\n", + "Create a function that applies a given single-qubit operation to all qubits in its quantum argument (call your function `my_apply_to_all`). Such a function is also called an operator; i.e., a function with an argument that is another function (its operand).\n", "\n", - "See also [Operators](https://docs.classiq.io/latest/qmod-reference/language-reference/operators/).\n", + "See [operators](https://docs.classiq.io/latest/qmod-reference/language-reference/operators/).\n", "\n", "Follow these guidelines:\n", - "1. Your function should declare a quantum argument of type qubit array. It should also declare an argument of a function type with a single qubit argument.\n", - "2. The body should apply the operand to all qubits in the argument.\n", + "1. Your function declares a quantum argument of type qubit array and an argument of a function type with a single qubit argument.\n", + "2. The body applies the operand to all qubits in the argument.\n", "\n", - "When you're done, re-implement `my_hadamard_transform` from exercise 2 using this function instead of `repeat`.\n", - "Use the same main function from exercise 2." + "Now, re-implement `my_hadamard_transform` from Exercise 2 using this function instead of `repeat`.\n", + "Use the same main function from Exercise 2." ] }, { @@ -411,12 +411,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Exercise 5 - Quantum Conditionals\n", + "### Exercise 5 - Quantum Conditionals\n", "\n", - "### Exercise 5a - Control Operator\n", - "Use the built-in `control` operator to create a function that receives two single qubit variables and uses one of the variables to control an RY gate with a `pi/2` angle acting on the other variable (without using the `CRY` function).\n", + "#### Exercise 5a - Control Operator\n", + "Use the built-in `control` operator to create a function that receives two single qubit variables and uses one of them to control an RY gate with a `pi/2` angle acting on the other variable (without using the `CRY` function).\n", "\n", - "See also [Control](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/control/#syntax).\n" + "See [control](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/control/#syntax).\n" ] }, { @@ -453,15 +453,15 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 5b - Control Operator with Quantum Expressions\n", - "The `control` operator is the conditional application of some operation, with the condition being that all control qubits are in the state |1>. This notion is generalized in QMOD to other control states, where the condition is specified as a comparison between a quantum numeric variable and a numeric value, similar to a classical `if` statement. Quantum numeric variables are declared with class `QNum`.\n", + "#### Exercise 5b - Control Operator with Quantum Expressions\n", + "The `control` operator is the conditional application of some operation, with the condition being that all control qubits are in the state |1>. This notion is generalized in Qmod to other control states, where the condition is specified as a comparison between a quantum numeric variable and a numeric value, similar to a classical `if` statement. Quantum numeric variables are declared with class `QNum`.\n", "\n", - "See also [Numeric types](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types/#syntax).\n", + "See [numeric types](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types/#syntax).\n", "\n", "1. Declare a `QNum` output argument using `Output[QNum]` and name it `x`.\n", - "2. Use the `prepare_int` function to initialize it to `9`. Note that you don't need to specify the `QNum` attributes - size, sign, and fraction digits, as they are inferred at the point of initialization.\n", + "2. Use the `prepare_int` function to initialize it to `9`. Note that you don't need to specify the `QNum` attributes: size, sign, and fraction digits, as they are inferred at the point of initialization.\n", "3. Execute the circuit and observe the results.\n", - "4. Declare another output argument of type `QBit` and perform a `control` such that under the condition that `x` is 9, the qubit is flipped. Execute the circuit and observe the results. Repeat for a different condition." + "4. Declare another output argument of type `QBit` and perform a `control` such that if `x` is 9, the qubit is flipped. Execute the circuit and observe the results. Repeat for a different condition." ] }, { @@ -636,7 +636,7 @@ } ], "source": [ - "# Solution to exercise 3:\n", + "# Solution to Exercise 3:\n", "\n", "\n", "from typing import List\n", @@ -683,7 +683,7 @@ }, "outputs": [], "source": [ - "# Solution for exercise 4:\n", + "# Solution for Exercise 4:\n", "\n", "\n", "from classiq import *\n", @@ -733,7 +733,7 @@ } ], "source": [ - "# Solution for exercise 5a:\n", + "# Solution for Exercise 5a:\n", "\n", "\n", "from classiq import *\n", @@ -778,7 +778,7 @@ } ], "source": [ - "# Solution for exercise 5b:\n", + "# Solution for Exercise 5b:\n", "\n", "\n", "from classiq import *\n", diff --git a/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_2.ipynb b/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_2.ipynb index 88ac17b0..05d12515 100644 --- a/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_2.ipynb +++ b/tutorials/workshops/QMOD_workshop/QMOD_Workshop_Part_2.ipynb @@ -4,28 +4,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# The Qmod Workshop - Part 2: Higher-Level Concepts\n", + "# Qmod Workshop - Part 2: Higher-Level Concepts\n", "\n", - "This is the second part of the Qmod workshop, covering exercises 6 through 10. Make sure to go through Part 1 before continuing with this notebook." + "This second part of the Qmod workshop covers exercises 6 through 10. Make sure to go through Part 1 before continuing with this notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 6 - Exponentiation and Pauli Operators\n", + "## Exercise 6 - Exponentiation and Pauli Operators\n", "\n", - "The Qmod language supports different classical types: scalars, arrays, and structs. Structs are objects with member variables, or fields.\n", + "The Qmod language supports different classical types: scalars, arrays, and structs. Structs are objects with member variables or fields.\n", "\n", - "See also [Classical Types](https://docs.classiq.io/latest/qmod-reference/language-reference/classical-types/#structs).\n", + "See [classical types](https://docs.classiq.io/latest/qmod-reference/language-reference/classical-types/#structs).\n", "\n", - "The builtin struct type `PauliTerm` is defined as follows:" + "The built-in `PauliTerm` struct type is defined as follows:" ] }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:16.997105Z", + "start_time": "2024-10-07T13:38:14.764009Z" + } + }, "outputs": [], "source": [ "from dataclasses import dataclass\n", @@ -45,17 +50,22 @@ "source": [ "Note that `Pauli` is an enum for all the Pauli matrices (I, X, Y, Z).\n", "\n", - "Pauli based hamiltonian can be represented as a list of `PauliTerm`s. A Pauli operator defined this way is the argument to a hamiltonian evolution functions.\n", + "A Pauli-based Hamiltonian can be represented as a list of `PauliTerm`s. A Pauli operator defined this way is the argument to Hamiltonian evolution functions.\n", "\n", - "In this exercise we will use the Suzuki-Trotter function to find the evolution of `H=0.5XZXX + 0.25YIZI + 0.3 XIZY` (captured as a literal value for the pauli-operator), with the evolution coefficient being 3, the order being 2, and use 4 repetitions.\n", + "This exercise uses the Suzuki-Trotter function to find the evolution of `H=0.5XZXX + 0.25YIZI + 0.3 XIZY` (captured as a literal value for the Pauli operator), with the evolution coefficient being 3, the order being 2, and using 4 repetitions.\n", "\n", - "The declaration of the `suzuki_trotter` function is:" + "The declaration of the `suzuki_trotter` function:" ] }, { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:17.008592Z", + "start_time": "2024-10-07T13:38:17.006309Z" + } + }, "outputs": [], "source": [ "@qfunc(external=True)\n", @@ -73,7 +83,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Allocate q and invoke the suzuki_trotter quantum function to complete this exercise:\n", + "To complete this exercise, allocate q and invoke the `suzuki_trotter` quantum function:\n", "\n", "
\n", " HINT\n", @@ -90,16 +100,13 @@ { "cell_type": "code", "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Opening: https://platform.classiq.io/circuit/1bb9845d-ce2f-40ff-b47b-b0e1dcc53137?version=0.42.1\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:29.067853Z", + "start_time": "2024-10-07T13:38:17.012016Z" } - ], + }, + "outputs": [], "source": [ "from classiq import *\n", "\n", @@ -118,28 +125,36 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 7 - Basic Arithmetics\n", + "## Exercise 7 - Basic Arithmetics\n", + "\n", + "This exercise uses quantum numeric variables and calculates expressions over them.\n", + "\n", + "See details on the syntax of numeric types in [quantum types](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types/#syntax).\n", + "See more on quantum expressions in [numeric assignment](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/numeric-assignment/).\n", "\n", - "#### Exercise 7a\n", - "In this exercise we will use quantum numeric variables and calculate expressions over them.\n", + "### Exercise 7a\n", "\n", - "See details on the syntax of numeric types under [Quantum types](https://docs.classiq.io/latest/qmod-reference/language-reference/quantum-types/#syntax).\n", - "See more on quantum expressions under [Numeric assignment](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/numeric-assignment/).\n", + "Create these quantum programs:\n", "\n", - "Create the following quantum programs:\n", - "1. Initialize variables `x=2`, `y=7` and computes `res = x + y`.\n", - "2. Initialize variables `x=2`, `y=7` and computes `res = x * y`.\n", - "3. Initialize variables `x=2`, `y=7`, `z=1` and computes `res = x * y - z`.\n", + "1. Initialize variables `x=2`, `y=7` and compute `res = x + y`.\n", + "2. Initialize variables `x=2`, `y=7` and compute `res = x * y`.\n", + "3. Initialize variables `x=2`, `y=7`, `z=1` and compute `res = x * y - z`.\n", "\n", "Guidance:\n", - "* Use the operator `|=` to perform out-of-place assignment of arithmetic expression.\n", - "* To initialize the variables, use the function `prepare_int`.\n" + "\n", + "* Use the `|=` operators to perform out-of-place assignment of arithmetic expressions.\n", + "* To initialize the variables, use the `prepare_int` function.\n" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:35.979170Z", + "start_time": "2024-10-07T13:38:29.332984Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -155,20 +170,25 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exercise 7b\n", - "Declare `x` to be a 2-qubit variable and `y` to be 3-qubit variable.\n", + "### Exercise 7b\n", + "Declare `x` to be a 2-qubit variable and `y` a 3-qubit variable.\n", "\n", - "We will perform an addition of two superposition states: `x` is an equal superposition of `0` and `2`, and `y` is an equal superposition of `1`, `2`, `3`, and `6`.\n", + "Add two superposition states such that `x` is an equal superposition of `0` and `2`, and `y` is an equal superposition of `1`, `2`, `3`, and `6`.\n", "\n", "1. Use `prepare_state` to initialize `x` and `y`. Note that `prepare_state` works with probabilities, not amplitudes.\n", - " The declaration of the `prepare_state` function is:\n", + " The declaration of the `prepare_state` function:\n", " " ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:35.999428Z", + "start_time": "2024-10-07T13:38:35.989273Z" + } + }, "outputs": [], "source": [ "@qfunc(external=True)\n", @@ -192,8 +212,13 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:39.116182Z", + "start_time": "2024-10-07T13:38:36.020261Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -209,18 +234,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 8 - Within-Apply\n", + "## Exercise 8 - Within-Apply\n", + "\n", + "The within-apply statement applies the `U_dagger V U` pattern that appears frequently in quantum computing.\n", + "It allows you to compute a function `V` within the context of another function `U`, and afterward uncompute `U` to release auxiliary qubits storing intermediate results.\n", "\n", - "The within-apply statement applies the pattern `U_dagger V U` that appears frequently in quantum computing.\n", - "It allows you to compute some function `V` within the context of another function `U`, and afterward uncompute `U` in order to release auxiliary qubits storing intermediate results.\n", + "See [within apply](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/within-apply/).\n", "\n", - "See also [Within Apply](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/within-apply/).\n", + "### Exercise 8a\n", "\n", - "#### Exercise 8a\n", + "This exercise uses `within-apply` to compute an arithmetic expression in steps.\n", "\n", - "In this exercise, we will use within-apply to compute an arithmetic expression in steps.\n", + "Use the `within_apply` operation to calculate `res = x + y + z` from a two-variable addition building block with these steps:\n", "\n", - "Use the `within_apply` operation to calculate `res = x + y + z` from a two-variable addition building block with the following steps:\n", "1. Add `x` and `y`\n", "2. Add the result to `z`\n", "3. Uncompute the result of the first operation\n", @@ -237,8 +263,13 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:49.235798Z", + "start_time": "2024-10-07T13:38:39.125653Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -254,37 +285,34 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exercise 8b\n", + "### Exercise 8b\n", "\n", - "Why should we use `within-apply` and not just write three concatenated functions?\n", - "To understand the motivation, we will create another arithmetic circuit.\n", - "This time, however, we will also set Classiq’s synthesis engine to optimize on the circuit’s number of qubits, i.e., its width.\n", + "Why use `within-apply` and not just write three concatenated functions?\n", + "To understand the motivation, create another arithmetic circuit.\n", + "This time, however, set the Classiq synthesis engine to optimize on the circuit’s number of qubits; i.e., its width.\n", "\n", - "Setting constraints can be done via the `set_constraints` operation - see [here](https://docs.classiq.io/latest/user-guide/synthesis/constraints/).\n", + "Determine constraints with the `set_constraints` operation. (See [here](https://docs.classiq.io/latest/user-guide/synthesis/constraints/)\\).\n", "\n", "Perform the operation `res = w + x + y + z`, where w is initialized to 4 and the rest as before:\n", "\n", "1. Add `x` and `y` (as part of the `within_apply` operation)\n", - "2. Add the result to `z` (as part of the within_apply operation)\n", + "2. Add the result to `z` (as part of the `within_apply` operation)\n", "3. Uncompute the result of the first operation (as part of the `within_apply` operation)\n", - "4. Add the result of the second operation to `w`. There’s no need to perform another uncomputation, as this brings our calculation to an end.\n", + "4. Add the result of the second operation to `w`. There is no need to perform another uncomputation, as this brings the calculation to an end.\n", "\n", "Create the model, optimize on the circuit’s width, and run the circuit. Can you identify where qubits have been released and reused?" ] }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Opening: https://platform.classiq.io/circuit/c2147d5f-03da-46f9-abb9-9f224cf494b5?version=0.42.1\n" - ] + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:54.717424Z", + "start_time": "2024-10-07T13:38:49.244374Z" } - ], + }, + "outputs": [], "source": [ "from classiq import *\n", "\n", @@ -299,18 +327,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Bonus: Use a Single Arithmetic Expression\n", + "### Bonus: Use a Single Arithmetic Expression\n", "\n", - "What happens when we don't manually decompose this expression?\n", + "What happens when you don't manually decompose this expression?\n", "\n", - "Use Classiq’s arithmetic engine to calculate `res |= x + y + z + w` and optimize for width.\n", - "Look at the resulting quantum program - can you identify the computation and uncomputation blocks? What else did you notice?" + "Use the Classiq arithmetic engine to calculate `res |= x + y + z + w` and optimize for width.\n", + "Look at the resulting quantum program. Can you identify the computation and uncomputation blocks? What else do you notice?" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:38:59.101064Z", + "start_time": "2024-10-07T13:38:54.754764Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -326,17 +359,17 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 9 - In-place Arithmetics\n", + "## Exercise 9 - In-place Arithmetics\n", "\n", - "For the following exercise we will use numeric quantum variables that represent fixed-point reals.\n", + "This exercise uses numeric quantum variables that represent fixed-point reals.\n", "\n", - "Arithmetic expressions can be calculated in-place into a target variable, without allocating new qubits to store the result. This is done using the in-place-xor operator.\n", + "Arithmetic expressions can be calculated in place into a target variable, without allocating new qubits to store the result. This is done using the in-place-xor operator.\n", "\n", - "See also [Numeric assignment](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/numeric-assignment/#semantics).\n", + "See [numeric assignment](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/numeric-assignment/#semantics).\n", "\n", - "In-place assignment is often used to nest arithmetic expressions under quantum operators. Note that out-of-place assignment requires its left-value variable to be un-initialized, and therefore cannot be used under an operator if the variable is declared outside its scope. Applying operators to arithmetic expressions is required in many algorithms. One example is the piecewise evaluation of mathematical functions - calculating different expressions over `x` depending on the subdomain where `x` falls.\n", + "In-place assignment is often used to nest arithmetic expressions under quantum operators. Note that out-of-place assignment requires its left-value variable to be uninitialized, and therefore cannot be used under an operator if the variable is declared outside its scope. Applying operators to arithmetic expressions is required in many algorithms. One example is the piecewise evaluation of mathematical functions; calculating different expressions over `x` depending on the subdomain where `x` falls.\n", "\n", - "For this exercise, replace the missing parts in the code snippet below to evaluate the result of:\n", + "For this exercise, replace the missing parts in the code snippet below to evaluate the result:\n", "\n", "$$\n", "f(x) = \\begin{cases}\n", @@ -346,8 +379,8 @@ "$$\n", "\n", "Notes:\n", - "- We cannot use `x` directly as the control variable in a `constrol` operator, because it also occurs in the nested scope. to determine if `x` is in the lower or higher half of the domain we duplicate the most significant bit onto a separate variable called `label`.\n", - "- In Python assignment operators cannot be used in lambda expressions, so the computation of the function needs to be factored out to a named Python function (but not necessarily a Qmod function).\n", + "- You cannot use `x` directly as the control variable in a `control` operator because it also occurs in the nested scope. To determine if `x` is in the lower or upper half of the domain, duplicate the most significant bit (MSB) onto a separate variable called `label`.\n", + "- In Python, assignment operators cannot be used in lambda expressions, so the computation of the function needs to be factored out to a named Python function (but not necessarily a Qmod function).\n", "\n", "\n", "
\n", @@ -362,8 +395,13 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:02.550042Z", + "start_time": "2024-10-07T13:38:59.191353Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -394,25 +432,22 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercise 10 - State-preparation Algorithm using Quantum-if\n", + "## Exercise 10 - State-preparation Algorithm Using quantum-if\n", "\n", - "#### Binding\n", - "The `bind` operation allows to convert smoothly between different quantum types and split or slice bits when necessary. Here’s an example:" + "### Binding\n", + "The `bind` operation smoothly converts between different quantum types and splits or slices bits when necessary. Here is an example:" ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Opening: https://platform.classiq.io/circuit/ac3ae5f1-7af8-46d6-ac00-aead9e95ecbd?version=0.42.1\n" - ] + "execution_count": 11, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:07.035217Z", + "start_time": "2024-10-07T13:39:02.581092Z" } - ], + }, + "outputs": [], "source": [ "from classiq import *\n", "\n", @@ -438,33 +473,39 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The first `bind` operation splits the 3-qubit register `x` into the 2-qubit and single-qubit registers `lsb` and `msb`, respectively.\n", + "The first `bind` operation splits the 3-qubit register `x` into the 2-qubit and single-qubit `lsb` and `msb` registers, respectively.\n", "\n", "After the `bind` operation:\n", - "1. The registers `lsb` and `msb` can be operated on as separated registers.\n", - "2. The register`x` is consumed and can no longer be used.\n", "\n", - "The second `bind` operation concatenates the registers to the output register `res`.\n", + "1. The `lsb` and `msb` registers can be operated on separately.\n", + "2. The `x` register is consumed and can no longer be used.\n", + "\n", + "The second `bind` operation concatenates the registers to the `res` output register.\n", "\n", - "For this exercise, fill in the missing code parts in the above snippet and use the `control` statement to manually generate the following lovely 3-qubit probability distribution: `[1/8, 1/8, 1/8, -sqrt(3)/16, 1/8 + sqrt(3)/16, 1/8, 1/8, 1/8, 1/8]`.\n", + "For this exercise, fill in the missing code parts in the above snippet and use the `control` statement to manually generate a lovely 3-qubit probability distribution: `[1/8, 1/8, 1/8, -sqrt(3)/16, 1/8 + sqrt(3)/16, 1/8, 1/8, 1/8, 1/8]`.\n", "\n", "The following series of gates generate it:\n", "\n", "Perform the Hadamard transform on all three qubits.\n", "\n", - "Apply a rotation on the LSB (least-significant bit) conditioned by the MSB being |0> and the second to last MSB being |1>. How would you write this condition using a QNum?\n", + "Apply a rotation on the least-significant bit (LSB) conditioned by the MSB being |0> and the second-to-last MSB being |1>. How would you write this condition using a QNum?\n", "\n", "The following series of gates generate it:\n", "1. Perform the Hadamard transform on all three qubits.\n", - "2. Apply a `pi/3` rotation on the LSB (least-significant bit) conditioned by the MSB being |0> and the second to last MSB being |1>. How would you write this condition using a QNum?\n", + "2. Apply a `pi/3` rotation on the LSB conditioned by the MSB being |0> and the second-to-last MSB being |1>. How would you write this condition using a QNum?\n", "\n", - "If you want to validate your results without looking at the full solution, compare them to running using Classiq’s built-in `prepare_state` function.\n" + "To validate your results without looking at the full solution, compare them to running using the Classiq built-in `prepare_state` function.\n" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 12, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:07.114464Z", + "start_time": "2024-10-07T13:39:07.109176Z" + } + }, "outputs": [], "source": [ "from classiq import *\n", @@ -509,11 +550,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 13, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:07.126045Z", + "start_time": "2024-10-07T13:39:07.122916Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 6:\n", + "# Solution to Exercise 6:\n", "\n", "\n", "from classiq import *\n", @@ -544,11 +590,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 14, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:07.167263Z", + "start_time": "2024-10-07T13:39:07.160530Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 7a:\n", + "# Solution to Exercise 7a:\n", "\n", "\n", "from classiq import *\n", @@ -569,11 +620,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 15, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:10.853181Z", + "start_time": "2024-10-07T13:39:07.187009Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 7b:\n", + "# Solution to Exercise 7b:\n", "\n", "\n", "from classiq import *\n", @@ -602,11 +658,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 16, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:17.883614Z", + "start_time": "2024-10-07T13:39:10.857886Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 8:\n", + "# Solution to Exercise 8:\n", "\n", "\n", "from classiq import *\n", @@ -637,11 +698,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 17, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:26.245095Z", + "start_time": "2024-10-07T13:39:17.891400Z" + } + }, "outputs": [], "source": [ - "# Solution to the advanced part of exercise 8:\n", + "# Solution to the advanced part of Exercise 8:\n", "\n", "\n", "from classiq import *\n", @@ -688,11 +754,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 18, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:26.331226Z", + "start_time": "2024-10-07T13:39:26.326156Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 9:\n", + "# Solution to Exercise 9:\n", "\n", "\n", "from classiq import *\n", @@ -731,11 +802,16 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 19, + "metadata": { + "ExecuteTime": { + "end_time": "2024-10-07T13:39:36.928795Z", + "start_time": "2024-10-07T13:39:26.340807Z" + } + }, "outputs": [], "source": [ - "# Solution to exercise 10:\n", + "# Solution to Exercise 10:\n", "\n", "\n", "from classiq import *\n", @@ -765,7 +841,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.11.7 ('classiq_devolpment')", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -779,7 +855,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.7" + "version": "3.11.9" }, "vscode": { "interpreter": { @@ -788,5 +864,5 @@ } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 }