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