{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Mitiq Tutorial\n", "\n", "Before running this tutorial, make sure you have `mitiq` installed. We recommend using virtual environments, either conda or venv.\n", "\n", "```bash\n", "pip install mitiq\n", "```\n", "\n", "Use `pip list | grep mitiq` to ensure it is installed.\n", "\n", "Make sure you have selected the right kernel corresponding to your virtual environment for your Jupyter notebook!\n", "# Goals\n", "\n", "- learn how to apply ZNE on a basic workflow\n", "- learn which parameters in ZNE can be changed to improve performance" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# You can use the magic command % to install from within your Jupyter notebook. Be sure to restart after installing\n", "%pip install mitiq" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pip list | grep mitiq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Define the circuit\n", "\n", "First, we define a simple circuit to work with." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import cirq\n", "\n", "a, b, c = cirq.LineQubit.range(3)\n", "\n", "circuit = cirq.Circuit([\n", " cirq.H(a),\n", " cirq.CNOT(a, b),\n", " cirq.CNOT(b, c),\n", " cirq.S(a),\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(circuit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Unitary Folding\n", "\n", "Making the circuit longer, and hence noisier." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mitiq.zne.scaling import fold_gates_at_random, fold_global\n", "\n", "\n", "folded_circuit = fold_gates_at_random(circuit, scale_factor=2.)\n", "\n", "print(folded_circuit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Executors\n", "\n", "Executors are python functions that consume a quantum circuit, and output an expectation value.\n", "A type signature might look something like `Circuit -> float`.\n", "That said, executors can have additional arguments used to control other parts of the execution process.\n", "The circuit must be the first argument, however." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def execute(circuit, noise_level=0.005):\n", " \"\"\"Returns Tr[ρ |0⟩⟨0|] where ρ is the state prepared by the circuit\n", " with depolarizing noise.\"\"\"\n", " # TODO: add depolarizing noise\n", " noisy_circuit = ...\n", " \n", " return (\n", " cirq.DensityMatrixSimulator()\n", " .simulate(noisy_circuit)\n", " .final_density_matrix[0, 0]\n", " .real\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Extrapolation\n", "\n", "Computing the Zero-Noise limit." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mitiq.zne.inference import RichardsonFactory, LinearFactory, ExpFactory\n", "\n", "lin = LinearFactory([1, 3, 5])\n", "\n", "lin.run(circuit, execute)\n", "lin.reduce()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lin.plot_fit();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Randomized Benchmarking (RB)\n", "RB circuits are circuits that are in effect, equivalent to the identity. Hence, the ideal probability that the end state is $|00\\cdots 0\\rangle$ is 1." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mitiq.benchmarks import generate_rb_circuits\n", "\n", "circuit = generate_rb_circuits(2, num_cliffords=20)[0]\n", "\n", "print(circuit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mitiq import zne\n", "\n", "\n", "true_value = execute(circuit, noise_level=0.0)\n", "noisy_value = execute(circuit)\n", "zne_value = zne.execute_with_zne(circuit, execute)\n", "\n", "print(f\"Error w/o Mitiq: {abs((true_value - noisy_value) / true_value):.3f}\")\n", "print(f\"Error w Mitiq: {abs((true_value - zne_value) / true_value):.3f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise\n", "\n", "Keeping the circuit the same, can you get a smaller error by modifying some of the ZNE options?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from mitiq.zne.scaling import fold_global, fold_gates_at_random, identity_insertion\n", "from mitiq.zne.inference import (\n", " LinearFactory,\n", " RichardsonFactory,\n", " PolyFactory,\n", " ExpFactory,\n", ")\n", "# TODO: select inference method and scaling factors\n", "inference_method = ...\n", "\n", "# TODO: select scaling method\n", "noise_scaling_method = ...\n", "\n", "zne_value = zne.execute_with_zne(\n", " circuit,\n", " execute,\n", " factory=inference_method,\n", " scale_noise=noise_scaling_method,\n", ")\n", "\n", "print(f\"Error w/o Mitiq: {abs((true_value - noisy_value) / true_value):.3f}\")\n", "print(f\"Error w Mitiq: {abs((true_value - zne_value) / true_value):.3f}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "dev", "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.12.4" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }