Example #1
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'
Example #2
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.')
Example #3
0
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'
Example #4
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'
Example #5
0
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))
Example #6
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)')
Example #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'
Example #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.')
Example #9
0
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.'
Example #10
0
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.'
Example #11
0
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'
Example #12
0
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)')
Example #13
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'
Example #14
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)
Example #15
0
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'])
Example #16
0
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)'
Example #17
0
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. '
Example #18
0
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))
Example #19
0
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)
Example #20
0
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')
Example #21
0
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')
Example #22
0
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
Example #23
0
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'
Example #24
0
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.'
Example #25
0
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'
Example #26
0
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):
Example #27
0
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'
    ]
Example #28
0
        # 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 = [
Example #29
0
        (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))
Example #30
0
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)')