diff --git a/community/QClass_2024/Submissions/HW4/HW_4_Bill_Wisotsky.ipynb b/community/QClass_2024/Submissions/HW4/HW_4_Bill_Wisotsky.ipynb
index 0527c4e6f..a8bd7ad8a 100644
--- a/community/QClass_2024/Submissions/HW4/HW_4_Bill_Wisotsky.ipynb
+++ b/community/QClass_2024/Submissions/HW4/HW_4_Bill_Wisotsky.ipynb
@@ -6,7 +6,7 @@
"source": [
"# Kidney Exchange QAOA Example\n",
"Used samples from Classiq github on QAOA and internet for pyomo models \n",
- "Modified as needed for specific problem and limitations based on account. \n",
+ "Modified as needed for specfic problem and limitations based on account. \n",
"\n",
"What is the Problem? \n",
"Currently there are more than 100,000 patients on the waitling list in the United States for a kidney transplant from a deceased donor. This is addressed by the a program called the Kidney Exchange Program. This program won the Nobel Prize in Economics for Alvin E. Roth and Lloyd S. Shapley's contributions to the theory of stable matchings and the design of markets on 2012.\n",
diff --git a/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.ipynb b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.ipynb
new file mode 100644
index 000000000..6fea6965a
--- /dev/null
+++ b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.ipynb
@@ -0,0 +1,138 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "f6834a62-d124-48f6-bd87-d313b7eb5054",
+ "metadata": {},
+ "source": [
+ "# Modular Exponentiation\n",
+ "\n",
+ "The `modular_exp` function raises a classical integer `a` to the power of a quantum number `power` modulo classical integer `n`, times a quantum number `x`.\n",
+ "\n",
+ "The function performs:\n",
+ "$$|x\\rangle |power\\rangle = |(a^{power} \\mod n)\\cdot x\\rangle | power\\rangle$$\n",
+ "\n",
+ "Specifically if at the input $x=1$, at the output $x=a^{power} \\mod n$."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b54ad820-bdd9-4fbe-bbe7-a7d6a3db046b",
+ "metadata": {},
+ "source": [
+ "# Example\n",
+ "\n",
+ "This example generates a quantum program that initializes a `power` variable with a uniform superposition, and exponentiate the classical value `A` with `power` as the exponent, in superposition. The result is calculated inplace to the variable `x` module `N`.\n",
+ "\n",
+ "Notice that `x` should have size of at least $\\lceil(log_2(N) \\rceil$, so it is first allocated with a fixed size, then initialized with the value '1'."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "6fca39ac-e769-4d85-b9a9-0bed93d2b775",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "\n",
+ "from classiq import *\n",
+ "from classiq.qmod.symbolic import ceiling, log\n",
+ "\n",
+ "# constants\n",
+ "N = 5\n",
+ "A = 4\n",
+ "\n",
+ "\n",
+ "@qfunc\n",
+ "def main(power: Output[QNum], x: Output[QNum]) -> None:\n",
+ " allocate(ceiling(log(N, 2)), x)\n",
+ " inplace_prepare_int(1, x)\n",
+ "\n",
+ " # initialize a uniform superposition of powers\n",
+ " allocate(3, power)\n",
+ " hadamard_transform(power)\n",
+ "\n",
+ " modular_exp(n=N, a=A, x=x, power=power)\n",
+ "\n",
+ "\n",
+ "qmod = create_model(main)\n",
+ "qmod = create_model(main, out_file=\"modular_exp_example\")\n",
+ "qprog = synthesize(qmod)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "d7931d74-f1b6-4374-832e-eee4e3e0ab4b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[{'power': 3, 'x': 4}: 136,\n",
+ " {'power': 1, 'x': 4}: 135,\n",
+ " {'power': 7, 'x': 4}: 130,\n",
+ " {'power': 5, 'x': 4}: 124,\n",
+ " {'power': 2, 'x': 1}: 124,\n",
+ " {'power': 4, 'x': 1}: 123,\n",
+ " {'power': 6, 'x': 1}: 117,\n",
+ " {'power': 0, 'x': 1}: 111]"
+ ]
+ },
+ "execution_count": 40,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "result = execute(qprog).result_value()\n",
+ "result.parsed_counts"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0398be45-a152-4225-ba7b-49c1f37b197d",
+ "metadata": {},
+ "source": [
+ "Verify all results are as expected:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "1363a9ae-567a-4bf1-911d-f17da9d6859c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "assert np.all(\n",
+ " [\n",
+ " count.state[\"x\"] == (A ** count.state[\"power\"] % N)\n",
+ " for count in result.parsed_counts\n",
+ " ]\n",
+ ")"
+ ]
+ }
+ ],
+ "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.4"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.metadata.json b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.metadata.json
new file mode 100644
index 000000000..fee5b77e5
--- /dev/null
+++ b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.metadata.json
@@ -0,0 +1,6 @@
+{
+ "friendly_name": "Modular Exponentiation",
+ "description": "Modular Exponentiation with an Exponent of Quantum Variable",
+ "qmod_type": ["function"],
+ "level": ["demos", "basic"]
+}
diff --git a/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.qmod b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.qmod
new file mode 100644
index 000000000..9721197a0
--- /dev/null
+++ b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.qmod
@@ -0,0 +1,7 @@
+qfunc main(output power: qnum, output x: qnum) {
+ allocate(ceiling(log(5, 2)), x);
+ inplace_prepare_int(1, x);
+ allocate(3, power);
+ hadamard_transform(power);
+ modular_exp(5, 4, x, power);
+}
diff --git a/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.synthesis_options.json b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.synthesis_options.json
new file mode 100644
index 000000000..fa4fb24f1
--- /dev/null
+++ b/functions/function_usage_examples/arithmetic/modular_exp/modular_exp_example.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": [
+ "cx",
+ "rz",
+ "t",
+ "z",
+ "u",
+ "sx",
+ "sxdg",
+ "u2",
+ "y",
+ "x",
+ "cy",
+ "cz",
+ "sdg",
+ "p",
+ "s",
+ "id",
+ "ry",
+ "rx",
+ "r",
+ "h",
+ "u1",
+ "tdg"
+ ],
+ "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": 1209628880
+ }
+}
diff --git a/functions/open_library_definitions/qft.qmod b/functions/open_library_definitions/qft.qmod
new file mode 100644
index 000000000..f11a535bc
--- /dev/null
+++ b/functions/open_library_definitions/qft.qmod
@@ -0,0 +1,6 @@
+qfunc qft(target: qbit[]) {
+ repeat (index: target.len / 2) {
+ SWAP(target[index], target[(target.len - 1) - index]);
+ }
+ qft_no_swap(target);
+}
diff --git a/tutorials/getting_started/part3_deutsch_jozsa.ipynb b/tutorials/getting_started/part3_deutsch_jozsa.ipynb
index 2f820cffa..c6cd26cca 100644
--- a/tutorials/getting_started/part3_deutsch_jozsa.ipynb
+++ b/tutorials/getting_started/part3_deutsch_jozsa.ipynb
@@ -32,15 +32,16 @@
"The circuit that we want to create is pictured below.\n",
"To create this circuit we need to implement 4 steps:\n",
"\n",
- "1. Apply the `hadamard_transform()` function on the qubits passed to the `main` function.\n",
- "2. create an oracle with the `phase_oracle()` function, this is the function signature: (if you are stuck more details are below) \n",
+ "1. Declare and initialize a single auxiliary qubit called `aux`\n",
+ "2. Apply the `hadamard_transform()` function on the qubits passed to the `main` function.\n",
+ "3. create an oracle with the `phase_oracle()` function, this is the function signature: (if you are stuck more details are below) \n",
"\n",
- " def phase_oracle(\n",
+ " def simple_oracle(\n",
" predicate: QCallable[QArray[QBit], QBit],\n",
" target: QArray[QBit],\n",
" )\n",
" \n",
- "3. Uncompute step 2 by applying the `hadamard_transform()` function to the \n",
+ "4. Uncompute step 2 by applying the `hadamard_transform()` function to the \n",
"\n",
"Synthesize the circuit and execute in the IDE\n",
"\n",
@@ -61,7 +62,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2024-05-07T14:26:56.085409Z",
@@ -70,14 +71,22 @@
"shell.execute_reply": "2024-05-07T14:27:01.549100Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Opening: https://platform.classiq.io/circuit/48398168-acd9-4aa9-a9f3-c148338fb4ee?version=0.41.0.dev39%2B79c8fd0855\n"
+ ]
+ }
+ ],
"source": [
"from classiq import *\n",
"\n",
"\n",
"@qfunc\n",
- "def my_black_box_prediate(aux: QNum, target: QNum):\n",
- " aux ^= target > 4\n",
+ "def my_black_box_prediate(aux: QBit, target: QNum):\n",
+ " aux ^= target > 30\n",
"\n",
"\n",
"@qfunc\n",
@@ -114,7 +123,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2024-05-07T14:27:01.585989Z",
@@ -123,7 +132,15 @@
"shell.execute_reply": "2024-05-07T14:27:03.832712Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Opening: https://platform.classiq.io/circuit/4cf4b44d-b7ef-48f8-bbf4-554b07a7fae6?version=0.41.0.dev39%2B79c8fd0855\n"
+ ]
+ }
+ ],
"source": [
"@qfunc\n",
"def main(target: Output[QNum]):\n",
@@ -181,7 +198,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2024-05-07T14:27:03.838462Z",
@@ -190,17 +207,28 @@
"shell.execute_reply": "2024-05-07T14:27:06.300732Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Opening: https://platform.classiq.io/circuit/051aa7e3-4453-4faf-94cf-9bdb2b22761d?version=0.41.0.dev39%2B79c8fd0855\n"
+ ]
+ }
+ ],
"source": [
"@qfunc\n",
- "def my_black_box_prediate(aux: QNum, target: QNum):\n",
- " aux ^= target > 4\n",
+ "def my_black_box_prediate(aux: QBit, target: QNum):\n",
+ " aux ^= target > 40\n",
"\n",
"\n",
"@qfunc\n",
"def main(target: Output[QNum]):\n",
" allocate(3, target) # Allocate 3 qubits to the target register\n",
"\n",
+ " aux = QBit(\"aux\")\n",
+ " allocate(1, aux)\n",
+ "\n",
" within_apply(\n",
" within=lambda: hadamard_transform(target=target),\n",
" apply=lambda: phase_oracle(\n",
@@ -209,17 +237,12 @@
" ),\n",
" )\n",
"\n",
+ " free(aux)\n",
+ "\n",
"\n",
"qprog = synthesize(create_model(main))\n",
"show(qprog)"
]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
@@ -238,7 +261,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.10.13"
+ "version": "3.11.9"
}
},
"nbformat": 4,
diff --git a/tutorials/getting_started/part4_ghz_state.ipynb b/tutorials/getting_started/part4_ghz_state.ipynb
index 0f19976c1..f8e4cf8a5 100644
--- a/tutorials/getting_started/part4_ghz_state.ipynb
+++ b/tutorials/getting_started/part4_ghz_state.ipynb
@@ -24,7 +24,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2024-05-07T14:26:33.289983Z",
@@ -33,7 +33,15 @@
"shell.execute_reply": "2024-05-07T14:26:37.833226Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Opening: https://platform.classiq.io/circuit/109c864c-1ee0-4886-86df-1a66b8f1c3f7?version=0.41.0.dev39%2B79c8fd0855\n"
+ ]
+ }
+ ],
"source": [
"from classiq import *\n",
"\n",
@@ -44,30 +52,6 @@
" # your code here\n",
" pass\n",
"\n",
- "qprog = synthesize(create_model(main))\n",
- "show(qprog)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Generative functions\n",
- "\n",
- "Next to using the native `repeat()` function it is also possible to use the python for loop when `generative` is set to true in the `@qfunc` decorator. Let's look how that would work."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "@qfunc(generative=True)\n",
- "def main(reg: Output[QArray]):\n",
- " allocate(6, reg)\n",
- " # your code here\n",
- " pass\n",
"\n",
"qprog = synthesize(create_model(main))\n",
"show(qprog)"
@@ -77,13 +61,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "### The full solution for your reference\n",
- "Using the `repeat()` function."
+ "### The full solution for your reference"
]
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2024-05-07T14:26:37.963005Z",
@@ -92,7 +75,15 @@
"shell.execute_reply": "2024-05-07T14:26:40.239952Z"
}
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Opening: https://platform.classiq.io/circuit/ad6f8b4d-efcb-492e-8e29-624ff3f60a16?version=0.41.0.dev39%2B79c8fd0855\n"
+ ]
+ }
+ ],
"source": [
"from classiq import *\n",
"\n",
@@ -110,38 +101,6 @@
"qprog = synthesize(create_model(main))\n",
"show(qprog)"
]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Using native Python for loop"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "@qfunc(generative=True)\n",
- "def main(reg: Output[QArray]):\n",
- " allocate(6, reg)\n",
- " H(reg[0])\n",
- " for index in range(reg.len - 1):\n",
- " CX(control=reg[index], target=reg[index + 1])\n",
- "\n",
- "\n",
- "qprog = synthesize(create_model(main))\n",
- "show(qprog)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
}
],
"metadata": {
@@ -160,7 +119,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.10.13"
+ "version": "3.11.9"
}
},
"nbformat": 4,
diff --git a/tutorials/hamiltonian_simulation/hamiltonian_simulation_guide/hamiltonian_simulation_guide.ipynb b/tutorials/hamiltonian_simulation/hamiltonian_simulation_guide/hamiltonian_simulation_guide.ipynb
index 4465aa88b..2f3adbbc2 100644
--- a/tutorials/hamiltonian_simulation/hamiltonian_simulation_guide/hamiltonian_simulation_guide.ipynb
+++ b/tutorials/hamiltonian_simulation/hamiltonian_simulation_guide/hamiltonian_simulation_guide.ipynb
@@ -25,7 +25,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Table of contents\n",
+ "## Table of contents\n",
"\n",
"1. [Intoduction](#Intoduction)\n",
"3. [Suzuki-Trotter decomposition](#Suzuki-Trotter-decomposition)\n",
@@ -40,7 +40,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Intoduction"
+ "## Intoduction"
]
},
{
@@ -197,7 +197,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Exponentiation with Depth Constraint\n",
+ "### Exponentiation with Depth Constraint\n",
"\n",
"It is also possible to generate an efficient decomposition of an evolution operator with the Classiq `exponentiation_with_depth_constraint` function. Given the maximum depth of the decomposition and the inputs related to the Hamiltonian, the synthesizer finds and applies the most accurate higher-order Trotter decomposition. Its inputs are the same as in `suzuki_trotter`, except that `max_depth` replaces explicitly specifying the number of `repetitions`.\n",
"\n",
@@ -338,7 +338,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Hamiltonian Simulation with Block Encoding"
+ "## Hamiltonian Simulation with Block Encoding"
]
},
{
@@ -380,7 +380,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Measuring the Expected Magnetization as a Function of Time"
+ "## Measuring the Expected Magnetization as a Function of Time"
]
},
{
@@ -589,7 +589,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Summary and Exercises"
+ "## Summary and Exercises"
]
},
{
@@ -609,7 +609,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Read More\n",
+ "## Read More\n",
"\n",
"Besides the methods presented in this guide, there are also mixed approaches. One of them, proposed by Matthew Hagan and Nathan Wiebe [[6]](#quantum_sim_paper), offers an interesting combination of the Suzuki-Trotter and qDRIFT methods."
]
@@ -618,7 +618,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# References\n",
+ "## References\n",
"\n",
"[1]: [Finding exponential product formulas of higher orders (Naomichi Hatano and Masuo Suzuki)](https://arxiv.org/abs/math-ph/0506007)\n",
"\n",