qecsim demos¶
Simulating error correction with a color 6.6.6 stabilizer code¶
This demo shows verbosely how to simulate one error correction run.
qecsim.app.run_once(code, error_model, decoder, error_probability)
,qecsim.app.run(code, error_model, decoder, error_probability, max_runs, max_failures)
.Notes:
Operators can be visualised in binary symplectic form (bsf) or Pauli form, e.g.
[1 1 0|0 1 0] = XYI
.The binary symplectic product is denoted by \(\odot\) and defined as \(A \odot B \equiv A \Lambda B \bmod 2\) where \(\Lambda = \left[\begin{matrix} 0 & I \\ I & 0 \end{matrix}\right]\).
Binary addition is denoted by \(\oplus\) and defined as addition modulo 2, or equivalently exclusive-or.
Initialise the models¶
%run qsu.ipynb # color-printing functions
import numpy as np
from qecsim import paulitools as pt
from qecsim.models.generic import DepolarizingErrorModel
from qecsim.models.color import Color666Code, Color666MPSDecoder
# initialise models
my_code = Color666Code(5)
my_error_model = DepolarizingErrorModel()
my_decoder = Color666MPSDecoder()
# print models
print(my_code)
print(my_error_model)
print(my_decoder)
Color666Code(5)
DepolarizingErrorModel()
Color666MPSDecoder(None, None)
Generate a random error¶
# set physical error probability to 10%
error_probability = 0.1
# seed random number generator for repeatability
rng = np.random.default_rng(13)
# error: random error based on error probability
error = my_error_model.generate(my_code, error_probability, rng)
qsu.print_pauli('error:\n{}'.format(my_code.new_pauli(error)))
error:
·
|
·
\
·-·
| \
·-Y ·
| \ |
· X-Z
\ | \
·-· ·-·
| \ | \
·-· ·-· ·
Evaluate the syndrome¶
The syndrome is a binary array indicating the stabilizers with which the error does not commute. It is calculated as \(syndrome = error \odot stabilisers^T\).
# syndrome: stabilizers that do not commute with the error
syndrome = pt.bsp(error, my_code.stabilizers.T)
qsu.print_pauli('syndrome:\n{}'.format(my_code.ascii_art(syndrome)))
syndrome:
·
|
·
\
Y ·-·
| \
·-· ·
| \ |
· X ·-· X
\ | \
·-· Y ·-·
| \ | \
·-· ·-· ·
Find a recovery operation¶
In this case, the recovery operation is found by contracting a tensor network defined to have the value of the coset :
Create a sample recovery operation by applying strings of Paulis between syndrome plaquettes and appropriate boundaries.
Define tensor networks corresponding to the probability of each left coset of the generator group with the sample recovery and logical Pauli operations.
Contract each tensor network (approximately) to evaluate the coset probabilities.
Return any recovery from the most probable coset.
# recovery: best match recovery operation based on decoder
recovery = my_decoder.decode(my_code, syndrome)
qsu.print_pauli('recovery:\n{}'.format(my_code.new_pauli(recovery)))
recovery:
·
|
·
\
Y-Y
| \
·-· ·
| \ |
· ·-·
\ | \
Z-· X-Y
| \ | \
·-Z ·-Z ·
As a sanity check, we expect \(recovery \oplus error\) to commute with all stabilizers, i.e. \((recovery \oplus error) \odot stabilisers^T = 0\).
# check recovery ^ error commutes with stabilizers (by construction)
print(pt.bsp(recovery ^ error, my_code.stabilizers.T))
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Visualise \(recovery \oplus error\)¶
Just out of curiosity, we can see what \(recovery \oplus error\) looks like. If successful, it should be a product of stabilizer plaquette operators.
# print recovery ^ error (out of curiosity)
qsu.print_pauli('recovery ^ error:\n{}'.format(my_code.new_pauli(recovery ^ error)))
recovery ^ error:
·
|
·
\
Y-Y
| \
·-Y ·
| \ |
· X-Z
\ | \
Z-· X-Y
| \ | \
·-Z ·-Z ·
Test if the recovery operation is successful¶
The recovery operation is successful iff \(recovery \oplus error\) commutes with all logical operators, i.e. \((recovery \oplus error) \odot logicals^T = 0.\)
# success iff recovery ^ error commutes with logicals
print(pt.bsp(recovery ^ error, my_code.logicals.T))
[0 0]
Note: The decoder is not guaranteed to find a successful recovery operation. The color 6.6.6 5 code has distance \(d = 5\) so we can only guarantee to correct errors up to weight \((d - 1)/2=2\).
Equivalent code in single call¶
The above demo is equivalent to the following code.
# repeat demo in single call
from qecsim import app
print(app.run_once(my_code, my_error_model, my_decoder, error_probability))
{'error_weight': 2, 'success': True}