def test_get_interaction_operator_one_body(self): interaction_operator = get_interaction_operator( FermionOperator('2^ 2'), self.n_qubits) one_body = numpy.zeros((self.n_qubits, self.n_qubits), float) one_body[2, 2] = 1. self.assertEqual(interaction_operator, InteractionOperator(0.0, one_body, self.two_body))
def test_get_interaction_operator_two_body_distinct(self): interaction_operator = get_interaction_operator( FermionOperator('0^ 1^ 2 3'), self.n_qubits) two_body = numpy.zeros((self.n_qubits, self.n_qubits, self.n_qubits, self.n_qubits), float) two_body[1, 0, 3, 2] = 1. self.assertEqual(interaction_operator, InteractionOperator(0.0, self.one_body, two_body))
def setUp(self): self.n_qubits = 5 self.fermion_term = FermionOperator('1^ 2^ 3 4', -3.17) self.fermion_operator = self.fermion_term + hermitian_conjugated( self.fermion_term) self.qubit_operator = jordan_wigner(self.fermion_operator) self.interaction_operator = get_interaction_operator( self.fermion_operator)
def test_get_interaction_operator_identity(self): interaction_operator = InteractionOperator(-2j, self.one_body, self.two_body) qubit_operator = jordan_wigner(interaction_operator) self.assertTrue(qubit_operator == -2j * QubitOperator(())) self.assertEqual(interaction_operator, get_interaction_operator(reverse_jordan_wigner( qubit_operator), self.n_qubits))
def test_get_interaction_operator_two_body(self): interaction_operator = get_interaction_operator( FermionOperator('2^ 2 3^ 4'), self.n_qubits) two_body = numpy.zeros((self.n_qubits, self.n_qubits, self.n_qubits, self.n_qubits), float) two_body[3, 2, 4, 2] = -1. self.assertEqual(interaction_operator, InteractionOperator(0.0, self.one_body, two_body))
def test_jordan_wigner_twobody_interaction_op_allunique(self): test_op = FermionOperator('1^ 2^ 3 4') test_op += hermitian_conjugated(test_op) retransformed_test_op = reverse_jordan_wigner( jordan_wigner(get_interaction_operator(test_op))) self.assertTrue( normal_ordered(retransformed_test_op) == normal_ordered(test_op))
def test_get_interaction_operator_one_body_twoterm(self): interaction_operator = get_interaction_operator( FermionOperator('2^ 3', -2j) + FermionOperator('3^ 2', 3j), self.n_qubits) one_body = numpy.zeros((self.n_qubits, self.n_qubits), complex) one_body[2, 3] = -2j one_body[3, 2] = 3j self.assertEqual(interaction_operator, InteractionOperator(0.0, one_body, self.two_body))
def test_jordan_wigner_interaction_op_with_zero_term(self): test_op = FermionOperator('1^ 2^ 3 4') test_op += hermitian_conjugated(test_op) interaction_op = get_interaction_operator(test_op) interaction_op.constant = 0.0 retransformed_test_op = reverse_jordan_wigner( jordan_wigner(interaction_op))
def test_bk_n_qubits_too_small(self): with self.assertRaises(ValueError): bravyi_kitaev(FermionOperator('2^ 3^ 5 0'), n_qubits=4) with self.assertRaises(ValueError): bravyi_kitaev(MajoranaOperator((2, 3, 9, 0)), n_qubits=4) with self.assertRaises(ValueError): bravyi_kitaev(get_interaction_operator( FermionOperator('2^ 3^ 5 0')), n_qubits=4)
def test_case_one_body_op_success(self): # Case A: Simplest class of operators # (Number operators and Excitation operators) for i in range(self.test_range): for j in range(i): ham = self.two_op(i, j) + self.two_op(j, i) n_qubits = count_qubits(ham) opf_ham = bravyi_kitaev(ham, n_qubits) custom = bravyi_kitaev(get_interaction_operator(ham)) assert custom == opf_ham
def test_one_body_constraints(self): for constraint in one_body_fermion_constraints( self.n_orbitals, self.n_fermions): interaction_operator = get_interaction_operator( constraint, self.n_orbitals) constraint_value = self.fci_rdm.expectation(interaction_operator) self.assertAlmostEqual(constraint_value, 0.) for term, _ in constraint.terms.items(): if len(term) == 2: self.assertTrue(term[0][1]) self.assertFalse(term[1][1]) else: self.assertEqual(term, ())
def test_coulomb_and_exchange_ops_success(self): # Case B: Coulomb and exchange operators for i in range(self.test_range): for j in range(i): ham = self.coulomb_exchange_operator(i, j) opf_ham = bravyi_kitaev(ham) custom = bravyi_kitaev(get_interaction_operator(ham)) print(opf_ham) print(custom) assert custom == opf_ham
def test_number_excitation_op_success(self): # Case C: Number-excitation operator for i in range(self.test_range): for j in range(self.test_range): if i != j: for k in range(self.test_range): if k not in (i, j): ham = self.number_excitation_operator(i, j, k) opf_ham = bravyi_kitaev(ham) custom = bravyi_kitaev( get_interaction_operator(ham)) assert custom == opf_ham
def interaction_operator_generator( self, *, operator: Optional['openfermion.InteractionOperator'] = None, modes: Optional[Sequence[int]] = None ) -> 'openfermion.InteractionOperator': """Constructs the Hamiltonian corresponding to the gate's generator.""" if modes is None: modes = tuple(range(self.num_qubits())) if operator is None: n_modes = max(modes) + 1 operator = ops.InteractionOperator.zero(n_modes) else: n_modes = operator.n_qubits fermion_operator = self.fermion_generator return get_interaction_operator(fermion_operator, n_qubits=n_modes)
def test_abstract_molecule(self): """Test an abstract molecule like jellium for saving and loading""" jellium_interaction = get_interaction_operator( jellium_model(Grid(2, 2, 1.0))) jellium_molecule = get_molecular_data(jellium_interaction, geometry="Jellium", basis="PlaneWave22", multiplicity=1, n_electrons=4) jellium_filename = jellium_molecule.filename jellium_molecule.save() jellium_molecule.load() correct_name = "Jellium_PlaneWave22_singlet" self.assertEqual(jellium_molecule.name, correct_name) os.remove("{}.hdf5".format(jellium_filename))
def load_and_transform(filename, orbitals, transform): # Load data print('--- loading molecule ---') molecule = MolecularData(filename=filename) print('filename: {}'.format(molecule.filename)) #print('n_atoms: {}'.format(molecule.n_atoms)) #print('n_electrons: {}'.format(molecule.n_electrons)) #print('n_orbitals: {}'.format(molecule.n_orbitals)) #print('Canonical Orbitals: {}'.format(molecule.canonical_orbitals)) #print('n_qubits: {}'.format(molecule.n_qubits)) # get the Hamiltonian for a specific choice of active space # set the Hamiltonian parameters occupied_orbitals, active_orbitals = orbitals molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=range(occupied_orbitals), active_indices=range(active_orbitals)) # map the operator to fermions and then qubits fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian) # get interaction operator interaction_hamiltonian = get_interaction_operator(fermion_hamiltonian) if transform is 'JW': qubit_h = jordan_wigner(fermion_hamiltonian) qubit_h.compress() elif transform is 'BK': qubit_h = bravyi_kitaev(fermion_hamiltonian) qubit_h.compress() elif transform is 'BKSF': qubit_h = bravyi_kitaev_fast(interaction_hamiltonian) qubit_h.compress() elif transform is 'BKT': qubit_h = bravyi_kitaev_tree(fermion_hamiltonian) qubit_h.compress() elif transform is 'PC': qubit_h = binary_code_transform(fermion_hamiltonian, parity_code(2 * active_orbitals)) qubit_h.compress() else: print('ERROR: Unrecognized qubit transformation: {}'.format(transform)) sys.exit(2) return qubit_h
def test_double_excitation_op_success(self): # Case D: Double-excitation operator for i in range(self.test_range): for j in range(self.test_range): for k in range(self.test_range): for l in range(self.test_range): if len({i, j, k, l}) == 4: print(i, j, k, l) ham = self.four_op(i, j, k, l) + self.four_op( k, l, i, j) n_qubits = count_qubits(ham) opf_ham = bravyi_kitaev(ham, n_qubits) custom = bravyi_kitaev( get_interaction_operator(ham)) assert custom == opf_ham
def double_commutator_einsum( ridx: int, rgen: FermionOperator, sidx: int, sgen: FermionOperator ) -> Tuple[int, int, float]: # testpragma: no cover # coverage: ignore """ Evaluate <psi|[[H, p^q - q^p], r^s - s^r]|psi> :param ridx: index of p^q - q^p operator in ordered list of operators :param rgen: FermionOperator of p^q - q^p :param sidx: ndex of r^s - s^r operator in ordered list of operators :param sgen: FermionOperator of r^s - s^r :return: index of p^q-q^p, index of r^s - s^r, and the commutator value """ rgen_tensor = get_interaction_operator( rgen, n_qubits=num_qubits).one_body_tensor sgen_tensor = get_interaction_operator( sgen, n_qubits=num_qubits).one_body_tensor opdm = rdms.n_body_tensors[(1, 0)].copy() tpdm = rdms.n_body_tensors[(1, 1, 0, 0)].copy() commutator_expectation = 0 # ( -1.00000) kdelta(i,q) kdelta(j,r) cre(p) des(s) commutator_expectation += -1.0 * np.einsum( 'ij,pq,rs,iq,jr,ps', rhf_objective.hamiltonian.one_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, opdm, optimize=True) # ( 1.00000) kdelta(i,q) kdelta(p,s) cre(r) des(j) commutator_expectation += 1.0 * np.einsum( 'ij,pq,rs,iq,ps,rj', rhf_objective.hamiltonian.one_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, opdm, optimize=True) # ( -1.00000) kdelta(i,s) kdelta(j,p) cre(r) des(q) commutator_expectation += -1.0 * np.einsum( 'ij,pq,rs,is,jp,rq', rhf_objective.hamiltonian.one_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, opdm, optimize=True) # ( 1.00000) kdelta(j,p) kdelta(q,r) cre(i) des(s) commutator_expectation += 1.0 * np.einsum( 'ij,pq,rs,jp,qr,is', rhf_objective.hamiltonian.one_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, opdm, optimize=True) # ( 1.00000) kdelta(i,q) kdelta(j,s) cre(p) cre(r) des(k) des(l) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,iq,js,prkl', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(i,q) kdelta(k,r) cre(j) cre(p) des(l) des(s) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,iq,kr,jpls', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(i,q) kdelta(l,r) cre(j) cre(p) des(k) des(s) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,iq,lr,jpks', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(i,q) kdelta(p,s) cre(j) cre(r) des(k) des(l) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,iq,ps,jrkl', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(i,s) kdelta(j,q) cre(p) cre(r) des(k) des(l) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,is,jq,prkl', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(i,s) kdelta(k,p) cre(j) cre(r) des(l) des(q) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,is,kp,jrlq', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(i,s) kdelta(l,p) cre(j) cre(r) des(k) des(q) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,is,lp,jrkq', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(j,q) kdelta(k,r) cre(i) cre(p) des(l) des(s) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,jq,kr,ipls', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(j,q) kdelta(l,r) cre(i) cre(p) des(k) des(s) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,jq,lr,ipks', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(j,q) kdelta(p,s) cre(i) cre(r) des(k) des(l) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,jq,ps,irkl', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(j,s) kdelta(k,p) cre(i) cre(r) des(l) des(q) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,js,kp,irlq', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(j,s) kdelta(l,p) cre(i) cre(r) des(k) des(q) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,js,lp,irkq', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(k,p) kdelta(l,r) cre(i) cre(j) des(q) des(s) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,kp,lr,ijqs', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(k,p) kdelta(q,r) cre(i) cre(j) des(l) des(s) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,kp,qr,ijls', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(k,r) kdelta(l,p) cre(i) cre(j) des(q) des(s) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,rs,kr,lp,ijqs', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(l,p) kdelta(q,r) cre(i) cre(j) des(k) des(s) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,rs,lp,qr,ijks', rhf_objective.hamiltonian.two_body_tensor, rgen_tensor, sgen_tensor, kdelta_mat, kdelta_mat, tpdm, optimize=True) return ridx, sidx, commutator_expectation
def single_commutator_einsum( idx: int, rot_gen: FermionOperator ) -> Tuple[int, float]: # testpragma: no cover # coverage: ignore """ Evaluate <psi|[H, p^q - q^p]|psi> :param idx: integer index of p^q - q^p in the ordered set :param rot_gen: Rotation generator p^q - q^p as a FermionOperator :return: index and value for the commutator """ rot_gen_tensor = get_interaction_operator( rot_gen, n_qubits=num_qubits).one_body_tensor opdm = rdms.n_body_tensors[(1, 0)].copy() tpdm = rdms.n_body_tensors[(1, 1, 0, 0)].copy() commutator_expectation = 0 # ( -1.00000) kdelta(i,q) cre(p) des(j) commutator_expectation += -1.0 * np.einsum( 'ij,pq,iq,pj', rhf_objective.hamiltonian.one_body_tensor, rot_gen_tensor, kdelta_mat, opdm, optimize=True) # ( 1.00000) kdelta(j,p) cre(i) des(q) commutator_expectation += 1.0 * np.einsum( 'ij,pq,jp,iq', rhf_objective.hamiltonian.one_body_tensor, rot_gen_tensor, kdelta_mat, opdm, optimize=True) # ( 1.00000) kdelta(i,q) cre(j) cre(p) des(k) des(l) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,iq,jpkl', rhf_objective.hamiltonian.two_body_tensor, rot_gen_tensor, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(j,q) cre(i) cre(p) des(k) des(l) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,jq,ipkl', rhf_objective.hamiltonian.two_body_tensor, rot_gen_tensor, kdelta_mat, tpdm, optimize=True) # ( -1.00000) kdelta(k,p) cre(i) cre(j) des(l) des(q) commutator_expectation += -1.0 * np.einsum( 'ijkl,pq,kp,ijlq', rhf_objective.hamiltonian.two_body_tensor, rot_gen_tensor, kdelta_mat, tpdm, optimize=True) # ( 1.00000) kdelta(l,p) cre(i) cre(j) des(k) des(q) commutator_expectation += 1.0 * np.einsum( 'ijkl,pq,lp,ijkq', rhf_objective.hamiltonian.two_body_tensor, rot_gen_tensor, kdelta_mat, tpdm, optimize=True) return idx, commutator_expectation
def test_jordan_wigner_twobody_interaction_op_reversal_symmetric(self): test_op = FermionOperator('1^ 2^ 2 1') test_op += hermitian_conjugated(test_op) self.assertTrue( jordan_wigner(test_op) == jordan_wigner( get_interaction_operator(test_op)))