らんだむな記憶

blogというものを体験してみようか!的なー

逆量子 Fourier 変換 (1)

先へ進みたいが、逆 Fourier 変換の回路図を押さえておきたいので、量子 Fourier 変換 - らんだむな記憶 の内容を可視化したい。Quantum Fourier Transform のコードをそのまま利用する。

import numpy as np
from numpy import pi
# importing Qiskit
from qiskit import QuantumCircuit, execute, Aer

def qft_rotations(circuit, n):
    """Performs qft on the first n qubits in circuit (without swaps)"""
    if n == 0:
        return circuit
    n -= 1
    circuit.h(n)
    for qubit in range(n):
        circuit.cp(pi/2**(n-qubit), qubit, n)
    # At the end of our function, we call the same function again on
    # the next qubits (we reduced n by one earlier in the function)
    qft_rotations(circuit, n)

def swap_registers(circuit, n):
    for qubit in range(n//2):
        circuit.swap(qubit, n-qubit-1)
    return circuit

def qft(circuit, n):
    """QFT on the first n qubits in circuit"""
    qft_rotations(circuit, n)
    swap_registers(circuit, n)
    return circuit

が量子 Fourier 変換の実装で、$n=3$ の場合に以下のように可視化する:

# Let's see how it looks:
qc = QuantumCircuit(3)
qft(qc,3)

qc.measure_all()

qc.draw('mpl')

f:id:derwind:20220131015116p:plain

次に逆量子 Fourier 変換についてみる。これは以下のような実装になるらしい:

def inverse_qft(circuit, n):
    """Does the inverse QFT on the first n qubits in circuit"""
    # First we create a QFT circuit of the correct size:
    qft_circ = qft(QuantumCircuit(n), n)
    # Then we take the inverse of this circuit
    invqft_circ = qft_circ.inverse()
    # And add it to the first n qubits in our existing circuit
    circuit.append(invqft_circ, circuit.qubits[:n])
    return circuit.decompose() # .decompose() allows us to see the individual gates

これを以下で可視化する:

qc = QuantumCircuit(3)
qc = inverse_qft(qc, 3)

qc.measure_all()

qc.draw('mpl')

f:id:derwind:20220131020753p:plain

逆の回路図になっている。

最後に、量子 Fourier 変換をして、逆量子 Fourier 変換をした時に元の値が観測されることを見よう:

qc = QuantumCircuit(3)
number = 3
for i, b in enumerate(reversed(bin(number)[2:])):
    if b == '1':
        qc.x(i)

qc = qft(qc, 3)
qc = inverse_qft(qc, 3)

qc.measure_all()
# qc.draw('mpl')
backend = Aer.get_backend('qasm_simulator')
shots = 1024
results = execute(qc, backend=backend, shots=shots).result()
answer = results.get_counts()

plot_histogram(answer)

f:id:derwind:20220131022903p:plain

number に 3 = 0b011 を与えると、$\ket{011}$ が観測されていることが分かる。5 = 0b101 を与えると $\ket{101}$ が観測される。
なお、qc.draw('mpl') すると、左右対象は絵が出るかと思ったが、最適化のせいか?見た目は非対称な絵が出た。内容的には上記の 2 つの回路図を結合したものと等価だとは思うのだが・・・。