Ejemplo n.º 1
0
    def generate_marginal(self, qubit_set):
        """
        Construct a marginal

        :param qubit_set:
        :return:
        """
        pauli_label_basis = list(product(pauli_labels, repeat=len(qubit_set)))
        marginal_rank = len(qubit_set)
        marginal = np.zeros((2**marginal_rank, 2**marginal_rank),
                            dtype=complex)

        # get set of matrices serving as the operator basis
        marginal_basis = {}
        for ops in pauli_label_basis:
            pauli_group_op = sI(0)
            for qubit_idx, p_op in enumerate(ops):
                pauli_group_op *= pauli_basis[p_op](qubit_idx)
            marginal_basis[ops] = tensor_up(PauliSum([pauli_group_op]),
                                            marginal_rank)

        for ops in pauli_label_basis:
            pauli_group_op = sI(0)
            for qubit_idx, p_op in zip(qubit_set, ops):
                pauli_group_op *= pauli_basis[p_op](qubit_idx)
            p_op_full_space = tensor_up(PauliSum([pauli_group_op]),
                                        self.num_qubits)
            p_op_full_space /= 2**marginal_rank
            # TODO: Normalize pauli coefficients...Did we do it properly?
            basis_coeff = np.trace(p_op_full_space.dot(self.rho))
            marginal += basis_coeff * marginal_basis[ops]

        return marginal
Ejemplo n.º 2
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)
def test_tensor_up_error_catch():
    """Testing tensor up type checking"""
    x_term = PauliTerm("X", 5)

    # testing type rejection
    with pytest.raises(TypeError):
        tensor_up(x_term, 5)

    # testing index rejection
    with pytest.raises(IndexError):
        tensor_up(PauliSum([x_term]), 3)
Ejemplo n.º 4
0
def test_marginal():
    """
    Generate ground state of heinsenberg spin model and general
    all 1-marginals

    Heisenberg spin model is

    H = sum_{<ij>} X_{i}X_{j} + Y_{i}Y_{j} + Z_{i}Z_{j}

    :return:
    """
    # generate state for Heisenberg spin-model
    qubits = 4
    hamiltonian = sI(0) * 0.0
    for ii in range(qubits):
        hamiltonian += sX(ii) * sX((ii + 1) % qubits)
        hamiltonian += sY(ii) * sY((ii + 1) % qubits)
        hamiltonian += sZ(ii) * sZ((ii + 1) % qubits)

    hamiltonian_matrix = tensor_up(hamiltonian, qubits)
    w, v = np.linalg.eigh(hamiltonian_matrix)
    rho = v[:, [0]].dot(np.conj(v[:, [0]]).T)
    mg = MarginalGenerator(rho)
    marginals = mg.construct_p_marginals(2)
    for marginal_id, marginal in marginals.items():
        assert np.isclose(marginal.trace(), 1.0)
Ejemplo n.º 5
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)
def test_tensor_up_correctness():
    """Check the correctness of the tensor up routine"""
    xy_term = PauliSum([PauliTerm("X", 0)*PauliTerm("Y", 1)])

    # test correctness
    trial_matrix = tensor_up(xy_term, 2)
    true_matrix = np.kron(gate_matrix['Y'], gate_matrix['X'])
    np.testing.assert_allclose(trial_matrix, true_matrix)

    x1_term = PauliSum([PauliTerm("X", 1)])
    trial_matrix = tensor_up(x1_term, 2)
    true_matrix = np.kron(gate_matrix['X'], gate_matrix['I'])
    np.testing.assert_allclose(trial_matrix, true_matrix)

    zpz_term = PauliTerm("Z", 0) + PauliTerm("Z", 1)
    trial_matrix = tensor_up(zpz_term, 2)
    true_matrix = np.zeros((4, 4))
    true_matrix[0, 0] = 2
    true_matrix[-1, -1] = -2
    np.testing.assert_allclose(trial_matrix, true_matrix)
Ejemplo n.º 7
0
def rotate_density(rho, pauli_term, debug=False):
    """
    Rotate the density so I can read off in the computational basis
    """
    # rotate operator into computational basis
    rot_prog = Program()
    n_qubits = int(np.log2(rho.shape[0]))

    marked_qubits = []
    for key, value in pauli_term._ops.iteritems():
        marked_qubits.append(key)
        if value == "X":
            rot_prog.inst(H(key))
        elif value == "Y":
            rot_prog.inst(RX(np.pi / 2)(key))
    rot_prog.inst(I(n_qubits - 1))

    qvm_unitary = QVMConnection(type_trans='unitary')
    if debug:
        ham_op = tensor_up(PauliSum([pauli_term]), n_qubits)
        e_true = np.trace(ham_op.dot(rho))

    unitary = qvm_unitary.unitary(rot_prog)
    rho = unitary.dot(rho.dot(np.conj(unitary).T))

    if debug:
        z_term = PauliTerm("I", 0)
        for idx in marked_qubits:
            z_term = z_term * PauliTerm("Z", idx)

        ham_op_2 = tensor_up(pauli_term.coefficient * PauliSum([z_term]),
                             n_qubits)
        test_expect = np.trace(np.dot(ham_op_2, rho))
        assert np.isclose(test_expect, e_true)

    return rho, marked_qubits
