Exemplo n.º 1
0
def OptimizeVQEOpenFermion(u,v,t):
    '''
    Function to optimize a VQE for the hamiltonian and ansatz we are looking at by using the built in optimizer in openfermion.

    Parameters
    ----------
    U : float
        One the parameters in the Hamiltonian, see report for description.
    V : float
        One the parameters in the Hamiltonian, see report for description.
    t : float
        One the parameters in the Hamiltonian, see report for description.

    Returns
    -------
    List
        List containing 4 values: 1) theta at minimum, 2) phi at minimum, 3) energy at minimum, 4) Error in the energy w.r.t. the exact ground state energy.

    '''
    ansatz = Ansatz()
    hamiltonian = Hamiltonian(u,v,t)
    
    objective = ofc.HamiltonianObjective(hamiltonian)
    
    study = ofc.VariationalStudy(
        name='TritonToy',
        ansatz=ansatz,
        objective=objective)
        
    optimization_params = OptimizationParams(
        algorithm=COBYLA,
        initial_guess=[1,1])
    result = study.optimize(optimization_params)
        
    minimum_energy = result.optimal_value + (8*t + 3*u/4 + v/16)
    minimum_energy_error = result.optimal_value - np.amin(of.eigenspectrum(hamiltonian))
    
    minimum_theta = result.optimal_parameters[0]
    minimum_phi = result.optimal_parameters[1]
    
    text = "Minimum E = {}, at theta = {} and phi = {} error = {}.".format(minimum_energy, minimum_theta, minimum_phi, minimum_energy_error)   
    print(text)
    
    return [minimum_theta, minimum_phi, minimum_energy, minimum_energy_error]
Exemplo n.º 2
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 = None
    active_indices = None

    #import pdb; pdb.set_trace()

    # Try:
    occupied_indices = range(183)
    active_indices = range(15)
    # when it stops lagging

    # 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)

    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'))

    # Adapted from 10.5281/zenodo.2880550
    hamd = openfermion.get_diagonal_coulomb_hamiltonian(
        hamf, ignore_incompatible_terms=True)
    nqubits = openfermion.count_qubits(hamd)
    ansatz = openfermioncirq.SwapNetworkTrotterAnsatz(hamd, iterations=3)
    print(ansatz.circuit.to_text_diagram(transpose=True))

    nelectrons = 8  # TODO: CHECK WHICH ORBITALS ARE SAMPLED!!

    prep_circuit = cirq.Circuit(
        openfermioncirq.prepare_gaussian_state(
            ansatz.qubits, openfermion.QuadraticHamiltonian(
                hamd.one_body)))  # TODO: Verify this line
    objective = openfermioncirq.HamiltonianObjective(hamd)
    study = openfermioncirq.VariationalStudy(name='hamil',
                                             ansatz=ansatz,
                                             objective=objective,
                                             preparation_circuit=prep_circuit)

    print("The energy of the default initial guess is {}.".format(
        study.value_of(ansatz.default_initial_params())))
    print()

    alg = openfermioncirq.optimization.ScipyOptimizationAlgorithm(
        kwargs={'method': 'COBYLA'}, uses_bounds=False)
    opt_params = openfermioncirq.optimization.OptimizationParams(
        algorith=alg, initial_guess=ansat.default_initial_params())
    result = study.optimize(opt_param)

    print("Optimized energy: {}".format(result.optimal_value))
    print()
# Initialize the model and compute its ground energy in the correct particle number manifold
fermion_hamiltonian = openfermion.jellium_model(grid,
                                                spinless=spinless,
                                                plane_wave=False)
hamiltonian_sparse = openfermion.get_sparse_operator(fermion_hamiltonian)
ground_energy, _ = openfermion.jw_get_ground_state_at_particle_number(
    hamiltonian_sparse, n_electrons)
print('The ground energy of the jellium Hamiltonian at {} electrons is {}'.
      format(n_electrons, ground_energy))

# Convert to DiagonalCoulombHamiltonian type.
hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian(fermion_hamiltonian)

# Define the objective function
objective = openfermioncirq.HamiltonianObjective(hamiltonian)

# Create a swap network Trotter ansatz.
iterations = 1  # This is the number of Trotter steps to use in the ansatz.
ansatz = openfermioncirq.SwapNetworkTrotterAnsatz(hamiltonian,
                                                  iterations=iterations)

print('Created a variational ansatz with the following circuit:')
print(ansatz.circuit.to_text_diagram(transpose=True))

# Use preparation circuit for mean-field state
import cirq
preparation_circuit = cirq.Circuit(
    openfermioncirq.prepare_gaussian_state(
        ansatz.qubits,
        openfermion.QuadraticHamiltonian(hamiltonian.one_body),
Exemplo n.º 4
0
# Wave Function Ansatz (parameterized guess) U(theta)
ansatz = MyAnsatz()
q0, q1, _, _ = ansatz.qubits

# Initialize to |11> state
##  U(theta)|11> --> best guess ground state
preparation_circuit = cq.Circuit.from_ops(cq.X(q0), cq.X(q1))

#%%

## Run a study on a single bond length
molecule = of.MolecularData([('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))],
                            'sto-3g', 1, 0)
molecule.load()
objective = ofcq.HamiltonianObjective(molecule.get_molecular_hamiltonian())

study = ofcq.VariationalStudy(name='my_hydrogen_study',
                              ansatz=ansatz,
                              objective=objective,
                              preparation_circuit=preparation_circuit)

result = study.optimize(optimization_params)
print("Initial state energy in Hartrees: {}".format(molecule.hf_energy))
print("Optimized energy result in Hartree: {}".format(result.optimal_value))
print("Exact energy result in Hartees for reference: {}".format(
    molecule.fci_energy))

#%%

# for storing results at different bond lengths