<jupyter_start><jupyter_text>qecsim demos  Simulating error correction with a basic stabilizer codeThis demo shows verbosely how to simulate one error correction run. | For normal use, the code in this demo is encapsulated in the function:| `qecsim.app.run_once(code, error_model, decoder, error_probability)`,| and the simulation of many error correction runs is encapsulated in the function:| `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<jupyter_code>%run qsu.ipynb  # color-printing functions
import numpy as np
from qecsim import paulitools as pt
from qecsim.models.generic import DepolarizingErrorModel, NaiveDecoder
from qecsim.models.basic import FiveQubitCode

# initialise models
my_code = FiveQubitCode()
my_error_model = DepolarizingErrorModel()
my_decoder = NaiveDecoder()
# print models
print(my_code)
print(my_error_model)
print(my_decoder)<jupyter_output>FiveQubitCode()
DepolarizingErrorModel()
NaiveDecoder(10)<jupyter_text>Generate a random error<jupyter_code># set physical error probability to 10%
error_probability = 0.1
# seed random number generator for repeatability
rng = np.random.default_rng(8)

# error: random error based on error probability
error = my_error_model.generate(my_code, error_probability, rng)
qsu.print_pauli('error: {} {}'.format(error, pt.bsf_to_pauli(error)))<jupyter_output><empty_output><jupyter_text>Evaluate the syndromeThe syndrome is a binary array indicating the stabilizers with which the error does not commute. It is calculated as $syndrome = error \odot stabilisers^T$.<jupyter_code># syndrome: stabilizers that do not commute with the error
syndrome = pt.bsp(error, my_code.stabilizers.T)
print('syndrome: {}'.format(syndrome))<jupyter_output>syndrome: [0 1 0 1]<jupyter_text>Find a recovery operationIn this case, the recovery operation is found by using a naive decoder that iterates through all possible Pauli operations, in ascending weight, until it finds a recovery operation that gives the same syndrome as the random error, i.e. $recovery \odot stabilisers^T = syndrome$.<jupyter_code># recovery: best match recovery operation based on decoder
recovery = my_decoder.decode(my_code, syndrome)
qsu.print_pauli('recovery: {} {}'.format(recovery, pt.bsf_to_pauli(recovery)))<jupyter_output><empty_output><jupyter_text>As a sanity check, we expect $recovery \oplus error$ to commute with all stabilizers, i.e. $(recovery \oplus error) \odot stabilisers^T = 0$.<jupyter_code># check recovery ^ error commutes with stabilizers (by construction)
print(pt.bsp(recovery ^ error, my_code.stabilizers.T))<jupyter_output>[0 0 0 0]<jupyter_text>Test if the recovery operation is successfulThe recovery operation is successful iff $recovery \oplus error$ commutes with all logical operators, i.e. $(recovery \oplus error) \odot logicals^T = 0.$<jupyter_code># success iff recovery ^ error commutes with logicals
print(pt.bsp(recovery ^ error, my_code.logicals.T))<jupyter_output>[0 0]<jupyter_text>Note: The decoder is not guaranteed to find a successful recovery operation. The five qubit code has distance $d = 3$ so we can only guarantee to correct errors up to weight $(d - 1)/2=1$.  Equivalent code in single callThe above demo is equivalent to the following code.<jupyter_code># repeat demo in single call
from qecsim import app
print(app.run_once(my_code, my_error_model, my_decoder, error_probability))<jupyter_output>{'error_weight': 1, 'success': True}
{'fraction_non_alphanumeric': 0.0905339179778179, 'fraction_numerical': 0.008769667268506576, 'mean_word_length': 6.194805194805195, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '561355', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1249, 'n_tokens_neox': 1177, 'n_words': 425, 'path': 'original_demos/demo_basic.ipynb', 'repo_name': 'dua-arpit/qecsim', 'size': '3877'}