def lih_hamiltonian(): """ Generate test Hamiltonian from LiH. Args: None Return: hamiltonian: FermionicOperator spectrum: List of energies. """ geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))] active_space_start = 1 active_space_stop = 3 molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45") molecule.load() molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=range(active_space_start), active_indices=range(active_space_start, active_space_stop)) hamiltonian = get_fermion_operator(molecular_hamiltonian) spectrum = eigenspectrum(hamiltonian) return hamiltonian, spectrum
def test_consistency(self): """Test consistency with JW for FermionOperators.""" # Random interaction operator n_qubits = 5 iop = random_interaction_operator(n_qubits, real=False) op1 = jordan_wigner(iop) op2 = jordan_wigner(get_fermion_operator(iop)) self.assertEqual(op1, op2) # Interaction operator from molecule geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))] basis = 'sto-3g' multiplicity = 1 filename = os.path.join(DATA_DIRECTORY, 'H1-Li1_sto-3g_singlet_1.45') molecule = MolecularData(geometry, basis, multiplicity, filename=filename) molecule.load() iop = molecule.get_molecular_hamiltonian() op1 = jordan_wigner(iop) op2 = jordan_wigner(get_fermion_operator(iop)) self.assertEqual(op1, op2)
def test_mrd_return_type(): filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5") molecule = MolecularData(filename=filename) reduced_ham = make_reduced_hamiltonian( molecule.get_molecular_hamiltonian(), molecule.n_electrons) assert isinstance(reduced_ham, InteractionOperator)
def plot_data(bond_lengths, data): basis = 'sto-3g' multiplicity = 1 bond_length_interval = 0.1 n_points = 25 # Generate molecule at different bond lengths. hf_energies = [] fci_energies = [] for bond_length in bond_lengths: description = str(round(bond_length, 2)) # print(description) geometry = [('H', (0., 0., 0.)), ('H', (0., 0., bond_length))] molecule = MolecularData(geometry, basis, multiplicity, description=description) # Load data. molecule.load() hf_energies += [molecule.hf_energy] fci_energies += [molecule.fci_energy] plt.figure(0) plt.plot(bond_lengths, fci_energies, 'x-') plt.plot(bond_lengths, [e for e, _ in data], 'o-') plt.ylabel('Energy in Hartree') plt.xlabel('Bond length in angstrom') plt.show()
def create_molecule(): geometry = make_geometry() basis = 'sto-3g' charge = 0 multiplicity = 1 moleculefilename = '/app/moleculefile.hdf5' molecule = MolecularData(geometry, basis, multiplicity, charge, description, filename=moleculefilename) # openfermion's run_psi4 molecule = run_psi4(molecule, run_scf=1, run_mp2=1, run_cisd=0, run_ccsd=0, run_fci=0, verbose=1, tolerate_error=1) molecule.save()
def system_h4(): print('Running System Setup H4') basis = 'sto-3g' multiplicity = 1 charge = 0 r = 0.75 geometry = [('H', [0.0, 0.0, 0.0]), ('H', [0, 0, r]), ('H', [0, 0, 2 * r]), ('H', [0, 0, 3 * r])] molecule = MolecularData(geometry, basis, multiplicity, charge) # Run Psi4. molecule = run_psi4(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True, delete_input=False) op_mat = of.get_sparse_operator( molecule.get_molecular_hamiltonian()).toarray() w, v = np.linalg.eigh(op_mat) n_density = v[:, [0]] @ v[:, [0]].conj().T rdm_generator = AntiSymmOrbitalDensity(n_density, molecule.n_qubits) transform = jordan_wigner return n_density, rdm_generator, transform, molecule
def exp_hamiltoniantrot_H2(time, atomic_distance, trotter_order): """ Here we are using some packages related to quantum chemistry to obtain hamiltonian of H2 molecule. The we are translating this hamiltonian into sequence of pyquil gates. And finally, we are trotterazing the exponent of the hamiltonian (exp(-iHt)) of our system and returning the obtained pyquil program :param time: is t in the exp(iHt). Note the + sign. :param atomic_distance: the distance between to H atoms in H2 molecule :return: program of the Trotter-Suzuki decomposition of hamiltonian exp(iHt) for H2 molecule """ geometry = [['H', [0, 0, 0]], ['H', [0, 0, atomic_distance]]] # H--H distance = 0.74angstrom basis = 'sto-3g' multiplicity = 1 # (2S+1) charge = 0 h2_molecule = MolecularData(geometry, basis, multiplicity, charge) h2_molecule = run_pyscf(h2_molecule) h2_qubit_hamiltonian = jordan_wigner(get_fermion_operator(h2_molecule.get_molecular_hamiltonian())) pyquil_h2_qubit_hamiltonian = qubitop_to_pyquilpauli(h2_qubit_hamiltonian) return trotterization(pyquil_h2_qubit_hamiltonian, float(time), trotter_order)
def test_erpa_eom_ham_h2(): filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5") molecule = MolecularData(filename=filename) reduced_ham = make_reduced_hamiltonian( molecule.get_molecular_hamiltonian(), molecule.n_electrons) rha_fermion = of.get_fermion_operator(reduced_ham) permuted_hijkl = np.einsum('ijlk', reduced_ham.two_body_tensor) opdm = np.diag([1] * molecule.n_electrons + [0] * (molecule.n_qubits - molecule.n_electrons)) tpdm = 2 * of.wedge(opdm, opdm, (1, 1), (1, 1)) rdms = of.InteractionRDM(opdm, tpdm) dim = reduced_ham.one_body_tensor.shape[0] // 2 full_basis = {} # erpa basis. A, B basis in RPA language cnt = 0 for p, q in product(range(dim), repeat=2): if p < q: full_basis[(p, q)] = cnt full_basis[(q, p)] = cnt + dim * (dim - 1) // 2 cnt += 1 for rkey in full_basis.keys(): p, q = rkey for ckey in full_basis.keys(): r, s = ckey for sigma, tau in product([0, 1], repeat=2): test = erpa_eom_hamiltonian(permuted_hijkl, tpdm, 2 * q + sigma, 2 * p + sigma, 2 * r + tau, 2 * s + tau).real qp_op = of.FermionOperator( ((2 * q + sigma, 1), (2 * p + sigma, 0))) rs_op = of.FermionOperator( ((2 * r + tau, 1), (2 * s + tau, 0))) erpa_op = of.normal_ordered( of.commutator(qp_op, of.commutator(rha_fermion, rs_op))) true = rdms.expectation(of.get_interaction_operator(erpa_op)) assert np.isclose(true, test)
def setUp(self): geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = 'sto-3g' multiplicity = 1 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') self.molecule = MolecularData(geometry, basis, multiplicity, filename=filename) self.molecule.load() # Get molecular Hamiltonian. self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian() # Get FCI RDM. self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1) # Get explicit coefficients. self.nuclear_repulsion = self.molecular_hamiltonian.constant self.one_body = self.molecular_hamiltonian.one_body_tensor self.two_body = self.molecular_hamiltonian.two_body_tensor # Get fermion Hamiltonian. self.fermion_hamiltonian = normal_ordered( get_fermion_operator(self.molecular_hamiltonian)) # Get qubit Hamiltonian. self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian) # Get the sparse matrix. self.hamiltonian_matrix = get_sparse_operator( self.molecular_hamiltonian)
def get_molecular_data(interaction_operator, geometry=None, basis=None, multiplicity=None, n_electrons=None, reduce_spin=True, data_directory=None): """Output a MolecularData object generated from an InteractionOperator Args: interaction_operator(InteractionOperator): two-body interaction operator defining the "molecular interaction" to be simulated. geometry(string or list of atoms): basis(string): String denoting the basis set used to discretize the system. multiplicity(int): Spin multiplicity desired in the system. n_electrons(int): Number of electrons in the system reduce_spin(bool): True if one wishes to perform spin reduction on integrals that are given in interaction operator. Assumes spatial (x) spin structure generically. Returns: molecule(MolecularData): Instance that captures the interaction_operator converted into the format that would come from an electronic structure package adorned with some meta-data that may be useful. """ n_spin_orbitals = interaction_operator.n_qubits # Introduce bare molecular operator to fill molecule = MolecularData(geometry=geometry, basis=basis, multiplicity=multiplicity, data_directory=data_directory) molecule.nuclear_repulsion = interaction_operator.constant # Remove spin from integrals and put into molecular operator if reduce_spin: reduction_indices = list(range(0, n_spin_orbitals, 2)) else: reduction_indices = list(range(n_spin_orbitals)) molecule.n_orbitals = len(reduction_indices) molecule.one_body_integrals = interaction_operator.one_body_tensor[ numpy.ix_(reduction_indices, reduction_indices)] molecule.two_body_integrals = interaction_operator.two_body_tensor[ numpy.ix_(reduction_indices, reduction_indices, reduction_indices, reduction_indices)] # Fill in other metadata molecule.overlap_integrals = numpy.eye(molecule.n_orbitals) molecule.n_qubits = n_spin_orbitals molecule.n_electrons = n_electrons molecule.multiplicity = multiplicity return molecule
def decompose_hamiltonian(mol_name, hf_data, mapping="jordan_wigner", docc_mo_indices=None, active_mo_indices=None): r"""Decomposes the electronic Hamiltonian into a linear combination of Pauli operators using OpenFermion tools. **Example usage:** >>> decompose_hamiltonian('h2', './pyscf/sto-3g/', mapping='bravyi_kitaev') (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] + (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] + (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] + (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] + (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] + (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] + (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] + (-0.2427428049645989+0j) [Z2] Args: mol_name (str): name of the molecule hf_data (str): path to the directory containing the file with the Hartree-Fock electronic structure mapping (str): optional argument to specify the fermion-to-qubit mapping Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'`` docc_mo_indices (list): indices of doubly-occupied molecular orbitals, i.e., the orbitals that are not correlated in the many-body wave function active_mo_indices (list): indices of active molecular orbitals, i.e., the orbitals used to build the correlated many-body wave function Returns: transformed_operator: instance of the QubitOperator class representing the electronic Hamiltonian """ # loading HF data from a hdf5 file molecule = MolecularData( filename=os.path.join(hf_data.strip(), mol_name.strip())) # getting the terms entering the second-quantized Hamiltonian terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=docc_mo_indices, active_indices=active_mo_indices) # generating the fermionic Hamiltonian fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian) mapping = mapping.strip().lower() if mapping not in ("jordan_wigner", "bravyi_kitaev"): raise TypeError( "The '{}' transformation is not available. \n " "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.". format(mapping)) # fermionic-to-qubit transformation of the Hamiltonian if mapping == "bravyi_kitaev": return bravyi_kitaev(fermionic_hamiltonian) return jordan_wigner(fermionic_hamiltonian)
def get_qubit_hamiltonian(mol, geometry, basis, charge=0, multiplicity=1, qubit_transf='bk'): ''' Generating qubit hamiltonina of the given molecules with specified geometry, basis sets, charge and multiplicity Give its qubit form using specified transformation ''' g = get_molecular_data(mol, geometry) mol = MolecularData(g, basis, multiplicity, charge) mol = run_pyscf(mol) ham = mol.get_molecular_hamiltonian() hamf = get_fermion_operator(ham) if qubit_transf == 'bk': hamq = bravyi_kitaev(hamf) elif qubit_transf == 'jw': hamq = jordan_wigner(hamf) else: raise (ValueError(qubit_transf, 'Unknown transformation specified')) return hamq
def test_constant_one_body(): filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5") molecule = MolecularData(filename=filename) reduced_ham = make_reduced_hamiltonian( molecule.get_molecular_hamiltonian(), molecule.n_electrons) assert np.isclose(reduced_ham.constant, molecule.nuclear_repulsion) assert np.allclose(reduced_ham.one_body_tensor, 0)
def decompose(hf_file, mapping="jordan_wigner", core=None, active=None): r"""Decomposes the molecular Hamiltonian into a linear combination of Pauli operators using OpenFermion tools. This function uses OpenFermion functions to build the second-quantized electronic Hamiltonian of the molecule and map it to the Pauli basis using the Jordan-Wigner or Bravyi-Kitaev transformation. Args: hf_file (str): absolute path to the hdf5-formatted file with the Hartree-Fock electronic structure mapping (str): Specifies the transformation to map the fermionic Hamiltonian to the Pauli basis. Input values can be ``'jordan_wigner'`` or ``'bravyi_kitaev'``. core (list): indices of core orbitals, i.e., the orbitals that are not correlated in the many-body wave function active (list): indices of active orbitals, i.e., the orbitals used to build the correlated many-body wave function Returns: QubitOperator: an instance of OpenFermion's ``QubitOperator`` **Example** >>> decompose('./pyscf/sto-3g/h2', mapping='bravyi_kitaev') (-0.04207897696293986+0j) [] + (0.04475014401986122+0j) [X0 Z1 X2] + (0.04475014401986122+0j) [X0 Z1 X2 Z3] +(0.04475014401986122+0j) [Y0 Z1 Y2] + (0.04475014401986122+0j) [Y0 Z1 Y2 Z3] +(0.17771287459806262+0j) [Z0] + (0.17771287459806265+0j) [Z0 Z1] +(0.1676831945625423+0j) [Z0 Z1 Z2] + (0.1676831945625423+0j) [Z0 Z1 Z2 Z3] +(0.12293305054268105+0j) [Z0 Z2] + (0.12293305054268105+0j) [Z0 Z2 Z3] +(0.1705973832722409+0j) [Z1] + (-0.2427428049645989+0j) [Z1 Z2 Z3] +(0.1762764080276107+0j) [Z1 Z3] + (-0.2427428049645989+0j) [Z2] """ # loading HF data from the hdf5 file molecule = MolecularData(filename=hf_file.strip()) # getting the terms entering the second-quantized Hamiltonian terms_molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=core, active_indices=active ) # generating the fermionic Hamiltonian fermionic_hamiltonian = get_fermion_operator(terms_molecular_hamiltonian) mapping = mapping.strip().lower() if mapping not in ("jordan_wigner", "bravyi_kitaev"): raise TypeError( "The '{}' transformation is not available. \n " "Please set 'mapping' to 'jordan_wigner' or 'bravyi_kitaev'.".format(mapping) ) # fermionic-to-qubit transformation of the Hamiltonian if mapping == "bravyi_kitaev": return bravyi_kitaev(fermionic_hamiltonian) return jordan_wigner(fermionic_hamiltonian)
def test_one_body_square_decomposition(self): # Initialize H2 InteractionOperator. n_qubits = 4 n_orbitals = 2 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') molecule = MolecularData(filename=filename) molecule_interaction = molecule.get_molecular_hamiltonian() fermion_operator = get_fermion_operator(molecule_interaction) two_body_coefficients = molecule_interaction.two_body_tensor # Decompose. eigenvalues, one_body_squares, one_body_correction, error = ( low_rank_two_body_decomposition(two_body_coefficients)) rank = eigenvalues.size for l in range(rank): one_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (q, 0)) coefficient = one_body_squares[l, p, q] one_body_operator += FermionOperator(term, coefficient) one_body_squared = one_body_operator**2 # Get the squared one-body operator via one-body decomposition. if abs(eigenvalues[l]) < 1e-6: with self.assertRaises(ValueError): prepare_one_body_squared_evolution(one_body_squares[l]) continue else: density_density_matrix, basis_transformation_matrix = ( prepare_one_body_squared_evolution(one_body_squares[l])) two_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (p, 0), (q, 1), (q, 0)) coefficient = density_density_matrix[p, q] two_body_operator += FermionOperator(term, coefficient) # Confirm that the rotations diagonalize the one-body squares. hopefully_diagonal = basis_transformation_matrix.dot( numpy.dot( one_body_squares[l], numpy.transpose( numpy.conjugate(basis_transformation_matrix)))) diagonal = numpy.diag(hopefully_diagonal) difference = hopefully_diagonal - numpy.diag(diagonal) self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) density_density_alternative = numpy.outer(diagonal, diagonal) difference = density_density_alternative - density_density_matrix self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) # Test spectra. one_body_squared_spectrum = eigenspectrum(one_body_squared) two_body_spectrum = eigenspectrum(two_body_operator) difference = two_body_spectrum - one_body_squared_spectrum self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
def test_molecular_operator_consistency(self): # Initialize H2 InteractionOperator. n_qubits = 4 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') molecule = MolecularData(filename=filename) molecule_interaction = molecule.get_molecular_hamiltonian() molecule_operator = get_fermion_operator(molecule_interaction) constant = molecule_interaction.constant one_body_coefficients = molecule_interaction.one_body_tensor two_body_coefficients = molecule_interaction.two_body_tensor # Perform decomposition. eigenvalues, one_body_squares, one_body_corrections, trunc_error = ( low_rank_two_body_decomposition(two_body_coefficients)) self.assertAlmostEqual(trunc_error, 0.) # Build back operator constant and one-body components. decomposed_operator = FermionOperator((), constant) for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (q, 0)) coefficient = (one_body_coefficients[p, q] + one_body_corrections[p, q]) decomposed_operator += FermionOperator(term, coefficient) # Build back two-body component. for l in range(one_body_squares.shape[0]): one_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (q, 0)) coefficient = one_body_squares[l, p, q] if abs(eigenvalues[l]) > 1e-6: self.assertTrue(is_hermitian(one_body_squares[l])) one_body_operator += FermionOperator(term, coefficient) decomposed_operator += eigenvalues[l] * (one_body_operator ** 2) # Test for consistency. difference = normal_ordered(decomposed_operator - molecule_operator) self.assertAlmostEqual(0., difference.induced_norm()) # Decompose with slightly negative operator that must use eigen molecule = MolecularData(filename=filename) molecule.two_body_integrals[0, 0, 0, 0] -= 1 eigenvalues, one_body_squares, one_body_corrections, trunc_error = ( low_rank_two_body_decomposition(two_body_coefficients)) self.assertAlmostEqual(trunc_error, 0.) # Check for property errors with self.assertRaises(TypeError): eigenvalues, one_body_squares, _, trunc_error = ( low_rank_two_body_decomposition( two_body_coefficients + 0.01j, truncation_threshold=1., final_rank=1))
def run_simulation(bond_lengths): # Load saved file for H3. basis = 'sto-3g' spin = 2 # Set Hamiltonian parameters. active_space_start = 1 active_space_stop = 3 # Set calculation parameters. run_scf = 1 run_mp2 = 1 run_cisd = 0 run_ccsd = 0 run_fci = 1 delete_input = True delete_output = True # Begin Running Simulation, Convert distance_counter to angstroms geometry = [('H', (0., 0., bond_lengths[1][-1] * 0.529177249)), ('H', (0., 0., bond_lengths[2][-1] * 0.529177249)), ('H', (0., 0., bond_lengths[3][-1] * 0.529177249))] # Generate and populate instance of MolecularData. molecule = MolecularData(geometry, basis, spin, description="h3") molecule = run_pyscf(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) # Use a Jordan-Wigner encoding, and compress to remove 0 imaginary components molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=range(active_space_start), active_indices=range(active_space_start, active_space_stop)) fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian) qubit_hamiltonian = jordan_wigner(fermion_hamiltonian) qubit_hamiltonian.compress() compiler_engine = uccsd_trotter_engine() initial_energy = energy_objective(opt_amplitudes) # Run VQE Optimization to find new CCSD parameters opt_result = minimize(energy_objective, opt_amplitudes, method="CG", options={'disp': True}) opt_energy, opt_amplitudes = opt_result.fun, opt_result.x return ({ "Name": molecule.name, "UCCSD Energy": opt_energy, "FCI Energy": molecule.fci_energy })
def get_BK_ham(distance, basis="sto-3g", multiplicity=1, charge=1): geometry = [["He", [0, 0, 0]], ["H", [0, 0, distance]]] description = str(distance) molecule = MolecularData(geometry, basis, multiplicity, charge, description) molecule = run_pyscf(molecule, run_fci=1) bk_hamiltonian = get_sparse_operator( bravyi_kitaev( get_fermion_operator(molecule.get_molecular_hamiltonian()))) return bk_hamiltonian
def __init__(self, geometry=None, basis=None, multiplicity=None, charge=0, description="", filename="", data_directory=None): MolecularData.__init__(self, geometry, basis, multiplicity, charge, description, filename, data_directory) self._pyscf_data = {}
def lih_hamiltonian(): geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))] active_space_start = 1 active_space_stop = 3 molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45") molecule.load() molecular_hamiltonian = molecule.get_molecular_hamiltonian( occupied_indices=range(active_space_start), active_indices=range(active_space_start, active_space_stop)) hamiltonian = get_fermion_operator(molecular_hamiltonian) ground_state_energy = eigenspectrum(hamiltonian)[0] return hamiltonian, ground_state_energy
def get_qubit_hamiltonian(g, basis, charge=0, spin=1, qubit_transf='jw'): ## Create OpenFermion molecule #mol = gto.Mole() #mol.atom = g #mol.basis = basis #mol.spin = spin #mol.charge = charge #mol.symmetry = False ##mol.max_memory = 1024 #mol.build() multiplicity = spin + 1 # spin here is 2S ? mol = MolecularData(g, basis, multiplicity, charge) #mol.load() # Convert to PySCF molecule and run SCF print("Running run_pyscf...") print(f"Time: {time()}") print("=" * 20) mol = run_pyscf(mol) # Freeze some orbitals? occupied_indices = range(183) active_indices = range(183, 183+5) # Get Hamiltonian print("Running get_molecular_hamiltonian...") print(f"Time: {time()}") print("=" * 20) ham = mol.get_molecular_hamiltonian( occupied_indices=occupied_indices, active_indices=active_indices) import pdb; pdb.set_trace() print("Running get_fermion_operator...") print(f"Time: {time()}") print("=" * 20) hamf = get_fermion_operator(ham) print(f"Running {qubit_transf}...") print(f"Time: {time()}") print("=" * 20) if qubit_transf == 'bk': hamq = bravyi_kitaev(hamf) elif qubit_transf == 'jw': hamq = jordan_wigner(hamf) else: raise(ValueError(qubit_transf, 'Unknown transformation specified')) return remove_complex(hamq)
class InteractionRDMTest(unittest.TestCase): def setUp(self): geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = 'sto-3g' multiplicity = 1 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') self.molecule = MolecularData(geometry, basis, multiplicity, filename=filename) self.molecule.load() self.cisd_energy = self.molecule.cisd_energy self.rdm = self.molecule.get_molecular_rdm() self.hamiltonian = self.molecule.get_molecular_hamiltonian() def test_get_qubit_expectations(self): qubit_operator = jordan_wigner(self.hamiltonian) qubit_expectations = self.rdm.get_qubit_expectations(qubit_operator) test_energy = 0.0 for qubit_term in qubit_expectations.terms: term_coefficient = qubit_operator.terms[qubit_term] test_energy += (term_coefficient * qubit_expectations.terms[qubit_term]) self.assertLess(abs(test_energy - self.cisd_energy), EQ_TOLERANCE) def test_get_qubit_expectations_nonmolecular_term(self): with self.assertRaises(InteractionRDMError): self.rdm.get_qubit_expectations(QubitOperator('X1 X2 X3 X4 Y6')) def test_get_qubit_expectations_through_expectation_method(self): qubit_operator = jordan_wigner(self.hamiltonian) test_energy = self.rdm.expectation(qubit_operator) self.assertLess(abs(test_energy - self.cisd_energy), EQ_TOLERANCE) def test_get_molecular_operator_expectation(self): expectation = self.rdm.expectation(self.hamiltonian) self.assertAlmostEqual(expectation, self.cisd_energy, places=7) def test_expectation_bad_type(self): with self.assertRaises(InteractionRDMError): self.rdm.expectation(12) def test_addition(self): rdm2 = self.rdm + self.rdm self.assertTrue( numpy.array_equal(rdm2.one_body_tensor, rdm2.n_body_tensors[(1, 0)])) self.assertTrue( numpy.array_equal(rdm2.two_body_tensor, rdm2.n_body_tensors[(1, 1, 0, 0)]))
def setUp(self): geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))] basis = 'sto-3g' multiplicity = 1 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') self.molecule = MolecularData( geometry, basis, multiplicity, filename=filename) self.molecule.load() self.cisd_energy = self.molecule.cisd_energy self.rdm = self.molecule.get_molecular_rdm() self.hamiltonian = self.molecule.get_molecular_hamiltonian()
def get_single_two_body_file(molecule_file_name): """ Loads the molecule from a file. :param molecule_file_name: Filename :return: Molecule """ molecule = MolecularData(filename=molecule_file_name) molecule.load() # _molecule = run_pyscf(molecule) return molecule.one_body_integrals, molecule.two_body_integrals
def get_h2_dimer(bond_length): # Set molecule parameters. basis = "sto-3g" multiplicity = 1 charge = 0 geometry = [("H", [0.0, 0.0, 0.0]), ("H", [0.0, 0.0, bond_length])] molecule = MolecularData(geometry, basis, multiplicity, charge) molecule.filename = "./" + molecule.filename.split("/")[-1] # Run Psi4. molecule = run_psi4( molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=True, run_fci=True ) return molecule
def LiH_sto3g(): """ Generates the Hamiltonian for LiH in the STO-3G basis, at a distance of 1.45 A. """ geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))] molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45") molecule.load() molecular_hamiltonian = molecule.get_molecular_hamiltonian() hamiltonian = get_fermion_operator(molecular_hamiltonian) num_electrons = molecule.n_electrons num_orbitals = 2 * molecule.n_orbitals return hamiltonian, num_orbitals, num_electrons
def do_make_molecule(self, *args, **kwargs): """ Parameters ---------- args kwargs Returns ------- """ # integrals need to be passed in base class assert ("one_body_integrals" in kwargs) assert ("two_body_integrals" in kwargs) assert ("nuclear_repulsion" in kwargs) assert ("n_orbitals" in kwargs) molecule = MolecularData(**self.parameters.molecular_data_param) molecule.one_body_integrals = kwargs["one_body_integrals"] molecule.two_body_integrals = kwargs["two_body_integrals"] molecule.nuclear_repulsion = kwargs["nuclear_repulsion"] molecule.n_orbitals = kwargs["n_orbitals"] molecule.save() return molecule
def test_h2_rpa(): filename = os.path.join(DATA_DIRECTORY, "H2_sto-3g_singlet_0.7414.hdf5") molecule = MolecularData(filename=filename) reduced_ham = make_reduced_hamiltonian( molecule.get_molecular_hamiltonian(), molecule.n_electrons) hf_opdm = np.diag([1] * molecule.n_electrons + [0] * (molecule.n_qubits - molecule.n_electrons)) hf_tpdm = 2 * of.wedge(hf_opdm, hf_opdm, (1, 1), (1, 1)) pos_spectrum, xy_eigvects, basis = singlet_erpa( hf_tpdm, reduced_ham.two_body_tensor) assert np.isclose(pos_spectrum, 0.92926444) # pyscf-rpa value assert isinstance(xy_eigvects, np.ndarray) assert isinstance(basis, dict)
def h_n_linear_molecule(bond_distance: float, n_hydrogens: int, basis: str = 'sto-3g'): # coverage: ignore if n_hydrogens < 1 or n_hydrogens % 2 != 0: raise ValueError('Must specify a positive, even number of hydrogens.') molecule = MolecularData( geometry=_h_n_linear_geometry(bond_distance, n_hydrogens), charge=0, basis=basis, multiplicity=1, description=f"linear_r-{bond_distance}", ) if NO_OFPSI4: raise NOOFPsi4Error("openfermion-psi4 is not installed") molecule = run_psi4(molecule, run_fci=False, run_mp2=False, run_cisd=False, run_ccsd=False, delete_input=False, delete_output=False) return molecule
def get_openfermion_molecule(geometry, basis, charge, multiplicity, calc_type='fci'): """ Get openfermion molecule objects :param geometry: list of tuples where first element of the tuple is the atom string, and next three coordinates are XYZ geom :param basis: (string) of basis set :param multiplicity: eigenvalue of S^{2} (2S + 1) :param charge: (int) charge on molecule :param calc_type: (string) valid calculation types are: ['scf', 'mp2', 'cisd', 'ccsd', 'fci']. default is 'fci' if 'fci' is selected the fci_one_rdm and fci_two_rdm fields are populated and can be used later. Conversion to particle and holes can occur with methods in the representability.purification.fermionic_marginal :return: """ valid_calc_types = ['scf', 'mp2', 'cisd', 'ccsd', 'fci'] if calc_type not in valid_calc_types: raise TypeError("Calculation type is not valid") molecule = MolecularData(geometry, basis, multiplicity, charge) # get the calculation type run_scf = 1 run_mp2 = 0 run_cisd = 0 run_ccsd = 0 run_fci = 1 # default to fci run molecule = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) return molecule