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
def test_spin_symmetric_bogoliubov_transform( n_spatial_orbitals, conserves_particle_number, atol=5e-5): n_qubits = 2*n_spatial_orbitals qubits = LineQubit.range(n_qubits) # Initialize a random quadratic Hamiltonian quad_ham = random_quadratic_hamiltonian( n_spatial_orbitals, conserves_particle_number, real=True, expand_spin=True, seed=28166) # Reorder the Hamiltonian and get sparse matrix quad_ham = openfermion.get_quadratic_hamiltonian( openfermion.reorder( openfermion.get_fermion_operator(quad_ham), openfermion.up_then_down) ) quad_ham_sparse = get_sparse_operator(quad_ham) # Compute the orbital energies and transformation_matrix up_orbital_energies, _, _ = ( quad_ham.diagonalizing_bogoliubov_transform(spin_sector=0)) down_orbital_energies, _, _ = ( quad_ham.diagonalizing_bogoliubov_transform(spin_sector=1)) _, transformation_matrix, _ = ( quad_ham.diagonalizing_bogoliubov_transform()) # Pick some orbitals to occupy up_orbitals = list(range(2)) down_orbitals = [0, 2, 3] energy = sum(up_orbital_energies[up_orbitals]) + sum( down_orbital_energies[down_orbitals]) + quad_ham.constant # Construct initial state initial_state = ( sum(2**(n_qubits - 1 - int(i)) for i in up_orbitals) + sum(2**(n_qubits - 1 - int(i+n_spatial_orbitals)) for i in down_orbitals) ) # Apply the circuit circuit = cirq.Circuit.from_ops( bogoliubov_transform( qubits, transformation_matrix, initial_state=initial_state)) state = circuit.apply_unitary_effect_to_state(initial_state) # Check that the result is an eigenstate with the correct eigenvalue numpy.testing.assert_allclose( quad_ham_sparse.dot(state), energy * state, atol=atol)
def test_prepare_gaussian_state_with_spin_symmetry(n_spatial_orbitals, conserves_particle_number, occupied_orbitals, initial_state, atol=1e-5): n_qubits = 2 * n_spatial_orbitals qubits = LineQubit.range(n_qubits) # Initialize a random quadratic Hamiltonian quad_ham = random_quadratic_hamiltonian( n_spatial_orbitals, conserves_particle_number, real=True, expand_spin=True, seed=639) # Reorder the Hamiltonian and get sparse matrix quad_ham = openfermion.get_quadratic_hamiltonian( openfermion.reorder( openfermion.get_fermion_operator(quad_ham), openfermion.up_then_down) ) quad_ham_sparse = get_sparse_operator(quad_ham) # Compute the energy of the desired state energy = 0.0 for spin_sector in range(2): orbital_energies, _, _ = ( quad_ham.diagonalizing_bogoliubov_transform( spin_sector=spin_sector) ) energy += sum(orbital_energies[i] for i in occupied_orbitals[spin_sector]) energy += quad_ham.constant # Get the state using a circuit simulation circuit = cirq.Circuit.from_ops( prepare_gaussian_state( qubits, quad_ham, occupied_orbitals, initial_state=initial_state)) if isinstance(initial_state, list): initial_state = sum(1 << (n_qubits - 1 - i) for i in initial_state) state = circuit.apply_unitary_effect_to_state(initial_state) # Check that the result is an eigenstate with the correct eigenvalue numpy.testing.assert_allclose( quad_ham_sparse.dot(state), energy * state, atol=atol)
def __call__(self, fermion_operator: openfermion.FermionOperator, *args, **kwargs) -> QubitHamiltonian: """ :param fermion_operator: an openfermion FermionOperator :return: The openfermion QubitOperator of this class ecoding """ if self.up_then_down: op = openfermion.reorder(operator=fermion_operator, order_function=openfermion.up_then_down, num_modes=2 * self.n_orbitals) else: op = fermion_operator fop = self.do_transform(fermion_operator=op, *args, **kwargs) fop.compress() return self.post_processing(QubitHamiltonian.from_openfermion(fop))
@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
longer_time = 1.0 long_time = 0.1 short_time = 0.05 # 5-qubit random DiagonalCoulombHamiltonian diag_coul_hamiltonian = openfermion.random_diagonal_coulomb_hamiltonian( 5, real=False, seed=65233) diag_coul_initial_state, diag_coul_exact_state = ( produce_simulation_test_parameters(diag_coul_hamiltonian, long_time, seed=49075)) # Hubbard model, reordered hubbard_model = openfermion.fermi_hubbard(2, 2, 1.0, 4.0) hubbard_model = openfermion.reorder(hubbard_model, openfermion.up_then_down) hubbard_hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian( hubbard_model) hubbard_initial_state, hubbard_exact_state = ( produce_simulation_test_parameters(hubbard_hamiltonian, long_time, seed=8200)) # 4-qubit H2 2-2 with bond length 0.7414 bond_length = 0.7414 geometry = [('H', (0., 0., 0.)), ('H', (0., 0., bond_length))] h2_hamiltonian = openfermion.load_molecular_hamiltonian( geometry, 'sto-3g', 1, format(bond_length), 2, 2) h2_initial_state, h2_exact_state = produce_simulation_test_parameters( h2_hamiltonian, longer_time, seed=44303)