def kevin_hubbard_cirq(self): # Create Hubbard model Hamiltonian # -------------------------------- x_dim = 3 y_dim = 2 n_sites = x_dim * y_dim n_modes = 2 * n_sites tunneling = 1.0 coulomb = 4.0 hubbard_model = of.fermi_hubbard(x_dim, y_dim, tunneling, coulomb) # Reorder indices hubbard_model = of.reorder(hubbard_model, of.up_then_down) # Convert to DiagonalCoulombHamiltonian hubbard_hamiltonian = of.get_diagonal_coulomb_hamiltonian( hubbard_model) # Create qubits qubits = cirq.LineQubit.range(n_modes) # State preparation circuit for eigenstate of one-body term # --------------------------------------------------------- # Set the pseudo-particle orbitals to fill up_orbitals = range(n_sites // 2) down_orbitals = range(n_sites // 2) # Create the circuit hubbard_state_preparation_circuit = cirq.Circuit.from_ops( ofc.prepare_gaussian_state( qubits, of.QuadraticHamiltonian(hubbard_hamiltonian.one_body), occupied_orbitals=(up_orbitals, down_orbitals)), strategy=cirq.InsertStrategy.EARLIEST) # Trotter simulation circuit # -------------------------- n_steps = 10 order = 0 hubbard_simulation_circuit = cirq.Circuit.from_ops( ofc.simulate_trotter(qubits, hubbard_hamiltonian, time=1.0, n_steps=n_steps, order=order, algorithm=ofc.trotter.LINEAR_SWAP_NETWORK), strategy=cirq.InsertStrategy.EARLIEST) t0 = time.time() self.kevin_optimize_circuit(hubbard_state_preparation_circuit) self.kevin_optimize_circuit(hubbard_simulation_circuit) t1 = time.time() # print('Optimizing circuits took {} seconds'.format(t1 - t0)) # print(hubbard_state_preparation_circuit.to_text_diagram(transpose=True)) return hubbard_state_preparation_circuit, hubbard_simulation_circuit
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import numpy import cirq import openfermion from openfermioncirq.variational.ansatzes import SwapNetworkTrotterAnsatz # Construct a Hubbard model Hamiltonian hubbard_model = openfermion.fermi_hubbard(2, 2, 1., 4.) hubbard_hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian( hubbard_model) # Construct an empty Hamiltonian zero_hamiltonian = openfermion.DiagonalCoulombHamiltonian(one_body=numpy.zeros( (4, 4)), two_body=numpy.zeros( (4, 4))) def test_swap_network_trotter_ansatz_params(): ansatz = SwapNetworkTrotterAnsatz(hubbard_hamiltonian) assert (set(ansatz.params()) == { cirq.Symbol(name) for name in { 'T_0_2_0', 'T_4_6_0', 'T_1_3_0', 'T_5_7_0', 'T_0_4_0', 'T_2_6_0',
@pytest.mark.parametrize( 'ansatz, trotter_algorithm, order, hamiltonian, atol', [ (SwapNetworkTrotterAnsatz(diag_coul_hamiltonian, iterations=1), LINEAR_SWAP_NETWORK, 1, diag_coul_hamiltonian, 5e-5), (SplitOperatorTrotterAnsatz(diag_coul_hamiltonian, iterations=1), SPLIT_OPERATOR, 1, diag_coul_hamiltonian, 5e-5), (LowRankTrotterAnsatz(h2_hamiltonian, iterations=1), LOW_RANK, 0, h2_hamiltonian, 5e-5), (LowRankTrotterAnsatz(lih_hamiltonian, iterations=1, final_rank=3), LowRankTrotterAlgorithm(final_rank=3), 0, lih_hamiltonian, 5e-5), (SwapNetworkTrotterHubbardAnsatz(2, 2, 1.0, 4.0, iterations=1), LINEAR_SWAP_NETWORK, 1, openfermion.get_diagonal_coulomb_hamiltonian( openfermion.reorder( openfermion.fermi_hubbard(2, 2, 1.0, 4.0), openfermion.up_then_down) ), 5e-5) ]) def test_trotter_ansatzes_default_initial_params_iterations_1( ansatz, trotter_algorithm, order, hamiltonian, atol): """Check that a Trotter ansatz with one iteration and default parameters is consistent with time evolution with one Trotter step.""" objective = HamiltonianObjective(hamiltonian) qubits = ansatz.qubits if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian): one_body = hamiltonian.one_body
length_scale = openfermion.wigner_seitz_length_scale(wigner_seitz_radius, n_electrons, n_dimensions) grid = openfermion.Grid(n_dimensions, grid_length, length_scale) # 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(
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()