def test_color666_mps_decoder_cosets_probability_triplet_optimisation(): code = Color666Code(5) decoder = Color666MPSDecoder() # probabilities prob_dist = BiasedDepolarizingErrorModel(bias=10).probability_distribution(probability=0.1) # coset probabilities for null Pauli coset_i_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli()) coset_x_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli().logical_x()) coset_y_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli().logical_x().logical_z()) coset_z_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli().logical_z()) # expect Pr(iIG) ~= Pr(xXG) assert _is_close(coset_i_ps[0], coset_x_ps[1], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iIG) ~= Pr(xXG)') # expect Pr(iXG) ~= Pr(xIG) assert _is_close(coset_i_ps[1], coset_x_ps[0], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iXG) ~= Pr(xIG)') # expect Pr(iIG) ~= Pr(yYG) assert _is_close(coset_i_ps[0], coset_y_ps[2], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iIG) ~= Pr(yYG)') # expect Pr(iYG) ~= Pr(yIG) assert _is_close(coset_i_ps[2], coset_y_ps[0], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iXG) ~= Pr(xIG)') # expect Pr(iIG) ~= Pr(zZG) assert _is_close(coset_i_ps[0], coset_z_ps[3], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iIG) ~= Pr(zZG)') # expect Pr(iZG) ~= Pr(zIG) assert _is_close(coset_i_ps[3], coset_z_ps[0], rtol=0, atol=0), ( 'Coset probabilites do not satisfy Pr(iZG) ~= Pr(zIG)')
def test_color666_mps_decoder_decode_value(): # expected coset_ps expected_coset_ps = ( mp.mpf('1.4290529991554288e-9'), # I mp.mpf('2.1657729564075353e-13'), # X mp.mpf('2.2541268663248664e-13'), # Y mp.mpf('9.3780172173812118e-12'), # Z ) code = Color666Code(7) decoder = Color666MPSDecoder(chi=16) # error error = code.new_pauli() error.site('X', (2, 1)) # error.site('Y', (3, 1), (4, 2), (7, 3), (9, 6)) error.site('Y', (7, 3)) error.site('Z', (6, 0), (3, 3), (7, 6)) # syndrome syndrome = pt.bsp(error.to_bsf(), code.stabilizers.T) # sample sample = decoder.sample_recovery(code, syndrome) print(sample) # probabilities prob_dist = DepolarizingErrorModel().probability_distribution(0.1) # coset probabilities coset_ps, _ = decoder._coset_probabilities(prob_dist, sample) print('# expected Pr(G)=', expected_coset_ps) print('# actual Pr(G)=', coset_ps) assert all(_is_close(expected_coset_ps, coset_ps, rtol=1e-11, atol=0)), ( 'Coset probabilites do not satisfy expected Pr(G) ~= Pr(G)')
def test_color666_mps_decoder_decode_small_codes_exact_approx(): code = Color666Code(5) exact_decoder = Color666MPSDecoder() approx_decoder = Color666MPSDecoder(chi=16) identity = code.new_pauli() # probabilities prob_dist = BiasedDepolarizingErrorModel(bias=10).probability_distribution(probability=0.1) # coset probabilities exact_coset_ps, _ = exact_decoder._coset_probabilities(prob_dist, identity) approx_coset_ps, _ = approx_decoder._coset_probabilities(prob_dist, identity) print('#exact Pr(G)=', exact_coset_ps) print('#approx Pr(G)=', approx_coset_ps) assert all(_is_close(exact_coset_ps, approx_coset_ps, rtol=1e-11, atol=0)), ( 'Coset probabilites do not satisfy exact Pr(G) ~= approx Pr(G)')
def test_color666_mps_decoder_cosets_probability_inequality_biased_noise(chi, tol, rtol): code = Color666Code(5) decoder = Color666MPSDecoder(chi=chi, tol=tol) # probabilities prob_dist = BiasedDepolarizingErrorModel(bias=100).probability_distribution(0.1) # coset probabilities for null Pauli coset_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli()) coset_i_p, coset_x_p, coset_y_p, coset_z_p = coset_ps # expect Pr(IG) > Pr(YG) > Pr(XG) ~= Pr(ZG) print() print('Pr(IG){!r} > Pr(YG){!r} > Pr(XG){!r} ~= Pr(ZG){!r}. rtol={}'.format( coset_i_p, coset_y_p, coset_x_p, coset_z_p, abs(coset_x_p - coset_z_p) / abs(coset_z_p))) print('types: Pr(IG):{}, Pr(YG):{}, Pr(XG):{}, Pr(ZG):{}'.format( type(coset_i_p), type(coset_y_p), type(coset_x_p), type(coset_z_p))) assert coset_i_p > coset_y_p, 'Coset probabilites do not satisfy Pr(IG) > Pr(YG)' assert coset_y_p > coset_x_p, 'Coset probabilites do not satisfy Pr(YG) > Pr(XG)' assert coset_y_p > coset_z_p, 'Coset probabilites do not satisfy Pr(YG) > Pr(ZG)' assert _is_close(coset_x_p, coset_z_p, rtol=rtol, atol=0), 'Coset probabilites do not satisfy Pr(XG) ~= Pr(ZG)'
def test_color666_mps2d_contract(): code = Color666Code(5) sample = code.new_pauli().site('X', (3, 1)).site('Y', (2, 2)).site('Z', (6, 4)) print() print(code.ascii_art(pauli=sample)) prob_dist = DepolarizingErrorModel().probability_distribution(0.1) tnc = Color666MPSDecoder.TNC() tn = tnc.create_tn(prob_dist, sample) result_forwards = tt.mps2d.contract(tn) print('Forward contraction result: ', repr(result_forwards)) assert isinstance(result_forwards, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result_forwards <= 1, 'Contracted tensor network not within bounds' result_backwards = tt.mps2d.contract(tn, start=-1, step=-1) print('Backward contraction result:', repr(result_backwards)) assert isinstance(result_backwards, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result_backwards <= 1, 'Contracted tensor network not within bounds' assert _is_close(result_forwards, result_backwards, rtol=1e-14, atol=0), ( 'Contracting forwards does not give the same result as contracting backwards' )
def test_color666_lattice_not_is_in_bounds(index): lattice = Color666Code(5) assert not lattice.is_in_bounds(index)
def test_color666_code_properties(size): code = Color666Code(size) assert isinstance(code.label, str) assert isinstance(repr(code), str)
def test_color666_pauli_operator_invalid_index(size, index): pauli = Color666Code(size).new_pauli() with pytest.raises(IndexError): pauli.operator(index)
@pytest.mark.parametrize('chi, tol', [ (-1, None), # invalid chi (0.1, None), # invalid chi ('asdf', None), # invalid chi (None, -1), # invalid tol (None, 'asdf'), # invalid tol ]) def test_color666_mps_decoder_new_invalid_parameters(chi, tol): with pytest.raises((ValueError, TypeError), match=r"^Color666MPSDecoder") as exc_info: Color666MPSDecoder(chi=chi, tol=tol) print(exc_info) @pytest.mark.parametrize('error_pauli', [ Color666Code(3).new_pauli().site('X', (2, 1)).site('Y', (3, 3)), Color666Code(5).new_pauli().site('X', (3, 1)).site('Y', (2, 2)).site('Z', (6, 4)), Color666Code(7).new_pauli().site('X', (4, 2)).site('Y', (4, 3)).site('Z', (8, 4), (8, 5)), ]) def test_color666_mps_decoder_sample_recovery(error_pauli): error = error_pauli.to_bsf() code = error_pauli.code syndrome = pt.bsp(error, code.stabilizers.T) recovery_pauli = Color666MPSDecoder.sample_recovery(code, syndrome) recovery = recovery_pauli.to_bsf() assert np.array_equal(pt.bsp(recovery, code.stabilizers.T), syndrome), ( 'recovery {} does not give the same syndrome as the error {}'.format(recovery, error)) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers.'.format(recovery, error))
def test_color666_pauli_invalid_plaquette(size, operator, index): pauli = Color666Code(size).new_pauli() with pytest.raises(IndexError): pauli.plaquette(operator, index)
def test_color666_pauli_properties(size): lattice = Color666Code(size) pauli = lattice.new_pauli() assert pauli.code == lattice assert isinstance(repr(pauli), str) assert isinstance(str(pauli), str)
def test_color666_lattice_is_plaquette(index): assert Color666Code.is_plaquette(index)
def test_color666_lattice_invalid_virtual_plaquette_index(size, index): code = Color666Code(size) with pytest.raises(IndexError): code.virtual_plaquette_index(index)
def test_color666_code_logicals(): assert len(Color666Code(5).logicals) == 2
class _FixedDecoder(Decoder): def __init__(self, decoding): self.decoding = decoding def decode(self, code, syndrome, **kwargs): return self.decoding @property def label(self): return 'fixed' @pytest.mark.parametrize('code, error_model, decoder', [ # each code with each valid decoder (Color666Code(5), DepolarizingErrorModel(), Color666MPSDecoder(chi=8)), (FiveQubitCode(), DepolarizingErrorModel(), NaiveDecoder()), (PlanarCode(5, 5), DepolarizingErrorModel(), PlanarCMWPMDecoder()), (PlanarCode(5, 5), DepolarizingErrorModel(), PlanarMPSDecoder(chi=6)), (PlanarCode(5, 5), DepolarizingErrorModel(), PlanarMWPMDecoder()), (PlanarCode(5, 5), DepolarizingErrorModel(), PlanarRMPSDecoder(chi=6)), (PlanarCode(4, 5), BitPhaseFlipErrorModel(), PlanarYDecoder()), (RotatedPlanarCode(7, 7), DepolarizingErrorModel(), RotatedPlanarMPSDecoder(chi=8)), (RotatedPlanarCode(7, 7), DepolarizingErrorModel(), RotatedPlanarRMPSDecoder(chi=8)), (RotatedPlanarCode(7, 7), BiasedDepolarizingErrorModel(100), RotatedPlanarSMWPMDecoder()), (RotatedToricCode(6, 6), BiasedDepolarizingErrorModel(100), RotatedToricSMWPMDecoder()), (SteaneCode(), DepolarizingErrorModel(), NaiveDecoder()), (ToricCode(5, 5), DepolarizingErrorModel(), ToricMWPMDecoder()), # each generic noise model (PlanarCode(5, 5), BiasedDepolarizingErrorModel(10), PlanarMPSDecoder(chi=6)), (PlanarCode(5, 5), BiasedYXErrorModel(10), PlanarMPSDecoder(chi=6)),
def test_color666_code_stabilizers(size, expected): assert len(Color666Code(size).stabilizers) == expected
def test_color666_code_n_k_d(size, expected): code = Color666Code(size) assert code.n_k_d == expected
def test_color666_code_new_invalid_parameters(size): with pytest.raises((ValueError, TypeError), match=r"^Color666Code") as exc_info: Color666Code(size) print(exc_info)
def test_color666_lattice_is_site(index): assert Color666Code.is_site(index)
from qecsim import paulitools as pt from qecsim.models.color import Color666Code @pytest.mark.parametrize('size', [3, 5, 7, 9]) def test_color666_pauli_properties(size): lattice = Color666Code(size) pauli = lattice.new_pauli() assert pauli.code == lattice assert isinstance(repr(pauli), str) assert isinstance(str(pauli), str) @pytest.mark.parametrize('pauli', [ Color666Code(5).new_pauli(), Color666Code(5).new_pauli().plaquette('X', (2, 0)).plaquette('Z', (5, 3)), Color666Code(5).new_pauli().logical_x().plaquette('X', (6, 5)).plaquette( 'Y', (4, 1)), Color666Code(5).new_pauli().logical_z().plaquette('Z', (1, 1)).plaquette( 'Z', (6, 2)), Color666Code(5).new_pauli().logical_x().plaquette('X', (5, 3)).plaquette( 'X', (4, 4)), Color666Code(5).new_pauli().logical_z().plaquette('Z', (4, 1)).plaquette( 'Z', (3, 2)), ]) def test_color666_pauli_new_to_bsf(pauli): assert pauli.code.new_pauli(pauli.to_bsf()) == pauli, ( 'Conversion to_bsf+from_bsf does not result in equality.')
def test_color666_code_validate(size): code = Color666Code(size) code.validate() # no error raised
def test_color666_lattice_virtual_plaquette_index(size, index, expected): assert Color666Code(size).virtual_plaquette_index(index) == expected
def test_color666_lattice_properties(size): lattice = Color666Code(size) assert lattice.size == size assert isinstance(repr(lattice), str)
@pytest.mark.parametrize('index', [ (-1, 0), (3, -1), (3, 4), (6, -1), (6, 7), (7, 0), ]) def test_color666_lattice_not_is_in_bounds(index): lattice = Color666Code(5) assert not lattice.is_in_bounds(index) @pytest.mark.parametrize('error, expected', [ (Color666Code(3).new_pauli().site('X', (0, 0)), (set(), {(1, 1)})), (Color666Code(3).new_pauli().site('X', (1, 0)), (set(), {(1, 1), (2, 0)})), (Color666Code(3).new_pauli().site('X', (2, 1)), (set(), {(1, 1), (2, 0), (3, 2)})), (Color666Code(3).new_pauli().site('X', (2, 2)), (set(), {(1, 1), (3, 2)})), (Color666Code(3).new_pauli().site('X', (3, 0)), (set(), {(2, 0)})), (Color666Code(3).new_pauli().site('X', (3, 1)), (set(), {(2, 0), (3, 2)})), (Color666Code(3).new_pauli().site('X', (3, 3)), (set(), {(3, 2)})), (Color666Code(3).new_pauli().site('Z', (0, 0)), ({(1, 1)}, set())), (Color666Code(3).new_pauli().site('Z', (1, 0)), ({(1, 1), (2, 0)}, set())), (Color666Code(3).new_pauli().site('Z', (2, 1)), ({(1, 1), (2, 0), (3, 2)}, set())), (Color666Code(3).new_pauli().site('Z', (2, 2)), ({(1, 1), (3, 2)}, set())), (Color666Code(3).new_pauli().site('Z', (3, 0)), ({(2, 0)}, set())), (Color666Code(3).new_pauli().site('Z', (3, 1)), ({(2, 0), (3, 2)}, set())), (Color666Code(3).new_pauli().site('Z', (3, 3)), ({(3, 2)}, set())),