解説
この問題は 問題 B5 のオラクルを利用して、量子位相推定 1 と呼ばれる量子アルゴリズムを適用することで解くことができます。
n = 2 , m = 2 n = 2,\ m = 2 n = 2 , m = 2 の場合の回路図は次のように表されます。
以下、下位 m m m ビットをレジスタ ∣ y ⟩ m \ket{y}_m ∣ y ⟩ m と表記して、上位 n n n ビットの計算基底状態 ∣ x ⟩ n \ket{x}_n ∣ x ⟩ n に対するレジスタ ∣ y ⟩ m \ket{y}_m ∣ y ⟩ m の状態遷移をみていきます。
はじめにレジスタ ∣ y ⟩ m = ∣ 0 ⟩ \ket{y}_m = \ket{0} ∣ y ⟩ m = ∣ 0 ⟩ の各量子ビットにアダマールゲートを作用させ、一様重ね合わせ状態を生成します。
∣ 0 ⟩ m → H ⊗ n 1 2 m ∑ k = 0 2 m − 1 ∣ k ⟩ m = 1 2 m ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) \begin{align}
\ket{0}_m &\xrightarrow{H^{\otimes n}} \frac{1}{\sqrt{2^m}} \sum_{k=0}^{2^m-1} \ket{k}_m \nonumber\\
&= \frac{1}{\sqrt{2^m}} (\ket{0} + \ket{1}) \otimes (\ket{0} + \ket{1}) \otimes \cdots \otimes (\ket{0} + \ket{1})
\end{align} ∣ 0 ⟩ m H ⊗ n 2 m 1 k = 0 ∑ 2 m − 1 ∣ k ⟩ m = 2 m 1 ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ )
ここで、問題 B5 では次の遷移を実現するオラクルを実装しました。
∣ x ⟩ → O exp ( 2 π i f ( x ) 2 m ) ∣ x ⟩ \begin{equation}
\ket{x} \xrightarrow{O} \exp{\left(\frac{2\pi i f(x)}{2^m}\right)}\ket{x}
\end{equation} ∣ x ⟩ O exp ( 2 m 2 πi f ( x ) ) ∣ x ⟩
ここで、このオラクルの位相に 2 j 2^j 2 j をかけたようなオラクルを P S 2 j P_{S}^{2^j} P S 2 j として定義します。
∣ x ⟩ → P S 2 j exp ( 2 π i f ( x ) 2 m ⋅ 2 j ) ∣ x ⟩ \begin{equation}
\ket{x} \xrightarrow{P_{S}^{2^j}} \exp{\left(\frac{2\pi i f(x)}{2^m} \cdot 2^j\right)}\ket{x}
\end{equation} ∣ x ⟩ P S 2 j exp ( 2 m 2 πi f ( x ) ⋅ 2 j ) ∣ x ⟩
次に、生成した一様重ね合わせ状態に対して、レジスタ ∣ y ⟩ m \ket{y}_m ∣ y ⟩ m の j j j 番目を制御ビットとしたオラクル P S 2 j P_{S}^{2^j} P S 2 j をそれぞれ ∣ x ⟩ \ket{x} ∣ x ⟩ に対して作用させます。
1 2 m ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) → P S 2 0 , P S 2 1 , ⋯ , P S 2 m − 1 1 2 m ( ∣ 0 ⟩ + e 2 π i f ( x ) ⋅ 2 0 2 m ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + e 2 π i f ( x ) ⋅ 2 1 2 m ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + e 2 π i f ( x ) ⋅ 2 m − 1 2 m ∣ 1 ⟩ ) = 1 2 m ∑ k = 0 2 m − 1 e 2 π i f ( x ) k 2 m ∣ k ⟩ m \begin{align}
&\frac{1}{\sqrt{2^m}} (\ket{0} + \ket{1}) \otimes (\ket{0} + \ket{1}) \otimes \cdots \otimes (\ket{0} + \ket{1}) \nonumber \\
\xrightarrow{P_S^{2^0}, P_S^{2^1}, \cdots, P_S^{2^{m-1}}} &\frac{1}{\sqrt{2^m}} (\ket{0} + e^{\frac{2\pi i f(x)\cdot 2^0}{2^m}}\ket{1}) \otimes (\ket{0} + e^{\frac{2\pi i f(x)\cdot 2^1}{2^m}}\ket{1}) \otimes \cdots \otimes (\ket{0} + e^{\frac{2\pi i f(x)\cdot 2^{m-1}}{2^m}}\ket{1}) \nonumber\\
= &\frac{1}{\sqrt{2^m}} \sum_{k=0}^{2^m-1} e^{\frac{2\pi i f(x)k}{2^m}} \ket{k}_m
\end{align} P S 2 0 , P S 2 1 , ⋯ , P S 2 m − 1 = 2 m 1 ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + ∣ 1 ⟩ ) 2 m 1 ( ∣ 0 ⟩ + e 2 m 2 πi f ( x ) ⋅ 2 0 ∣ 1 ⟩ ) ⊗ ( ∣ 0 ⟩ + e 2 m 2 πi f ( x ) ⋅ 2 1 ∣ 1 ⟩ ) ⊗ ⋯ ⊗ ( ∣ 0 ⟩ + e 2 m 2 πi f ( x ) ⋅ 2 m − 1 ∣ 1 ⟩ ) 2 m 1 k = 0 ∑ 2 m − 1 e 2 m 2 πi f ( x ) k ∣ k ⟩ m
最後に、問題 B4 で実装した量子フーリエ変換の逆変換である逆量子フーリエ変換を作用させることでレジスタ ∣ y ⟩ m \ket{y}_m ∣ y ⟩ m を目的の状態に遷移させることができます。
1 2 m ∑ k = 0 2 m − 1 e 2 π i f ( x ) k 2 m ∣ k ⟩ m → I Q F T ∣ f ( x ) ⟩ m \begin{align}
\frac{1}{\sqrt{2^m}} \sum_{k=0}^{2^m-1} e^{\frac{2\pi i f(x)k}{2^m}} \ket{k}_m \xrightarrow{\mathrm{IQFT}} \ket{f(x)}_m
\end{align} 2 m 1 k = 0 ∑ 2 m − 1 e 2 m 2 πi f ( x ) k ∣ k ⟩ m IQFT ∣ f ( x ) ⟩ m
(5) 式の遷移は、次式で表される量子フーリエ変換の定義から明らかです。
∣ j ⟩ m → Q F T 1 2 m ∑ k = 0 2 m − 1 exp ( 2 π i j k 2 m ) ∣ k ⟩ m \begin{equation}
\ket{j}_m \xrightarrow{\mathrm{QFT}} \sqrt{\frac{1}{2^m}} \sum_{k=0}^{2^m-1} \exp{\left(\frac{2\pi i j k}{2^m}\right)} \ket{k}_m
\end{equation} ∣ j ⟩ m QFT 2 m 1 k = 0 ∑ 2 m − 1 exp ( 2 m 2 πijk ) ∣ k ⟩ m
以上の操作により、次の状態遷移を実現する量子回路を実装できます。
∣ x ⟩ n ∣ 0 ⟩ m → q c ∣ x ⟩ n ∣ f ( x ) m o d 2 m ⟩ m \begin{equation}
\ket{x}_{n}\ket{0}_{m} \xrightarrow{\mathrm{qc}} \ket{x}_{n}\ket{f(x)\ \mathrm{mod}\ 2^m}_{m}
\end{equation} ∣ x ⟩ n ∣ 0 ⟩ m qc ∣ x ⟩ n ∣ f ( x ) mod 2 m ⟩ m
回路の深さは 1 + m a x ( n , m ) + 2 m 1 + \mathrm{max}(n, m) + 2m 1 + max ( n , m ) + 2 m です。
Writer 解説
解答例
解答例は以下の通りです。
import math
from qiskit import QuantumCircuit, QuantumRegister
def qft ( 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
def solve ( n : int , m : int , S : list[ int ]) -> QuantumCircuit:
x, y = QuantumRegister(n), QuantumRegister(m)
qc = QuantumCircuit(x, y)
qc.h(y)
for j in range (m):
for i in range (n):
theta = ( 2 * math.pi * S[i] / 2 ** m) * 2 ** j
qc.cp(theta, x[i], y[j])
qc.compose(qft(m).inverse(), y, inplace = True )
return qc