diff --git a/doc/getting_started.ipynb b/doc/getting_started.ipynb index 4bd015a6..1e8d625e 100644 --- a/doc/getting_started.ipynb +++ b/doc/getting_started.ipynb @@ -45,7 +45,7 @@ "\n", "- Familiarity with basic Python syntax, and having a working Python 3.7+ environment. (Perhaps you are reading this notebook in such an environment.)\n", "\n", - "- Familiarity with the basic concepts of *quantum circuits*, such as qubits and common quantum gates like Hadamard and CNOT.\n", + "- Familiarity with the basic concepts of *quantum circuits*, such as qubits and common quantum gates like [Hadamard](https://en.wikipedia.org/wiki/Quantum_logic_gate#Hadamard_gate) and [CNOT](https://en.wikipedia.org/wiki/Quantum_logic_gate#Controlled_gates).\n", "\n", "- A basic understanding of stabilizer circuits. For example, this tutorial assumes you've heard that they can be simulated cheaply and that they can represent protocols such as quantum error correction.\n", "\n", @@ -87,7 +87,7 @@ "\n", "The first thing to do is to install and import Stim.\n", "Thanks to the Python ecosystem, this is easy to do!\n", - "Stim is available as a [PyPI](https://pypi.org/project/stim/) package, and can be installed using `pip install stim` and then imported with `import stim` (just like any other python package)." + "Stim is available as a [PyPI](https://pypi.org/project/stim/) package, and can be installed using `pip install stim` and then imported with `import stim` (just like any other Python package)." ] }, { @@ -133,9 +133,9 @@ "\n", "# 3. Create a simple circuit, and sample from it\n", "\n", - "In Stim, circuits are instances of the `stim.Circuit` class. You create a new empty circuit with `stim.Circuit()`, and add operations to it by calling `circuit.append(name_of_gate, list_of_targets)`.\n", + "In Stim, circuits are instances of the [`stim.Circuit`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit) class. You create a new empty circuit with `stim.Circuit()`, and add operations to it by calling `circuit.append(name_of_gate, list_of_targets)`.\n", "\n", - "You can find the name of the gate you want from the [Stim gates reference](https://github.com/quantumlib/Stim/blob/main/doc/gates.md). Most of them are straightforward, like \"H\" for the Hadamard gate. Targets are just a number indicating a qubit. There's a qubit `0`, a qubit `1`, etc.\n", + "You can find the name of the gate you want from the [Stim gates reference](https://github.com/quantumlib/Stim/blob/main/doc/gates.md). Most of the names are straightforward, like \"H\" for the Hadamard gate. A *target* is just a number representing the identity of a qubit. There's a qubit `0`, a qubit `1`, etc.\n", "\n", "The first circuit you'll make is a circuit that prepares a [Bell pair](https://en.wikipedia.org/wiki/Bell_state) and then measures it:" ] @@ -164,7 +164,7 @@ "id": "ySG_dqfQ-qOQ" }, "source": [ - "Stim has a few ways to look at the circuits you've made. The circuit's `repr` is an expression that recreates the circuit using [Stim's circuit file syntax](https://github.com/quantumlib/Stim/blob/main/doc/file_format_stim_circuit.md):" + "Stim has a few ways to let you look at the circuits you've made. The circuit's `repr` is an expression that recreates the circuit using [Stim's circuit file syntax](https://github.com/quantumlib/Stim/blob/main/doc/file_format_stim_circuit.md):" ] }, { @@ -203,7 +203,7 @@ "id": "D-RpRUTw-qOQ" }, "source": [ - "You can also use the `circuit.diagram` method to get an annotated text diagram of the circuit:" + "You can also use the [`circuit.diagram`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.diagram) method to get an annotated text diagram of the circuit:" ] }, { @@ -245,7 +245,7 @@ "id": "XKnYuBEB-qOQ" }, "source": [ - "There are also other types of diagrams. For example, specifying `timeline-svg` will return a Scalable Vector Graphics picture of the circuit instead of a text diagram:" + "There are also other types of diagrams. For example, specifying `timeline-svg` will return a Scalable Vector Graphics ([SVG](https://en.wikipedia.org/wiki/SVG)) picture of the circuit instead of a text diagram:" ] }, { @@ -321,7 +321,7 @@ "id": "5dRl_-WZHDP2" }, "source": [ - "Anyways, let's stop looking at your circuit and start using it. You can sample from the circuit by using the `circuit.compile_sampler()` method to get a sampler object, and then calling `sample` on that object.\n", + "Anyways, let's stop looking at your circuit and start using it. You can sample from the circuit by using the [`circuit.compile_sampler()`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.compile_sampler) method to get a sampler object, and then calling `sample` on that object.\n", "\n", "Try taking 10 shots from the circuit:" ] @@ -384,7 +384,7 @@ "For example, in the circuit you created above, the two measurement results should always be equal.\n", "You can tell Stim you care about that by adding a `DETECTOR` annotation to the circuit.\n", "\n", - "The `DETECTOR` annotation will take two targets: the two measurements whose parity you are asserting should be consistent from run to run. You point at the measurements by using the `stim.target_rec` method (short for \"target measurement record\"). The most recent measurement is `stim.target_rec(-1)` (also known as `rec[-1]` in stim's circuit language), and the second most recent measurement is `stim.target_rec(-2)`:" + "The `DETECTOR` annotation will take two targets: the two measurements whose parity you are asserting should be consistent from run to run. You point at the measurements by using the [`stim.target_rec`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.target_rec) method (short for \"target measurement record\"). The most recent measurement is `stim.target_rec(-1)` (also known as `rec[-1]` in Stim's circuit language), and the second most recent measurement is `stim.target_rec(-2)`:" ] }, { @@ -427,8 +427,8 @@ "A detector doesn't say whether the parity should be even or should be odd, only that it should always be the same.\n", "You annotate that a pair of measurements is always different in the same way that you annotate that a pair of measurements is always the same; it's the *consistency* that's key.\n", "\n", - "Anyways, now that you've annotated the circuit with a detector, you can sample from the circuit's detectors instead of sampling from its measurements.\n", - "You do that by creating a detector sampler, using the `compile_detector_sampler` method, and then calling `sample` on it." + "Moving on, now that you've annotated the circuit with a detector, you can sample from the circuit's detectors instead of sampling from its measurements.\n", + "You do that by creating a detector sampler, using the [`compile_detector_sampler`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.compile_detector_sampler) method, and then calling [`sample`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.CompiledDetectorSampler.sample) on it." ] }, { @@ -469,7 +469,7 @@ "There's one entry per row, because you put one detector in the circuit.\n", "\n", "Notice how the results are always `False`.\n", - "The detector is never producing a detection event.\n", + "This means the detector is never producing a detection event.\n", "That's because there's no noise in the circuit; nothing to disturb the peace and quiet of a perfectly working machine.\n", "Well... time to fix that!\n", "\n", @@ -707,9 +707,9 @@ "Well... a classical error-correcting circuit:\n", "the *repetition* code.\n", "\n", - "You could generate a repetition code circuit for yourself, but for the purposes of this tutorial it's easiest to use the example one included with Stim.\n", - "You can do this by calling `stim.Circuit.generated` with an argument of `\"repetition_code:memory\"`.\n", - "(You can find other valid arguments in the method's doc string, or just by passing in a bad one and looking at the exception message that comes out.)\n", + "You could generate a repetition code circuit for yourself, but for the purposes of this tutorial it's easiest to use the example included with Stim.\n", + "You can do this by calling [`stim.Circuit.generated`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.generated) with an argument of `\"repetition_code:memory\"`.\n", + "(You can find out about other valid arguments in the method's doc string, or just by passing in a bad one and looking at the exception message that comes out.)\n", "\n", "Stim takes a few different parameters when generating circuits.\n", "You have to decide how many times the stabilizers of the code are measured by specifying `rounds`, you have to decide on the size of the code by specifying `distance`, and you can specify what kind of noise to include using a few optional parameters.\n", @@ -1998,7 +1998,7 @@ "Stim has a key feature that makes it easier to use a decoder: converting a circuit into a detector error model.\n", "A detector error model is just a list of all the independent error mechanisms in a circuit, as well as their symptoms (which detectors they set off) and frame changes (which logical observables they flip).\n", "\n", - "You can get the detector error mode for a circuit by calling `circuit.detector_error_model()`:" + "You can get the detector error mode for a circuit by calling [`circuit.detector_error_model()`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.detector_error_model):" ] }, { @@ -2123,13 +2123,22 @@ "print(repr(dem))" ] }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "QgqQ90GlBcB_" + }, + "execution_count": null, + "outputs": [] + }, { "cell_type": "markdown", "metadata": { "id": "2NpcBtBM-qOS" }, "source": [ - "You can view the detector error model as a graph by using the `matchgraph-svg` diagram. Note that this diagram looking good is relying heavily on the circuit specifying coordinate data for its detectors. Fortunately, the circuit you generated includes good coordinate data:" + "You can view the detector error model as a graph by using the `matchgraph-svg` diagram. Note that this diagram looking good relies heavily on the circuit specifying coordinate data for its detectors. Fortunately, the circuit you generated includes good coordinate data:" ] }, { @@ -2586,15 +2595,15 @@ "id": "fLY3a5w9PT1L" }, "source": [ - "In the above diagram, each node is a detector and each edge is an error mechanism. The matcher is going to decode errors by trying to match each excited node to another nearby excited node, or to the side boundaries, which minimizing the number of edges that were used.\n", + "In the diagram above, each node is a detector and each edge is an error mechanism. The matcher is going to decode errors by trying to match each excited node to another nearby excited node, or to the side boundaries, which minimizes the number of edges that were used.\n", "\n", - "The detector error model format is easier for decoders to consume than a raw circuit, because everything is explained in terms of observable symptoms and hidden symptoms, which is how decoders usually conceptualize of the problem space.\n", - "For example, some decoders can be configured using a weighted graph, and `stim.DetectorErrorModel` is effectively just a weighted graph.\n", - "It might be a pain to write the glue code that converts the `stim.DetectorErrorModel` into exactly the right kind of graph expected by the decoder, but it's much easier than starting from the circuit or generating the graph from scratch and you only have to write that code once instead of once per circuit.\n", + "The detector error model format is easier for decoders to consume than a raw circuit, because everything is explained in terms of observable symptoms and hidden symptoms, which is how decoders usually conceptualize the problem space.\n", + "For example, some decoders can be configured using a weighted graph, and [`stim.DetectorErrorModel`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.DetectorErrorModel) is effectively just a weighted graph.\n", + "It might be a pain to write the glue code that converts the [`stim.DetectorErrorModel`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.DetectorErrorModel) into exactly the right kind of graph expected by the decoder, but it's much easier than starting from the circuit or generating the graph from scratch – and you only have to write that code once instead of once per circuit.\n", "\n", - "For this tutorial you'll use existing packages instead of writing your own glue code.\n", - "Specifically, you'll use [`pymatching`](https://github.com/oscarhiggott/PyMatching) as your decoder.\n", - "PyMatching is an open-source minimum weight perfect matching decoder written by Oscar Higgott.\n", + "For this tutorial, you'll use existing packages instead of writing your own glue code.\n", + "Specifically, you'll use the open-source package [PyMatching](https://github.com/oscarhiggott/PyMatching) as your decoder.\n", + "PyMatching is a minimum-weight perfect matching decoder written by Oscar Higgott.\n", "You can install it using `pip install pymatching`:" ] }, @@ -2626,18 +2635,18 @@ "id": "ewrxiwXMQ-Yz" }, "source": [ - "Now you're going to write a method for sampling a circuit using stim, then decoding it using pymatching, and counting how often it gets the answer right.\n", + "Now you're going to write a method that will sample a circuit using Stim, decode it using PyMatching, and count how often it gets the right answer.\n", "\n", "First, you sample detection events and observable flips from the circuit.\n", - "You do this by creating a sampler with `circuit.compile_detector_sampler()` and then calling `sampler.sample(shots, separate_observables=True)`.\n", + "You do this by creating a sampler with [`circuit.compile_detector_sampler()`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.compile_detector_sampler) and then calling [`sampler.sample(shots, separate_observables=True)`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.CompiledDetectorSampler.sample).\n", "The `separate_observables=True` argument is saying that you want the result of the method to be a tuple where the first entry is detection event data to give to the decoder and the second entry is the observable flip data the decoder is supposed to predict.\n", "\n", - "Second, you extract decoder information by using `stim.Circuit.detector_error_model(...)` and create a decoder from this information using `pymatching.Matching.from_detector_error_model`.\n", + "Second, you extract decoder information by using [`stim.Circuit.detector_error_model(...)`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.detector_error_model) and create a decoder from this information using [`pymatching.Matching.from_detector_error_model`](https://pymatching.readthedocs.io/en/latest/api.html#pymatching.matching.Matching.from_detector_error_model).\n", "\n", "Third, you run `matching.predict` to get the predicted observable flips.\n", "\n", - "Fourth, you compare the predictions made by pymatching to the actual observable flip data that was sampled.\n", - "Anytime the prediction differs, that's a logical error." + "Fourth, you compare the predictions made by PyMatching to the actual observable flip data that was sampled.\n", + "Anytime the prediction differs, it indicates a logical error." ] }, { @@ -2825,7 +2834,7 @@ "id": "J5TZ-AlJVGmk" }, "source": [ - "From the results here you can see that the repetition code has amazingly good performance! Well... it's not *quite* so amazing when you remember that you're using a phenomenological noise model (instead of a circuit level noise model) and also that you're inserting depolarizing errors instead of bit flip errors (the repetition code is immune to Z errors, and when a depolarizing error occurs it's a Z error one third of the time).\n", + "From the results here you can see that the repetition code has amazingly good performance! Well... it's not *quite* so amazing when you remember that you're using a phenomenological noise model (instead of a circuit-level noise model) and also that you're inserting depolarizing errors instead of bit-flip errors (the repetition code is immune to Z errors, and when a depolarizing error occurs it's a Z error one third of the time).\n", "\n", "Still, you can see that it's not so hard to run a few different cases and plot them out. A bit tedious, maybe." ] @@ -2841,7 +2850,7 @@ "\n", "Now that you understand the basic workflow of sampling from a circuit, making a decoder predict the observable flips, and plotting out the result, you probably never want to do that by hand ever again. And that's without even getting into dividing work into batches, or across multiple CPU cores!\n", "\n", - "Fortunately, you can use `sinter` to do almost the entire thing for you. Install sinter using `pip install sinter`:" + "Fortunately, you can use [Sinter](https://pypi.org/project/sinter/) to do almost the entire thing for you. Install Sinter using `pip install sinter`:" ] }, { @@ -2873,9 +2882,9 @@ "id": "dxTADjNX-qOW" }, "source": [ - "Wrap your circuits into `sinter.Task` instances, and give those tasks to `sinter.collect`.\n", + "Wrap your circuits into [`sinter.Task`](https://github.com/quantumlib/Stim/blob/main/doc/sinter_api.md#sinter.Task) instances, and give those tasks to [`sinter.collect`](https://github.com/quantumlib/Stim/blob/main/doc/sinter_api.md#sinter.collect).\n", "Sinter will spin up multiple worker processes to sample from and decode these circuits.\n", - "`sinter.collect` takes a variety of useful options, such as the maximum number of shots or errors to take from each task, as well as the number of workers to use:" + "[`sinter.collect`](https://github.com/quantumlib/Stim/blob/main/doc/sinter_api.md#sinter.collect) takes a variety of useful options, such as the maximum number of shots or errors to take from each task, as well as the number of workers to use:" ] }, { @@ -2915,7 +2924,7 @@ "id": "mVDInHcUbAc0" }, "source": [ - "Sinter also has a `sinter.plot_error_rate` method which can be used to plot the logical error rates. This method automatically adds highlighted regions quantifying uncertainty in the estimates." + "Sinter also has a [`sinter.plot_error_rate`](https://github.com/quantumlib/Stim/blob/main/doc/sinter_api.md#sinter.plot_error_rate) method which can be used to plot the logical error rates. This method automatically adds highlighted regions quantifying uncertainty in the estimates." ] }, { @@ -2982,12 +2991,12 @@ "Estimating the threshold of a repetition code under phenomenelogical noise is one thing.\n", "Estimating the threshold of a true quantum code, such as a surface code, under circuit noise, is...\n", "well, historically, it would be a whole other thing.\n", - "But when using stim, and pymatching, and sinter, the workflow is exactly identical.\n", + "But when using Stim, and PyMatching, and Sinter, the workflow is exactly identical.\n", "The only thing that changes are the circuits input into the process.\n", "\n", "The hard part is making the circuits in the first place.\n", "So, for this tutorial, you'll continue to lean on Stim's example circuits.\n", - "You can make simple surface code circuits using `stim.Circuit.generated`." + "You can make simple surface code circuits using [`stim.Circuit.generated`](https://github.com/quantumlib/Stim/blob/main/doc/python_api_reference_vDev.md#stim.Circuit.generated)." ] }, { @@ -3014,7 +3023,7 @@ "id": "huyjsuMBfSP9" }, "source": [ - "Surface code circuits have a much more complex structure than repetition codes, because they are laid out in a 2d grid instead of a 1d line. A time slice diagram of the circuit without noise will be much clearer than a timeline diagram:" + "Surface code circuits have a much more complex structure than repetition codes, because they are laid out in a 2-D grid instead of a 1-D line. A time slice diagram of the circuit without noise will be much clearer than a timeline diagram:" ] }, { @@ -7903,7 +7912,7 @@ "id": "fPOBAR4T-qOW" }, "source": [ - "You can also make 3d diagrams of the circuit, using `timeline-3d`." + "You can also make 3-D diagrams of the circuit, using `timeline-3d`." ] }, { @@ -8087,8 +8096,8 @@ }, "source": [ "Yet another useful type of diagram, for understanding the structure of this circuit, is a \"detector slice diagram\".\n", - "A detslice diagram shows how the stabilizers checked by the circuit's detectors are changing over time.\n", - "If you look carefully you can see the stabilizers establspot that, halfway through the measurement cycle of the surface code, its state is actually temporarily an even larger surface code!\n", + "A detslice diagram shows how the stabilizers checked by the circuit's detectors change over time.\n", + "If you look carefully, you can see that, halfway through the measurement cycle of the surface code, its state is actually temporarily an even larger surface code!\n", "You can also see the stabilizers establish themselves at the beginning of the circuit, and drain away at the end." ] }, @@ -18708,7 +18717,7 @@ "id": "pWcO6j68-qOW" }, "source": [ - "There is also the diagram type `detslice-with-ops-svg`, which is a overlays the time slice and detslice diagrams. For example, `detslice-with-ops-svg` shows how the first round gradually projects the system into the surface code state." + "There is also the diagram type `detslice-with-ops-svg`, which overlays the time slice and detslice diagrams. For example, `detslice-with-ops-svg` shows how the first round gradually projects the system into the surface code state." ] }, { @@ -20642,7 +20651,7 @@ "source": [ "Okay, enough looking at the circuits, time to collect.\n", "\n", - "Collecting data using `sinter.collect` will take a bit longer this time.\n", + "Collecting data using [`sinter.collect`](https://github.com/quantumlib/Stim/blob/main/doc/sinter_api.md#sinter.collect) will take a bit longer this time.\n", "You can specify `print_progress=True` to get progress updates while the collection runs.\n", "Another useful argument (not used here) is `save_resume_filepath`, which allows you to cancel and restart collection without losing the work that was done." ] @@ -20800,7 +20809,7 @@ }, "source": [ "To a good first approximation, logical error rates decrease exponentially with code distance.\n", - "Use scipy's linear regression to get a line fit of code distance versus log error rate." + "Use [SciPy](https://scipy.org/)'s [linear regression facilities](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html) to get a line fit of code distance versus log error rate." ] }, { @@ -20903,7 +20912,7 @@ "Based on this data, it looks like a distance 20 patch would be sufficient to survive a trillion rounds.\n", "That's a surface code with around 800 physical qubits.\n", "\n", - "Beware that this line fit is being extrapolated quite far. It would be wise to sample a few more code distances. Also, keep in mind that the footprint you just estimated is for a **specific realization of the surface code circuit**, using a **specific choice of circuit level noise**, and using **a specific kind of decoder**. Also, you only estimated the error of memory in one basis (Z); to be thorough you have to also check the X basis." + "Beware that this line fit is being extrapolated quite far. It would be wise to sample a few more code distances. Also, keep in mind that the footprint you just estimated is for a **specific realization of the surface code circuit**, using a **specific choice of circuit-level noise**, and using **a specific kind of decoder**. Also, you only estimated the error of memory in one basis (Z); to be thorough you have to also check the X basis." ] }, { @@ -20956,12 +20965,17 @@ "\n", "## Learning quantum computing\n", "\n", + "\n", + "- [Quantum computing for the very curious](https://quantum.country/qcvc) by Andy Matuschak and Michael Nielsen\n", "- [Building Google's quantum computer]() by Marissa Giustina (2018)\n", "- MIT's [Quantum Information Science I](https://openlearninglibrary.mit.edu/courses/course-v1:MITx+8.370.1x+1T2018/about)\n", "- John Preskill's [Ph/CS 219A Quantum Computation](https://www.youtube.com/playlist?list=PL0ojjrEqIyPy-1RRD8cTD_lF1hflo89Iu) on YouTube\n", "- Quantum AI's YouTube content:\n", " - [Quantum Programming with Cirq](https://www.youtube.com/playlist?list=PLpO2pyKisOjLVt_tDJ2K6ZTapZtHXPLB4)\n", " - [QuantumCasts](https://www.youtube.com/playlist?list=PLQY2H8rRoyvwcpm6Nf-fL4sIYQUXtq3HR)\n", + "- [Quantum computing for the determined](https://michaelnielsen.org/blog/quantum-computing-for-the-determined/) by Michael Nielsen\n", + "- Michael Nielsen and Isaac Chuang's [Quantum Computation And Quantum Information](https://archive.org/embed/QuantumComputationAndQuantumInformation10thAnniversaryEdition)\n", + "\n", "\n", "## Learning quantum error correction\n", "\n",