Ejemplo n.º 1
0
def _measure_list_of_pauli_terms(pauli_terms, variance_bound, program,
                                 quantum_resource):
    """
    Measure the expected value of a list of Pauli terms and return as a dict

    :param pauli_terms: Pauli Terms to measure
    :param variance_bound: variance bound for measurement.  Right now this is
                           the bound on the variance if you summed up all the
                           individual terms. 1.0E-6 is a good place to start.
    :param program: pyquil Program preparing state
    :param quantum_resource: quantum abstract machine connection object
    :return: results dictionary where the key is the Pauli term ID and the value
             is the expected value
    """
    # group them into commuting sets and then measure
    grouped_terms = commuting_sets_by_zbasis(sum(pauli_terms))

    # measure the terms
    result_dictionary = {}
    for key, terms in grouped_terms.items():
        pauli_sum, identity_term = remove_identity(terms)
        if isinstance(identity_term, int):
            # no identity term
            pass
        elif isinstance(identity_term, PauliSum):
            result_dictionary[identity_term[0].id()] = 1.0
        else:
            print(identity_term, type(identity_term))
            raise TypeError("This type is not recognized for identity_term")

        results = estimate_pauli_sum(pauli_sum, dict(key), program,
                                     variance_bound / len(terms),
                                     quantum_resource)
        for idx, term in enumerate(pauli_sum.terms):
            result_dictionary[term.id()] = results.pauli_expectations[idx] / \
                                           term.coefficient
    return result_dictionary
Ejemplo n.º 2
0
def test_estimate_pauli_sum():
    """
    Full test of the estimation procedures
    """
    quantum_resource = QVMConnection()

    # type checks
    with pytest.raises(TypeError):
        estimate_pauli_sum('5', {0: 'X', 1: 'Z'}, Program(), 1.0E-3,
                           quantum_resource)

    with pytest.raises(CommutationError):
        estimate_pauli_sum([sX(0), sY(0)], {0: 'X', 1: 'Z'}, Program(), 1.0E-3,
                           quantum_resource)

    with pytest.raises(TypeError):
        estimate_pauli_sum(sX(0), {0: 'X', 1: 'Z'}, Program(), 1.0E-3,
                           quantum_resource)

    # mock out qvm
    np.random.seed(87655678)
    brv1 = bernoulli(p=0.25)
    brv2 = bernoulli(p=0.4)
    n = 500
    two_qubit_measurements = list(zip(brv1.rvs(size=n), brv2.rvs(size=n)))
    pauli_terms = [sZ(0), sZ(1), sZ(0) * sZ(1)]

    fakeQVM = Mock(spec=QVMConnection())
    fakeQVM.run = Mock(return_value=two_qubit_measurements)
    mean, means, cov, estimator_var, shots = estimate_pauli_sum(pauli_terms,
                                                         {0: 'Z', 1: 'Z'},
                                                         Program(),
                                                         1.0E-1, fakeQVM)
    parity_results = np.zeros((len(pauli_terms), n))
    parity_results[0, :] = [-2 * x[0] + 1 for x in two_qubit_measurements]
    parity_results[1, :] = [-2 * x[1] + 1 for x in two_qubit_measurements]
    parity_results[2, :] = [-2 * (sum(x) % 2) + 1 for x in
                            two_qubit_measurements]

    assert np.allclose(np.cov(parity_results), cov)
    assert np.isclose(np.sum(np.mean(parity_results, axis=1)), mean)
    assert np.allclose(np.mean(parity_results, axis=1), means)
    assert np.isclose(shots, n)
    variance_to_beat = np.sum(cov) / n
    assert np.isclose(variance_to_beat, estimator_var)

    # Double the shots by ever so slightly decreasing variance bound
    double_two_q_measurements = two_qubit_measurements + two_qubit_measurements
    mean, means, cov, estimator_var, shots = estimate_pauli_sum(pauli_terms,
                                                         {0: 'Z', 1: 'Z'},
                                                         Program(),
                                                         variance_to_beat - \
                                                         1.0E-8, fakeQVM)

    parity_results = np.zeros((len(pauli_terms), 2 * n))
    parity_results[0, :] = [-2 * x[0] + 1 for x in double_two_q_measurements]
    parity_results[1, :] = [-2 * x[1] + 1 for x in double_two_q_measurements]
    parity_results[2, :] = [-2 * (sum(x) % 2) + 1 for x in
                            double_two_q_measurements]

    assert np.allclose(np.cov(parity_results), cov)
    assert np.isclose(np.sum(np.mean(parity_results, axis=1)), mean)
    assert np.allclose(np.mean(parity_results, axis=1), means)
    assert np.isclose(shots, 2 * n)
    assert np.isclose(np.sum(cov) / (2 * n), estimator_var)
