Toric code
Next we'll discuss a specific CSS code known as the toric code, which was discovered by Alexei Kitaev in 1997. In fact, the toric code isn't a single code, but rather it's a family of codes, one for each positive integer starting from 2. These codes possess a few key properties:
-
The stabilizer generators have low weight, and in particular they all have weight 4. In coding theory parlance, the toric code is an example of a quantum low-density parity check code, or quantum LDPC code (where low means 4 in this case). This is nice because each stabilizer generator measurement doesn't need to involve too many qubits.
-
The toric code has geometric locality. This means that not only do the stabilizer generators have low weight, but it's also possible to arrange the qubits spatially so that each of the stabilizer generator measurements only involves qubits that are close together. In principle, this makes these measurements easier to implement than if they involved spatially distant qubits.
-
Members of the toric code family have increasingly large distance and can tolerate a relatively high error rate.
Toric code description
Let be a positive integer, and consider an lattice with so-called periodic boundaries. For example, this figure depicts an lattice for
Notice that the lines on the right and on the bottom are dotted lines. This is meant to indicate that dotted line on the right is the same line as the line all the way on the left, and similarly, the dotted line on the bottom is the same line as the one on the very top.
To realize this sort of configuration physically requires three dimensions. In particular, we could form the lattice into a cylinder by first matching up the left and right sides, and then bend the cylinder around so that the circles at the ends, which used to be the top and bottom edges of the lattice, meet. Or we could match up the top and bottom first and then the sides; it works both ways and doesn't matter which we choose for the purposes of this discussion.
What we obtain is a torus — or, in other words, a doughnut (although thinking about it as an inner tube of a tire is perhaps a better image to have in mind because this isn't a solid: the lattice has become just the surface of a torus). This is where the name "toric code" comes from.
The way one can "move around" on a torus like this, between adjacent points on the lattice, will likely be familiar to those that have played old-school video games, where moving off the top of the screen causes you emerge on the bottom, and likewise for the left and right edges of the screen. This is how we will view this lattice with periodic boundaries, as opposed to speaking specifically about a torus in 3-dimensional space.
Next, qubits are arranged on the edges of this lattice, as illustrated in the following figure, where qubits are indicated by solid blue circles.
Note that the qubits placed on the dotted lines aren't solid because they're already represented on the topmost and leftmost lines in the lattice. In total there are qubits: qubits on horizontal lines and qubits on vertical lines.
To describe the toric code itself, it remains to describe the stabilizer generators:
-
For each tile formed by the lines in the lattice there is one stabilizer generator, obtained by tensoring matrices on the four qubits touching that tile along with identity matrices on all other qubits.
-
For each vertex formed by the lines in the lattice there is one stabilizer generator, obtained by tensoring matrices on the four qubits adjacent to that vertex along with identity matrices on all other qubits.
In both cases we obtain a weight-4 Pauli operation. Individually, these stabilizer generators may be illustrated as follows.
Here's an illustration showing some examples of stabilizer generators in the context of the lattice itself. Notice that the stabilizer generators that wrap around the periodic boundaries are included. These generators that wrap around the periodic boundaries are not special or in any way distinguished from the ones that don't.
The stabilizer generators must commute for this to be a valid stabilizer code. As usual, the stabilizer generators all commute with one another, because commutes with itself and the identity commutes with everything, and likewise for the stabilizer generators. The and stabilizer generators clearly commute when they act nontrivially on disjoint sets of qubits, like for the examples shown in the previous figure. The remaining possibility is that a stabilizer generator and an stabilizer generator overlap on the qubits upon which they act nontrivially, and whenever this happens the generators must always overlap on two qubits, like in the next figure.
Consequently, two stabilizer generators like this commute, just like and commute. The stabilizer generators therefore all commute with one another.
The second required condition on the stabilizer generators for a stabilizer code is that they form a minimal generating set. This condition is actually not satisfied by this collection: if we multiply all of the stabilizer generators together, we obtain the identity operation, and likewise for the stabilizer generators. Thus, any one of the stabilizer generators can be expressed as the product of all of the remaining ones, and similarly, any one of the stabilizer generators can be expressed as the product of the remaining stabilizer generators. If we remove any one of the stabilizer generators and any one of the stabilizer generators, however, we do obtain a minimal generating set.
To be clear about this, we do in fact care equally about all of the stabilizer generators, and in a strictly operational sense there isn't any need to select one stabilizer generator of each type to remove. But, for the sake of analyzing the code — and counting the generators in particular — we can imagine that one stabilizer generator of each type has been removed, so that we get a minimal generating set, keeping in mind that we could always infer the results of these removed generators (thinking of them as observables) from the results of all of the other stabilizer generator observables of the same type.
This leaves stabilizer generators of each type, or in total, in a (hypothetical) minimal generating set. Given that there are qubits in total, this means that the toric code encodes qubits.
The final condition required of stabilizer generators is that at least one quantum state vector is fixed by all of the stabilizer generators. We will see that this is the case as we proceed with the analysis of the code, but it's also possible to reason that there's no way to generate times the identity on all qubits from the stabilizer generators.
Detecting errors
The toric code has a simple and elegant description, but its quantum error-correcting properties may not be at all clear from a first glance. As it turns out, it's an amazing code! To understand why and how it works, let's begin by considering different errors and the syndromes they generate.
The toric code is a CSS code, because all of our stabilizer generators are either or stabilizer generators. This means that errors and errors can be detected (and possibly corrected) separately. In fact, there's a simple symmetry between the and stabilizer generators that allows us to analyze errors and errors in essentially the same way. So, we shall focus on errors, which are possibly detected by the stabilizer generators — but the entire discussion that follows can be translated from errors to errors, which are analogously detected by the stabilizer generators.
The following diagram depicts the effect of an error on a single qubit. Here, the assumption is that our qubits were previously in a state contained in the code space of the toric code, causing all of the stabilizer generator measurements to output The stabilizer generators detect errors, and there is one such stabilizer generator for each tile in the figure, so we can indicate the measurement outcome of the corresponding stabilizer generator with the color of that tile: outcomes are indicated by white tiles and outcomes are indicated by gray tiles. If a bit-flip error occurs on one of the qubits, the effect is that the stabilizer generator measurements corresponding to the two tiles touching the affected qubit now output
This is intuitive when we consider stabilizer generators and how they behave. In essence, each stabilizer generator measures the parity of the four qubits that touch the corresponding tile (with respect to the standard basis). So, a outcome doesn't indicate that no errors have occurred on these four qubits, but rather it indicates that an even number of errors have occurred on these qubits, whereas a outcome indicates that an odd number of errors have occurred. A single error therefore flips the parity of the four bits on both of the tiles it touches, causing the stabilizer generator measurements to output
Next let's introduce multiple errors to see what happens. In particular, we'll consider a chain of adjacent errors, where two errors are adjacent if they affect qubits touching the same tile.
The two stabilizer generators at the endpoints of the chain both give the outcome in this case, because an odd number of errors have occurred on those two corresponding tiles. All of the other stabilizer generators, on the other hand, give the outcome including the ones touching the chain but not at the endpoints, because an even number of errors have occurred on the qubits touching the corresponding tiles.
Thus, as long as we have a chain of errors that has endpoints, the toric code will detect that errors have occurred, resulting in measurement outcomes for the stabilizer generators corresponding to the endpoints of the chain. Note that the actual chain of errors is not revealed, only the endpoints! This is OK — in the next subsection we'll see that we don't need to know exactly which qubits were affected by errors to correct them. (The toric code is an example of a highly degenerate code, in the sense that it generally does not uniquely identify the errors it corrects.)
It is, however, possible for a chain of adjacent errors not to have endpoints, which is to say that a chain of errors could form a closed loop, like in the following figure.
In such a case, an even number of errors have occurred on every tile, so every stabilizer generator measurement results in a outcome. Closed loops of adjacent errors are therefore not detected by the code.
This might seem disappointing, because we only need four errors to form a closed loop (and we're hoping for something a lot better than a distance 4 code). However, a closed loop of errors of the form depicted in the previous figure is not actually an error — because it's in the stabilizer! Recall that, in addition to the stabilizer generators, we also have an stabilizer generator for each vertex in the lattice. And if we multiply adjacent stabilizer generators together, the result is that we obtain closed loops of operations. For instance, the closed loop in the previous figure can be obtained by multiplying together the stabilizer generators indicated in the following figure.
This is, however, not the only type of closed loop of errors that we can have — and it is not the case that every closed loop of errors is included in the stabilizer. In particular, the different types of loops can be characterized as follows.
-
Closed loops of errors with an even number of errors on every horizontal line and every vertical line of qubits. (The example shown above falls into this category.) Loops of this form are always contained in the stabilizer, as they can effectively be shrunk down to nothing by multiplying them by stabilizer generators.
-
Closed loops of errors with an odd number of errors on at least one horizontal line or at least one vertical line of qubits. Loops of this form are never contained in the stabilizer and therefore represent nontrivial errors that go undetected by the code.
An example of a closed loop of errors in the second category is shown in the following diagram.
Such a chain of errors is not contained in the stabilizer because every stabilizer generator places an even number of operations on every horizontal line and every vertical line of qubits. This is therefore an actual example of a nontrivial error that the code fails to detect.
The key is that the only way to form a loop of the second sort is to go around the torus, meaning either around the hole in the middle of the torus, through it, or both. Intuitively speaking, a chain of errors like this cannot be shrunk down to nothing by multiplying it by stabilizer generators because the topology of a torus prohibits it. The toric code is sometimes categorized as a topological quantum error correcting code for this reason. The shortest that such a loop can be is and therefore this is the distance of the toric code: any closed loop of errors with length less than must fall into the first category, and is therefore contained in the stabilizer; and any chain of errors with endpoints is detected by the code.
Given that the toric code uses qubits to encode qubits and has distance it follows that it's a stabilizer code.
Correcting errors
We've discussed error detection for the toric code, and now we'll briefly discuss how to correct errors. The toric code is a CSS code, so errors and errors can be detected and corrected independently. Keeping our focus on stabilizer generators, which detect errors, let us consider how a chain of errors can be corrected. ( errors are corrected in a symmetric way.)
If a syndrome different from the syndrome appears when the stabilizer generators are measured, the outcomes reveal the endpoints of one or more chains of errors. We can attempt to correct these errors by pairing together the outcomes and forming a chain of corrections between them. When doing this, it makes sense to choose shortest paths along which the corrections take place.
For instance, consider the following diagram, which depicts a syndrome with two outcomes, indicated by gray tiles, caused by a chain of errors illustrated by the magenta line and circles. As we have already remarked, the chain itself is not revealed by the syndrome; only the endpoints are visible.
To attempt to correct this chain of errors, a shortest path between the measurement outcomes is selected and gates are applied as corrections to the qubits along this path (indicated in yellow in the figure). While the corrections may not match up with the actual chain of errors, the errors and corrections together form a closed loop of operations that is contained in the stabilizer of the code. The correction is therefore successful in this situation, as the combined effect of the errors and corrections is to do nothing to an encoded state.
This strategy won't always be successful. For example, a different explanation for the same syndrome as in the previous figure is shown in the following figure.
This time, the same chain of corrections as before fails to correct for this chain of errors, because the combined effect of the errors and corrections is that we obtain a closed loop of operations that wraps around the torus, and therefore has a nontrivial effect on the code space. So, there's no guarantee that the strategy just described, of choosing a shortest path of corrections between two syndrome measurement outcomes, will properly correct the error that caused this syndrome.
Perhaps more likely, depending on the noise model, is that a syndrome with more than two entries is measured, like the following figure suggests.
In such a case, there are different correction strategies known. One natural strategy is to attempt to pair up the measurement outcomes and perform corrections along shortest paths that connect the pairs, as is indicated in the figure in yellow. In particular, a minimum-weight perfect matching between the measurement outcomes can be computed, and then the pairs are connected by shortest paths of corrections. The computation of a minimum-weight perfect matching can be done efficiently with a classical algorithm known as the blossom algorithm, which was discovered by Edmonds in the 1960s.
This approach is generally not optimal for the most typically studied noise models, but based on numerical simulations it works very well in practice below a noise rate of approximately 10%, assuming independent Pauli errors where and are equally likely. Increasing doesn't have a significant effect on the break-even point at which the code starts to help, but does lead to a faster decrease in the probability for a logical error as the error rate decreases past the break-even point.