B4: Quantum Fourier Transform

実行時間制限:3 秒

メモリ制限:512 MiB

配点:200点

Writer:PSL

解説

問題のとおり、量子フーリエ変換は次式の遷移を満たすオラクルとして定義されます。

jnQFT12nk=02n1exp(2πijk2n)kn\begin{equation} \ket{j}_n \xrightarrow{\mathrm{QFT}} \sqrt{\frac{1}{2^n}} \sum_{k=0}^{2^n-1} \exp{\left(\frac{2\pi i j k}{2^n}\right)} \ket{k}_n \end{equation}

このとき、右辺は次のように各量子ビットごとに独立な状態の積として表すことができます。

k=02n1exp(2πijk2n)kn=k0=01kn1=01exp(2πijl=0n1(2lkl)2n)k0kn1=k0=01kn1=01exp(2πijl=0n1(2lnkl))k0kn1=(k0=01e2πij2nk0k0)(k0=01e2πij21nk1k1)(k0=01e2πij21kn1kn1)=(0+e2πi0.jn1j01)(0+e2πi0.jn2j01)(0+e2πi0.j01)\begin{align} \sum_{k=0}^{2^n-1} \exp{\left(\frac{2\pi i j k}{2^n}\right)} \ket{k}_n &= \sum_{k_0=0}^{1} \cdots \sum_{k_{n-1}=0}^{1} \exp{\left(\frac{2\pi i j \sum_{l=0}^{n-1} (2^l k_l)}{2^n}\right)} \ket{k_0 \cdots k_{n-1}} \nonumber\\ &= \sum_{k_0=0}^{1} \cdots \sum_{k_{n-1}=0}^{1} \exp{\left(2\pi i j \sum_{l=0}^{n-1} (2^{l-n} k_l)\right)} \ket{k_0 \cdots k_{n-1}} \nonumber\\ &= \left(\sum_{k_0=0}^{1} e^{2\pi i j 2^{-n} k_0}\ket{k_0}\right) \otimes \left(\sum_{k_0=0}^{1} e^{2\pi i j 2^{1-n} k_1}\ket{k_1}\right)\otimes \cdots \otimes \left(\sum_{k_0=0}^{1} e^{2\pi i j 2^{-1} k_{n-1}}\ket{k_{n-1}}\right) \nonumber\\ &= (\ket{0} + e^{2\pi i 0.j_{n-1} \cdots j_0}\ket{1}) \otimes (\ket{0} + e^{2\pi i 0.j_{n-2} \cdots j_0}\ket{1}) \otimes \cdots \otimes (\ket{0} + e^{2\pi i 0.j_{0}}\ket{1}) \end{align}

ただし、0.x0x1xm=k=0m12(k+1)xk0.x_0x_1 \cdots x_m = \sum_{k=0}^{m-1} 2^{-(k+1)} x_k は二進法の小数表記を表します。

(2) 式の操作は、次の量子回路(n=3n=3)のようにアダマールゲートと制御位相ゲート、スワップゲートを用いて実装できます。

QCoder・Qiskit ではリトルエンディアンを採用しているため、一般的な回路図 とはビットの並びが逆になっていることに注意して下さい。

例えば、この図で 3 つ目の量子ビットの状態は次のように遷移します。

j2H(0+e2πi0.j21)/2CP(π/2,1,0)(0+e2πi0.j2j11)/2CP(π/4,2,0)(0+e2πi0.j2j1j01)/2\begin{align} \ket{j_2} &\xrightarrow{H} (\ket{0} + e^{2\pi i 0.j_2}\ket{1})/\sqrt{2}\nonumber\\ &\xrightarrow{CP(\pi/2, 1, 0)} (\ket{0} + e^{2\pi i 0.j_2j_1}\ket{1})/\sqrt{2}\nonumber\\ &\xrightarrow{CP(\pi/4, 2, 0)} (\ket{0} + e^{2\pi i 0.j_2j_1j_0}\ket{1})/\sqrt{2} \end{align}

最後にスワップゲートによってこの状態は 1 つ目の量子ビットと交換されます。 こうして最終的な 1 つ目の量子ビットの状態は (0+e2πi0.j2j1j01)/2(\ket{0} + e^{2\pi i 0.j_2j_1j_0}\ket{1})/\sqrt{2} となります。 その他の量子ビットについても最終的な状態が (2) 式と一致するかぜひ確かめてみてください。

ゲートを左に詰めていくことでこの回路の深さは 2n2n とわかります。

量子フーリエ変換はショアのアルゴリズムや量子位相推定などの量子アルゴリズムに用いられる重要なサブルーチンとして知られています。

Writer 解説

解答例

解答例は以下の通りです。

import math
 
from qiskit import QuantumCircuit
 
 
def solve(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
 
    for i in reversed(range(n)):
        qc.h(i)
        for j in reversed(range(i)):
            qc.cp(math.pi / 2 ** (i - j), j, i)
 
    for i in range(n // 2):
        qc.swap(i, n - i - 1)
 
    return qc