9-2. quantum error

The underlying causes of error in the quantum bit itself are actually not that different from those in the classical bit.

One is the error caused by the leakage of information to the outside at a certain rate due to the interaction with the outside environment. In particular, when reading and writing information with electromagnetic waves such as light or microwaves as a quantum bit, a path must be secured for injecting electromagnetic waves, and a certain amount of information leaks out from there. In addition, even when experimenting with dilution refrigerators, microwaves are greatly affected by thermal noise because their energy scale is close to the ambient temperature, which is another source of noise. On the other hand, in the case of using traps such as ions or neutral atoms, in addition to decoherence, errors that cause materials to fall out of the traps are also a problem. When light is used as a quantum bit, the above decoherence is not a problem due to the difference in temperature scales. However, in order to scale optical quantum bits, it is necessary to secure the path by induction or mirror reflection using a fiber, and since there are also fluctuations in the laser, the loss of photons and coherence associated with these fluctuations can be a problem. The associated loss of photons and loss of coherence due to the passage of coherence time are effectively the lifetime of the qubit, which occurs even if nothing is done.

The second is the noise that occurs during manipulation of the device. In the case of microwave operation of devices such as superconducting qubits, errors in the operation include noise due to fluctuations in microwave frequency and power, and bias due to unintended contributions from interaction terms. Such noise can be divided into bias noise, which can be canceled by inversion, and stochastic noise, which is not. The result of noise can also be divided into noise that eventually moves a state to either 0 or 1 and leakage, and notise which moves a state to neither 0 nor 1. Noise such as stochastic noise and leakage is more serious in terms of error correction.

Such errors can in principle be avoided by calibrating the pulses or applying canceling pulses, but calibrating a huge number of bits is extremely difficult. The situation is similar for ions and neutral atoms. When light is used as a qubit, it is manipulated via interactions with optical crystals, which pose different problems from those of matter. First, the universal manipulation of optical qubits requires interactions with third-order or higher nonlinearities, and these higher-order nonlinearities are often accompanied by strong absorption. For this reason, we often give up on nondestructive third-order nonlinear operations and perform photon measurement and feedback operations with destruction on entangled photon qubits, and achieve the desired nonlinear operation in the form of gate teleportation. Such operations involve a large overhead compared to mere nondestructive manipulation.

Also, in operations using electromagnetic waves, the qubits do not move and the electromagnetic waves are sent out with time, so the size of the system does not depend on the time to perform the computation. On the other hand, in the usual experiment using optical qubits, the material is fixed and placed on an optical surface plate, so the number of optical devices used increases in dependence on the computation time. To avoid this, time multiplexing is necessary, in which an optical device is used once and then used again through a loop. Such time multiplexing of optical systems is currently the subject of intense research.

Quantum error correction

Quantum bits are extensions of ordinary bits that allow superposition of states. In quantum error correction, the qubit is made redundant, and the goal is to obtain an effectively small error probability, as in classical error correction. In this case, the nature of qubits makes the situation different from that of many classical codes, and most of them work in the direction that makes quantum error correction difficult.

