diff --git a/examples/Quantinuum_arbitrary_angle_zz.ipynb b/examples/Quantinuum_arbitrary_angle_zz.ipynb
index f6abf82a..5dd1773a 100644
--- a/examples/Quantinuum_arbitrary_angle_zz.ipynb
+++ b/examples/Quantinuum_arbitrary_angle_zz.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["
\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Arbitrary Angle ZZ Gates via pytket"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains a comparison of circuits with and without use of Quantinuum's native arbitrary-angle ZZ gate in `pytket`. The circuit primitive, the Quantum Fourier Transform (QFT) is constructed with `pytket`. The inverse QFT is an important primitive used in the [Phase Estimation Algorithm (PEA)](https://tket.quantinuum.com/examples/phase_estimation.html). PEA is used to estimate the phase corresponding to the eigenvalue of a specified unitary."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Arbitrary-angle two-qubit gates can be used to improve fidelity of the output and to decrease two-qubit gate depth. Specifically, the error from arbitrary-angle two-qubit gates is less than the fixed-angle two-qubit gate for small angles. The error from both gates is the same at angle $\\frac{\\phi}{2}$. The error from arbitrary-angle two-qubit gates increases with angle size."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* [Arbitrary Angle ZZ Gates](#Arbitrary-Angle-ZZ-Gates)
\n", "* [Quantum Fourier Transform](#Quantum-Fourier-Transform)
\n", "* [QFT with Fixed Angle Gates](#QFT-with-Fixed-Angle-Gates)
\n", "* [QFT with Arbitrary Angle ZZ Gates](#QFT-with-Arbitrary-Angle-ZZ-Gates)
\n", "* [Compare Results](#Compare-Results)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Arbitrary Angle ZZ Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantinuum System Model H1's native gate set includes arbitrary angle ZZ gates. This is beneficial for reducing the 2-qubit gate count for many quantum algorithms and gate sequences."]}, {"cell_type": "markdown", "metadata": {}, "source": ["$$RZZ(\\theta) = e^{-i\\frac{\\theta}{2}\\hat{Z} \\otimes \\hat{Z}}= e^{-i \\frac{\\theta}{2}} \\begin{bmatrix} 1 & 0 & 0 & 0\\\\ 0 & e^{-i\\theta} & 0 & 0\\\\ 0 & 0 & e^{-i\\theta} & 0\\\\ 0 & 0 & 0 & 1 \\end{bmatrix}$$"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that $RZZ(\\frac{\\pi}{2}) = ZZ()$."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantum circuits that use the gate sequence CNOT, RZ, CNOT can be replaced with the arbitrary angle ZZ gate, shown below. This enables a lower number of 2-qubit gates in a quantum circuit, improving performance by decreasing gate errors."]}, {"cell_type": "markdown", "metadata": {}, "source": ["
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\n", "
\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook demonstrates the Quantum Fourier Transform (QFT) with and without the $RZZ$ gate."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Quantum Fourier Transform"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The Quantum Fourier Transform (QFT) is an algorithm that serves as a sub-routine in multiple quantum algorithms, including Shor's factoring algorithm. Below are two functions, written in `pytket`, that work together to implement the QFT."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `QFT` function can be used to create the QFT. It takes the following arguments:
\n", "- `n`: number of qubits to use in the QFT circuit
\n", "- `arbZZ`: specify whether to use the arbitrary-angle ZZ gate or not, `True`/`False`, default: `False`
\n", "- `approx`: if set to integer `k`, then controlled rotations by angles less than $\\frac{\\pi}{2}^{k}$ do not occur"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Note:** In many presentations of the QFT, the circuit includes a round of SWAP gates at the end of the circuit that reverses the order of the qubits. The QFT circuits in this tutorial do not include this final SWAP step."]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Note:** In `pytket` the $RZZ$ gate is implemented with the $ZZPhase$ circuit function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["import numpy as np\n", "from pytket import Circuit\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def control_phase(circ, theta, q0, q1, arbZZ=False):\n", " \"\"\"circuit gadget for performing controlled-[1 0;0 e^i theta]\n", " Inputs:\n", " circ: pytket Circuit object\n", " theta: Z rotation angle (in units of pi)\n", " q0: control qubit\n", " q1: target qubit\n", " arbZZ (bool): enables arbitrary angle RZZ gate\n", " \"\"\"\n", " if arbZZ == False:\n", " # decompose into CNOTs\n", " circ.Rz(theta / 2, q1)\n", " circ.CX(q0, q1)\n", " circ.Rz(-theta / 2, q1)\n", " circ.CX(q0, q1)\n", " circ.Rz(theta / 2, q0)\n", " elif arbZZ == True:\n", " circ.Rz(theta / 2, q0)\n", " circ.Rz(theta / 2, q1)\n", " circ.ZZPhase(-theta / 2, q0, q1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def QFT(n, **kwargs):\n", " \"\"\"\n", " Function to implement the Quantum Fourier Transform\n", " n : number of qubits\n", " approx: if set to integer k, then sets that largest\n", " value of pi/2**k occuring in controlled rotation\n", " returns circ: pytket Circuit object\n", " \"\"\"\n\n", " # optional keyword arguments\n", " arbZZ = kwargs.get(\"arbZZ\", False)\n", " approx = kwargs.get(\"approx\", None)\n\n", " # initialize\n", " circ_name = \"QFT-arbZZ\" if arbZZ else \"QFT-fixed\"\n", " circ = Circuit(n, n, name=circ_name)\n", " for j in range(n - 1):\n", " q = n - 1 - j\n", " circ.H(q)\n", " for i in range(j + 1):\n", " if approx == None or approx >= j + 1 - i:\n", " control_phase(\n", " circ, 1 / (2 ** (j + 1 - i)), q - 1, n - 1 - i, arbZZ=arbZZ\n", " )\n", " circ.H(0)\n", " return circ"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## QFT with Fixed Angle Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["First, create the circuit with fixed-angle gates."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_qubits = 12"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fixed = QFT(n_qubits, arbZZ=False)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(qft_fixed)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## QFT with Arbitrary Angle ZZ Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Second, create the circuit with arbitrary-angle ZZ gates."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_arbZZ = QFT(n_qubits, arbZZ=True)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(qft_arbZZ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Compare Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now we compare the results of the QFT circuits with and without use of the arbitrary-angle ZZ gates on hardware."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### State Fidelity"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The QFT circuit applied to the computational basis state $|x\\rangle$ creates the state"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\\begin{align}
\n", "QFT|x\\rangle&=\\frac{1}{\\sqrt{d}}\\sum_{y=0}^{d-1} e^{2\\pi i x y/d} |y\\rangle\\\\
\n", "&= \\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\sum_{y_j=0}^1e^{2\\pi i x 2^j y_j/d}|y_j\\rangle\\\\
\n", "&= \\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\big(|0\\rangle+e^{2\\pi i x 2^j /d}|1\\rangle\\big)
\n", "\\end{align}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["where $d=2^n$. Note that this state is unentangled. Therefore the state fidelity can be measured by applying only single-qubit gates to map the state back to the computational basis. In the example circuits above, the initial state $|x\\rangle=|0\\rangle$, and so the output state is"]}, {"cell_type": "markdown", "metadata": {}, "source": ["$$\\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big) = |+\\rangle^{\\otimes n}$$"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The state fidelity can then be measured by applying a Hadamard gate to each qubit and recording the probability of measuring $|0\\rangle$."]}, {"cell_type": "markdown", "metadata": {}, "source": ["We define a function to measure all qubits in the Hadamard basis and append this circuit to the QFT circuits:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def meas_Had_basis(orig_circ, n_qubits):\n", " circ = orig_circ.copy()\n", " for j in range(n_qubits):\n", " circ.H(j)\n", " circ.add_barrier(range(n_qubits))\n", " circ.measure_all()\n", " return circ"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed = meas_Had_basis(qft_fixed, n_qubits)\n", "render_circuit_jupyter(qft_fid_fixed)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_arbZZ = meas_Had_basis(qft_arbZZ, n_qubits)\n", "render_circuit_jupyter(qft_fid_arbZZ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Select Device"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Login to the Quantinuum API using your credentials and check the device status."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-2E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Compilation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Compile the circuits to the Quantinuum backend."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled = backend.get_compiled_circuit(\n", " qft_fid_fixed, optimisation_level=1\n", ")\n", "render_circuit_jupyter(qft_fid_fixed_compiled)\n", "qft_fid_arbZZ_compiled = backend.get_compiled_circuit(\n", " qft_fid_arbZZ, optimisation_level=1\n", ")\n", "render_circuit_jupyter(qft_fid_arbZZ_compiled)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Depth and Two-Qubit Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that the circuit depth number of two-qubit gates for the fixed-angle vs. arbitrary angle is less. The difference increases as more qubits are used."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(\"Circuit Depth for fixed-angle QFT:\", qft_fixed.depth())\n", "print(\"Circuit Depth for arbitrary-angle QFT:\", qft_arbZZ.depth())\n", "print(\"Circuit Depth Difference:\", qft_fixed.depth() - qft_arbZZ.depth())\n", "print(\"Number of two-qubit gates for fixed-angle QFT:\", qft_fixed.n_2qb_gates())\n", "print(\"Number of two-qubit gates for arbitrary-angle QFT:\", qft_arbZZ.n_2qb_gates())\n", "print(\n", " \"Number of two-qubit gates Difference:\",\n", " qft_fixed.n_2qb_gates() - qft_arbZZ.n_2qb_gates(),\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Check Circuit Cost"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Check the cost in HQC's for each circuit. See that the Arbitrary angle ZZ QFT uses fewer HQCs, which is a plus."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that in this case because an emulator is used, the specific syntax checker the emulator uses is specified. This is an optional parameter not needed if you are using a quantum computer target."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_shots = 100\n", "print(\n", " \"Fixed angle QFT:\",\n", " backend.cost(qft_fid_fixed_compiled, n_shots=n_shots, syntax_checker=machine),\n", ")\n", "print(\n", " \"Arbitrary angle ZZ QFT:\",\n", " backend.cost(qft_fid_arbZZ_compiled, n_shots=n_shots, syntax_checker=\"H1-2SC\"),\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Run the Circuit"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now run the circuits on Quantinuum systems. First compiling the circuits to the backend, then submitting to the device."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_handle = backend.process_circuit(\n", " qft_fid_fixed_compiled, n_shots=n_shots\n", ")\n", "qft_fid_arbZZ_compiled_handle = backend.process_circuit(\n", " qft_fid_arbZZ_compiled, n_shots=n_shots\n", ")\n", "qft_fid_fixed_compiled_status = backend.circuit_status(qft_fid_fixed_compiled_handle)\n", "print(qft_fid_fixed_compiled_status)\n", "qft_fid_arbZZ_compiled_status = backend.circuit_status(qft_fid_arbZZ_compiled_handle)\n", "print(qft_fid_arbZZ_compiled_status)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Retrieve Results"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_result = backend.get_result(qft_fid_fixed_compiled_handle)\n", "qft_fid_arbZZ_compiled_result = backend.get_result(qft_fid_arbZZ_compiled_handle)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Analyze Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here the distribution of bitstrings is retrieved to inspect."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_distro = qft_fid_fixed_compiled_result.get_distribution()\n", "qft_fid_arbZZ_compiled_distro = qft_fid_arbZZ_compiled_result.get_distribution()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For the QFT with the appended measurement in the Hadamard basis, we expect the QFT to return all 0's in the result bitstring. Investigating the results for both the fixed and arbitrary ZZ versions of QFT, we see this is the bitstring with the highest frequency. This is good, this is what is desired."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_distro"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_arbZZ_compiled_distro"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Comparing the results between the fixed and arbitrary ZZ versions we see that the fidelity is higher using the arbitrary ZZ gate."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(\n", " \"Fixed angle QFT:\",\n", " qft_fid_fixed_compiled_distro[(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)],\n", ")\n", "print(\n", " \"Arbitrary Angle ZZ QFT:\",\n", " qft_fid_arbZZ_compiled_distro[(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)],\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Arbitrary Angle ZZ Gates via pytket"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains a comparison of circuits with and without use of Quantinuum's native arbitrary-angle ZZ gate in `pytket`. The circuit primitive, the Quantum Fourier Transform (QFT) is constructed with `pytket`. The inverse QFT is an important primitive used in the [Phase Estimation Algorithm (PEA)](https://tket.quantinuum.com/examples/phase_estimation.html). PEA is used to estimate the phase corresponding to the eigenvalue of a specified unitary."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Arbitrary-angle two-qubit gates can be used to improve fidelity of the output and to decrease two-qubit gate depth. Specifically, the error from arbitrary-angle two-qubit gates is less than the fixed-angle two-qubit gate for small angles. The error from both gates is the same at angle $\\frac{\\phi}{2}$. The error from arbitrary-angle two-qubit gates increases with angle size."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* [Arbitrary Angle ZZ Gates](#Arbitrary-Angle-ZZ-Gates)
\n", "* [Quantum Fourier Transform](#Quantum-Fourier-Transform)
\n", "* [QFT with Fixed Angle Gates](#QFT-with-Fixed-Angle-Gates)
\n", "* [QFT with Arbitrary Angle ZZ Gates](#QFT-with-Arbitrary-Angle-ZZ-Gates)
\n", "* [Compare Results](#Compare-Results)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Arbitrary Angle ZZ Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantinuum System Model H1's native gate set includes arbitrary angle ZZ gates. This is beneficial for reducing the 2-qubit gate count for many quantum algorithms and gate sequences."]}, {"cell_type": "markdown", "metadata": {}, "source": ["$$RZZ(\\theta) = e^{-i\\frac{\\theta}{2}\\hat{Z} \\otimes \\hat{Z}}= e^{-i \\frac{\\theta}{2}} \\begin{bmatrix} 1 & 0 & 0 & 0\\\\ 0 & e^{-i\\theta} & 0 & 0\\\\ 0 & 0 & e^{-i\\theta} & 0\\\\ 0 & 0 & 0 & 1 \\end{bmatrix}$$"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that $RZZ(\\frac{\\pi}{2}) = ZZ()$."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantum circuits that use the gate sequence CNOT, RZ, CNOT can be replaced with the arbitrary angle ZZ gate, shown below. This enables a lower number of 2-qubit gates in a quantum circuit, improving performance by decreasing gate errors."]}, {"cell_type": "markdown", "metadata": {}, "source": ["
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\n", "
\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook demonstrates the Quantum Fourier Transform (QFT) with and without the $RZZ$ gate."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Quantum Fourier Transform"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The Quantum Fourier Transform (QFT) is an algorithm that serves as a sub-routine in multiple quantum algorithms, including Shor's factoring algorithm. Below are two functions, written in `pytket`, that work together to implement the QFT."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `QFT` function can be used to create the QFT. It takes the following arguments:
\n", "- `n`: number of qubits to use in the QFT circuit
\n", "- `arbZZ`: specify whether to use the arbitrary-angle ZZ gate or not, `True`/`False`, default: `False`
\n", "- `approx`: if set to integer `k`, then controlled rotations by angles less than $\\frac{\\pi}{2}^{k}$ do not occur"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Note:** In many presentations of the QFT, the circuit includes a round of SWAP gates at the end of the circuit that reverses the order of the qubits. The QFT circuits in this tutorial do not include this final SWAP step."]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Note:** In `pytket` the $RZZ$ gate is implemented with the $ZZPhase$ circuit function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["import numpy as np\n", "from pytket import Circuit\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def control_phase(circ, theta, q0, q1, arbZZ=False):\n", " \"\"\"circuit gadget for performing controlled-[1 0;0 e^i theta]\n", " Inputs:\n", " circ: pytket Circuit object\n", " theta: Z rotation angle (in units of pi)\n", " q0: control qubit\n", " q1: target qubit\n", " arbZZ (bool): enables arbitrary angle RZZ gate\n", " \"\"\"\n", " if arbZZ == False:\n", " # decompose into CNOTs\n", " circ.Rz(theta / 2, q1)\n", " circ.CX(q0, q1)\n", " circ.Rz(-theta / 2, q1)\n", " circ.CX(q0, q1)\n", " circ.Rz(theta / 2, q0)\n", " elif arbZZ == True:\n", " circ.Rz(theta / 2, q0)\n", " circ.Rz(theta / 2, q1)\n", " circ.ZZPhase(-theta / 2, q0, q1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def QFT(n, **kwargs):\n", " \"\"\"\n", " Function to implement the Quantum Fourier Transform\n", " n : number of qubits\n", " approx: if set to integer k, then sets that largest\n", " value of pi/2**k occuring in controlled rotation\n", " returns circ: pytket Circuit object\n", " \"\"\"\n\n", " # optional keyword arguments\n", " arbZZ = kwargs.get(\"arbZZ\", False)\n", " approx = kwargs.get(\"approx\", None)\n\n", " # initialize\n", " circ_name = \"QFT-arbZZ\" if arbZZ else \"QFT-fixed\"\n", " circ = Circuit(n, n, name=circ_name)\n", " for j in range(n - 1):\n", " q = n - 1 - j\n", " circ.H(q)\n", " for i in range(j + 1):\n", " if approx == None or approx >= j + 1 - i:\n", " control_phase(\n", " circ, 1 / (2 ** (j + 1 - i)), q - 1, n - 1 - i, arbZZ=arbZZ\n", " )\n", " circ.H(0)\n", " return circ"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## QFT with Fixed Angle Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["First, create the circuit with fixed-angle gates."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_qubits = 12"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fixed = QFT(n_qubits, arbZZ=False)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(qft_fixed)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## QFT with Arbitrary Angle ZZ Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Second, create the circuit with arbitrary-angle ZZ gates."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_arbZZ = QFT(n_qubits, arbZZ=True)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(qft_arbZZ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Compare Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now we compare the results of the QFT circuits with and without use of the arbitrary-angle ZZ gates on hardware."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### State Fidelity"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The QFT circuit applied to the computational basis state $|x\\rangle$ creates the state"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\\begin{align}
\n", "QFT|x\\rangle&=\\frac{1}{\\sqrt{d}}\\sum_{y=0}^{d-1} e^{2\\pi i x y/d} |y\\rangle\\\\
\n", "&= \\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\sum_{y_j=0}^1e^{2\\pi i x 2^j y_j/d}|y_j\\rangle\\\\
\n", "&= \\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\big(|0\\rangle+e^{2\\pi i x 2^j /d}|1\\rangle\\big)
\n", "\\end{align}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["where $d=2^n$. Note that this state is unentangled. Therefore the state fidelity can be measured by applying only single-qubit gates to map the state back to the computational basis. In the example circuits above, the initial state $|x\\rangle=|0\\rangle$, and so the output state is"]}, {"cell_type": "markdown", "metadata": {}, "source": ["$$\\bigotimes_{j=0}^{n-1}\\frac{1}{\\sqrt{2}}\\big(|0\\rangle + |1\\rangle\\big) = |+\\rangle^{\\otimes n}$$"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The state fidelity can then be measured by applying a Hadamard gate to each qubit and recording the probability of measuring $|0\\rangle$."]}, {"cell_type": "markdown", "metadata": {}, "source": ["We define a function to measure all qubits in the Hadamard basis and append this circuit to the QFT circuits:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def meas_Had_basis(orig_circ, n_qubits):\n", " circ = orig_circ.copy()\n", " for j in range(n_qubits):\n", " circ.H(j)\n", " circ.add_barrier(range(n_qubits))\n", " circ.measure_all()\n", " return circ"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed = meas_Had_basis(qft_fixed, n_qubits)\n", "render_circuit_jupyter(qft_fid_fixed)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_arbZZ = meas_Had_basis(qft_arbZZ, n_qubits)\n", "render_circuit_jupyter(qft_fid_arbZZ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Select Device"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Login to the Quantinuum API using your credentials and check the device status."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Compilation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Compile the circuits to the Quantinuum backend."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled = backend.get_compiled_circuit(\n", " qft_fid_fixed, optimisation_level=1\n", ")\n", "render_circuit_jupyter(qft_fid_fixed_compiled)\n", "qft_fid_arbZZ_compiled = backend.get_compiled_circuit(\n", " qft_fid_arbZZ, optimisation_level=1\n", ")\n", "render_circuit_jupyter(qft_fid_arbZZ_compiled)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Depth and Two-Qubit Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that the circuit depth number of two-qubit gates for the fixed-angle vs. arbitrary angle is less. The difference increases as more qubits are used."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(\"Circuit Depth for fixed-angle QFT:\", qft_fixed.depth())\n", "print(\"Circuit Depth for arbitrary-angle QFT:\", qft_arbZZ.depth())\n", "print(\"Circuit Depth Difference:\", qft_fixed.depth() - qft_arbZZ.depth())\n", "print(\"Number of two-qubit gates for fixed-angle QFT:\", qft_fixed.n_2qb_gates())\n", "print(\"Number of two-qubit gates for arbitrary-angle QFT:\", qft_arbZZ.n_2qb_gates())\n", "print(\n", " \"Number of two-qubit gates Difference:\",\n", " qft_fixed.n_2qb_gates() - qft_arbZZ.n_2qb_gates(),\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Check Circuit Cost"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Check the cost in HQC's for each circuit. See that the Arbitrary angle ZZ QFT uses fewer HQCs, which is a plus."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that in this case because an emulator is used, the specific syntax checker the emulator uses is specified. This is an optional parameter not needed if you are using a quantum computer target."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_shots = 100\n", "print(\n", " \"Fixed angle QFT:\",\n", " backend.cost(qft_fid_fixed_compiled, n_shots=n_shots, syntax_checker=machine),\n", ")\n", "print(\n", " \"Arbitrary angle ZZ QFT:\",\n", " backend.cost(qft_fid_arbZZ_compiled, n_shots=n_shots, syntax_checker=\"H1-1SC\"),\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Run the Circuit"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now run the circuits on Quantinuum systems. First compiling the circuits to the backend, then submitting to the device."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_handle = backend.process_circuit(\n", " qft_fid_fixed_compiled, n_shots=n_shots\n", ")\n", "qft_fid_arbZZ_compiled_handle = backend.process_circuit(\n", " qft_fid_arbZZ_compiled, n_shots=n_shots\n", ")\n", "qft_fid_fixed_compiled_status = backend.circuit_status(qft_fid_fixed_compiled_handle)\n", "print(qft_fid_fixed_compiled_status)\n", "qft_fid_arbZZ_compiled_status = backend.circuit_status(qft_fid_arbZZ_compiled_handle)\n", "print(qft_fid_arbZZ_compiled_status)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Retrieve Results"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_result = backend.get_result(qft_fid_fixed_compiled_handle)\n", "qft_fid_arbZZ_compiled_result = backend.get_result(qft_fid_arbZZ_compiled_handle)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Analyze Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here the distribution of bitstrings is retrieved to inspect."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_distro = qft_fid_fixed_compiled_result.get_distribution()\n", "qft_fid_arbZZ_compiled_distro = qft_fid_arbZZ_compiled_result.get_distribution()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For the QFT with the appended measurement in the Hadamard basis, we expect the QFT to return all 0's in the result bitstring. Investigating the results for both the fixed and arbitrary ZZ versions of QFT, we see this is the bitstring with the highest frequency. This is good, this is what is desired."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_fixed_compiled_distro"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["qft_fid_arbZZ_compiled_distro"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Comparing the results between the fixed and arbitrary ZZ versions we see that the fidelity is higher using the arbitrary ZZ gate."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(\n", " \"Fixed angle QFT:\",\n", " qft_fid_fixed_compiled_distro[(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)],\n", ")\n", "print(\n", " \"Arbitrary Angle ZZ QFT:\",\n", " qft_fid_arbZZ_compiled_distro[(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)],\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
diff --git a/examples/Quantinuum_conditional_gates.ipynb b/examples/Quantinuum_conditional_gates.ipynb
index 6b67c80c..0993b15a 100644
--- a/examples/Quantinuum_conditional_gates.ipynb
+++ b/examples/Quantinuum_conditional_gates.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Conditional Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantinuum H-Series hardware and pytket support conditional gating. This may be for implementing error correction or reducing noise. This capability is well-supported by Quantinuum hardware, which supports mid-circuit measurement and reset and qubit reuse. See [Conditional Gates](https://tket.quantinuum.com/user-manual/manual_circuit.html#classical-and-conditional-operations) for more information on pytket's implementation. The following example demonstrates a quantum teleportation protocol."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import Circuit, if_bit\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "markdown", "metadata": {}, "source": ["create a circuit and add quantum and classical registers"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ = Circuit(name=\"Conditional Gates Example\")\n", "qreg = circ.add_q_register(\"q\", 3)\n", "creg = circ.add_c_register(\"b\", 2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["prepare q[0] to be in the state |->, which we wish to teleport to q[2]"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.X(qreg[0]).H(qreg[0])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["prepare a Bell state on qubits q[1] and q[2]"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.H(qreg[1])\n", "circ.CX(qreg[1], qreg[2])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["construct the teleportation protocol"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.CX(qreg[0], qreg[1])\n", "circ.H(qreg[0])\n", "circ.Measure(qreg[0], creg[0])\n", "circ.Measure(qreg[1], creg[1])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if (creg[1] == 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.X(qreg[2], condition=if_bit(creg[1]))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if (creg[0] == 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.Z(qreg[2], condition=if_bit(creg[0]))"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We can utilise pytket's [Assertion](https://tket.quantinuum.com/user-manual/manual_assertion.html) feature to verify the successful teleportation of the state $| - \\rangle$."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import ProjectorAssertionBox\n", "import numpy as np"]}, {"cell_type": "markdown", "metadata": {}, "source": ["|-><-|"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["proj = np.array([[0.5, -0.5], [-0.5, 0.5]])\n", "circ.add_assertion(ProjectorAssertionBox(proj), [qreg[2]], name=\"debug\")"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circ)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "n_shots = 100\n", "backend = QuantinuumBackend(device_name=machine)\n", "compiled_circuit = backend.get_compiled_circuit(circ)\n", "backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-2SC\")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)\n", "status = backend.circuit_status(handle)\n", "status"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `get_debug_info` function returns the success rate of the state assertion averaged across shots. Note that the failed shots are caused by the simulated device errors"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result.get_debug_info()"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Conditional Gates"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quantinuum H-Series hardware and pytket support conditional gating. This may be for implementing error correction or reducing noise. This capability is well-supported by Quantinuum hardware, which supports mid-circuit measurement and reset and qubit reuse. See [Conditional Gates](https://tket.quantinuum.com/user-manual/manual_circuit.html#classical-and-conditional-operations) for more information on pytket's implementation. The following example demonstrates a quantum teleportation protocol."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import Circuit, if_bit\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "markdown", "metadata": {}, "source": ["create a circuit and add quantum and classical registers"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ = Circuit(name=\"Conditional Gates Example\")\n", "qreg = circ.add_q_register(\"q\", 3)\n", "creg = circ.add_c_register(\"b\", 2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["prepare q[0] to be in the state |->, which we wish to teleport to q[2]"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.X(qreg[0]).H(qreg[0])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["prepare a Bell state on qubits q[1] and q[2]"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.H(qreg[1])\n", "circ.CX(qreg[1], qreg[2])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["construct the teleportation protocol"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.CX(qreg[0], qreg[1])\n", "circ.H(qreg[0])\n", "circ.Measure(qreg[0], creg[0])\n", "circ.Measure(qreg[1], creg[1])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if (creg[1] == 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.X(qreg[2], condition=if_bit(creg[1]))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if (creg[0] == 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circ.Z(qreg[2], condition=if_bit(creg[0]))"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circ)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We can utilise pytket's [Assertion](https://tket.quantinuum.com/user-manual/manual_assertion.html) feature to verify the successful teleportation of the state $| - \\rangle$."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import ProjectorAssertionBox\n", "import numpy as np"]}, {"cell_type": "markdown", "metadata": {}, "source": ["|-><-|"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["proj = np.array([[0.5, -0.5], [-0.5, 0.5]])\n", "circ.add_assertion(ProjectorAssertionBox(proj), [qreg[2]], name=\"debug\")"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circ)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "n_shots = 100\n", "backend = QuantinuumBackend(device_name=machine)\n", "compiled_circuit = backend.get_compiled_circuit(circ)\n", "backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-1SC\")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)\n", "status = backend.circuit_status(handle)\n", "status"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `get_debug_info` function returns the success rate of the state assertion averaged across shots. Note that the failed shots are caused by the simulated device errors"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result.get_debug_info()"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
diff --git a/examples/Quantinuum_mid_circuit_measurement.ipynb b/examples/Quantinuum_mid_circuit_measurement.ipynb
index 9a8cc06c..c274a134 100644
--- a/examples/Quantinuum_mid_circuit_measurement.ipynb
+++ b/examples/Quantinuum_mid_circuit_measurement.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Mid-Circuit Measurement"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains an example using mid-circuit measurement using the Quantinuum machines."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Repetition Code Circuit"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The use of mid-circuit measurement is straightforward, note the use of `measure` and `reset` on the ancilla qubits. This example also utlizes conditional logic available with Quantinuum devices as well as Registers and IDs available in `pytket`. See [Classical and conditional operations](https://tket.quantinuum.com/user-manual/manual_circuit.html#classical-and-conditional-operations) and [Registers and IDs](https://cqcl.github.io/pytket/manual/manual_circuit.html#registers-and-ids) for additional examples."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import Circuit, Qubit, Bit, OpType, reg_eq\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up Repetition Code with mid-circuit measurement and corrections"]}, {"cell_type": "markdown", "metadata": {}, "source": ["2 1 0 = data: data qubits
\n", "*----*----*
\n", " ZZ ZZ
\n", " 1 0 = syndromes
\n", " 0 0 = ancillas"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up circuit object"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit = Circuit(name=\"Repetition Code\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Reserve registries"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add qubit register, the data qubits"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["data = circuit.add_q_register(\"data\", 3)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add qubit register, the ancilla qubit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["ancilla = circuit.add_q_register(\"anc\", 1)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add classical registers for the syndromes"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["syndrome = circuit.add_c_register(\"syndrome\", 2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add classical registers for the output"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["output = circuit.add_c_register(\"output\", 3)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Prepare the logical state
\n", "Qubits always start in |0> and logical |0> == |000>.
\n", "So we already start in logical |0>."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Syndrome Extraction"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.add_gate(OpType.Reset, ancilla)\n", "circuit.CX(data[0], ancilla[0])\n", "circuit.CX(data[1], ancilla[0])\n", "circuit.Measure(ancilla[0], syndrome[0])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Syndrome Extraction"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.add_gate(OpType.Reset, ancilla)\n", "circuit.CX(data[1], ancilla[0])\n", "circuit.CX(data[2], ancilla[0])\n", "circuit.Measure(ancilla[0], syndrome[1])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Correction
\n", "if(syndromes==1) -> 01 -> check 0 bad -> X on qubit 0"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[0], condition=reg_eq(syndrome, 1))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if(syndromes==2) -> 10 -> check 1 bad -> X on qubit 2"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[2], condition=reg_eq(syndrome, 2))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if(syndromes==3) -> 11 -> check 1 and 2 bad -> X on qubit 1"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[1], condition=reg_eq(syndrome, 3))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Measure out data qubits"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.Measure(data[0], output[0])\n", "circuit.Measure(data[1], output[1])\n", "circuit.Measure(data[2], output[2])"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Select Device"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Login to the Quantinuum API using your credentials and check the device status."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(machine, \"status:\", backend.device_state(device_name=machine))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Compilation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`pytket` includes many features for optimizing circuits. This includes reducing the number of gates where possible and resynthesizing circuits for a quantum computer's native gate set. See the `pytket` [User Manual](https://cqcl.github.io/pytket/manual/index.html) for more information on all the options that are available."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here the circuit is compiled with `get_compiled_circuit`, which includes optimizing the gates and resynthesizing the circuit to Quantinuum's native gate set. The `optimisation_level` sets the level of optimisation to perform during compilation, check [Default Compilation](https://cqcl.github.io/pytket-quantinuum/api/index.html#default-compilation) in the pytket-quantinuum documentation for more details."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["compiled_circuit = backend.get_compiled_circuit(circuit, optimisation_level=1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(compiled_circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Submit and Run the Circuit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_shots = 100\n", "print(\n", " \"Cost in HQCs:\",\n", " backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-2SC\"),\n", ")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)\n", "print(handle)\n", "status = backend.circuit_status(handle)\n", "print(status)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["import json"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["with open(\"pytket_mcmr_example.json\", \"w\") as file:\n", " json.dump(result.to_dict(), file)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Analyze Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We will now take the raw results and apply a majority vote to determine how many times we got 0 vs 1."]}, {"cell_type": "markdown", "metadata": {}, "source": ["First, define a majority vote function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def majority(result):\n", " \"\"\"Returns whether the output should be considered a 0 or 1.\"\"\"\n", " if result.count(0) > result.count(1):\n", " return 0\n", " elif result.count(0) < result.count(1):\n", " return 1\n", " else:\n", " raise Exception(\"count(0) should not equal count(1)\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now process the output:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result_output_cnts = result.get_counts([output[i] for i in range(output.size)])"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result_output_cnts"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, determine how many times 0 vs 1 was observed using the majority vote function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["zeros = 0 # Counts the shots with majority zeros\n", "ones = 0 # Counts the shots with majority ones"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["for out in result_output_cnts:\n", " m = majority(out)\n", " if m == 0:\n", " zeros += result_output_cnts[out]\n", " else:\n", " ones += result_output_cnts[out]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A logical zero was initialized, so our error rate should be number of ones / total number of shots: `ones/shots`"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["p = ones / n_shots\n", "print(f\"The error-rate is: p = {p}\")"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Mid-Circuit Measurement"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains an example using mid-circuit measurement using the Quantinuum machines."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Repetition Code Circuit"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The use of mid-circuit measurement is straightforward, note the use of `measure` and `reset` on the ancilla qubits. This example also utlizes conditional logic available with Quantinuum devices as well as Registers and IDs available in `pytket`. See [Classical and conditional operations](https://tket.quantinuum.com/user-manual/manual_circuit.html#classical-and-conditional-operations) and [Registers and IDs](https://cqcl.github.io/pytket/manual/manual_circuit.html#registers-and-ids) for additional examples."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import Circuit, Qubit, Bit, OpType, reg_eq\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up Repetition Code with mid-circuit measurement and corrections"]}, {"cell_type": "markdown", "metadata": {}, "source": ["2 1 0 = data: data qubits
\n", "*----*----*
\n", " ZZ ZZ
\n", " 1 0 = syndromes
\n", " 0 0 = ancillas"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up circuit object"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit = Circuit(name=\"Repetition Code\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Reserve registries"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add qubit register, the data qubits"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["data = circuit.add_q_register(\"data\", 3)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add qubit register, the ancilla qubit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["ancilla = circuit.add_q_register(\"anc\", 1)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add classical registers for the syndromes"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["syndrome = circuit.add_c_register(\"syndrome\", 2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Add classical registers for the output"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["output = circuit.add_c_register(\"output\", 3)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Prepare the logical state
\n", "Qubits always start in |0> and logical |0> == |000>.
\n", "So we already start in logical |0>."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Syndrome Extraction"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.add_gate(OpType.Reset, ancilla)\n", "circuit.CX(data[0], ancilla[0])\n", "circuit.CX(data[1], ancilla[0])\n", "circuit.Measure(ancilla[0], syndrome[0])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Syndrome Extraction"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.add_gate(OpType.Reset, ancilla)\n", "circuit.CX(data[1], ancilla[0])\n", "circuit.CX(data[2], ancilla[0])\n", "circuit.Measure(ancilla[0], syndrome[1])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Correction
\n", "if(syndromes==1) -> 01 -> check 0 bad -> X on qubit 0"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[0], condition=reg_eq(syndrome, 1))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if(syndromes==2) -> 10 -> check 1 bad -> X on qubit 2"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[2], condition=reg_eq(syndrome, 2))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["if(syndromes==3) -> 11 -> check 1 and 2 bad -> X on qubit 1"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.X(data[1], condition=reg_eq(syndrome, 3))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Measure out data qubits"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["circuit.Measure(data[0], output[0])\n", "circuit.Measure(data[1], output[1])\n", "circuit.Measure(data[2], output[2])"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Select Device"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Login to the Quantinuum API using your credentials and check the device status."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["print(machine, \"status:\", backend.device_state(device_name=machine))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Circuit Compilation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`pytket` includes many features for optimizing circuits. This includes reducing the number of gates where possible and resynthesizing circuits for a quantum computer's native gate set. See the `pytket` [User Manual](https://cqcl.github.io/pytket/manual/index.html) for more information on all the options that are available."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here the circuit is compiled with `get_compiled_circuit`, which includes optimizing the gates and resynthesizing the circuit to Quantinuum's native gate set. The `optimisation_level` sets the level of optimisation to perform during compilation, check [Default Compilation](https://cqcl.github.io/pytket-quantinuum/api/index.html#default-compilation) in the pytket-quantinuum documentation for more details."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["compiled_circuit = backend.get_compiled_circuit(circuit, optimisation_level=1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(compiled_circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Submit and Run the Circuit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["n_shots = 100\n", "print(\n", " \"Cost in HQCs:\",\n", " backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-1SC\"),\n", ")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)\n", "print(handle)\n", "status = backend.circuit_status(handle)\n", "print(status)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["import json"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["with open(\"pytket_mcmr_example.json\", \"w\") as file:\n", " json.dump(result.to_dict(), file)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Analyze Results"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We will now take the raw results and apply a majority vote to determine how many times we got 0 vs 1."]}, {"cell_type": "markdown", "metadata": {}, "source": ["First, define a majority vote function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def majority(result):\n", " \"\"\"Returns whether the output should be considered a 0 or 1.\"\"\"\n", " if result.count(0) > result.count(1):\n", " return 0\n", " elif result.count(0) < result.count(1):\n", " return 1\n", " else:\n", " raise Exception(\"count(0) should not equal count(1)\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now process the output:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result_output_cnts = result.get_counts([output[i] for i in range(output.size)])"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result_output_cnts"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, determine how many times 0 vs 1 was observed using the majority vote function."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["zeros = 0 # Counts the shots with majority zeros\n", "ones = 0 # Counts the shots with majority ones"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["for out in result_output_cnts:\n", " m = majority(out)\n", " if m == 0:\n", " zeros += result_output_cnts[out]\n", " else:\n", " ones += result_output_cnts[out]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A logical zero was initialized, so our error rate should be number of ones / total number of shots: `ones/shots`"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["p = ones / n_shots\n", "print(f\"The error-rate is: p = {p}\")"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
diff --git a/examples/Quantinuum_parametrized_gates.ipynb b/examples/Quantinuum_parametrized_gates.ipynb
index c699bc51..36585d0f 100644
--- a/examples/Quantinuum_parametrized_gates.ipynb
+++ b/examples/Quantinuum_parametrized_gates.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# How to Submit Parametrized Circuits"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Parametrized circuits are common in variational algorithms. Pytket supports parameters within circuits via symbols. For more information, see [Symbolic Circuits](https://cqcl.github.io/pytket/manual/manual_circuit.html?highlight=paramet#symbolic-circuits) and [Symbolic Compilation](https://tket.quantinuum.com/user-manual/manual_compiler.html#compiling-symbolic-circuits)."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import fresh_symbol\n", "from pytket.circuit import Circuit\n", "from pytket.circuit.display import render_circuit_jupyter\n", "from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up parametrized circuit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["a = fresh_symbol(\"a\")\n", "circuit = Circuit(3, name=\"Parametrized Circuit\")\n", "circuit.X(0)\n", "circuit.CX(0, 1).CX(1, 2)\n", "circuit.Rz(a, 2)\n", "circuit.CX(1, 2).CX(0, 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note the substitution of an actual value to the `a` variable below."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Create a version of the circuit that utilizes a specific value for the variable a"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["simulation_circuit = circuit.copy()\n", "simulation_circuit.measure_all()\n", "simulation_circuit.symbol_substitution({a: -0.09})"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Compile the circuit: this includes optimizing the gates and resynthesizing the circuit to Quantinuum's native gate set"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["compiled_circuit = backend.get_compiled_circuit(simulation_circuit)\n", "render_circuit_jupyter(compiled_circuit)\n", "n_shots = 100\n", "backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-2SC\")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["status = backend.circuit_status(handle)\n", "print(status)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)\n", "print(result)"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# How to Submit Parametrized Circuits"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Parametrized circuits are common in variational algorithms. Pytket supports parameters within circuits via symbols. For more information, see [Symbolic Circuits](https://cqcl.github.io/pytket/manual/manual_circuit.html?highlight=paramet#symbolic-circuits) and [Symbolic Compilation](https://tket.quantinuum.com/user-manual/manual_compiler.html#compiling-symbolic-circuits)."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import fresh_symbol\n", "from pytket.circuit import Circuit\n", "from pytket.circuit.display import render_circuit_jupyter\n", "from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\"\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Set up parametrized circuit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["a = fresh_symbol(\"a\")\n", "circuit = Circuit(3, name=\"Parametrized Circuit\")\n", "circuit.X(0)\n", "circuit.CX(0, 1).CX(1, 2)\n", "circuit.Rz(a, 2)\n", "circuit.CX(1, 2).CX(0, 1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["render_circuit_jupyter(circuit)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note the substitution of an actual value to the `a` variable below."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Create a version of the circuit that utilizes a specific value for the variable a"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["simulation_circuit = circuit.copy()\n", "simulation_circuit.measure_all()\n", "simulation_circuit.symbol_substitution({a: -0.09})"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Compile the circuit: this includes optimizing the gates and resynthesizing the circuit to Quantinuum's native gate set"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["compiled_circuit = backend.get_compiled_circuit(simulation_circuit)\n", "render_circuit_jupyter(compiled_circuit)\n", "n_shots = 100\n", "backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker=\"H1-1SC\")\n", "handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["status = backend.circuit_status(handle)\n", "print(status)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = backend.get_result(handle)\n", "print(result)"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
diff --git a/examples/Quantinuum_signing_in.ipynb b/examples/Quantinuum_signing_in.ipynb
index ffe490fd..2bb74cc7 100644
--- a/examples/Quantinuum_signing_in.ipynb
+++ b/examples/Quantinuum_signing_in.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Signing into the Quantinuum User Portal"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains examples of how to sign in via the Quantinuum API."]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Requirements:**
\n", "* You must a verified Quantinuum account
\n", "* You must have accepted the latest [terms and conditions](https://um.qapi.honeywell.com/static/media/user_terms_and_conditions.46957d35.pdf) which can only be done by logging into the [Quantinuum User Portal](https://um.qapi.quantinuum.com)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Login "]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you already have a verified user portal account you will be asked to provide your credentials after initializing the `QuantinuumBackend` interface. If you opted to set up a native account during your user registration we recommend you use this approach."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 1: `Enter your email:`"]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 2: `Enter your password: `"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you opted to set up Multi-factor Authentication (MFA), you will also be required to provide a verification `code`. This code automatically refreshes every 30 seconds and can be found on the authenticator app used to setup MFA on your account. The interface does not change when MFA is setup. To enable MFA navigate to the *Account* tab in the user view on the user portal. MFA is not available for users logging in through a Microsoft account."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 3: `Enter your MFA verification code: `"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-2E\" # Substitute any Quantinuum target\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["\n", "
"]}, {"cell_type": "markdown", "metadata": {}, "source": ["# Signing into the Quantinuum User Portal"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook contains examples of how to sign in via the Quantinuum API."]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Requirements:**
\n", "* You must a verified Quantinuum account
\n", "* You must have accepted the latest [terms and conditions](https://um.qapi.honeywell.com/static/media/user_terms_and_conditions.46957d35.pdf) which can only be done by logging into the [Quantinuum User Portal](https://um.qapi.quantinuum.com)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Login "]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you already have a verified user portal account you will be asked to provide your credentials after initializing the `QuantinuumBackend` interface. If you opted to set up a native account during your user registration we recommend you use this approach."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 1: `Enter your email:`"]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 2: `Enter your password: `"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you opted to set up Multi-factor Authentication (MFA), you will also be required to provide a verification `code`. This code automatically refreshes every 30 seconds and can be found on the authenticator app used to setup MFA on your account. The interface does not change when MFA is setup. To enable MFA navigate to the *Account* tab in the user view on the user portal. MFA is not available for users logging in through a Microsoft account."]}, {"cell_type": "markdown", "metadata": {}, "source": ["* Prompt 3: `Enter your MFA verification code: `"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.quantinuum import QuantinuumBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["machine = \"H1-1E\" # Substitute any Quantinuum target\n", "backend = QuantinuumBackend(device_name=machine)\n", "backend.login()"]}, {"cell_type": "markdown", "metadata": {}, "source": [" © 2024 by Quantinuum. All Rights Reserved.
"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
\ No newline at end of file
diff --git a/examples/python/Quantinuum_arbitrary_angle_zz.py b/examples/python/Quantinuum_arbitrary_angle_zz.py
index 72e6978a..b2778ed5 100644
--- a/examples/python/Quantinuum_arbitrary_angle_zz.py
+++ b/examples/python/Quantinuum_arbitrary_angle_zz.py
@@ -168,7 +168,7 @@ def meas_Had_basis(orig_circ, n_qubits):
from pytket.extensions.quantinuum import QuantinuumBackend
-machine = "H1-2E"
+machine = "H1-1E"
backend = QuantinuumBackend(device_name=machine)
backend.login()
@@ -212,7 +212,7 @@ def meas_Had_basis(orig_circ, n_qubits):
)
print(
"Arbitrary angle ZZ QFT:",
- backend.cost(qft_fid_arbZZ_compiled, n_shots=n_shots, syntax_checker="H1-2SC"),
+ backend.cost(qft_fid_arbZZ_compiled, n_shots=n_shots, syntax_checker="H1-1SC"),
)
# ### Run the Circuit
diff --git a/examples/python/Quantinuum_conditional_gates.py b/examples/python/Quantinuum_conditional_gates.py
index 0f4c5c7e..a624a599 100644
--- a/examples/python/Quantinuum_conditional_gates.py
+++ b/examples/python/Quantinuum_conditional_gates.py
@@ -51,7 +51,7 @@
n_shots = 100
backend = QuantinuumBackend(device_name=machine)
compiled_circuit = backend.get_compiled_circuit(circ)
-backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-2SC")
+backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-1SC")
handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)
status = backend.circuit_status(handle)
status
diff --git a/examples/python/Quantinuum_mid_circuit_measurement.py b/examples/python/Quantinuum_mid_circuit_measurement.py
index ecffdea9..79fd64c0 100644
--- a/examples/python/Quantinuum_mid_circuit_measurement.py
+++ b/examples/python/Quantinuum_mid_circuit_measurement.py
@@ -97,7 +97,7 @@
n_shots = 100
print(
"Cost in HQCs:",
- backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-2SC"),
+ backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-1SC"),
)
handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)
print(handle)
diff --git a/examples/python/Quantinuum_parametrized_gates.py b/examples/python/Quantinuum_parametrized_gates.py
index 858b4151..9e32cb5a 100644
--- a/examples/python/Quantinuum_parametrized_gates.py
+++ b/examples/python/Quantinuum_parametrized_gates.py
@@ -37,7 +37,7 @@
compiled_circuit = backend.get_compiled_circuit(simulation_circuit)
render_circuit_jupyter(compiled_circuit)
n_shots = 100
-backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-2SC")
+backend.cost(compiled_circuit, n_shots=n_shots, syntax_checker="H1-1SC")
handle = backend.process_circuit(compiled_circuit, n_shots=n_shots)
status = backend.circuit_status(handle)
diff --git a/examples/python/Quantinuum_signing_in.py b/examples/python/Quantinuum_signing_in.py
index 353a0018..c58dabbd 100644
--- a/examples/python/Quantinuum_signing_in.py
+++ b/examples/python/Quantinuum_signing_in.py
@@ -23,7 +23,7 @@
from pytket.extensions.quantinuum import QuantinuumBackend
-machine = "H1-2E" # Substitute any Quantinuum target
+machine = "H1-1E" # Substitute any Quantinuum target
backend = QuantinuumBackend(device_name=machine)
backend.login()