def test_planar_cmwpm_decoder_null_decoding(): code = PlanarCode(3, 3) error = code.new_pauli().site('Y', (2, 0), (2, 4)).to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) decoder_null = PlanarCMWPMDecoder(max_iterations=0) recovery = decoder_null.decode(code, syndrome) assert np.all(recovery == 0), 'Null decoder does not return null recovery'
def test_planar_cmwpm_decoder_odd_diagonal_correlated_error(): """ ·─┬─·─┬─·─┬─· · · · ·─┼─·─┼─·─┼─· · · · ·─┼─Y─┼─·─┼─· · Y · ·─┼─·─┼─Y─┼─· · · · ·─┼─·─┼─·─┼─· · · · ·─┴─·─┴─·─┴─· """ code = PlanarCode(6, 4) error = code.new_pauli().site('Y', (4, 2), (5, 3), (6, 4)).to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) decoder_mwpm = PlanarCMWPMDecoder(max_iterations=1) decoder_cmwpm = PlanarCMWPMDecoder(factor=3, max_iterations=4, box_shape='t', distance_algorithm=1) # show mwpm fails recovery = decoder_mwpm.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'MWPM recovery does not commute with stabilizers.') assert not np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'MWPM recovery does commute with logicals.') # show cmwpm succeeds recovery = decoder_cmwpm.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'CMWPM recovery does not commute with stabilizers.') assert np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'CMWPM recovery does not commute with logicals.')
def test_planar_y_decoder_decode_equal_coset_probabilities(): code = PlanarCode(2, 3) decoder = PlanarYDecoder() # The following error Pauli gives identical coset probabilities: # I-+-I-+-Y # I I # Y-+-Y-+-I # So we expect approximately equal success and failure error_pauli = PlanarCode(2, 3).new_pauli().site('Y', (2, 0), (2, 2), (0, 4)) # count success and fail success, fail = 0, 0 # run simulations error = error_pauli.to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) for _ in range(2000): recovery = decoder.decode(code, syndrome) 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)) if np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0): success += 1 else: fail += 1 assert _is_close( success, fail, rtol=0.2, atol=0 ), 'Success and fail not equally likely with equal coset probabilities'
def test_planar_mps_decoder_small_code_negative_coset_probability(chi, mode): # parameters code = PlanarCode(3, 3) decoder = PlanarMPSDecoder(chi=chi, mode=mode) error_model = DepolarizingErrorModel() error_probability = 0.1 # logged run values error = pt.unpack(["e0048000", 26]) syndrome = pt.bsp(error, code.stabilizers.T) # debug print() print(code.ascii_art(syndrome, code.new_pauli(error))) # decode prob_dist = error_model.probability_distribution(error_probability) any_recovery = decoder.sample_recovery(code, syndrome) # coset probabilities coset_ps, recoveries = decoder._coset_probabilities( prob_dist, any_recovery) print('chi={}, mode={}, coset_ps={}'.format(chi, mode, coset_ps)) max_coset_p, max_recovery = max( zip(coset_ps, recoveries), key=lambda coset_p_recovery: coset_p_recovery[0]) success = np.all( pt.bsp(max_recovery.to_bsf() ^ error, code.logicals.T) == 0) print('### success=', success) assert mp.isfinite( max_coset_p ) and max_coset_p > 0, 'Max coset probability not as expected' assert np.all( np.array(coset_ps) >= 0), 'At least one coset probability is negative'
def test_planar_rmps_decoder_correlated_errors(): # check MPS decoder successfully decodes for error # I--+--I--+--I # I I # Y--+--I--+--Y # I I # I--+--I--+--I # and MWPM decoder fails as expected code = PlanarCode(3, 3) error = code.new_pauli().site('Y', (2, 0), (2, 4)).to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) # MPS decoder decoder = PlanarRMPSDecoder() recovery = decoder.decode(code, syndrome) # check recovery ^ error commutes with stabilizers (by construction) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers for MPS decoder.' .format(recovery, error)) # check recovery ^ error commutes with logicals (we expect this to succeed for MPS) assert np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with logicals for MPS decoder.' .format(recovery, error)) # MWPM decoder decoder = PlanarMWPMDecoder() recovery = decoder.decode(code, syndrome) # check recovery ^ error commutes with stabilizers (by construction) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers for MWPM decoder.' .format(recovery, error)) # check recovery ^ error commutes with logicals (we expect this to fail for MWPM) assert not np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'recovery ^ error ({} ^ {}) does commute with logicals for MWPM decoder.' .format(recovery, error))
def test_planar_mps_decoder_cosets_probability_pair_optimisation(mode): code = PlanarCode(5, 5) decoder = PlanarMPSDecoder(mode=mode) # 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()) # 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(iZG) ~= Pr(xYG) assert _is_close( coset_i_ps[3], coset_x_ps[2], rtol=0, atol=0), ('Coset probabilites do not satisfy Pr(iZG) ~= Pr(xYG)') # expect Pr(iYG) ~= Pr(xZG) assert _is_close( coset_i_ps[2], coset_x_ps[3], rtol=0, atol=0), ('Coset probabilites do not satisfy Pr(iYG) ~= Pr(xZG)')
def test_planar_mps2d_contract(): code = PlanarCode(3, 3) sample = code.new_pauli().site('Y', (2, 0), (2, 4)) prob_dist = DepolarizingErrorModel().probability_distribution(0.1) tnc = PlanarMPSDecoder.TNC() tn = tnc.create_tn(prob_dist, sample) result = tt.mps2d.contract(tn) assert isinstance(result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result <= 1, 'Contracted tensor network not within bounds'
def test_planar_cmwpm_decoder_dog_leg_correlated_error(): """ ·─┬─·─┬─·─┬─·─┬─· · · · · ·─┼─Y─┼─·─┼─·─┼─· · Y Y · ·─┼─·─┼─Y─┼─·─┼─· · · · · ·─┴─·─┴─·─┴─·─┴─· """ code = PlanarCode(4, 5) error = code.new_pauli().site('Y', (2, 2), (3, 3), (4, 4), (3, 5)).to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) decoder_mwpm = PlanarCMWPMDecoder(max_iterations=1) decoder_cmwpm_t_2 = PlanarCMWPMDecoder(factor=3, max_iterations=4, box_shape='t', distance_algorithm=2) decoder_cmwpm_t_4 = PlanarCMWPMDecoder(factor=3, max_iterations=4, box_shape='t', distance_algorithm=4) decoder_cmwpm_r_1 = PlanarCMWPMDecoder(factor=3, max_iterations=4, box_shape='r', distance_algorithm=1) # show mwpm fails recovery = decoder_mwpm.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'MWPM recovery does not commute with stabilizers.') assert not np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'MWPM recovery does commute with logicals.') # show cmwpm_t_2 fails recovery = decoder_cmwpm_t_2.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'CMWPM (t,2) recovery does not commute with stabilizers.') assert not np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'CMWPM (t,2) recovery does commute with logicals.') # show cmwpm_t_4 succeeds recovery = decoder_cmwpm_t_4.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'CMWPM (t,4) recovery does not commute with stabilizers.') assert np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'CMWPM (t,4) recovery does not commute with logicals.') # show cmwpm_r_1 succeeds recovery = decoder_cmwpm_r_1.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'CMWPM (r,1) recovery does not commute with stabilizers.') assert np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'CMWPM (r,1) recovery does not commute with logicals.')
def test_planar_cmwpm_step_grid_loose_box(): """ Matches {((0, 1), (4, 5))}: ──X───┬───┬── │ │ │ ──┼───┼───┼── │ │ │ ──┴───┴───X── """ code = PlanarCode(3, 4) grid = PlanarCMWPMDecoder.StepGrid(code) # set background from matches grid.set_background({((0, 1), (4, 5))}, factor=3, initial=1, box_shape='l') # expected grid. Note: border of virtual indices around grid. expected = np.array([[3., 0., 1., 0., 1., 0., 1., 0., 3.], [0., 1., 0., 1., 0., 1., 0., 1., 0.], [3., 0., 1., 0., 1., 0., 1., 0., 3.], [0., 1., 0., 1., 0., 1., 0., 1., 0.], [3., 0., 1., 0., 1., 0., 1., 0., 3.], [0., 1., 0., 1., 0., 1., 0., 1., 0.], [3., 0., 1., 0., 1., 0., 1., 0., 3.]]) assert np.array_equal(grid._grid, expected), 'Loose box not expected shape.' # test with alternative corners grid.set_background({((0, 5), (4, 1))}, factor=3, initial=1, box_shape='l') assert np.array_equal( grid._grid, expected), 'Loose box for alternative corners not expected shape.'
def test_planar_cmwpm_step_grid_tight_box(): """ Matches {((0, 1), (4, 5))}: ──X───┬───┬── │ │ │ ──┼───┼───┼── │ │ │ ──┴───┴───X── """ code = PlanarCode(3, 4) # error = code.new_pauli().site('Z', (0, 2), (1, 3), (2, 4), (3, 5)).to_bsf() # syndrome = pt.bsp(error, code.stabilizers.T) # matches = {tuple(code.syndrome_to_plaquette_indices(syndrome))} # {((0, 1), (4, 5))} # print(code.ascii_art(syndrome=syndrome)) # print(matches) grid = PlanarCMWPMDecoder.StepGrid(code) # set background from matches grid.set_background({((0, 1), (4, 5))}, factor=3, initial=1, box_shape='t') # expected grid. Note: border of virtual indices around grid. expected = np.array([[3., 0., 3., 0., 3., 0., 3., 0., 3.], [0., 3., 0., 1., 0., 1., 0., 3., 0.], [3., 0., 1., 0., 1., 0., 1., 0., 3.], [0., 3., 0., 1., 0., 1., 0., 3., 0.], [3., 0., 1., 0., 1., 0., 1., 0., 3.], [0., 3., 0., 1., 0., 1., 0., 3., 0.], [3., 0., 3., 0., 3., 0., 3., 0., 3.]]) assert np.array_equal(grid._grid, expected), 'Tight box not expected shape.' # test with alternative corners grid.set_background({((0, 5), (4, 1))}, factor=3, initial=1, box_shape='t') assert np.array_equal( grid._grid, expected), 'Tight box for alternative corners not expected shape.'
def test_planar_mps_decoder_positive_max_coset_probability(mode): # parameters code = PlanarCode(9, 9) decoder = PlanarMPSDecoder(chi=48, mode=mode) error_model = BiasedDepolarizingErrorModel(bias=100) error_probability = 0.41 # logged run values error = pt.unpack([ "c96aa012210dc2254031f15d9ce80c871fb864b510c91086e112a018f8aece7406638fdc00", 290 ]) syndrome = pt.unpack(["8f59cd273bd1c027b3b925085af85f2aaf22", 144]) assert np.array_equal(syndrome, pt.bsp(error, code.stabilizers.T)) # debug # print(code.ascii_art(syndrome, code.new_pauli(error))) # decode prob_dist = error_model.probability_distribution(error_probability) any_recovery = decoder.sample_recovery(code, syndrome) # coset probabilities coset_ps, recoveries = decoder._coset_probabilities( prob_dist, any_recovery) print('mode={}, coset_ps={}'.format(mode, coset_ps)) max_coset_p, max_recovery = max( zip(coset_ps, recoveries), key=lambda coset_p_recovery: coset_p_recovery[0]) success = np.all( pt.bsp(max_recovery.to_bsf() ^ error, code.logicals.T) == 0) print('### success=', success) assert mp.isfinite( max_coset_p ) and max_coset_p > 0, 'Max coset probability not as expected'
def test_planar_rmps_decoder_small_codes_exact_approx(): code = PlanarCode(4, 4) exact_decoder = PlanarRMPSDecoder() approx_decoder = PlanarRMPSDecoder(chi=8) 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_planar_y_decoder_partial_recovery_idempotence(): # tests for bug where destabilizer modified cached return value of _snake_fill code = PlanarCode(4, 3) syndrome_index = (2, 1) # create partial_recovery1, destabilzer and partial_recovery2, copying to test for changes partial_recovery1 = np.copy( PlanarYDecoder._partial_recovery(code, syndrome_index)) destabilizer = np.copy(PlanarYDecoder._destabilizer(code, syndrome_index)) partial_recovery2 = np.copy( PlanarYDecoder._partial_recovery(code, syndrome_index)) print(code.new_pauli(partial_recovery1)) print(code.new_pauli(destabilizer)) print(code.new_pauli(partial_recovery2)) assert np.array_equal( partial_recovery1, partial_recovery2), '_partial_recovery is not idempotent' assert not np.array_equal( partial_recovery2, destabilizer), '_partial_recovery == _destabilizer'
def test_planar_cmwpm_decoder_overflow(caplog): """ Error: ·─┬─·─┬─·─┬─·─┬─· · · · · ·─┼─Y─┼─·─┼─·─┼─· · Y · · ·─┼─·─┼─·─┼─·─┼─· · · · · ·─┼─·─┼─·─┼─Z─┼─· · · · · ·─┴─·─┴─·─┴─·─┴─· Syndrome: ──┬───┬───┬───┬── │ Z │ │ │ ──X───┼───┼───┼── │ │ Z │ │ ──┼───X───┼───┼── │ │ │ │ ──┼───┼───X───X── │ │ │ │ ──┴───┴───┴───┴── """ factor = 1e+308 # This is just a bit smaller than max float, so it causes overflow with multiple matched indices code = PlanarCode(5, 5) error = code.new_pauli().site('Y', (2, 2), (3, 3)).site('Z', (6, 6)).to_bsf() syndrome = pt.bsp(error, code.stabilizers.T) decoder_cmwpm = PlanarCMWPMDecoder(factor=factor, max_iterations=4, box_shape='t', distance_algorithm=4) # show cmwpm succeeds print() recovery = decoder_cmwpm.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'CMWPM recovery does not commute with stabilizers.') assert np.all(pt.bsp(recovery ^ error, code.logicals.T) == 0), ( 'CMWPM recovery does not commute with logicals.') assert 'FPE RAISED FloatingPointError' in caplog.text, 'FloatingPointError not logged' print(caplog.text)
def test_run_once_seeded(): code = PlanarCode(5, 5) error_model = DepolarizingErrorModel() decoder = PlanarMWPMDecoder() error_probability = 0.15 data1 = app.run_once(code, error_model, decoder, error_probability, rng=np.random.default_rng(5)) data2 = app.run_once(code, error_model, decoder, error_probability, rng=np.random.default_rng(5)) assert data1['error_weight'] == data2['error_weight'] assert data1['success'] == data2['success'] assert np.array_equal(data1['logical_commutations'], data2['logical_commutations']) assert np.array_equal(data1['custom_values'], data2['custom_values'])
def test_planar_rmps_decoder_cosets_probability_inequality(mode, rtol): code = PlanarCode(25, 25) decoder = PlanarRMPSDecoder(chi=5, mode=mode) # probabilities prob_dist = DepolarizingErrorModel().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(XG) ~= Pr(ZG) > Pr(YG) print('{} > {} ~= {} > {}. rtol={}'.format( coset_i_p, coset_x_p, coset_z_p, coset_y_p, abs(coset_x_p - coset_z_p) / abs(coset_z_p))) print('types: Pr(IG):{}, Pr(XG):{}, Pr(ZG):{}, Pr(YG):{}'.format( type(coset_i_p), type(coset_x_p), type(coset_z_p), type(coset_y_p))) assert coset_i_p > coset_x_p, 'Coset probabilites do not satisfy Pr(IG) > Pr(XG)' assert coset_i_p > coset_z_p, 'Coset probabilites do not satisfy Pr(IG) > Pr(ZG)' assert _is_close( coset_x_p, coset_z_p, rtol=rtol, atol=0), 'Coset probabilites do not satisfy Pr(XG) ~= Pr(ZG)' assert coset_x_p > coset_y_p, 'Coset probabilites do not satisfy Pr(XG) > Pr(YG)' assert coset_z_p > coset_y_p, 'Coset probabilites do not satisfy Pr(ZG) > Pr(YG)'
def test_run_seeded(): code = PlanarCode(5, 5) error_model = DepolarizingErrorModel() decoder = PlanarMPSDecoder() error_probability = 0.101 max_runs = 5 random_seed = 5 data1 = app.run(code, error_model, decoder, error_probability, max_runs=max_runs, random_seed=random_seed) data2 = app.run(code, error_model, decoder, error_probability, max_runs=max_runs, random_seed=random_seed) # remove wall_time from data for data in (data1, data2): del data['wall_time'] assert data1 == data2, 'Identically seeded runs are not the same. '
def test_planar_mps_decoder_svd_does_not_converge(): code = PlanarCode(21, 21) decoder = PlanarMPSDecoder(chi=4) error = pt.unpack(( '001281500200080080000000000080001000000c0000002012000000801040004000000100000000004000002100000800800000000000' '02000100028022001000002044841000080080008110020000400801200000801040112008010004400000000000000002000000402201' '10040000000000000481000200000601000080080000000820200020000000008820000100000010045000004000010000000000000000' '40010000840010200008000400024000880000000004000000004000200890040001082000000000000002000000', 1682)) syndrome = pt.bsp(error, code.stabilizers.T) recovery = decoder.decode(code, syndrome) # no error raised assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers.'.format( recovery, error))
def test_planar_mps_decoder_zero_norm_in_left_canonical_form(): # parameters random_seed = 13 code = PlanarCode(7, 7) error_model = BitFlipErrorModel() decoder = PlanarMPSDecoder(chi=6, mode='c') error_probability = 0.1 # single run error = error_model.generate(code, error_probability, np.random.default_rng(random_seed)) syndrome = pt.bsp(error, code.stabilizers.T) decoder.decode(code, syndrome, error_model=error_model, error_probability=error_probability)
def test_planar_rmps_decoder_cosets_probability_stp(): # parameters sample = PlanarCode(3, 4).new_pauli().site('Y', (2, 0), (2, 4)) prob_dist = DepolarizingErrorModel().probability_distribution(0.1) # coset probabilities exact exact_coset_ps, _ = PlanarRMPSDecoder(mode='a')._coset_probabilities( prob_dist, sample) print('#exact_coset_ps=', exact_coset_ps) # coset probabilities approx (chi=6) approx_coset_ps, _ = PlanarRMPSDecoder(chi=6, mode='a')._coset_probabilities( prob_dist, sample) print('#approx_coset_ps=', approx_coset_ps) assert all( _is_close(exact_coset_ps, approx_coset_ps, rtol=1e-14, atol=0)), ('approx_coset_ps not close to exact_coset_ps') # coset probabilities approx (chi=6, stp=0) coset_ps, _ = PlanarRMPSDecoder(chi=6, mode='a', stp=0)._coset_probabilities( prob_dist, sample) print('#coset_ps (chi=6, stp=0)=', coset_ps) assert all(_is_close( approx_coset_ps, coset_ps, rtol=0, atol=0)), ('coset_ps (chi=6, stp=0) not equal to approx_coset_ps') # coset probabilities approx (chi=6, stp=1) coset_ps, _ = PlanarRMPSDecoder(chi=6, mode='a', stp=1)._coset_probabilities( prob_dist, sample) print('#coset_ps (chi=6, stp=1)=', coset_ps) assert all(_is_close( exact_coset_ps, coset_ps, rtol=0, atol=0)), ('coset_ps (chi=6, stp=1) not equal to exact_coset_ps') # coset probabilities approx (chi=6, stp=0.5) coset_ps, _ = PlanarRMPSDecoder(chi=6, mode='a', stp=0.5)._coset_probabilities( prob_dist, sample) print('#coset_ps (chi=6, stp=0.5)=', coset_ps) assert all(_is_close( exact_coset_ps, coset_ps, rtol=1e-10, atol=0)), ('coset_ps (chi=6, stp=0.5) not close to exact_coset_ps') assert all(_is_close( approx_coset_ps, coset_ps, rtol=1e-10, atol=0)), ('coset_ps (chi=6, stp=0.5) not close to approx_coset_ps')
def test_planar_mps_decoder_decode_logging_nonpositivefinite_max_coset_probability( caplog): # taken from corner case mode='a' of test_planar_mps_decoder_positive_max_coset_probability code = PlanarCode(9, 9) decoder = PlanarMPSDecoder(chi=48, mode='a') error_model = BiasedDepolarizingErrorModel(bias=100) error_probability = 0.41 error = pt.unpack([ "c96aa012210dc2254031f15d9ce80c871fb864b510c91086e112a018f8aece7406638fdc00", 290 ]) syndrome = pt.unpack(["8f59cd273bd1c027b3b925085af85f2aaf22", 144]) assert np.array_equal(syndrome, pt.bsp(error, code.stabilizers.T)) decoder.decode(code, syndrome, error_model=error_model, error_probability=error_probability) assert 'NON-POSITIVE-FINITE MAX COSET PROBABILITY' in caplog.text, ( 'Non-positive-finite max coset probability not logged')
def test_planar_y_decoder_coset_probability_performance(): print() with mp.workdps(50): n_run = 20 code = PlanarCode(16, 16) # 16, 16 prob_dist = (0.9, 0.0, 0.1, 0.0) # preload stabilizer cache PlanarYDecoder._y_stabilizers(code) # time runs start_time = time.time() for _ in range(n_run): coset = PlanarYDecoder._y_stabilizers(code) coset_probability = PlanarYDecoder._coset_probability( prob_dist, coset) print(repr(coset_probability)) run_time = time.time() - start_time print('run_time = {}'.format(run_time)) # test to avoid regression assert run_time < 7 # 5.423123121261597
def test_planar_rmps_mps_performance(): n_run = 5 code = PlanarCode(21, 21) error_model = DepolarizingErrorModel() error_probability = 0.2 def _timed_runs(decoder): start_time = time.time() for _ in range(n_run): error = error_model.generate(code, error_probability) syndrome = pt.bsp(error, code.stabilizers.T) recovery = decoder.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers.' .format(recovery, error)) return time.time() - start_time rmps_time = _timed_runs(PlanarRMPSDecoder(chi=8)) mps_time = _timed_runs(PlanarMPSDecoder(chi=8)) # expect rmps_time < mps_time print('rmps_time = {} < {} = mps_time'.format(rmps_time, mps_time)) assert rmps_time < mps_time, 'RMPS decoder slower than MPS decoder'
def test_planar_cmwpm_step_grid_fitted_vertical_line(): """ Matches {((0, 3), (4, 3))}: ──┬───X───┬── │ │ │ ──┼───┼───┼── │ │ │ ──┴───X───┴── """ code = PlanarCode(3, 4) grid = PlanarCMWPMDecoder.StepGrid(code) # set background from matches grid.set_background({((0, 3), (4, 3))}, factor=3, initial=1, box_shape='f') # expected grid. Note: border of virtual indices around grid. expected = np.array([[3., 0., 3., 0., 3., 0., 3., 0., 3.], [0., 3., 0., 3., 0., 3., 0., 3., 0.], [3., 0., 3., 0., 1., 0., 3., 0., 3.], [0., 3., 0., 1., 0., 1., 0., 3., 0.], [3., 0., 3., 0., 1., 0., 3., 0., 3.], [0., 3., 0., 3., 0., 3., 0., 3., 0.], [3., 0., 3., 0., 3., 0., 3., 0., 3.]]) assert np.array_equal(grid._grid, expected), 'Fitted box not expected shape.'
def test_planar_mps_mwpm_performance(): n_run = 5 code = PlanarCode(25, 25) error_model = DepolarizingErrorModel() error_probability = 0.4 rng = np.random.default_rng(13) def _timed_runs(decoder): start_time = time.time() for _ in range(n_run): error = error_model.generate(code, error_probability, rng) syndrome = pt.bsp(error, code.stabilizers.T) recovery = decoder.decode(code, syndrome) assert np.all(pt.bsp(recovery ^ error, code.stabilizers.T) == 0), ( 'recovery ^ error ({} ^ {}) does not commute with stabilizers.' .format(recovery, error)) return time.time() - start_time mps_time = _timed_runs(PlanarMPSDecoder(chi=6)) mwpm_time = _timed_runs(PlanarMWPMDecoder()) # expect mps_time < mwpm_time print('mps_time = {} < {} = mwpm_time'.format(mps_time, mwpm_time)) assert mps_time < mwpm_time, 'MPS decoder slower than MWPM decoder'
import multiprocessing as mp import collections import itertools import numpy as np import matplotlib.pyplot as plt from functools import partial import qecsim from qecsim import app from qecsim.models.generic import PhaseFlipErrorModel from qecsim.models.planar import PlanarCode, PlanarMPSDecoder # set models codes = [PlanarCode(*size) for size in [(3, 3), (5, 5)]] error_model = PhaseFlipErrorModel() decoder = PlanarMPSDecoder() # set physical error probabilities error_probability_min, error_probability_max = 0, 0.4 error_probabilities = np.linspace(error_probability_min, error_probability_max, 5) # set max_runs for each probability max_runs = 10 # print run parameters print('Codes:', [code.label for code in codes]) print('Error model:', error_model.label) print('Decoder:', decoder.label) print('Error probabilities:', error_probabilities) print('Maximum runs:', max_runs) def parallel_step_p(code, error_model, decoder, max_runs, error_probability):
import numpy as np from qecsim import paulitools as pt import matplotlib.pyplot as plt import qecsim from qecsim import app from qecsim.models.generic import PhaseFlipErrorModel, DepolarizingErrorModel, BiasedDepolarizingErrorModel, BiasedYXErrorModel from qecsim.models.planar import PlanarCode, PlanarMPSDecoder import importlib as imp import os, time import multiprocessing as mp from functools import partial if __name__ == '__main__': sizes = range(8, 9, 2) codes_and_size = [PlanarCode(*(size, size)) for size in sizes] bias_list = [10] layout_name = 'planar' bdry_name = 'surface' p_min, p_max = 0.01, 0.40 error_probabilities = np.linspace(p_min, p_max, 40) pL_list = np.zeros(len(error_probabilities)) std_list = np.zeros(len(error_probabilities)) log_pL_list = np.zeros(len(error_probabilities)) log_std_list = np.zeros(len(error_probabilities)) code_names = [ 'random_XY', 'XY', 'CSS', 'XZZX', 'spiral_XZ', 'random_XZ', 'random_XZ_YZ', 'random_all' ]
# plt.figure(figsize=(20,10)) # lines=['-',':','--','-.'] # linecycler=cycle(lines) # plt.title('TND failure rate scaling comparison at bias='+str(bias)[:7]+' for '+layout+' '+bdry_name+'L='+str(sizes[L_index])) #XYZ,ZYX,XZY,YXZ,YZX,ZXY for code_name in code_names: pL_list_chi, std_list_chi, log_pL_list_chi, log_std_list_chi = np.zeros( len(bond_dimensions)), np.zeros( len(bond_dimensions)), np.zeros( len(bond_dimensions)), np.zeros(len(bond_dimensions)) for chi_val_index, chi_val in enumerate(bond_dimensions): if code_name == 'CSS': codes_and_size = [ PlanarCode(*(size, size)) for size in sizes ] layout = 'planar' num_realiz = 1 bias_str = 'Z' max_runs = 20000 elif code_name == 'XY': codes_and_size = [ PlanarCode(*(size, size)) for size in sizes ] layout = 'planar' bias_str = 'Y' num_realiz = 1 max_runs = 20000 elif code_name == 'rotXY': codes_and_size = [
(None, 2, None, None), # invalid mode (None, 'c', -0.1, None), # invalid stp (None, 'c', 1.1, None), # invalid stp (None, 'c', 'asdf', None), # invalid stp (None, 'c', None, -1), # invalid tol (None, 'c', None, 'asdf'), # invalid tol ]) def test_planar_rmps_decoder_new_invalid_parameters(chi, mode, stp, tol): with pytest.raises((ValueError, TypeError), match=r"^PlanarRMPSDecoder") as exc_info: PlanarRMPSDecoder(chi=chi, mode=mode, stp=stp, tol=tol) print(exc_info) @pytest.mark.parametrize('error_pauli', [ PlanarCode(3, 3).new_pauli().site('X', (2, 0)).site('Y', (3, 3)), PlanarCode(5, 5).new_pauli().site('X', (3, 1)).site('Y', (2, 2)).site('Z', (6, 4)), PlanarCode(7, 7).new_pauli().site('X', (4, 2)).site('Y', (3, 3)).site( 'Z', (8, 4), (7, 3)), ]) def test_planar_rmps_decoder_sample_recovery(error_pauli): error = error_pauli.to_bsf() code = error_pauli.code syndrome = pt.bsp(error, code.stabilizers.T) recovery_pauli = PlanarRMPSDecoder.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))
def test_planar_rmps_decoder_cosets_probability_pair_optimisation(shape, mode): code = PlanarCode(*shape) decoder = PlanarRMPSDecoder(mode=mode) # probabilities prob_dist = BiasedDepolarizingErrorModel( bias=10).probability_distribution(0.1) # coset probabilities for null Pauli coset_i_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli()) # X coset_x_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli().logical_x()) # expect Pr(iIG) ~= Pr(xXG) assert _is_close( coset_i_ps[0], coset_x_ps[1], rtol=1e-15, 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=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iXG) ~= Pr(xIG)') # expect Pr(iYG) ~= Pr(xZG) assert _is_close( coset_i_ps[2], coset_x_ps[3], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iYG) ~= Pr(xZG)') # expect Pr(iZG) ~= Pr(xYG) assert _is_close( coset_i_ps[3], coset_x_ps[2], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iZG) ~= Pr(xYG)') # Y coset_y_ps, _ = decoder._coset_probabilities( prob_dist, code.new_pauli().logical_x().logical_z()) # expect Pr(iIG) ~= Pr(yYG) assert _is_close( coset_i_ps[0], coset_y_ps[2], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iIG) ~= Pr(yYG)') # expect Pr(iXG) ~= Pr(yZG) assert _is_close( coset_i_ps[1], coset_y_ps[3], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iXG) ~= Pr(yZG)') # expect Pr(iYG) ~= Pr(yIG) assert _is_close( coset_i_ps[2], coset_y_ps[0], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iYG) ~= Pr(yIG)') # expect Pr(iZG) ~= Pr(yXG) assert _is_close( coset_i_ps[3], coset_y_ps[1], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iZG) ~= Pr(yXG)') # Z coset_z_ps, _ = decoder._coset_probabilities(prob_dist, code.new_pauli().logical_z()) # expect Pr(iIG) ~= Pr(zZG) assert _is_close( coset_i_ps[0], coset_z_ps[3], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iIG) ~= Pr(zZG)') # expect Pr(iXG) ~= Pr(zYG) assert _is_close( coset_i_ps[1], coset_z_ps[2], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iXG) ~= Pr(zYG)') # expect Pr(iYG) ~= Pr(zXG) assert _is_close( coset_i_ps[2], coset_z_ps[1], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iYG) ~= Pr(zXG)') # expect Pr(iZG) ~= Pr(zIG) assert _is_close( coset_i_ps[3], coset_z_ps[0], rtol=1e-15, atol=0), ('Coset probabilites do not satisfy Pr(iZG) ~= Pr(zIG)')