Exemple #1
0
def test_construct_opdm():
    """
    Test the construction of one-particle density matrix

    <psi|a_{p}^{\dagger}a_{q}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    dim = molecule.n_qubits
    opdm_a = np.zeros((int(dim/2), int(dim/2)), dtype=complex)
    opdm_b = np.zeros((int(dim/2), int(dim/2)), dtype=complex)

    for p, q in product(range(int(dim/2)), repeat=2):
        pauli_proj_op = transform(FermionOperator(((2 * p, 1), (2 * q, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        opdm_element = np.trace(lifted_op.dot(rho))
        opdm_a[p, q] = opdm_element

        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 1), (2 * q + 1, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        opdm_element = np.trace(lifted_op.dot(rho))
        opdm_b[p, q] = opdm_element

    opdm_a_test, opdm_b_test = rdm_generator.construct_opdm()
    assert np.allclose(opdm_b, opdm_b_test)
    assert np.allclose(opdm_a, opdm_a_test)
    opdm_b_test = rdm_generator._tensor_construct(2, [-1, 1], [1, 1])
    assert np.allclose(opdm_b_test, opdm_b)
    opdm_a_test = rdm_generator._tensor_construct(2, [-1, 1], [0, 0])
    assert np.allclose(opdm_a_test, opdm_a)
Exemple #2
0
def test_construct_phdm():
    """
    Construct the particle-hole density matrix

    <psi|a_{p}^{\dagger}a_{q}a_{s}^{\dagger}a_{r}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    dim = molecule.n_qubits
    phdm = np.zeros((dim, dim, dim, dim), dtype=complex)
    for p, q, r, s in product(range(dim), repeat=4):
        pauli_proj_op = transform(
            FermionOperator(((p, 1), (q, 0), (s, 1), (r, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        phdm[p, q, r, s] = phdm_element

    phdm_test = rdm_generator._tensor_construct(4, [-1, 1, -1, 1])
    assert np.allclose(phdm_test, phdm)

    phdm_true = map_two_pdm_to_particle_hole_dm(molecule.fci_two_rdm,
                                                molecule.fci_one_rdm)
    phdm_true = np.einsum('ijkl->ijlk', phdm_true)
    assert np.allclose(phdm_true, phdm)
Exemple #3
0
def test_qubitop_to_paulisum_zero():

    identity_term = QubitOperator()
    forest_term = qubitop_to_pyquilpauli(identity_term)
    ground_truth = PauliTerm("I", 0, 0)

    assert ground_truth == forest_term
Exemple #4
0
def pauli_terms_for_tpdm_aa(spatial_dim, transform=jordan_wigner):
    """
    Generate a set of pauli operators to measure to evaluate the alpha-alpha
    block of the 2-RDM

    Given a dictionary of expected values of Pauli terms, populate the
    alpha-beta block of the 2-RDM

    :param Int spatial_dim: Dimension of the spatial-orbital basis.
    :param transform: fermion-to-qubit transform from OpenFermion
    :return: List of PauliTerms that corresponds to set of pauli terms to
             measure to construct the 2-RDM.
    """
    # build basis lookup table
    bas_aa = {}
    cnt_aa = 0
    for p, q in product(range(spatial_dim), repeat=2):
        if q < p:
            bas_aa[(p, q)] = cnt_aa
            cnt_aa += 1

    pauli_terms_to_measure = []
    pauli_to_rdm = {}
    for p, q, r, s in product(range(spatial_dim), repeat=4):
        if p < q and s < r:
            # generator 1/sqrt(2) * (a_{p, \alpha}^{\dagger}
            # a_{q, \alpha}^{\dagger} -
            # a_{p, \beta}^{\dagger}a_{q, \beta}^{\dagger})
            spin_adapted_term = FermionOperator(
                ((2 * p, 1), (2 * q, 1), (2 * r, 0), (2 * s, 0))) - \
                                FermionOperator(((2 * p, 1), (2 * q, 1),
                                                 (2 * s, 0), (2 * r, 0))) - \
                                FermionOperator(((2 * q, 1), (2 * p, 1),
                                                 (2 * r, 0), (2 * s, 0))) + \
                                FermionOperator(((2 * q, 1), (2 * p, 1),
                                                 (2 * s, 0), (2 * r, 0)))
            spin_adapted_term *= 0.5

            tpdm_element_as_pauli = remove_imaginary_terms(
                qubitop_to_pyquilpauli(transform(spin_adapted_term)))
            for term in tpdm_element_as_pauli:
                pauli_terms_to_measure.append(term)

    for term in pauli_terms_to_measure:
        # convert term into numerically order pauli tensor term
        pauli_tensor_list = sorted(list(term.operations_as_set()),
                                   key=lambda x: x[0])
        rev_order_pauli_tensor_list = list(
            map(lambda x: (x[1], x[0]), pauli_tensor_list))
        pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                         coefficient=term.coefficient)

        if pauli_term.id() not in pauli_to_rdm.keys():
            pauli_to_rdm[pauli_term.id()] = pauli_term
        else:
            if (abs(pauli_to_rdm[pauli_term.id()].coefficient) < abs(
                    pauli_term.coefficient)):
                pauli_to_rdm[pauli_term.id()] = pauli_term

    return list(pauli_to_rdm.values())
def TimeEvolution(time, hamiltonian):
    """
    Time evolve a hamiltonian

    Converts the Hamiltonian to an instance of the pyQuil Pauliterms and returns the time evolution
    operator. This method mirrors the ProjectQ TimeEvolution interface.

    :param [float, int] time: time to evolve
    :param QubitOperator hamiltonian: a Hamiltonian as a OpenFermion QubitOperator
    :return: a pyquil Program representing the Hamiltonian
    :rtype: Program
    """
    if not isinstance(time, (int, float)):
        raise TypeError("float must be a float or an int")
    if not isinstance(hamiltonian, QubitOperator):
        raise TypeError("hamiltonian must be an OpenFermion "
                        "QubitOperator object")

    pyquil_pauli_term = qubitop_to_pyquilpauli(hamiltonian)
    pyquil_pauli_term *= time
    prog = Program()
    for term in pyquil_pauli_term.terms:
        prog += pyquil_exponentiate(term)

    return prog
Exemple #6
0
def pauli_to_tpdm_bb(spatial_dim, pauli_to_coeff, transform=jordan_wigner):
    """
    Populate the beta-beta block of the 2-RDM

    :param Int spatial_dim: spatial basis set rank
    :param pauli_to_coeff: a map between the Pauli term label to the expected
                           value.
    :param transform: Openfermion fermion-to-qubit transform
    :return: the 2-RDM alpha-beta block of the 2-RDM
    """
    aa_dim = int(spatial_dim * (spatial_dim - 1) / 2)
    d2_aa = np.zeros((aa_dim, aa_dim), dtype=complex)

    # build basis lookup table
    bas_aa = {}
    cnt_aa = 0
    for p, q in product(range(spatial_dim), repeat=2):
        if p < q:
            bas_aa[(p, q)] = cnt_aa
            cnt_aa += 1

    for p, q, r, s in product(range(spatial_dim), repeat=4):
        if p < q and s < r:
            # generator 1/sqrt(2) * (a_{p, \alpha}^{\dagger}
            # a_{q, \alpha}^{\dagger} -
            # a_{p, \beta}^{\dagger}a_{q, \beta}^{\dagger})
            spin_adapted_term = FermionOperator(((2 * p + 1, 1), (2 * q + 1, 1),
                                                 (2 * r + 1, 0),
                                                 (2 * s + 1, 0))) - \
                                FermionOperator(((2 * p + 1, 1), (2 * q + 1, 1),
                                                 (2 * s + 1, 0),
                                                 (2 * r + 1, 0))) - \
                                FermionOperator(((2 * q + 1, 1), (2 * p + 1, 1),
                                                 (2 * r + 1, 0),
                                                 (2 * s + 1, 0))) + \
                                FermionOperator(((2 * q + 1, 1), (2 * p + 1, 1),
                                                 (2 * s + 1, 0),
                                                 (2 * r + 1, 0)))
            spin_adapted_term *= 0.5

            tpdm_element_as_pauli = remove_imaginary_terms(
                qubitop_to_pyquilpauli(transform(spin_adapted_term)))

            for term in tpdm_element_as_pauli:
                pauli_tensor_list = sorted(list(term.operations_as_set()),
                                           key=lambda x: x[0])
                rev_order_pauli_tensor_list = list(
                    map(lambda x: (x[1], x[0]), pauli_tensor_list))
                pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                                 coefficient=term.coefficient)
                try:
                    d2_aa[bas_aa[(p, q)], bas_aa[(s, r)]] += pauli_to_coeff[
                                                        pauli_term.id()] * \
                                                        pauli_term.coefficient
                except KeyError:
                    raise Warning("key was not in the coeff matrix.")
    return d2_aa
Exemple #7
0
def test_qubitop_to_paulisum():
    """
    Conversion of QubitOperator; accuracy test
    """
    hop_term = FermionOperator(((2, 1), (0, 0)))
    term = hop_term + hermitian_conjugated(hop_term)

    pauli_term = jordan_wigner(term)

    forest_term = qubitop_to_pyquilpauli(pauli_term)
    ground_truth = PauliTerm("X", 0) * PauliTerm("Z", 1) * PauliTerm("X", 2)
    ground_truth += PauliTerm("Y", 0) * PauliTerm("Z", 1) * PauliTerm("Y", 2)
    ground_truth *= 0.5

    assert ground_truth == forest_term
Exemple #8
0
def pauli_terms_for_tpdm_ab(spatial_dim, transform=jordan_wigner):
    """
    Build the alpha-beta block of the 2-RDM

    Note: OpenFermion ordering is used.  The 2-RDM(alpha-beta) block
          is spatial_dim**2 linear size. (DOI: 10.1021/acs.jctc.6b00190)

    :param spatial_dim: rank of spatial orbitals in the basis set.
    :param transform: type of fermion-to-qubit transformation.
    :return: list of Pauli terms to measure required to construct a the alpha-
             beta block.
    """
    # build basis look up table
    bas_ab = {}
    cnt_ab = 0
    # iterate over spatial orbital indices
    for p, q in product(range(spatial_dim), repeat=2):
        bas_ab[(p, q)] = cnt_ab
        cnt_ab += 1

    pauli_terms_to_measure = []
    pauli_to_rdm = {}
    for p, q, r, s in product(range(spatial_dim), repeat=4):
        spin_adapted_term = FermionOperator(
            ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)))

        tpdm_element_as_pauli = remove_imaginary_terms(
            qubitop_to_pyquilpauli(transform(spin_adapted_term)))
        for term in tpdm_element_as_pauli:
            pauli_terms_to_measure.append(term)

    for term in pauli_terms_to_measure:
        # convert term into numerically order pauli tensor term
        pauli_tensor_list = sorted(list(term.operations_as_set()),
                                   key=lambda x: x[0])
        rev_order_pauli_tensor_list = list(
            map(lambda x: (x[1], x[0]), pauli_tensor_list))
        pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                         coefficient=term.coefficient)

        if pauli_term.id() not in pauli_to_rdm.keys():
            pauli_to_rdm[pauli_term.id()] = pauli_term
        else:
            if (abs(pauli_to_rdm[pauli_term.id()].coefficient) < abs(
                    pauli_term.coefficient)):
                pauli_to_rdm[pauli_term.id()] = pauli_term

    return list(pauli_to_rdm.values())
