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_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_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
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
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
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
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())
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)
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
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)
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
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())
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)
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)
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)