Пример #1
0
def test_term_grouping():
    """
    Test clumping terms into terms that share the same diagonal basis
    """
    x_term = sX(0) * sX(1)
    z1_term = sZ(1)
    z2_term = sZ(0)
    zz_term = sZ(0) * sZ(1)
    h2_hamiltonian = zz_term + z2_term + z1_term + x_term
    clumped_terms = commuting_sets_by_zbasis(h2_hamiltonian)
    true_set = {
        ((0, 'X'), (1, 'X')): set([x_term.id()]),
        ((0, 'Z'), (1, 'Z')): set([z1_term.id(),
                                   z2_term.id(),
                                   zz_term.id()])
    }

    for key, value in clumped_terms.items():
        assert set(map(lambda x: x.id(), clumped_terms[key])) == true_set[key]

    zzzz_terms = sZ(1) * sZ(2) + sZ(3) * sZ(4) + \
                 sZ(1) * sZ(3) + sZ(1) * sZ(3) * sZ(4)
    xzxz_terms = sX(1) * sZ(2) + sX(3) * sZ(4) + \
                 sX(1) * sZ(2) * sX(3) * sZ(4) + sX(1) * sX(3) * sZ(4)
    xxxx_terms = sX(1) * sX(2) + sX(2) + sX(3) * sX(4) + sX(4) + \
                 sX(1) * sX(3) * sX(4) + sX(1) * sX(4) + sX(1) * sX(2) * sX(3)
    yyyy_terms = sY(1) * sY(2) + sY(3) * sY(4) + sY(1) * sY(2) * sY(3) * sY(4)

    pauli_sum = zzzz_terms + xzxz_terms + xxxx_terms + yyyy_terms
    clumped_terms = commuting_sets_by_zbasis(pauli_sum)

    true_set = {
        ((1, 'Z'), (2, 'Z'), (3, 'Z'), (4, 'Z')):
        set(map(lambda x: x.id(), zzzz_terms)),
        ((1, 'X'), (2, 'Z'), (3, 'X'), (4, 'Z')):
        set(map(lambda x: x.id(), xzxz_terms)),
        ((1, 'X'), (2, 'X'), (3, 'X'), (4, 'X')):
        set(map(lambda x: x.id(), xxxx_terms)),
        ((1, 'Y'), (2, 'Y'), (3, 'Y'), (4, 'Y')):
        set(map(lambda x: x.id(), yyyy_terms))
    }
    for key, value in clumped_terms.items():
        assert set(map(lambda x: x.id(), clumped_terms[key])) == true_set[key]
Пример #2
0
def test_term_grouping_weird_term():
    term1 = PauliTerm.from_list([('X', 1), ('Z', 2), ('Y', 3), ('Y', 5),
                                 ('Z', 6), ('X', 7)],
                                coefficient=0.012870253243021476)

    term2 = PauliTerm.from_list([('Z', 0), ('Z', 6)],
                                coefficient=0.13131672212575296)

    term_dictionary = commuting_sets_by_zbasis(term1 + term2)
    true_term_key = ((0, 'Z'), (1, 'X'), (2, 'Z'), (3, 'Y'), (5, 'Y'),
                     (6, 'Z'), (7, 'X'))
    assert list(term_dictionary.keys())[0] == true_term_key
Пример #3
0
def estimate_locally_commuting_operator(
        program: Program, pauli_sum: PauliSum, variance_bound: float,
        quantum_resource: QuantumComputer) -> Tuple[float, float, int]:
    """
    Estimate the expected value of a Pauli sum to fixed precision.

    :param program: The state preparation program.
    :param pauli_sum: The pauli sum of operators to estimate expected value.
    :param variance_bound: The variance bound on the estimator.
    :param quantum_resource: The QuantumComputer object to address.
    :return: expected value, estimator variance, total number of experiments.
    """
    pauli_sum, identity_term = remove_identity(pauli_sum)
    psets = commuting_sets_by_zbasis(pauli_sum)
    variance_bound_per_set = variance_bound / len(psets)

    if isinstance(identity_term, int):
        if np.isclose(identity_term, 0):
            expected_value = 0
        else:
            expected_value = identity_term

    elif isinstance(identity_term, (PauliTerm, PauliSum)):
        if isinstance(identity_term, PauliTerm):
            expected_value = identity_term.coefficient
        else:
            expected_value = identity_term[0].coefficient
    else:
        print(type(identity_term))
        raise TypeError("identity_term must be a PauliTerm or integer")

    total_shots = 0
    estimator_variance = 0

    for qubit_op_key, pset in psets.items():
        results = estimate_pauli_sum(pset,
                                     dict(qubit_op_key),
                                     program,
                                     variance_bound_per_set,
                                     quantum_resource,
                                     commutation_check=False)

        expected_value += results.expected_value
        total_shots += results.n_shots
        estimator_variance += results.variance

    return expected_value, estimator_variance, total_shots
Пример #4
0
def estimate_locally_commuting_operator(program, pauli_sum, variance_bound,
                                        quantum_resource):
    """
    Estimate the expected value of a Pauli sum to fixed precision

    :param program: state preparation program
    :param pauli_sum: pauli sum of operators to estimate expected value
    :param variance_bound: variance bound on the estimator
    :param quantum_resource: quantum abstract machine object
    :return: expected value, estimator variance, total number of experiments
    """
    pauli_sum, identity_term = remove_identity(pauli_sum)
    psets = commuting_sets_by_zbasis(pauli_sum)
    variance_bound_per_set = variance_bound / len(psets)

    if isinstance(identity_term, int):
        if np.isclose(identity_term, 0):
            expected_value = 0
        else:
            expected_value = identity_term

    elif isinstance(identity_term, (PauliTerm, PauliSum)):
        if isinstance(identity_term, PauliTerm):
            expected_value = identity_term.coefficient
        else:
            expected_value = identity_term[0].coefficient
    else:
        print(type(identity_term))
        raise TypeError("identity_term must be a PauliTerm or integer")

    total_shots = 0
    estimator_variance = 0

    for qubit_op_key, pset in psets.items():
        results = estimate_pauli_sum(pset,
                                     dict(qubit_op_key),
                                     program,
                                     variance_bound_per_set,
                                     quantum_resource,
                                     commutation_check=False)

        expected_value += results[0].real
        total_shots += results[3]
        estimator_variance += results[2]

    return expected_value, estimator_variance, total_shots
Пример #5
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