Exemple #9
0
def test_construct_opdm():
    """
    Test the construction of one-particle density matrix

    <psi|a_{p}^{\dagger}a_{q}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    opdm = np.zeros((molecule.n_qubits, molecule.n_qubits), dtype=complex)
    for p, q in product(range(molecule.n_qubits), repeat=2):
        pauli_proj_op = transform(FermionOperator(((p, 1), (q, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        opdm_element = np.trace(lifted_op.dot(rho))
        opdm[p, q] = opdm_element

    assert np.allclose(molecule.fci_one_rdm, opdm)

    opdm_test = rdm_generator._tensor_construct(2, [-1, 1])
    assert np.allclose(opdm_test, molecule.fci_one_rdm)
Exemple #10
0
def pauli_to_tpdm_ab(spatial_dim, pauli_to_coeff, transform=jordan_wigner):
    """
    Populate the alpha-beta block of the 2-RDM

    Given a dictionary of expected values of Pauli terms, populate the
    alpha-beta block of the 2-RDM

    :param Int spatial_dim: spatial basis set rank
    :param pauli_to_coeff: a map between the Pauli term label to the expected
                           value.
    :param transform: Openfermion fermion-to-qubit transform
    :return: the 2-RDM alpha-beta block of the 2-RDM
    """
    d2_ab = np.zeros((spatial_dim**2, spatial_dim**2), dtype=complex)
    # build basis look up table
    bas_ab = {}
    cnt_ab = 0
    # iterate over spatial orbital indices
    for p, q in product(range(spatial_dim), repeat=2):
        bas_ab[(p, q)] = cnt_ab
        cnt_ab += 1

    for p, q, r, s in product(range(spatial_dim), repeat=4):
        spin_adapted_term = FermionOperator(
            ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)))

        tpdm_element_as_pauli = remove_imaginary_terms(
            qubitop_to_pyquilpauli(transform(spin_adapted_term)))

        for term in tpdm_element_as_pauli:
            pauli_tensor_list = sorted(list(term.operations_as_set()),
                                       key=lambda x: x[0])
            rev_order_pauli_tensor_list = list(
                map(lambda x: (x[1], x[0]), pauli_tensor_list))
            pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                             coefficient=term.coefficient)
            try:
                d2_ab[bas_ab[(p, q)], bas_ab[(s, r)]] += pauli_to_coeff[
                                                         pauli_term.id()] * \
                                                         pauli_term.coefficient
            except KeyError:
                raise Warning("key was not in the coeff matrix.")
    return d2_ab
Exemple #11
0
def test_construct_ohdm():
    """
    Test the construction of the one-hole density matrix

    <psi|a_{p}a_{q}^{\dagger}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    dim = molecule.n_qubits
    ohdm = np.zeros((dim, dim), dtype=complex)
    for p, q in product(range(dim), repeat=2):
        pauli_proj_op = transform(FermionOperator(((p, 0), (q, 1))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        ohdm_element = np.trace(lifted_op.dot(rho))
        ohdm[p, q] = ohdm_element

    ohdm_true = np.eye(4) - molecule.fci_one_rdm
    assert np.allclose(ohdm_true, ohdm)
    ohdm_test = rdm_generator._tensor_construct(2, [1, -1])
    assert np.allclose(ohdm_test, ohdm_true)
Exemple #12
0
def pauli_to_tpdm(dim, pauli_to_coeff, transform=jordan_wigner):
    """
    Construct the 2-RDM from expected values of Pauli operators

    Construct the 2-RDM by looping over the 2-RDM and loading up the
    coefficients for the expected values of each transformed Pauli operator.
    We assume the fermionic ladder operators are transformed via Jordan-Wigner.
    This constraint can be relaxed later.

    We don't check that the `pauli_expected` dictionary contains an
    informationally complete set of expected values.  This is useful for
    testing if under sampling the 2-RDM is okay if a projection technique is
    included in the calculation.

    :param Int dim: spin-orbital basis dimension
    :param Dict pauli_to_coeff: a map from pauli term ID's to
    :param func transform: optional argument defining how to transform
                           fermionic operators into Pauli operators
    """
    tpdm = np.zeros((dim, dim, dim, dim), dtype=complex)
    for p, q, r, s in product(range(dim), repeat=4):
        if p != q and r != s:
            tpdm_element = FermionOperator(((p, 1), (q, 1), (r, 0), (s, 0)))
            tpdm_element_as_pauli = remove_imaginary_terms(
                qubitop_to_pyquilpauli(transform(tpdm_element)))

            for term in tpdm_element_as_pauli:
                pauli_tensor_list = sorted(list(term.operations_as_set()),
                                           key=lambda x: x[0])
                rev_order_pauli_tensor_list = list(
                    map(lambda x: (x[1], x[0]), pauli_tensor_list))
                pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                                 coefficient=term.coefficient)
                try:
                    tpdm[p, q, r, s] += pauli_to_coeff[pauli_term.id()] * \
                                        pauli_term.coefficient
                except KeyError:
                    raise Warning("key was not in the coeff matrix.")
    return tpdm
def exponentiate(qubit_operator):
    """
    Generates a pyquil program corresponding to the QubitOperator generator.

    The OpenFermion qubit operator is translated to a pyQuil PauliSum which, in turn, is passed to
    the `exponentiate' method. The `exponentiate' method generates a circuit that can be simulated
    with the Forest-qvm or associated QVMs.

    :param QubitOperator qubit_operator: Generator of rotations
    :return: a pyQuil program representing the unitary evolution
    :rtype: Program
    """
    if not isinstance(qubit_operator, QubitOperator):
        raise TypeError("qubit_operator must be an OpenFermion "
                        "QubitOperator type")

    pauli_sum_representation = qubitop_to_pyquilpauli(qubit_operator)
    prog = Program()
    for term in pauli_sum_representation.terms:
        prog += pyquil_exponentiate(term)

    return prog
Exemple #14
0
def pauli_terms_for_tpdm(dim, transform=jordan_wigner):
    """
    Generate a set of pauli operators to measure to evaluate the 2-RDM

    :param Int dim: Dimension of the spin-orbital basis.
    :param transform: fermion-to-qubit transform from OpenFermion
    :return: List of PauliTerms that corresponds to set of pauli terms to
             measure to construct the 2-RDM.
    """

    # first make a map between pauli terms and elements of the 2-RDM
    pauli_to_rdm = {}
    pauli_terms_to_measure = []
    for p, q, r, s in product(range(dim), repeat=4):
        if p != q and r != s:
            tpdm_element = FermionOperator(((p, 1), (q, 1), (r, 0), (s, 0)))
            tpdm_element_as_pauli = remove_imaginary_terms(
                qubitop_to_pyquilpauli(transform(tpdm_element)))
            for term in tpdm_element_as_pauli:
                pauli_terms_to_measure.append(term)

    for term in pauli_terms_to_measure:
        # convert term into numerically order pauli tensor term
        pauli_tensor_list = sorted(list(term.operations_as_set()),
                                   key=lambda x: x[0])
        rev_order_pauli_tensor_list = list(
            map(lambda x: (x[1], x[0]), pauli_tensor_list))
        pauli_term = PauliTerm.from_list(rev_order_pauli_tensor_list,
                                         coefficient=term.coefficient)

        if pauli_term.id() not in pauli_to_rdm.keys():
            pauli_to_rdm[pauli_term.id()] = pauli_term
        else:
            if (abs(pauli_to_rdm[pauli_term.id()].coefficient) < abs(
                    pauli_term.coefficient)):
                pauli_to_rdm[pauli_term.id()] = pauli_term

    return list(pauli_to_rdm.values())
Exemple #15
0
def test_construct_phdm():
    """
    Construct the particle-hole density matrix

    <psi|a_{p}^{\dagger}a_{q}a_{s}^{\dagger}a_{r}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    dim = molecule.n_qubits

    phdm_ab = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)), dtype=complex)
    phdm_ba = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)), dtype=complex)
    phdm_aabb = np.zeros((2 * (int(dim/2))**2, 2 * (int(dim/2))**2), dtype=complex)
    sdim = int(dim/2)
    for p, q, r, s in product(range(sdim), repeat=4):
        # pauli_proj_op = transform.product_ops([2 * p, 2 * q + 1,
        #                                        2 * s + 1, 2 * r], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p, 1), (2 * q + 1, 0), (2 * s + 1, 1), (2 * r, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        phdm_ab[p, q, r, s] = phdm_element

        # pauli_proj_op = transform.product_ops([2 * p + 1, 2 * q,
        #                                        2 * s, 2 * r + 1], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 1), (2 * q, 0), (2 * s, 1), (2 * r + 1, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        phdm_ba[p, q, r, s] = phdm_element

        # pauli_proj_op = transform.product_ops([2 * p, 2 * q,
        #                                        2 * s, 2 * r], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p, 1), (2 * q, 0), (2 * s, 1), (2 * r, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        # phdm_aabb[0, 0, p, q, r, s] = phdm_element
        phdm_aabb[p * sdim + q, r * sdim + s] = phdm_element

        # pauli_proj_op = transform.product_ops([2 * p + 1, 2 * q + 1,
        #                                        2 * s + 1, 2 * r + 1], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 1), (2 * q + 1, 0), (2 * s + 1, 1), (2 * r + 1, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        # phdm_aabb[1, 1, p, q, r, s] = phdm_element
        phdm_aabb[p * sdim + q + sdim**2, r * sdim + s + sdim**2] = phdm_element

        # pauli_proj_op = transform.product_ops([2 * p, 2 * q,
        #                                        2 * s + 1, 2 * r + 1], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p, 1), (2 * q, 0), (2 * s + 1, 1), (2 * r + 1, 0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        # phdm_aabb[0, 1, p, q, r, s] = phdm_element
        phdm_aabb[p * sdim + q, r * sdim + s + sdim**2] = phdm_element


        # pauli_proj_op = transform.product_ops([2 * p + 1, 2 * q + 1,
        #                                        2 * s, 2 * r], [-1, 1, -1, 1])
        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 1), (2 * q + 1, 0), (2 * s, 1), (2 * r,  0))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        phdm_element = np.trace(lifted_op.dot(rho))
        # phdm_aabb[1, 0, p, q, r, s] = phdm_element
        phdm_aabb[p * sdim + q + sdim**2, r * sdim + s] = phdm_element

    phdm_ab_test, phdm_ba_test, phdm_aabb_test = rdm_generator.construct_phdm()

    assert np.allclose(phdm_ab, phdm_ab_test)
    assert np.allclose(phdm_ba, phdm_ba_test)
    assert np.allclose(phdm_aabb, phdm_aabb_test)
Exemple #16
0
def test_construct_thdm():
    """
    Construct the two-hole density matrix

    <psi|a_{p}a_{q}a_{s}^{\dagger}a_{r}^{\dagger}|psi>
    """
    rho, rdm_generator, transform, molecule = system()
    dim = molecule.n_qubits

    thdm_aa = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)),
                       dtype=complex)
    thdm_bb = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)),
                       dtype=complex)
    thdm_ab = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)),
                       dtype=complex)
    thdm_ba = np.zeros((int(dim/2), int(dim/2), int(dim/2), int(dim/2)),
                       dtype=complex)
    for p, q, r, s in product(range(int(dim/2)), repeat=4):
        # pauli_proj_op = transform.product_ops([2 * p + 1, 2 * q + 1,
        #                                        2 * s + 1, 2 * r + 1], [1, 1, -1, -1])
        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 0), (2 * q + 1, 0), (2 * s + 1, 1), (2 * r + 1, 1))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        tpdm_element = np.trace(lifted_op.dot(rho))
        thdm_bb[p, q, r, s] = tpdm_element

        # pauli_proj_op = transform.product_ops([2 * p, 2 * q,
        #                                        2 * s, 2 * r], [1, 1, -1, -1])
        pauli_proj_op = transform(FermionOperator(((2 * p, 0), (2 * q, 0), (2 * s, 1), (2 * r, 1))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        tpdm_element = np.trace(lifted_op.dot(rho))
        thdm_aa[p, q, r, s] = tpdm_element

        # pauli_proj_op = transform.product_ops([2 * p, 2 * q + 1,
        #                                        2 * s + 1, 2 * r], [1, 1, -1, -1])
        pauli_proj_op = transform(FermionOperator(((2 * p, 0), (2 * q + 1, 0), (2 * s + 1, 1), (2 * r, 1))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        tpdm_element = np.trace(lifted_op.dot(rho))
        thdm_ab[p, q, r, s] = tpdm_element

        # pauli_proj_op = transform.product_ops([2 * p + 1, 2 * q,
        #                                        2 * s, 2 * r + 1], [1, 1, -1, -1])
        pauli_proj_op = transform(FermionOperator(((2 * p + 1, 0), (2 * q, 0), (2 * s, 1), (2 * r + 1, 1))))
        pauli_proj_op = qubitop_to_pyquilpauli(pauli_proj_op)
        if isinstance(pauli_proj_op, PauliTerm):
            pauli_proj_op = PauliSum([pauli_proj_op])
        lifted_op = tensor_up(pauli_proj_op, molecule.n_qubits)
        tpdm_element = np.trace(lifted_op.dot(rho))
        thdm_ba[p, q, r, s] = tpdm_element

    thdm_aa_true, thdm_bb_true, thdm_ab_true, thdm_ba_true = rdm_generator.construct_thdm()
    assert np.allclose(thdm_aa, thdm_aa_true)
    assert np.allclose(thdm_bb, thdm_bb_true)
    assert np.allclose(thdm_ab, thdm_ab_true)
    assert np.allclose(thdm_ba, thdm_ba_true)
Exemple #17
0
def test_translation_type_enforcement():
    """
    Make sure type check works
    """
    create_one = FermionOperator('1^')
    empty_one_body = np.zeros((2, 2))
    empty_two_body = np.zeros((2, 2, 2, 2))
    interact_one = InteractionOperator(1, empty_one_body, empty_two_body)
    interact_rdm = InteractionRDM(empty_one_body, empty_two_body)

    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(create_one)
    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(interact_one)
    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(interact_rdm)

    # don't accept anything other than pyquil PauliSum or PauliTerm
    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(create_one)
    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(interact_one)
    with pytest.raises(TypeError):
        qubitop_to_pyquilpauli(interact_rdm)