Currently proposed quantum error correction methods are, in principle, extensions of linear codes to quantum versions. For confirmation, we restate the framework of linear codes.

  • code: Characterized by the generator matrix \(G\) and the parity check matrix matrix \(H_c\). They satisfy \(GH_c = 0\).

  • Before coding: \(k\)-bit transversal vector data \(V\).

  • Encoding: Using the generator matrix \(G\) of \(k \times n\), the encoded state \(v'\) is \(v'=vG\).

  • Error: \(n\)-bit sequence \(e\) is randomly added to \(v'\) after encoding.

  • Error checking: \(n \times (n-k)\) parity check \(H_c\) is used to obtain the syndrome \(s = e H_c\). If \(s \neq 0\), an error can be detected. If \(s=0\), either no error has occurred or the error is above the limit that can be inspected.

  • Error correction: Guess \(k\)-bit transverse vector data \(v\) according to the value of \((v'+e)\). The algorithm to find \(v\) from \(v'+e\) is called the decoding algorithm.

  • Distance: The minimum weight of \(e\) such that \(e H_c = 0\) is the distance \(d\) of the code.

If a qubit uses only two states of \(|0\rangle, |1\rangle\) and does not use superposition, it can be put on the framework of classical bits. Using this fact, the above classical error correction can be rewritten in terms of quantum information as follows.

  • code: Characterized by the generator matrix \(G\) and the parity check matrix \(H_c\). They satisfy \(GH_c = 0\).

  • Before coding: there is a quantum state \(|v\rangle\) of \(k\)-qubit of the computational basis .

  • Coding: a unitary matrix \(U_G\) of \(2^n \times 2^n\) consisting only of CNOT and Pauli-\(X\) such that \(|vG\rangle = U_G (|\psi\rangle \otimes |0\rangle^{n-k})\) can be constructed from \(G\).

  • Error: A random bit-flip operation \(E = X_1^{e_1} X_2 ^{e_2} \ldots X_n^{e_n}\) acts on the \(|vG \rangle\) after encoding, resulting in \(E |vG \rangle = |vG + e \rangle\).

  • Error checking: Checks if the parities are consistent. This is equivalent to the following operations Let \(h_i\) be the \(i\) column vector of the parity check matrix \(H_c\), consider the Pauli matrix \(P_i = Z_1^{h_{i1}} Z_2^{h_{i2}} \ldots Z_n^{h_{in}}\) and let \(M_0^{(i)} = (I+P_i)/2, M_1^{(i)} = (I-P_ i)/2\) , and consider the POVM \(\{ M_0^{(i)}, M_1^{(i)} \}\) . POVM is a generalization of the projective measurements; for Nielsen-Chuang, it is 2.2.6 POVM (measurements). We measure the state \(E |\psi' \rangle\) with \(n-k\) POVM \(\{M_0^{(i)}, M_1^{(i)}\}_i\) and obtain \(n-k\) bits \(s = (vG+e)H_c = eH_c\). Check whether this \(s\) is zero.

  • Decoding: \(|vG+e'\rangle\) all measured in \(Z\) basis yields \(n\)-bit sequence \((vG+e)\). According to the value of \((vG+e)\), we construct a unitary operation \(R = X_1^{e'_1} X_2 ^{e'_2} \ldots X_n^{e'_n}\) such that \(R E|vG\rangle = |vG\rangle\). The algorithm for finding \(e'\) from \((vG+e)\) is called the decoding algorithm.

  • Distance: The minimum weight of \(E\) such that \(s = 0\) is the distance \(d\) of the code.

The above protocol is a framework for classical error correction with qubits, and what we are saying is equivalent. As an example, we show a code in which one bit is increased to three bits to perform majority voting.

Generator matrix is

\[G =\left( \begin{matrix} 1 & 1 & 1 \end{matrix} \right)\]

Parity check matrix is

\[\begin{split}H_c = \left( \begin{matrix} 1 & 0 \\ 1 & 1 \\ 0 & 1 \end{matrix} \right)\end{split}\]
[120]:
# set code info
repetition = 3
error_probability = 0.2
initial_bit = 1
[121]:
def show_quantum_state(state, eps = 1e-10, round_digit=3):
    vector = state.get_vector()
    state_str = ""
    qubit_count = int( np.log2(len(vector)+eps))
    binary_format = "{" + ":0{}b".format(qubit_count) + "}"
    for ind in range(len(vector)):
        if abs(vector[ind]) > 1e-10:
            if len(state_str) > 0:
                state_str += " + "
            state_str += ("{} |" + binary_format + ">").format(round(vector[ind],round_digit ),ind)
    print(state_str)

Secure the quantum state and write the initial state to the 0-th bit.

[ ]:
## Run only for Google Colaboratory and local environment where Qulacs is not installed
!pip install qulacs

## Run only if you are in a Google Colaboratory / (Linux or Mac) jupyter notebook environment.
## Qulacs errors will be output normally.
!pip3 install wurlitzer
%load_ext wurlitzer
[122]:
import numpy as np
from qulacs import QuantumState
state = QuantumState(repetition)
state.set_computational_basis(initial_bit)
show_quantum_state(state)
(1+0j) |001>

Create a circuit for encoding.

[123]:
from qulacs import QuantumCircuit
encode_circuit = QuantumCircuit(repetition)
for ind in range(1,repetition):
    encode_circuit.add_CNOT_gate(0, ind)
encode_circuit.update_quantum_state(state)
show_quantum_state(state)
(1+0j) |111>

Create a quantum circuit to measure the syndrome values. At the current point, all the syndrome values are 0.

[124]:
from qulacs.gate import Instrument
from qulacs.gate import DenseMatrix

def parity_measure_gate(fst,scn,register_pos):
    parity_measure_matrix_0 = np.zeros( (4,4) )
    parity_measure_matrix_1 = np.zeros( (4,4) )
    parity_measure_matrix_0[0,0] = parity_measure_matrix_0[3,3] = 1
    parity_measure_matrix_1[1,1] = parity_measure_matrix_1[2,2] = 1
    parity_measure_0 = DenseMatrix([fst,scn],parity_measure_matrix_0)
    parity_measure_1 = DenseMatrix([fst,scn],parity_measure_matrix_1)
    parity_measure = Instrument([parity_measure_0, parity_measure_1],register_pos)
    return parity_measure

parity_measure_circuit = QuantumCircuit(repetition)
for ind in range(repetition-1):
    parity_measure_circuit.add_gate(parity_measure_gate(ind,ind+1,ind))

parity_measure_circuit.update_quantum_state(state)
show_quantum_state(state)
for ind in range(repetition-1):
    print("parity({},{}): {}".format(ind,ind+1,state.get_classical_value(ind)))
(1+0j) |111>
parity(0,1): 0
parity(1,2): 0

One bit error is made on a random data qubit. At this time, a bit error is equivalent to an unintended Pauli-\(X\) operation. The quantum state will be \(|vG+e\rangle\).

[125]:
# invoke random error
from qulacs.gate import Pauli
def random_X_error(num_qubit, error_probability):
    error_array = []
    for _ in range(num_qubit):
        if np.random.rand() < error_probability:
            error_array.append(1)
        else:
            error_array.append(0)
    return Pauli(np.arange(num_qubit), error_array)
error_operator = random_X_error(repetition, error_probability)
error_operator.update_quantum_state(state)
show_quantum_state(state)
(1+0j) |011>

Recover the parity measurement again.

[126]:
parity_measure_circuit.update_quantum_state(state)
show_quantum_state(state)
for ind in range(repetition-1):
    print("parity({},{}): {}".format(ind,ind+1,state.get_classical_value(ind)))
(1+0j) |011>
parity(0,1): 0
parity(1,2): 1

Decryption.

[135]:
# decoding process
def compute_recovery_operation(state, repetition):
    cand1 = []
    cand2 = []
    cand1.append(0)
    cand2.append(1)
    flag = True
    for ind in range(repetition-1):
        val = state.get_classical_value(ind)
        if val == 1:
            flag = not flag
        if flag:
            cand1.append(0)
            cand2.append(1)
        else:
            cand1.append(1)
            cand2.append(0)
    if np.sum(cand1) < np.sum(cand2):
        cand = cand1
    else:
        cand = cand2
    return Pauli(np.arange(repetition), cand)

recovery_operation = compute_recovery_operation(state,repetition)
recovery_operation.update_quantum_state(state)
show_quantum_state(state)
(1+0j) |111>

A series of operations can be performed even if the first quantum state is not a computational basis.

[146]:
# set code info
repetition = 3
error_probability = 0.2
initial_bit = 1

from qulacs.gate import RandomUnitary
state = QuantumState(repetition)
state.set_computational_basis(0)
RandomUnitary([0]).update_quantum_state(state)
print("initial state")
show_quantum_state(state)

encode_circuit.update_quantum_state(state)
print("encode")
show_quantum_state(state)

error_operator = random_X_error(repetition, error_probability)
error_operator.update_quantum_state(state)
print("error")
show_quantum_state(state)

parity_measure_circuit.update_quantum_state(state)
print("parity measurement")
show_quantum_state(state)

recovery_operation = compute_recovery_operation(state,repetition)
recovery_operation.update_quantum_state(state)
print("recovery")
show_quantum_state(state)

initial state
(-0.111+0.987j) |000> + (0.053-0.101j) |001>
encode
(-0.111+0.987j) |000> + (0.053-0.101j) |111>
error
(-0.111+0.987j) |010> + (0.053-0.101j) |101>
parity measurement
(-0.111+0.987j) |010> + (0.053-0.101j) |101>
recovery
(-0.111+0.987j) |000> + (0.053-0.101j) |111>

Quantum error correction is a framework that allows error correction even when a quantum state has not only bit-flip (Pauli-\(X\)) but also phase-flip (Pauli-\(Z\)) errors. Assuming that the errors that occur are probabilistic Pauli operators, the quantum error correction framework is as follows.

  • Code: characterized by generative unitary acting on \(N\)-qubit \(U_G\) and a Set of \(n-k\) POVMs \(\{M_0^{(i)}, M_1^{(i)}\}_i\). They satisfy \(\langle \psi,0 | U_G^{\dagger} M_j^{(i)} U_G | \psi,0 \rangle\) for any \(k\)-qubit state \(|\psi\rangle\).

  • Before coding: There is a quantum state \(|\psi\rangle\) of the computational basis of \(k\)-qubit.

  • Coding: Generate \(|\psi' \rangle = U_G (|\psi\rangle \otimes |0\rangle^{n-k})\) with unitary matrix \(U_G\).

  • Error: after encoding \(|\psi' \rangle\), a random Pauli operation \(E = X_1^{e_1} X_2 ^{e_2} \ldots X_n^{e_n} Z_1^{e_{n+1}} Z_2 ^{e_{n+2}} \ldots Z_n^{e_{2n}}\) is applied, and gets \(E |\psi' \rangle\).

  • Error Checking: Measure the state \(E |\psi' \rangle\) with \(n-k\) POVMs \(\{M_0^{(i)}, M_1^{(i)}\}_i\) and obtain \(n-k\) bits \(s\). Check whether this \(s\) is zero or not.

  • Decoding: according to the value of \(s\), unitary operation \(R = X_1^{e'_1} X_2 ^{e'_2} \ldots X_n^{e'_n} Z_1^{e'_{n+1}} Z_2 ^{e'_{n+2}} \ldots Z_n^{e '_{2n}}\) is constructed. The algorithm for finding \(R\) from \(s\) is called the decoding algorithm of quantum error correction.

  • Distance: The minimum weight of \(E\) such that \(s = 0\) is the distance \(d\) of the code.

There is an essential change in the framework of quantum error correction from classical error correction. Quantum error correction introduces errors that cause phase inversion. For this reason, the Pauli operator \(E\) of the error has a form that includes not only Pauli-\(X\) but also Pauli-\(Z\). This change requires that the code be error correctable for phase reversals. The code must also have a distance greater than \(1\) for Pauli-\(Z\) errors. The classical code rewritten in the framework of a quantum code is a code with \(d=1\) for Pauli-\(Z\). Also, the syndrome measurement by one code must not destroy the quantum state of \(k\)-qubit. This corresponds to the fact that any coded state is indistinguishable in \((n-k)\) POVM measurements. Thus, for all POVM elements, \(\langle \psi' |M_j^{(i)} | \psi' \rangle\) must be a value independent of \(|\psi'\rangle\) for any \(k\)-qubit encoded state \(|\psi'\rangle = U_B (|\psi\rangle \otimes |0\rangle^{n-k})\).

The stabilizer code described below is a framework that gives \(U_B\) and POVM such that the above is satisfied.

Finally, in classical codes, it is possible to obtain \((vG+e)\) by measuring all quantum states in the \(Z\) basis for decoding, but in quantum codes, such measurement cannot be done because the \(Z\) basis of quantum states destroys the information. Also, the operation used for correction is a Pauli operator that mixes Pauli-\(X\) and \(Z\). Therefore, the algorithm for estimating the decoding operation \(R\) from the obtained syndrome value \(s\) alone also needs to be modified for the quantum.

Stabilizer Codes

Just as the matrix \(H_c\) that constitutes parity is given in parity checking codes, there is a framework of stabilizer codes that constitute POVMs in quantum codes. Instead of directly specifying the code space, stabilizer codes specify the code space using a set of Pauli operators that satisfy certain properties called stabilizer operators.

The generator \(S\) of the stabilizer operator is a set \(S\) of Pauli operators satisfying the following properties.

  • Each element of \(S\) is mutually commutative for all. That is, for any \(s,s' \in s\), \(ss' = s's\).

  • Every element of \(S\) is independent. That is, for any \(s \in S\), the group generated from the set \(S\setminus \{s\}\) does not contain \(s\).

  • The group generated from \(S\) does not contain \(-I\).

When the above is satisfied, the logical code specified by the stabilizer operator is the subspace composed of quantum states satisfying the following properties.

  • \(|\psi\rangle\) is an eigenstate with eigenvalue +1 for all \(s \in S\).

When there are \(l\) independent stabilizer generators, the dimension of the spanned space of such quantum states is \(2^{n-l}\). Thus, if we want to construct a space of \(k\) logical qubits in a space of \(n\)-qubits, we need to have \(l = n-k\).

In this code, the syndrome value is given as the result of a projective measurement of the quantum state in \(s \in S\). Since it is the +1 eigenspace of all stabilizer operators that is now used for the calculation, the projective measurement of the stabilizer operator does not destroy the logical qubit of interest. Now, for simplicity, we assume that one of Pauli\(X,Y,Z\) is probabilistically applied to each qubit. Since Pauli\(Y\) is the product of \(X\) and \(Z\), we can regard this as a case where both Pauli\(X\) and \(Z\) occur.

If we decide to express whether \(X\)(\(Z\)) error is occurring in the \(i\)-th qubit in binary \(e^{(X)}_i\) (\(e^{(Z)}_i\)), measuring a qubit at \(Z\) is equivalent to obtaining \(e^{(X)}_i\), and the act of measuring at \(X\) is equivalent to obtaining \(e^{(Z)}_i\). If we measure with a Pauli operator acting on multiple qubits, we would obtain the XOR of each resulting bit. I.e., If \(P=Z_2 X_3 Z_4 Z_5\), then the measurement result is \(\left(e^{(X)}_2 + e^{(Z)}_3 + e^{(X)}_4 + e^{(X)}_5\right)\bmod 2\).

If \(P\) is only a product of Pauli \(Z\) and the only error acting on a qubit is a bit flip due to Pauli \(X\), then this is synonymous with parity checking, which computes the parity of some bits. Thus, it can be seen that the stabilizer code is a kind of extension of the parity checking code that allows it to be applied to errors related to Pauli\(Z\).

Given a certain stabilizer generator, the distance to its code can be considered as follows. First, consider the normalization group (Normalizer) for the stabilizer group. A normalization group is a group that satisfies the following equation.

\[C(S) = \{p \in P \mid \forall s \in S, sp = ps \}\]

The normalization group minus the stabilizer group, ignoring the difference in global phase, is called the logical operator. A logic operator is a set of operations that cannot detect errors by the syndrome but change the logical quantum state. Thus, if an error occurs in enough qubits to execute a logical operator, we cannot detect an error.

Let weight \(w(P)\) of \(P\) be the number of qubits on which Pauli operator \(P\) acts nontrivially (one of Pauli \(X,Y,Z\) acts). The code distance is the smallest weight in the set of logical operators, i.e..

\[d := \min_{P \in C(S)\setminus \langle S \rangle} w(P)\]

Topological Codes

Topological codes are codes that originated from the idea of using the degenerate ground state of topological matter as the space of logical qubits. From an experimental point of view, a topological code is a kind of stabilizer code that satisfies the following good properties.

  • The parity check matrix \(H_c\) is a sparse matrix. Such codes are known to have good performance due to their similarity to low-density parity checking codes, and each syndrome is represented as \(O(1)\) parities.

  • The data qubits to be checked in each syndrome are spatially clustered within a distance of \(O(1)\). Therefore, even in physical systems where CNOT can only be applied to adjacent qubits, it is possible to efficiently measure the syndrome.

Among topological codes, surface codes, with which measurement qubits can also be embedded on a two-dimensional plane, are the closest to realization.

Topological codes also inherit the drawbacks of low-density parity checking codes, which generally make decoding NP-hard. In reality, some approximations to the nature of the error are often used to formulate an efficient decoding algorithm that can be solved.

Computation on stabilizer codes

Since quantum computation introduces errors as the operation is performed, the operation must be performed with the quantum state encoded for the duration of the computation. In this computation, too, there is a significant difference from the classical case.

In parity check codes, the inversion operation on one logical bit corresponds to an inversion operation on at least \(O(d)\) and at most \(O(n)\) bits. This can obviously be accomplished with \(O(n)\) bit flips, which can be completed in 1step if parallelized.

In stabilizer codes, a quantum operation on one logical bit similarly maps to some unitary operation on at least \(O(d)\) qubits. Here, the difference from the classical case is that \(O(2^d)\) gates are generally required to realize unitary operations on \(O(d)\) qubits. Therefore, on a quantum code, even the operation on one logical bit cannot be performed efficiently in general, and the error correction operation will create a new error and the computation on the code will not scale.

On the other hand, depending on the code, there exists \(U\) such that the quantum operation \(U'\) of \(O(d)\) qubits corresponding to the operation \(U\) of one logical bit can be completed in \(O(1)\) steps. Such an operation on a logic bit that can be efficiently realized on a code is called a transversal operation. If the transversal operation constructs a universal gate set, universal quantum computation can be efficiently performed on the code, but unfortunately, it has been proved that there is no such stabilizer code.

Therefore, it is necessary to somehow procure the missing operations for universal operation. On the surface code, \(X, Y, Z, H\), etc. are transversals, and although it is nontrivial whether CNOT is possible, it is known that it can be done efficiently by lattice surgery. Since \(S\), \(T\), etc. are not transversal, it is possible to create \(S\), \(T\)gate states, etc. with another code and use a method called magic state distillation to gate-teleport these states, thereby creating a universal set.