Ejemplo n.º 1
0
def merge_with_pauli_noise(prog_list: Iterable, probabilities: List, qubits: List):
    """
    Insert pauli noise channels between each item in the list of programs.
    This noise channel is implemented as a single noisy identity gate acting on the provided qubits.
    This method does not rely on merge_programs and so avoids the inclusion of redundant Kraus Pragmas
    that would occur if merge_programs was called directly on programs with distinct noisy gate definitions.

    :param prog_list: an iterable such as a program or a list of programs.
        If a program is provided, a single noise gate will be applied after each gate in the program.
        If a list of programs is provided, the noise gate will be applied after each program.
    :param probabilities: The 4^num_qubits list of probabilities specifying the desired pauli channel.
        There should be either 4 or 16 probabilities specified in the order
        I, X, Y, Z or II, IX, IY, IZ, XI, XX, XY, etc respectively.
    :param qubits: a list of the qubits that the noisy gate should act on.
    :return: A single program with noisy gates inserted between each element of the program list.
    :rtype: Program
    """
    p = Program()
    p.defgate("pauli_noise", np.eye(2 ** len(qubits)))
    p.define_noisy_gate("pauli_noise", qubits, pauli_kraus_map(probabilities))
    for elem in prog_list:
        p.inst(Program(elem))
        if isinstance(elem, Measurement):
            continue  # do not apply noise after measurement
        p.inst(("pauli_noise", *qubits))
    return p
Ejemplo n.º 2
0
def test_2q_general_pauli_noise(qvm, benchmarker):
    qvm.qam.random_seed = 1

    expected_decay = .8
    probs = [expected_decay + .2 / 4, .06] + [0] * 12 + [.04, .05]
    kraus_ops = pauli_kraus_map(probs)

    num_sequences_per_depth = 5
    num_shots = 25
    depths = [2, 10, 12, 25]
    depths = [
        depth for depth in depths for _ in range(num_sequences_per_depth)
    ]
    qubits = (0, 1)

    sequences = generate_rb_experiment_sequences(benchmarker, qubits, depths)
    add_noise_to_sequences(sequences, qubits)

    expts = group_sequences_into_parallel_experiments([sequences], [qubits])

    for expt in expts:
        add_noise_definition(expt, qubits, kraus_ops)

    results = acquire_rb_data(qvm, expts, num_shots)
    stats = get_stats_by_qubit_group([qubits], results)[qubits]
    fit = fit_rb_results(depths, stats['expectation'], stats['std_err'],
                         num_shots)

    observed_decay = fit.params['decay'].value
    decay_error = fit.params['decay'].stderr

    np.testing.assert_allclose(expected_decay,
                               observed_decay,
                               atol=2.5 * decay_error)
Ejemplo n.º 3
0
def test_pauli_kraus_map():
    probabilities = [.1, .2, .3, .4]
    k1, k2, k3, k4 = pauli_kraus_map(probabilities)
    assert np.allclose(k1, np.sqrt(.1) * np.eye(2), atol=1 * 10**-8)
    assert np.allclose(k2,
                       np.sqrt(.2) * np.array([[0, 1.], [1., 0]]),
                       atol=1 * 10**-8)
    assert np.allclose(k3,
                       np.sqrt(.3) * np.array([[0, -1.j], [1.j, 0]]),
                       atol=1 * 10**-8)
    assert np.allclose(k4,
                       np.sqrt(.4) * np.array([[1, 0], [0, -1]]),
                       atol=1 * 10**-8)

    two_q_pauli_kmaps = pauli_kraus_map(
        np.kron(probabilities, list(reversed(probabilities))))
    q1_pauli_kmaps = [k1, k2, k3, k4]
    q2_pauli_kmaps = pauli_kraus_map(list(reversed(probabilities)))
    tensor_kmaps = tensor_kraus_maps(q1_pauli_kmaps, q2_pauli_kmaps)
    assert np.allclose(two_q_pauli_kmaps, tensor_kmaps)
Ejemplo n.º 4
0
def depolarizing_noise(num_qubits: int, p: float = .95):
    """
    Generate the Kraus operators corresponding to a given unitary
    single qubit gate followed by a depolarizing noise channel.

    :params float num_qubits: either 1 or 2 qubit channel supported
    :params float p: parameter in depolarizing channel as defined by: p $\rho$ + (1-p)/d I
    :return: A list, eg. [k0, k1, k2, k3], of the Kraus operators that parametrize the map.
    :rtype: list
    """
    num_of_operators = 4 ** num_qubits
    probabilities = [p + (1.0 - p) / num_of_operators] + [(1.0 - p) / num_of_operators] * (num_of_operators - 1)
    return pauli_kraus_map(probabilities)
Ejemplo n.º 5
0
def pauli_noise_z_gate(p_I=.7, p_x=0.1, p_y=0.1, p_z=0.1):
    corrupted_Z = append_kraus_to_gate(pauli_kraus_map([p_I, p_x, p_y, p_z]),
                                       np.array([[1, 0], [0, -1]]))
    return corrupted_Z