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_fermionops_tomatrix_hubbard_model(self): hubbard = fermi_hubbard(1, 4, tunneling=1.0, coulomb=2.0, periodic=False) init_wfn = Wavefunction([[2, 0, 4]]) init_wfn.set_wfn(strategy="random") # This calls fermionops_tomatrix. evolved_wfn = init_wfn.time_evolve(1.0, hubbard) # Check. wfn_cirq = to_cirq(init_wfn) unitary = scipy.linalg.expm(-1j * get_sparse_operator(hubbard)) evolved_wfn_cirq = unitary @ wfn_cirq fidelity = abs( vdot(evolved_wfn, from_cirq(evolved_wfn_cirq, thresh=1e-12)))**2 assert numpy.isclose(fidelity, 1.0)
# # 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)
@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
def test_convert_to_spin_blocks(): # skip test if openfermion not installed pytest.importorskip("openfermion") import openfermion hi = nkx.hilbert.SpinOrbitalFermions(3, s=1 / 2) term1 = (((0, 1), (1, 0)), ) term1_conv = _convert_terms_to_spin_blocks(term1, 3, 2) assert term1_conv == (((0, 1), (3, 0)), ) term2 = (((2, 1), (3, 0)), ((4, 1), (5, 0))) term2_conv = _convert_terms_to_spin_blocks(term2, 3, 2) assert term2_conv == (((1, 1), (4, 0)), ((2, 1), (5, 0))) term3 = (((0, 1), (0, 0), (1, 1), (1, 0)), ) term3_conv = _convert_terms_to_spin_blocks(term3, 3, 2) assert term3_conv == (((0, 1), (0, 0), (3, 1), (3, 0)), ) # check fermi-hubbard - netket L = 2 D = 2 t = 1 # tunneling/hopping U = 0.01 # coulomb # create the graph where fermions can hop on g = nk.graph.Hypercube(length=L, n_dim=D, pbc=True) Nsites = g.n_nodes hi = nkx.hilbert.SpinOrbitalFermions(Nsites, s=1 / 2) # create an operator representing fermi hubbard interactions up = +1 / 2 down = -1 / 2 terms = [] weights = [] for sz in (up, down): for u, v in g.edges(): c_u = hi._get_index(u, sz) c_v = hi._get_index(v, sz) terms.append([(c_u, 1), (c_v, 0)]) terms.append([(c_v, 1), (c_u, 0)]) weights.append(-t) weights.append(-t) for u in g.nodes(): nc_up = hi._get_index(u, up) nc_down = hi._get_index(u, down) terms.append([(nc_up, 1), (nc_up, 0), (nc_down, 1), (nc_down, 0)]) weights.append(U) op = nkx.operator.FermionOperator2nd(hi, terms, weights) # eigenspectrum eig = np.linalg.eigvalsh(op.to_dense()) # check fermi-hubbard - openfermion op_of = openfermion.fermi_hubbard(L, D, tunneling=t, coulomb=U, periodic=True, spinless=False) terms_conv = _convert_terms_to_spin_blocks(op_of.terms, Nsites, 2) op_conv = nkx.operator.FermionOperator2nd(hi, terms_conv, list(op_of.terms.values())) # eigenspectrum eig_conv = np.linalg.eigvalsh(op_conv.to_dense()) assert np.allclose(eig_conv, eig) assert np.allclose(op.to_dense(), op_conv.to_dense())
def test_hubbard_model(abscissa: int, ordinate: int, tunneling: float, coulomb: float, magnetic_field: float, chemical_potential: float, periodic: bool, spinless: bool, symmetry: bool): hubbard_operator = fermi_hubbard( x_dimension=abscissa, y_dimension=ordinate, tunneling=tunneling, coulomb=coulomb, chemical_potential=chemical_potential, magnetic_field=magnetic_field, periodic=periodic, spinless=spinless, particle_hole_symmetry=symmetry ) # print(hubbard_operator) jw_hamiltonian = jordan_wigner(hubbard_operator) print('Jordan-Wigner hamiltonian without compression: ') print(jw_hamiltonian) print() jw_hamiltonian.compress() print('Jordan-Wigner hamiltonian with compression: ') print(jw_hamiltonian) print() sparse_operator = get_sparse_operator(hubbard_operator) print('Sparse operator') print(sparse_operator) print() print(f'Energy of the model is {get_ground_state(sparse_operator)[0]} in units of T and J') # xs = range(1, 9) # energy_levels = [ # get_ground_state( # get_sparse_operator( # fermi_hubbard( # x_dimension=x, # y_dimension=ordinate, # tunneling=tunneling, # coulomb=coulomb, # chemical_potential=chemical_potential, # magnetic_field=magnetic_field, # periodic=periodic, # spinless=spinless, # particle_hole_symmetry=symmetry # ) # ) # )[0] # for x in xs # ] # # os.makedirs('assets/hubbard', exist_ok=True) # # draw_plot( # xs, energy_levels, # x_label='X coordinate', # y_label='Ground state energy in units of T and J', # title='Ground state energy of the Hubbard model', # path='assets/hubbard/x.jpeg' # ) # # energy_levels = [ # get_ground_state( # get_sparse_operator( # fermi_hubbard( # x_dimension=abscissa, # y_dimension=x, # tunneling=tunneling, # coulomb=coulomb, # chemical_potential=chemical_potential, # magnetic_field=magnetic_field, # periodic=periodic, # spinless=spinless, # particle_hole_symmetry=symmetry # ) # ) # )[0] # for x in xs # ] # draw_plot( # xs, energy_levels, # x_label='Y coordinate', # y_label='Ground state energy in units of T and J', # title='Ground state energy of the Hubbard model', # path='assets/hubbard/y.jpeg' # ) ts = np.arange(0, 4, 0.2) energy_levels = [ get_ground_state( get_sparse_operator( fermi_hubbard( x_dimension=abscissa, y_dimension=ordinate, tunneling=t, coulomb=coulomb, chemical_potential=chemical_potential, magnetic_field=magnetic_field, periodic=periodic, spinless=spinless, particle_hole_symmetry=symmetry ) ) )[0] for t in ts ] draw_plot( ts, energy_levels, x_label='Tunneling coefficient', y_label='Ground state energy in units of T and J', title='Ground state energy of the Hubbard model', path='assets/hubbard/t.jpeg' )
@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 elif isinstance(hamiltonian, openfermion.InteractionOperator): one_body = hamiltonian.one_body_tensor