Beispiel #1
0
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))
Beispiel #3
0
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'
Beispiel #4
0
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'
Beispiel #5
0
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.')
Beispiel #6
0
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'
Beispiel #7
0
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'
Beispiel #8
0
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)')
Beispiel #10
0
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)')
Beispiel #13
0
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')
Beispiel #14
0
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)