Ejemplo n.º 3
0
def test_estimate_pauli_sum():
    """
    Full test of the estimation procedures
    """
    quantum_resource = Mock(QuantumComputer)

    # type checks
    with pytest.raises(TypeError):
        estimate_pauli_sum('5', {
            0: 'X',
            1: 'Z'
        }, Program(), 1.0E-3, quantum_resource)

    with pytest.raises(CommutationError):
        estimate_pauli_sum([sX(0), sY(0)], {
            0: 'X',
            1: 'Z'
        }, Program(), 1.0E-3, quantum_resource)

    with pytest.raises(TypeError):
        estimate_pauli_sum(sX(0), {
            0: 'X',
            1: 'Z'
        }, Program(), 1.0E-3, quantum_resource)

    # mock out qvm
    np.random.seed(87655678)
    brv1 = bernoulli(p=0.25)
    brv2 = bernoulli(p=0.4)
    n = 500
    two_qubit_measurements = list(zip(brv1.rvs(size=n), brv2.rvs(size=n)))
    pauli_terms = [sZ(0), sZ(1), sZ(0) * sZ(1)]

    with patch("pyquil.api.QuantumComputer") as qc:
        # Mock the response
        qc.run.return_value = two_qubit_measurements

    mean, means, cov, estimator_var, shots = \
        estimate_pauli_sum(pauli_terms,
                           basis_transform_dict={0: 'Z', 1: 'Z'},
                           program=Program(),
                           variance_bound=1.0E-1,
                           quantum_resource=qc)

    parity_results = np.zeros((len(pauli_terms), n))
    parity_results[0, :] = [-2 * x[0] + 1 for x in two_qubit_measurements]
    parity_results[1, :] = [-2 * x[1] + 1 for x in two_qubit_measurements]
    parity_results[2, :] = [
        -2 * (sum(x) % 2) + 1 for x in two_qubit_measurements
    ]

    assert np.allclose(np.cov(parity_results), cov)
    assert np.isclose(np.sum(np.mean(parity_results, axis=1)), mean)
    assert np.allclose(np.mean(parity_results, axis=1), means)
    assert np.isclose(shots, n)
    variance_to_beat = np.sum(cov) / n
    assert np.isclose(variance_to_beat, estimator_var)

    # Double the shots by ever so slightly decreasing variance bound
    double_two_q_measurements = two_qubit_measurements + two_qubit_measurements
    mean, means, cov, estimator_var, shots = \
        estimate_pauli_sum(pauli_terms,
                           basis_transform_dict={0: 'Z', 1: 'Z'},
                           program=Program(),
                           variance_bound=variance_to_beat - 1.0E-8,
                           quantum_resource=qc)

    parity_results = np.zeros((len(pauli_terms), 2 * n))
    parity_results[0, :] = [-2 * x[0] + 1 for x in double_two_q_measurements]
    parity_results[1, :] = [-2 * x[1] + 1 for x in double_two_q_measurements]
    parity_results[2, :] = [
        -2 * (sum(x) % 2) + 1 for x in double_two_q_measurements
    ]

    assert np.allclose(np.cov(parity_results), cov)
    assert np.isclose(np.sum(np.mean(parity_results, axis=1)), mean)
    assert np.allclose(np.mean(parity_results, axis=1), means)
    assert np.isclose(shots, 2 * n)
    assert np.isclose(np.sum(cov) / (2 * n), estimator_var)