{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Visualizing Circuit objects: QEC experiment with a d=3 repetition code\n", "\n", "```{note}\n", "The widgets in this notebook are interactive!\n", "```\n", "\n", "In this notebook, we construct an experiment for a $d=3$ repetition code qubit. The circuit consists of a reset, 3 rounds of syndrome extraction and a logical readout operation. For the visualization purpose of this notebook, the syndrome extraction cycles are split into 2 individual sub-circuits — one subcircuit consists of one QEC cycle, and the other consists of two QEC cycles. Before the QEC cycles, there is an initialization circuit where all data qubits are reset to their $|0\\rangle$ state. After the three QEC cycles, the nine data qubits are all read out.\n", "\n", "After constructing this `Eka` object and interpreting it, we then visualize the `Circuit` and its nested structure." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from loom.eka import Eka, Lattice, Block, Stabilizer, PauliOperator, Circuit\n", "from loom.eka.operations import (\n", " MeasureBlockSyndromes,\n", " MeasureLogicalZ,\n", " ResetAllDataQubits,\n", ")\n", "from loom.interpreter import interpret_eka\n", "import loom.visualizer as vis\n", "from pprint import pprint" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start by defining the logical qubit as a repetition code of distance 3." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Create a custom block for a repetition code\n", "\n", "# Start by defining the geometry of the block\n", "lattice = Lattice.linear((5,))\n", "stabilizers = [\n", " Stabilizer(\n", " pauli=\"XX\",\n", " data_qubits=(\n", " (0, 0),\n", " (1, 0),\n", " ),\n", " ancilla_qubits=((3, 1),),\n", " ),\n", " Stabilizer(\n", " pauli=\"XX\",\n", " data_qubits=(\n", " (1, 0),\n", " (2, 0),\n", " ),\n", " ancilla_qubits=((4, 1),),\n", " ),\n", "]\n", "logical_x = PauliOperator(pauli=\"XXX\", data_qubits=((0, 0), (1, 0), (2, 0)))\n", "logical_z = PauliOperator(pauli=\"ZZZ\", data_qubits=((0, 0), (1, 0), (2, 0)))\n", "\n", "block = Block(\n", " stabilizers=stabilizers,\n", " logical_x_operators=[logical_x],\n", " logical_z_operators=[logical_z],\n", " unique_label=\"q1\",\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stabilizers\n", "\n", "Stabilizers are defined by hand using `Stabilizer`, we can print them for more details on which qubit coordinates are associated with each `Stabilizer` object." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(XX ((0, 0), (1, 0)) ((3, 1),), XX ((1, 0), (2, 0)) ((4, 1),))\n" ] } ], "source": [ "pprint(block.stabilizers)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quantum circuit for syndrome extraction\n", "\n", "The syndrome extraction circuits are defined automatically since we haven't specified them. We can print them for more details. Note that they are blueprints for the composition that occurs during interpretation. This means that the `Channel` s associated to these `Circuit` objects are not valid `Channel` s in the final circuit but placeholders that can be re-used.\n", "\n", "The `SyndromeCircuit` objects also bear information of which type of stabilizer they are associated to, as well as a name and uuid." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(SyndromeCircuit(pauli='XX',\n", " name='default_xx',\n", " circuit=stab_xx (6 ticks)\n", "0: reset_0\n", "1: h\n", "2: cx\n", "3: cx\n", "4: h\n", "5: measurement,\n", " uuid='46bb8d65-7ffc-4706-a5e0-b960ed8a2580'),)\n" ] } ], "source": [ "pprint(block.syndrome_circuits)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Construct and interpret the `Eka` object" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "final circuit (20 ticks)\n", "0: reset all data qubits of block q1 to |0>\n", "1: measure q1 syndromes 1 time(s)\n", "7: measure q1 syndromes 2 time(s)\n", "19: measure logical z of q1\n" ] } ], "source": [ "# We need todefine the operations we want to perform\n", "operations = [\n", " [ResetAllDataQubits(\"q1\", state=\"0\")],\n", " [MeasureBlockSyndromes(\"q1\", n_cycles=1)],\n", " [MeasureBlockSyndromes(\"q1\", n_cycles=2)],\n", " [MeasureLogicalZ(\"q1\")],\n", "]\n", "\n", "my_eka = Eka(\n", " lattice=lattice,\n", " blocks=[\n", " block,\n", " ],\n", " operations=operations,\n", ")\n", "\n", "interpreted = interpret_eka(my_eka)\n", "final_circuit = interpreted.final_circuit\n", "print(final_circuit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualization\n", "Now, let's visualize the `Circuit` object for the experiment:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "