解説
前問とほとんど同じ方法で解くことができます。
E(m,k) を末尾の n−1 量子ビットが ∣0⟩n−1 となる状態と、そうでない状態に分けて考えると見通しが良くなるので、以下のように分解します。
E(m,k)=2n+11F(m,k)+2n1G(m,k)
ここで、
F(m,k)=0≤a<2∑0≤b<2∑(−1)am+bk∣a⟩∣b⟩∣0⟩n−1
G(m,k)=1≤c<2n−1∑(XmRck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1
とします。
まず、ヒントの式を用いることによって、F(m′,k′) を mright,kright,m,k で表します。
F(m′,k′)=0≤a<2∑0≤b<2∑(−1)am′+bk′∣a⟩∣b⟩∣0⟩n−1=0≤a<2∑0≤b<2∑(−1)a(m+mright)+b((−1)mkrightk+kright)∣a⟩∣b⟩∣0⟩n−1=0≤a<2∑0≤b<2∑(−1)a(m+mright)+b(k+kright)∣a⟩∣b⟩∣0⟩n−1=0≤a<2∑0≤b<2∑(−1)amright+bkright(−1)am+bk∣a⟩∣b⟩∣0⟩n−1
よって、末尾の n−1 量子ビットが 0 のときに必要となる操作は以下の二つになります。
- mright≡1 (mod 2) なら、∣a⟩ に Z ゲートを作用させる。
- kright≡1 (mod 2) なら、∣b⟩ に Z ゲートを作用させる。
同様にして、ヒントの式を用いることによって、G(m′,k′) を mright,kright,m,k で表します。
G(m′,k′)=1≤c<2n−1∑(Xm′Rck′⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(Xm+mrightRc((−1)mrightk+kright)⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(Xm+mrightR(−1)mrightck+ckright⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(XmRckXmrightRckright⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1
さて、前問では Xmleft Rckleft が左から作用されていましたが、本問では Xmright Rckright が右から作用されています。
これが、この問題の核心となります。では、この Xmright Rckright をどう扱えば良いでしょうか。
実は任意の行列 U,V に対して、次の等式が成り立ちます。
(UV⊗I1)(∣0⟩∣0⟩+∣1⟩∣1⟩)=(U⊗VT)(∣0⟩∣0⟩+∣1⟩∣1⟩)
このことから、X=XT,R=RT という性質を用いることで、次の式変形が成り立ちます。
式 (11)=1≤c<2n−1∑(XmRck⊗(XmrightRckright)T⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(I1⊗(XmrightRckright)T⊗In−1)(XmRck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(I1⊗RckrightXmright⊗In−1)(XmRck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1
そして、c をビット毎に展開すると、RckrightXmright は以下のようになります。
RckrightXmright=Rc0krightRc1(2kright)... Rcn−2(2n−2kright)Xmright
よって、末尾の n−1 量子ビットに 1 が含まれるときに必要となる操作は以下の二つになります。
- mright≡1 (mod 2) なら、∣b⟩ に X を作用させる。(これは、問題 A3の回路を利用して実装できます。)
- 任意の j∈{0,1,…,n−2} に対して cj=1なら、∣b⟩ に R2jkright を作用させる。(これは、回転ゲート Rz を利用して実装できます。)
以上の操作を順に行うことで、目的の量子状態を得ることができます。
n=4,mright=1,kright=2 の場合の量子回路は次のように表されます。
回路の深さは O(n) です。
解答例
解答例は以下の通りです。
import math
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import XGate, ZGate, RZGate
def A3(n: int) -> QuantumCircuit:
m, k = QuantumRegister(1), QuantumRegister(n)
qc = QuantumCircuit(m, k)
qc.x(m[0])
qc.x(k)
qc.compose(XGate().control(len(k)), [*k, m[0]], inplace=True)
qc.x(k)
return qc
def solve(n: int, m_right: int, k_right: int) -> QuantumCircuit:
a, b, c = QuantumRegister(1), QuantumRegister(1), QuantumRegister(n - 1)
qc = QuantumCircuit(a, b, c)
qc.x(c)
if m_right:
qc.compose(ZGate().control(len(c)), [*c, a[0]], inplace=True)
if k_right % 2:
qc.compose(ZGate().control(len(c)), [*c, b[0]], inplace=True)
qc.x(c)
if m_right:
qc.compose(A3(n - 1), [b[0], *c], inplace=True)
theta = 2 * math.pi / 2 ** (n - 1)
for i in range(n - 1):
angle = theta * k_right * (2 ** i)
qc.compose(RZGate(angle).control(1),
[c[i], b[0]], inplace=True)
return qc