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
예제 #2
0
    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)
예제 #3
0
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)
예제 #4
0
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()
예제 #5
0
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()
예제 #6
0
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)
예제 #8
0
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)
예제 #9
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()

        # 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)
예제 #10
0
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
예제 #11
0
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)
예제 #12
0
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
예제 #13
0
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)
예제 #14
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)
예제 #15
0
    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)))
예제 #16
0
    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
예제 #19
0
 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 = {}
예제 #20
0
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
예제 #21
0
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)]))
예제 #23
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()
예제 #24
0
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
예제 #25
0
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
예제 #27
0
파일: qc_base.py 프로젝트: akpc/margarita
    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
예제 #28
0
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