Ejemplo n.º 8
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)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
    def density(self, pyquil_program):
        """
        Run program and compute the density matrix

        Loads and checks program if all gates are within the stabilizer set.
        Then executes program and returns the final density matrix for the
        stabilizer

        :param Program pyquil_program: a pyquil Program containing only
                                       CNOT-H-S-MEASUREMENT operations
        :return:
        """
        self.load_program(pyquil_program)
        self.tableau = self._n_qubit_tableau(self.num_qubits)
        self.kernel()
        stabilizers = binary_stabilizer_to_pauli_stabilizer(
            self.stabilizer_tableau())
        pauli_ops = reduce(lambda x, y: x * y,
                           [0.5 * (sI(0) + b) for b in stabilizers])
        return tensor_up(pauli_ops, self.num_qubits)
Ejemplo n.º 11
0
    def _tensor_construct(self, rank, conjugates):
        """
        General procedure for evaluating the expected value of second quantized ops

        General procedure for finding p-rank correlators such as the 1-RDM or 2-RDM
        :param Int rank: number of second quantized operators to product out
        :param List conjugates: Indicator of the conjugate type of the second quantized operator
        :returns: a tensor of (rank) specified by input
        :rytpe: np.ndarray
        """
        tensor = np.zeros(tuple([self.dim] * rank), dtype=complex)
        for tindices in product(range(self.dim), repeat=rank):
            print(tindices)
            pauli_proj_op = self.transform.product_ops(
                list(tindices[:int(rank / 2)] +
                     tindices[int(rank / 2):][::-1]), conjugates)
            lifted_op = tensor_up(pauli_proj_op, self.num_qubits)
            # element = np.trace(lifted_op.dot(self.rho))
            element = (lifted_op.dot(self.rho)).diagonal().sum()
            tensor[tindices] = element
        return tensor
Ejemplo n.º 12
0
def get_molecule_openfermion(molecule, eigen_index=0):
    # check if the molecule is in the molecules data directory
    if molecule.name + '.hdf5' in os.listdir(DATA_DIRECTORY):
        print("\tLoading File from {}".format(DATA_DIRECTORY))
        molecule.load()
    else:
        # compute properties with run_psi4
        molecule = run_psi4(molecule, run_fci=True)
        print("\tPsi4 Calculation Completed")
        print("\tSaved in {}".format(DATA_DIRECTORY))
        molecule.save()

    fermion_hamiltonian = molecule.get_molecular_hamiltonian()
    qubitop_hamiltonian = jordan_wigner(fermion_hamiltonian)
    psum = qubitop_to_pyquilpauli(qubitop_hamiltonian)
    ham = tensor_up(psum, molecule.n_qubits)
    if isinstance(ham, (csc_matrix, csr_matrix)):
        ham = ham.toarray()
    w, v = np.linalg.eigh(ham)
    gs_wf = v[:, [eigen_index]]
    n_density = gs_wf.dot(np.conj(gs_wf).T)
    return molecule, v[:, [eigen_index]], n_density, w[eigen_index]
Ejemplo n.º 13
0
    def _tensor_construct(self, rank, conjugates, updown):
        """
        General procedure for evaluating the expected value of second quantized ops

        :param Int rank: number of second quantized operators to product out
        :param List conjugates: Indicator of the conjugate type of the second
                                quantized operator
        :param List updown: SymmOrbitalDensity matrices are index by spatial orbital
                            Indices.  This value is self.dim/2 for Fermionic systems.
                            When projecting out expected values to form the marginals,
                            we need to know if the spin-part of the spatial basis
                            funciton.  updown is a list corresponding with the
                            conjugates telling us if we are projecting an up spin or
                            down spin.  0 is for up. 1 is for down.

                            Example: to get the 1-RDM alpha-block we would pass the
                            following:

                                rank = 2, conjugates = [-1, 1], updown=[0, 0]

        :returns: a tensor of (rank) specified by input
        :rytpe: np.ndarray
        """
        # self.dim/2 because rank is now spatial basis function rank
        tensor = np.zeros(tuple([int(self.dim / 2)] * rank), dtype=complex)
        for tindices in product(range(int(self.dim / 2)), repeat=rank):
            # get the spatial indices
            spin_free_indices = list(
                map(lambda x: 2 * tindices[x] + updown[x],
                    range(len(tindices))))

            pauli_proj_op = self.transform.product_ops(
                list(spin_free_indices[:int(rank / 2)] +
                     spin_free_indices[int(rank / 2):][::-1]), conjugates)

            lifted_op = tensor_up(pauli_proj_op, self.num_qubits)
            element = np.trace(lifted_op.dot(self.rho))
            tensor[tindices] = element
        return tensor
