def test_8mode_ffft_with_external_swaps_on_single_logical_state(self): n_qubits = 8 grid = Grid(dimensions=1, length=n_qubits, scale=1.0) eng = MainEngine() register = eng.allocate_qureg(n_qubits) state_index = 157 prepare_logical_state(register, state_index) ffft(eng, register, n_qubits) Ph(3 * numpy.pi / 4) | register[0] eng.flush() wvfn = ordered_wavefunction(eng) fermion_operator = prepare_integer_fermion_operator(state_index) # Swap 01234567 to 45670123 for fourier_transform. Additionally, # the FFFT's ordering is 04261537, so swap 04261537 to 01234567, # and then 01234567 to 45670123. swap_mode_list = ([1, 3, 5, 2, 4, 1, 3, 5] + [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3]) for mode in swap_mode_list: fermion_operator = normal_ordered(fermion_operator) fermion_operator = swap_adjacent_fermionic_modes( fermion_operator, mode) ffft_result = fourier_transform(fermion_operator, grid, spinless=True) ffft_result = normal_ordered(ffft_result) # After the FFFT, swap 45670123 -> 01234567. swap_mode_list = [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3] for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) converted_wvfn = numpy.zeros(2 ** n_qubits, dtype=complex) for term in ffft_result.terms: index = sum(2 ** site[0] for site in term) converted_wvfn[index] = ffft_result.terms[term] All(Measure) | register self.assertTrue(numpy.allclose(wvfn, converted_wvfn))
def test_4mode_ffft_with_external_swaps_all_logical_states(self): n_qubits = 4 grid = Grid(dimensions=1, length=n_qubits, scale=1.0) for i in range(2**n_qubits): eng = MainEngine() register = eng.allocate_qureg(n_qubits) prepare_logical_state(register, i) ffft(eng, register, n_qubits) Ph(3 * numpy.pi / 4) | register[0] eng.flush() wvfn = ordered_wavefunction(eng) fermion_operator = prepare_integer_fermion_operator(i) # Reorder the modes for correct input to the FFFT. # Swap 0123 to 2301 for fourier_transform. Additionally, the # FFFT's ordering is 0213, so connect 0213 -> 0123 -> 2301. swap_mode_list = [1] + [1, 0, 2, 1] for mode in swap_mode_list: fermion_operator = normal_ordered(fermion_operator) fermion_operator = swap_adjacent_fermionic_modes( fermion_operator, mode) ffft_result = fourier_transform(fermion_operator, grid, spinless=True) ffft_result = normal_ordered(ffft_result) swap_mode_list = [1, 0, 2, 1] # After FFFT, swap 2301 -> 0123 for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) converted_wvfn = numpy.zeros(2**n_qubits, dtype=complex) for term in ffft_result.terms: index = sum(2**site[0] for site in term) converted_wvfn[index] = ffft_result.terms[term] All(Measure) | register self.assertTrue(numpy.allclose(wvfn, converted_wvfn))
def test_8mode_ffft_with_external_swaps_equal_expectation_values(self): n_qubits = 8 grid = Grid(dimensions=1, length=n_qubits, scale=1.0) dual_basis = jellium_model(grid, spinless=True, plane_wave=False) ffft_result = normal_ordered(dual_basis) # Swap 01234567 to 45670123 for fourier_transform. Additionally, # the FFFT's ordering is 04261537, so swap 04261537 to 01234567, # and then 01234567 to 45670123. swap_mode_list = ([1, 3, 5, 2, 4, 1, 3, 5] + [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3]) for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) ffft_result = normal_ordered(ffft_result) ffft_result = fourier_transform(ffft_result, grid, spinless=True) ffft_result = normal_ordered(ffft_result) # After the FFFT, swap 45670123 -> 01234567. swap_mode_list = [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3] for mode in swap_mode_list: ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode) ffft_result = normal_ordered(ffft_result) jw_dual_basis = jordan_wigner(dual_basis) jw_plane_wave = jordan_wigner(ffft_result) # Do plane wave and dual basis calculations simultaneously. pw_engine = MainEngine() pw_wavefunction = pw_engine.allocate_qureg(n_qubits) db_engine = MainEngine() db_wavefunction = db_engine.allocate_qureg(n_qubits) pw_engine.flush() db_engine.flush() # Choose random state. state = numpy.zeros(2 ** n_qubits, dtype=complex) for i in range(len(state)): state[i] = (random.random() * numpy.exp(1j * 2 * numpy.pi * random.random())) state /= numpy.linalg.norm(state) # Put randomly chosen state in the registers. pw_engine.backend.set_wavefunction(state, pw_wavefunction) db_engine.backend.set_wavefunction(state, db_wavefunction) prepare_logical_state(pw_wavefunction, i) prepare_logical_state(db_wavefunction, i) All(H) | [pw_wavefunction[1], pw_wavefunction[3]] All(H) | [db_wavefunction[1], db_wavefunction[3]] ffft(db_engine, db_wavefunction, n_qubits) Ph(3 * numpy.pi / 4) | db_wavefunction[0] # Flush the engine and compute expectation values and eigenvalues. pw_engine.flush() db_engine.flush() plane_wave_expectation_value = ( pw_engine.backend.get_expectation_value( jw_dual_basis, pw_wavefunction)) dual_basis_expectation_value = ( db_engine.backend.get_expectation_value( jw_plane_wave, db_wavefunction)) All(Measure) | pw_wavefunction All(Measure) | db_wavefunction self.assertAlmostEqual(plane_wave_expectation_value, dual_basis_expectation_value)
def test_basic_swap(self): operator = normal_ordered(FermionOperator('2^ 2 4^ 4')) operator_swapped = swap_adjacent_fermionic_modes(operator, 2) self.assertTrue(operator_swapped == FermionOperator('4^ 3^ 4 3', -1.0))