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_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_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_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_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_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_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_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_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_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)')
def test_planar_mps2d_contract_mask(): code = PlanarCode(3, 4) 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) rng = np.random.default_rng() # tn_contract exact exact_result = tt.mps2d.contract(tn) assert isinstance(exact_result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= exact_result <= 1, 'Contracted tensor network not within bounds' print('#exact_result=', exact_result) # tn_contract approx approx_result = tt.mps2d.contract(tn, chi=2) assert isinstance(approx_result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= approx_result <= 1, 'Contracted tensor network not within bounds' print('#approx_result=', approx_result, '#rtol=', abs(approx_result - exact_result) / abs(exact_result)) assert _is_close(exact_result, approx_result, rtol=1e-4, atol=0), 'tn_contract(chi=2) not as expected' # tn_contract with truncate (chi, mask=0) stp = 0 # skip truncate probability mask = rng.choice((True, False), size=tn.shape, p=(1 - stp, stp)) result = tt.mps2d.contract(tn, chi=2, mask=mask) assert isinstance(result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result <= 1, 'Contracted tensor network not within bounds' print('#result (chi=2, mask=0)=', result, '#rtol=', abs(result - approx_result) / abs(approx_result)) assert approx_result == result, 'tn_contract(chi=2, mask=0) not same as approx_result' # tn_contract with truncate (chi, mask=1) stp = 1 # skip truncate probability mask = rng.choice((True, False), size=tn.shape, p=(1 - stp, stp)) result = tt.mps2d.contract(tn, chi=2, mask=mask) assert isinstance(result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result <= 1, 'Contracted tensor network not within bounds' print('#result (chi=2, mask=1)=', result, '#rtol=', abs(result - exact_result) / abs(exact_result)) assert exact_result == result, 'tn_contract(chi=2, mask=1) not same as exact_result' # tn_contract with truncate (chi, mask=0.5) stp = 0.5 # skip truncate probability mask = rng.choice((True, False), size=tn.shape, p=(1 - stp, stp)) result = tt.mps2d.contract(tn, chi=2, mask=mask) assert isinstance(result, mp.mpf), 'Contracted tensor network is not an mp.mpf' assert 0 <= result <= 1, 'Contracted tensor network not within bounds' print('#result (chi=2, mask=0.5)=', result, '#rtol=', abs(result - exact_result) / abs(exact_result)) assert exact_result != result, 'tn_contract(chi=2, mask=0.5) should not equal exact_result' assert approx_result != result, 'tn_contract(chi=2, mask=0.5) should not equal approx_result' assert _is_close( exact_result, result, rtol=1e-4, atol=0), 'tn_contract(chi=2, mask=0.5) not close to exact_result' print('#result (chi=2, mask=0.5)=', result, '#rtol=', abs(result - approx_result) / abs(approx_result)) assert _is_close( approx_result, result, rtol=1e-4, atol=0), ('tn_contract(chi=2, mask=0.5) not close to approx_result')
def test_planar_pauli_properties(size): lattice = PlanarCode(*size) pauli = lattice.new_pauli() assert pauli.code == lattice assert isinstance(repr(pauli), str) assert isinstance(str(pauli), str)