Example #1
0
def test_identity_removal():
    test_term = 0.25 * sX(1) * sZ(2) * sX(3) + 0.25j * sX(1) * sZ(2) * sY(3)
    test_term += -0.25j * sY(1) * sZ(2) * sX(3) + 0.25 * sY(1) * sZ(2) * sY(3)
    identity_term = 200 * sI(5)

    new_psum, identity_term_result = remove_identity(identity_term + test_term)
    assert test_term == new_psum
    assert identity_term_result == identity_term
Example #2
0
def test_group_experiments(grouping_method):
    expts = [  # cf above, I removed the inner nesting. Still grouped visually
        ExperimentSetting(sI(), sX(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sX(1)),
        ExperimentSetting(sI(), sZ(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sZ(1)),
    ]
    suite = TomographyExperiment(expts, Program(), qubits=[0, 1])
    grouped_suite = group_experiments(suite, method=grouping_method)
    assert len(suite) == 4
    assert len(grouped_suite) == 2
def test_stabilizer_projection_ZZ():
    """
    test if we project out the correct state
    """
    stabilizer_state = project_stabilized_state([sZ(0) * sZ(1), sX(0) * sX(1)])
    true_state = np.zeros((4, 1))
    true_state[0, 0] = true_state[3, 0] = 1
    true_state /= np.sqrt(2)
    assert np.allclose(true_state, stabilizer_state.todense())
Example #4
0
def test_ps_adds_pt_2():
    term = ID()
    b = term + 1.0
    assert str(b) == "(2+0j)*I"
    assert str(b + 1.0) == "(3+0j)*I"
    assert str(1.0 + b) == "(3+0j)*I"
    b = sX(0) + 1.0
    assert str(b) == "(1+0j)*X0 + (1+0j)*I"
    b = 1.0 + sX(0)
    assert str(b) == "(1+0j)*I + (1+0j)*X0"
Example #5
0
def test_ps_sub():
    term = 3 * ID()
    b = term - 1.0
    assert str(b) == "(2+0j)*I"
    assert str(b - 1.0) == "(1+0j)*I"
    assert str(1.0 - b) == "(-1+0j)*I"
    b = 1.0 - sX(0)
    assert str(b) == "(1+0j)*I + (-1+0j)*X0"
    b = sX(0) - 1.0
    assert str(b) == "(1+0j)*X0 + (-1+0j)*I"
Example #6
0
def test_sum_equality():
    pauli_sum = sY(0) - sX(0)
    assert pauli_sum != 2 * pauli_sum
    assert pauli_sum != pauli_sum + sZ(0)
    assert pauli_sum + sZ(0) != pauli_sum
    assert pauli_sum != sY(1) - sX(1)
    assert pauli_sum == -1.0 * sX(0) + sY(0)
    assert pauli_sum == pauli_sum * 1.0
    with pytest.raises(TypeError):
        assert pauli_sum != 0
Example #7
0
def test_sum_equality():
    q0, q1 = QubitPlaceholder.register(2)
    pauli_sum = sY(q0) - sX(q0)
    assert pauli_sum != 2 * pauli_sum
    assert pauli_sum != pauli_sum + sZ(q0)
    assert pauli_sum + sZ(q0) != pauli_sum
    assert pauli_sum != sY(q1) - sX(q1)
    assert pauli_sum == -1.0 * sX(q0) + sY(q0)
    assert pauli_sum == pauli_sum * 1.0
    with pytest.raises(TypeError):
        assert pauli_sum != 0
Example #8
0
def test_expectation(client_configuration: QCSClientConfiguration):
    wfnsim = WavefunctionSimulator(client_configuration=client_configuration)
    bell = Program(H(0), CNOT(0, 1))
    expects = wfnsim.expectation(bell, [sZ(0) * sZ(1), sZ(0), sZ(1), sX(0) * sX(1)])
    assert expects.size == 4
    np.testing.assert_allclose(expects, [1, 0, 0, 1])

    pauli_sum = PauliSum([sZ(0) * sZ(1)])
    expects = wfnsim.expectation(bell, pauli_sum)
    assert expects.size == 1
    np.testing.assert_allclose(expects, [1])
def test_ps_sub():
    q0 = QubitPlaceholder()
    term = 3 * ID()
    b = term - 1.0
    assert str(b) == "(2+0j)*I"
    assert str(b - 1.0) == "(1+0j)*I"
    assert str(1.0 - b) == "(-1+0j)*I"
    b = 1.0 - sX(q0)
    assert re.match(r"\(1\+0j\)\*I \+ \(-1\+0j\)\*Xq\d+", str(b))
    b = sX(q0) - 1.0
    assert re.match(r"\(1\+0j\)\*Xq\d+ \+ \(-1\+0j\)\*I", str(b))
Example #10
0
def test_commuting_terms_indexed():
    """
    Test performance of commuting_sets_by_index
    """
    pauli_term_1 = PauliSum([sX(0) * sZ(1)])
    pauli_term_2 = PauliSum([sX(1) * sZ(2)])
    pauli_term_3 = PauliSum([sX(0) * sY(3)])
    commuting_set_tuples = commuting_sets_by_indices(
        [pauli_term_1, pauli_term_2, pauli_term_3], check_trivial_commutation)
    correct_tuples = [[(0, 0)], [(1, 0), (2, 0)]]

    assert commuting_set_tuples == correct_tuples
Example #11
0
def test_append():
    expts = [
        [ExperimentSetting(sI(), sX(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sX(1))],
        [ExperimentSetting(sI(), sZ(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sZ(1))],
    ]
    suite = TomographyExperiment(
        settings=expts,
        program=Program(X(0), Y(1)),
        qubits=[0, 1]
    )
    suite.append(ExperimentSetting(sI(), sY(0) * sX(1)))
    assert (len(str(suite))) > 0
def test_simulation_cnot():
    """
    Test if the simulation of CNOT is accurate
    :return:
    """
    prog = Program().inst([H(0), CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_hadamard(prog.instructions[0])
    qvmstab._apply_cnot(prog.instructions[1])

    # assert that ZZ XX stabilizes a bell state
    true_stabilizers = [sX(0) * sX(1), sZ(0) * sZ(1)]
    test_paulis = binary_stabilizer_to_pauli_stabilizer(qvmstab.tableau[2:, :])
    for idx, term in enumerate(test_paulis):
        assert term == true_stabilizers[idx]

    # test that CNOT does nothing to |00> state
    prog = Program().inst([CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_cnot(prog.instructions[0])
    true_tableau = np.array([
        [1, 1, 0, 0, 0],  # X1 -> X1 X2
        [0, 1, 0, 0, 0],  # X2 -> X2
        [0, 0, 1, 0, 0],  # Z1 -> Z1
        [0, 0, 1, 1, 0]
    ])  # Z2 -> Z1 Z2

    # note that Z1, Z1 Z2 still stabilizees |00>
    assert np.allclose(true_tableau, qvmstab.tableau)

    # test that CNOT produces 11 state after X
    prog = Program().inst([H(0), S(0), S(0), H(0), CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_hadamard(prog.instructions[0])
    qvmstab._apply_phase(prog.instructions[1])
    qvmstab._apply_phase(prog.instructions[2])
    qvmstab._apply_hadamard(prog.instructions[3])
    qvmstab._apply_cnot(prog.instructions[4])
    true_tableau = np.array([[1, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 1],
                             [0, 0, 1, 1, 0]])

    # note that -Z1, Z1 Z2 still stabilizees |11>
    assert np.allclose(true_tableau, qvmstab.tableau)

    test_paulis = binary_stabilizer_to_pauli_stabilizer(
        qvmstab.stabilizer_tableau())
    state = project_stabilized_state(test_paulis,
                                     qvmstab.num_qubits,
                                     classical_state=[1, 1])
    state_2 = project_stabilized_state(test_paulis, qvmstab.num_qubits)

    assert np.allclose(np.array(state.todense()), np.array(state_2.todense()))
Example #13
0
def test_max_tpb_overlap_1():
    tomo_expt_settings = [ExperimentSetting(sZ(1) * sX(0), sY(2) * sY(1)),
                          ExperimentSetting(sX(2) * sZ(1), sY(2) * sZ(0))]
    tomo_expt_program = Program(H(0), H(1), H(2))
    tomo_expt_qubits = [0, 1, 2]
    tomo_expt = TomographyExperiment(tomo_expt_settings, tomo_expt_program, tomo_expt_qubits)
    expected_dict = {
        ExperimentSetting(plusX(0) * plusZ(1) * plusX(2), sZ(0) * sY(1) * sY(2)): [
            ExperimentSetting(plusZ(1) * plusX(0), sY(2) * sY(1)),
            ExperimentSetting(plusX(2) * plusZ(1), sY(2) * sZ(0))
        ]
    }
    assert expected_dict == _max_tpb_overlap(tomo_expt)
Example #14
0
def test_merge_disjoint_experiments():
    sett1 = ExperimentSetting(TensorProductState(), sX(0) * sY(1))
    sett2 = ExperimentSetting(plusZ(1), sY(1))
    sett3 = ExperimentSetting(plusZ(0), sX(0))
    sett4 = ExperimentSetting(minusX(1), sY(1))
    sett5 = ExperimentSetting(TensorProductState(), sZ(2))

    expt1 = Experiment(settings=[sett1, sett2], program=Program(X(1)))
    expt2 = Experiment(settings=[sett3, sett4], program=Program(Z(0)))
    expt3 = Experiment(settings=[sett5], program=Program())

    merged_expt = merge_disjoint_experiments([expt1, expt2, expt3])
    assert len(merged_expt) == 2
def test_diagonal_basis_commutes():
    x_term = sX(0) * sX(1)
    z1_term = sZ(1)
    z0_term = sZ(0)
    z0z1_term = sZ(0) * sZ(1)
    assert not diagonal_basis_commutes(x_term, z1_term)
    assert not diagonal_basis_commutes(z0z1_term, x_term)

    assert diagonal_basis_commutes(z1_term, z0_term)
    assert diagonal_basis_commutes(z0z1_term, z0_term)
    assert diagonal_basis_commutes(z0z1_term, z1_term)
    assert diagonal_basis_commutes(z0z1_term, sI(1))
    assert diagonal_basis_commutes(z0z1_term, sI(2))
    assert diagonal_basis_commutes(z0z1_term, sX(5) * sY(7))
Example #16
0
def test_experiment_deser(tmpdir):
    expts = [
        [ExperimentSetting(sI(), sX(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sX(1))],
        [ExperimentSetting(sI(), sZ(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sZ(1))],
    ]

    suite = TomographyExperiment(
        settings=expts,
        program=Program(X(0), Y(1)),
        qubits=[0, 1]
    )
    to_json(f'{tmpdir}/suite.json', suite)
    suite2 = read_json(f'{tmpdir}/suite.json')
    assert suite == suite2
def test_rowsum_phase_accumulator():
    """
    Test the accuracy of the phase accumulator.  This subroutine keeps track of the power that $i$ is raised to
    when multiplying two PauliTerms together.  PauliTerms are now composed of multi single-qubit Pauli's.

    The formula is phase_accumulator(h, i) = 2 * rh + 2 * ri + \sum_{j}^{n}g(x_{ij}, z_{ij}, x_{hj}, z_{hj}

    The returned value is presented mod 4.

    notice that since r_h indicates +1 or -1 this corresponds to i^{0} or i^{2}.  Given r_{h/i} takes on {0, 1} then
    we need to multiply by 2 get the correct power of $i$ for the Pauli Term to account for multiplication.

    In order to test we will generate random elements of P_{n} and then multiply them together keeping track of the
    $i$ power.  We will then compare this to the phase_accumulator subroutine.

    We have to load in the stabilizer into an empty qvmstab object because the subroutine needs a tableau as a reference
    """
    num_qubits = 2
    pauli_terms = [sX(0) * sX(1), sZ(0) * sZ(1)]
    stab_mat = pauli_stabilizer_to_binary_stabilizer(pauli_terms)
    qvmstab = QVM_Stabilizer(num_qubits=num_qubits)
    qvmstab.tableau[num_qubits:, :] = stab_mat
    exp_on_i = qvmstab._rowsum_phase_accumulator(2, 3)
    assert exp_on_i == 2

    num_qubits = 2
    pauli_terms = [sZ(0) * sI(1), sZ(0) * sZ(1)]
    stab_mat = pauli_stabilizer_to_binary_stabilizer(pauli_terms)
    qvmstab = QVM_Stabilizer(num_qubits=num_qubits)
    qvmstab.tableau[num_qubits:, :] = stab_mat
    exp_on_i = qvmstab._rowsum_phase_accumulator(2, 3)
    assert exp_on_i == 0

    # now try generating random valid elements from 2-qubit group
    for _ in range(100):
        num_qubits = 6
        pauli_terms = []
        for _ in range(num_qubits):
            pauli_terms.append(
                reduce(lambda x, y: x * y, [
                    pauli_subgroup[x](idx) for idx, x in enumerate(
                        np.random.randint(1, 4, num_qubits))
                ]))
        stab_mat = pauli_stabilizer_to_binary_stabilizer(pauli_terms)
        qvmstab = QVM_Stabilizer(num_qubits=num_qubits)
        qvmstab.tableau[num_qubits:, :] = stab_mat
        p_on_i = qvmstab._rowsum_phase_accumulator(num_qubits, num_qubits + 1)
        coeff_test = pauli_terms[1] * pauli_terms[0]
        assert np.isclose(coeff_test.coefficient, (1j)**p_on_i)
Example #18
0
def test_expectation(forest: ForestConnection):
    # The forest fixture (argument) to this test is to ensure this is
    # skipped when a forest web api key is unavailable. You could also
    # pass it to the constructor of WavefunctionSimulator() but it is not
    # necessary.
    wfnsim = WavefunctionSimulator()
    bell = Program(H(0), CNOT(0, 1))
    expects = wfnsim.expectation(bell, [sZ(0) * sZ(1), sZ(0), sZ(1), sX(0) * sX(1)])
    assert expects.size == 4
    np.testing.assert_allclose(expects, [1, 0, 0, 1])

    pauli_sum = PauliSum([sZ(0) * sZ(1)])
    expects = wfnsim.expectation(bell, pauli_sum)
    assert expects.size == 1
    np.testing.assert_allclose(expects, [1])
Example #19
0
def test_check_commutation_trivial_grouping():
    """
    Check grouping of trivial terms
    """
    commuting_set_one = sX(0) * sZ(1) + sY(2)
    commuting_set_two = PauliSum([sX(1)])
    hamiltonian = commuting_set_one + commuting_set_two
    commuting_sets = commuting_sets_trivial(hamiltonian)
    for comm_set in commuting_sets:
        if len(comm_set) == 2:
            true_set = set(map(lambda x: x.id(), commuting_set_one.terms))
            assert set(map(lambda x: x.id(), comm_set)) == true_set
        elif len(comm_set) == 1:
            true_set = set(map(lambda x: x.id(), commuting_set_two.terms))
            assert set(map(lambda x: x.id(), comm_set)) == true_set
Example #20
0
def test_group_experiments(grouping_method):
    expts = [  # cf above, I removed the inner nesting. Still grouped visually
        ExperimentSetting(TensorProductState(),
                          sX(0) * sI(1)),
        ExperimentSetting(TensorProductState(),
                          sI(0) * sX(1)),
        ExperimentSetting(TensorProductState(),
                          sZ(0) * sI(1)),
        ExperimentSetting(TensorProductState(),
                          sI(0) * sZ(1)),
    ]
    suite = Experiment(expts, Program())
    grouped_suite = group_settings(suite, method=grouping_method)
    assert len(suite) == 4
    assert len(grouped_suite) == 2
Example #21
0
def test_experiment_deser(tmpdir):
    expts = [
        [
            ExperimentSetting(TensorProductState(), sX(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sX(1)),
        ],
        [
            ExperimentSetting(TensorProductState(), sZ(0) * sI(1)),
            ExperimentSetting(TensorProductState(), sI(0) * sZ(1)),
        ],
    ]

    suite = Experiment(settings=expts, program=Program(X(0), Y(1)))
    to_json(f"{tmpdir}/suite.json", suite)
    suite2 = read_json(f"{tmpdir}/suite.json")
    assert suite == suite2
Example #22
0
def test_experiment_result():
    er = ExperimentResult(
        setting=ExperimentSetting(sX(0), sZ(0)),
        expectation=0.9,
        stddev=0.05,
    )
    assert str(er) == '(1+0j)*X0→(1+0j)*Z0: 0.9 +- 0.05'
Example #23
0
def test_measure_observables(forest):
    expts = [
        ExperimentSetting(sI(), o1 * o2)
        for o1, o2 in itertools.product([sI(0), sX(0), sY(0), sZ(0)], [sI(1), sX(1), sY(1), sZ(1)])
    ]
    suite = TomographyExperiment(expts, program=Program(X(0), CNOT(0, 1)), qubits=[0, 1])
    assert len(suite) == 4 * 4
    gsuite = group_experiments(suite)
    assert len(gsuite) == 3 * 3  # can get all the terms with I for free in this case

    qc = get_qc('2q-qvm')
    for res in measure_observables(qc, gsuite, n_shots=10_000):
        if res.setting.out_operator in [sI(), sZ(0), sZ(1), sZ(0) * sZ(1)]:
            assert np.abs(res.expectation) > 0.9
        else:
            assert np.abs(res.expectation) < 0.1
Example #24
0
def test_qc_expectation_on_qvm(client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler):
    # regression test for https://github.com/rigetti/forest-tutorials/issues/2
    qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler)

    p = Program()
    theta = p.declare("theta", "REAL")
    p += RESET()
    p += RY(theta, 0)
    p.wrap_in_numshots_loop(10000)

    sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0)), out_operator=sX(0))
    e = Experiment(settings=[sx], program=p)

    thetas = [-np.pi / 2, 0.0, np.pi / 2]
    results = []

    # Verify that multiple calls to qc.experiment with the same experiment backed by a QVM that
    # requires_exectutable does not raise an exception.
    for theta in thetas:
        results.append(qc.experiment(e, memory_map={"theta": [theta]}))

    assert np.isclose(results[0][0].expectation, -1.0, atol=0.01)
    assert np.isclose(results[0][0].std_err, 0)
    assert results[0][0].total_counts == 20000

    # bounds on atol and std_err here are a little loose to try and avoid test flakiness.
    assert np.isclose(results[1][0].expectation, 0.0, atol=0.1)
    assert results[1][0].std_err < 0.01
    assert results[1][0].total_counts == 20000

    assert np.isclose(results[2][0].expectation, 1.0, atol=0.01)
    assert np.isclose(results[2][0].std_err, 0)
    assert results[2][0].total_counts == 20000
def test_for_negative_probabilities():
    # trivial program to do state tomography on
    prog = Program(I(0))

    # make TomographyExperiment
    expt_settings = [ExperimentSetting(zeros_state([0]), pt) for pt in [sI(0), sX(0), sY(0), sZ(0)]]
    experiment_1q = TomographyExperiment(settings=expt_settings, program=prog)

    # make a quantum computer object
    device = NxDevice(nx.complete_graph(1))
    qc_density = QuantumComputer(
        name="testy!",
        qam=PyQVM(n_qubits=1, quantum_simulator_type=ReferenceDensitySimulator),
        device=device,
        compiler=DummyCompiler(),
    )

    # initialize with a pure state
    initial_density = np.array([[1.0, 0.0], [0.0, 0.0]])
    qc_density.qam.wf_simulator.density = initial_density

    try:
        list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000))
    except ValueError as e:
        # the error is from np.random.choice by way of self.rs.choice in ReferenceDensitySimulator
        assert str(e) != "probabilities are not non-negative"

    # initialize with a mixed state
    initial_density = np.array([[0.9, 0.0], [0.0, 0.1]])
    qc_density.qam.wf_simulator.density = initial_density

    try:
        list(measure_observables(qc=qc_density, tomo_experiment=experiment_1q, n_shots=3000))
    except ValueError as e:
        assert str(e) != "probabilities are not non-negative"
Example #26
0
def benchmarker():
    try:
        bm = get_benchmarker(timeout=2)
        bm.apply_clifford_to_pauli(Program(I(0)), sX(0))
        return bm
    except (RequestException, TimeoutError) as e:
        return pytest.skip("This test requires a running local benchmarker endpoint (ie quilc): {}"
                           .format(e))
Example #27
0
def test_stats_from_measurements():
    d_results = {0: np.array([0] * 10), 1: np.array([1] * 10)}
    setting = ExperimentSetting(TensorProductState(), sZ(0) * sX(1))
    n_shots = 1000

    obs_mean, obs_var = _stats_from_measurements(d_results, setting, n_shots)
    assert obs_mean == -1.0
    assert obs_var == 0.0
Example #28
0
def test_tomo_experiment_pre_grouped():
    expts = [
        [ExperimentSetting(sI(), sX(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sX(1))],
        [ExperimentSetting(sI(), sZ(0) * sI(1)), ExperimentSetting(sI(), sI(0) * sZ(1))],
    ]

    suite = TomographyExperiment(
        settings=expts,
        program=Program(X(0), Y(1)),
        qubits=[0, 1]
    )
    assert len(suite) == 2  # number of groups
    for es1, es2 in zip(expts, suite):
        for e1, e2 in zip(es1, es2):
            assert e1 == e2
    prog_str = str(suite).splitlines()[0]
    assert prog_str == 'X 0; Y 1'
Example #29
0
def test_experiment_result_compat():
    er = ExperimentResult(
        setting=ExperimentSetting(sX(0), sZ(0)),
        expectation=0.9,
        stddev=0.05,
        total_counts=100,
    )
    assert str(er) == 'X0_0→(1+0j)*Z0: 0.9 +- 0.05'
Example #30
0
def test_is_identity():
    pt1 = -1.5j * sI(2)
    pt2 = 1.5 * sX(1) * sZ(2)

    assert is_identity(pt1)
    assert is_identity(pt2 + (-1 * pt2) + sI(0))
    assert not is_identity(0 * pt1)
    assert not is_identity(pt2 + (-1 * pt2))
Example #31
0
from pyquil.paulis import ID, sX, sY, sZ
from pyquil import *
from pyquil.gates import H

import pyquil.paulis as pl

# Pauli term takes an operator "X", "Y", "Z", or "I"; a qubit to act on, and
# an optional coefficient.
a = 1 * ID()
b = -0.75 * sX(0) * sY(1) * sZ(3)
c = (5-2j) * sZ(1) * sX(2)

# Construct a sum of Pauli terms.
sigma = a + b + c
print("sigma = {}".format(sigma))
p = Program()
p.inst(pl.exponentiate_commuting_pauli_sum(sigma))

print(p)