예제 #1
0
    def test_2mode_ffft_correct_frequencies(self):
        n_qubits = 2
        frequencies_seen = numpy.zeros(n_qubits)

        for qubit in range(n_qubits):
            engine = MainEngine()
            register = engine.allocate_qureg(n_qubits)
            X | register[qubit]
            ffft(engine, register, n_qubits)
            engine.flush()

            wavefunction = ordered_wavefunction(engine)
            nonzero_wavefunction_elmts = []
            for el in wavefunction:
                if abs(el) > 10 ** -5:
                    nonzero_wavefunction_elmts.append(el)
            All(Measure) | register

            phase_factor = (nonzero_wavefunction_elmts[1] /
                            nonzero_wavefunction_elmts[0])
            offset = numpy.angle(nonzero_wavefunction_elmts[0])

            self.assertAlmostEqual(offset, 0.0)
            for i in range(1, len(nonzero_wavefunction_elmts)):
                self.assertAlmostEqual(phase_factor,
                                       (nonzero_wavefunction_elmts[i] /
                                        nonzero_wavefunction_elmts[i - 1]))
            frequencies_seen[qubit] = numpy.angle(phase_factor)

        frequencies_seen = numpy.sort(frequencies_seen)
        expected = numpy.sort(2 * numpy.pi * numpy.arange(n_qubits) / n_qubits)

        self.assertTrue(numpy.allclose(frequencies_seen, expected))
예제 #2
0
    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))
예제 #3
0
    def test_ffft_2modes_properly_applied(self):
        eng_ft_0 = MainEngine()
        reg_ft_0 = eng_ft_0.allocate_qureg(2)

        eng_ffft_recursive = MainEngine()
        reg_ffft_recursive = eng_ffft_recursive.allocate_qureg(2)

        ffft(eng_ffft_recursive, reg_ffft_recursive, 2)
        fourier_transform_0(reg_ft_0, 0, 1)
        eng_ffft_recursive.flush()
        eng_ft_0.flush()

        All(Measure) | reg_ffft_recursive
        All(Measure) | reg_ft_0

        self.assertTrue(numpy.allclose(
            ordered_wavefunction(eng_ffft_recursive),
            ordered_wavefunction(eng_ft_0)))
예제 #4
0
    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))
예제 #5
0
    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)
예제 #6
0
 def test_ffft_1mode_error(self):
     eng = MainEngine()
     reg = eng.allocate_qureg(1)
     with self.assertRaises(ValueError):
         ffft(eng, reg, 1)