def test_s2_expected():
    n_density, rdm_gen, transform, molecule = heh_system()

    density = SpinOrbitalDensity(n_density, molecule.n_qubits)
    tpdm = density.construct_tpdm().real
    opdm = density.construct_opdm().real

    # calculate S^{2} by jordan-wigner of fermionic modes
    so_dim = int(opdm.shape[0])
    sp_dim = int(so_dim / 2)
    jw = JWTransform()
    sminus = sI(0) * 0
    splus = sI(0) * 0
    szop = sI(0) * 0
    for i in range(sp_dim):
        sminus += jw.product_ops([2 * i + 1, 2 * i], [-1, 1])
        splus += jw.product_ops([2 * i, 2 * i + 1], [-1, 1])
        szop += 0.5 * jw.product_ops([2 * i, 2 * i], [-1, 1])
        szop -= 0.5 * jw.product_ops([2 * i + 1, 2 * i + 1], [-1, 1])

    s2op = sminus * splus + szop + szop * szop
    s2op_matrix = tensor_up(s2op, so_dim)
    szop_matrix = tensor_up(szop, so_dim)
    szop2_matrix = tensor_up(szop * szop, so_dim)
    splus_matrix = tensor_up(splus, so_dim)
    sminus_matrix = tensor_up(sminus, so_dim)
    smsp_matrix = tensor_up(sminus * splus, so_dim)

    np.testing.assert_allclose(smsp_matrix, sminus_matrix.dot(splus_matrix))
    np.testing.assert_allclose(szop2_matrix, szop_matrix.dot(szop_matrix))
    np.testing.assert_allclose(szop2_matrix + szop_matrix,
                               szop_matrix.dot(szop_matrix) + szop_matrix)

    np.testing.assert_allclose(smsp_matrix + szop2_matrix + szop_matrix,
                               smsp_matrix + szop_matrix.dot(szop_matrix) + szop_matrix)

    np.testing.assert_allclose(smsp_matrix + szop2_matrix + szop_matrix,
                               s2op_matrix)

    # Now we can check if our two methods for computing the S^{2} value are
    # correct.
    s2_from_ndensity = np.trace(n_density.dot(s2op_matrix)).real
    trial_s2_expected = s2_expected(tpdm, opdm)
    np.testing.assert_almost_equal(s2_from_ndensity, trial_s2_expected)
Ejemplo n.º 15
0
            if np.isclose(term.coefficient.imag, 0.0):
                count += 1
    return count


if __name__ == "__main__":
    from representability.fermions.utils import get_molecule

    ham, ham_op, mol_data, gs_wf, n_density, gs_eig = get_molecule()
    n_qubits = ham.n_qubits
    M = 2 * mol_data.M_
    N = mol_data.nElectrons_

    d2ab_pauli_map, pauli_set = pauliD2set_sz(ham)

    # measure the following pauli term
    # expected value from density 0.002722159645
    # pauli_operator = PauliTerm("X", 1, 0.125)*PauliTerm("Z", 2)*PauliTerm("X", 3)
    pauli_operator = PauliTerm("Z", 2, 0.25) * PauliTerm("Z", 3, 1.0)
    p_op_mat = tensor_up(PauliSum([pauli_operator]), M)
    true_expectation = np.trace(np.dot(p_op_mat, n_density))
    # assert np.isclose(true_expectation, 0.002722159645)A
    assert np.isclose(true_expectation, 0.249863555819)

    for key, value in d2ab_pauli_map.iteritems():
        for pterm in value.terms:
            op = tensor_up(PauliSum([pterm]), n_qubits)
            if np.isclose(pterm.coefficient.real,
                          0) and not np.isclose(pterm.coefficient.imag, 0.0):
                assert np.isclose(np.trace(np.dot(op, n_density)), 0.0)
Ejemplo n.º 16
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)
Ejemplo n.º 17
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)
Ejemplo n.º 18
0
        bk_hamiltonian = symmetry_conserving_bravyi_kitaev(
            get_fermion_operator(hamiltonian), 4, 2)

        # generate the spin-adapted classical coupled-cluster amplitude to use as the input for the
        # circuit
        packed_amps = uccsd_singlet_get_packed_amplitudes(
            molecule.ccsd_single_amps, molecule.ccsd_double_amps,
            molecule.n_qubits, molecule.n_electrons)
        theta = packed_amps[-1]  # always take the doubles amplitude

        # now that we're done setting up the Hamiltonian and grabbing initial opt parameters
        # we can switch over to how to run things
        ucc_program = ucc_circuit(theta)

        paulis_bk_hamiltonian = qubitop_to_pyquilpauli(bk_hamiltonian)
        bk_mat = tensor_up(paulis_bk_hamiltonian, 2)

        w, v = np.linalg.eigh(bk_mat)

        wf = qvm.wavefunction(ucc_program)
        wf = wf.amplitudes.reshape((-1, 1))

        tenergy = np.conj(wf).T.dot(bk_mat).dot(wf)[0, 0].real

        # observable = objective_fun(theta, hamiltonian=paulis_bk_hamiltonian, quantum_resource=qvm)
        observable = objective_fun(theta,
                                   hamiltonian=bk_mat,
                                   quantum_resource=qvm)

        result = minimize(objective_fun,
                          x0=theta,