Editorial
You can gain better insight by splitting E(m,k) based on whether the last n−1 qubits are in the state ∣0⟩n−1 or not.
First, we decompose E(m,k) as follows:
E(m,k)=2n+11F(m,k)+2n1G(m,k)
where
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
Next, by using the given hint, we express F(m′,k′) in terms of mleft,kleft,m, and k as follows:
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(mleft+m)+b((−1)mkleft+k)∣a⟩∣b⟩∣0⟩n−1=0≤a<2∑0≤b<2∑(−1)a(mleft+m)+b(kleft+k)∣a⟩∣b⟩∣0⟩n−1=0≤a<2∑0≤b<2∑(−1)amleft+bkleft(−1)am+bk∣a⟩∣b⟩∣0⟩n−1
Therefore, when the last n−1 qubits are in the ∣0⟩ state, the following two operations are required:
- If mleft≡1 (mod 2), apply a Z gate to ∣a⟩.
- If kleft≡1 (mod 2), apply a Z gate to ∣b⟩.
Similarly, by using the hint, we express G(m′,k′) in terms of mleft,kleft,m, and k:
G(m′,k′)=1≤c<2n−1∑(Xm′Rck′⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(Xmleft+mRc((−1)mkleft+k)⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(Xmleft+mR(−1)mckleft+ck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(XmleftRckleftXmRck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1=1≤c<2n−1∑(XmleftRckleft⊗I1⊗In−1)(XmRck⊗I1⊗In−1)(∣0⟩∣0⟩+∣1⟩∣1⟩)∣c⟩n−1
Then, by expanding c bitwise, the expression XmleftRckleft becomes:
XmleftRckleft=XmleftRc0kleftRc1(2kleft)... Rcn−2(2n−2kleft)
Therefore, when at least one of the last n−1 qubits is in the ∣1⟩ state, the following two operations are required:
- For any j∈{0,1,…,n−2}, if cj=1, apply the R2jkleft to ∣a⟩. (You can implement this using the rotation gate Rz.)
- If mleft≡1 (mod 2), apply an X gate to ∣a⟩. (You can implement this using the Problem A3 circuit.)
By performing the above operations in sequence, you can obtain the desired quantum state.
The circuit diagram for n=4,mleft=1, and kleft=2 is as follows.
The circuit depth is O(n).
Sample Code
Below is a sample program:
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_left: int, k_left: int) -> QuantumCircuit:
a, b, c = QuantumRegister(1), QuantumRegister(1), QuantumRegister(n - 1)
qc = QuantumCircuit(a, b, c)
qc.x(c)
if m_left:
qc.compose(ZGate().control(len(c)), [*c, a[0]], inplace=True)
if k_left % 2:
qc.compose(ZGate().control(len(c)), [*c, b[0]], inplace=True)
qc.x(c)
theta = 2 * math.pi / 2 ** (n - 1)
for i in range(n - 1):
angle = theta * k_left * (2 ** i)
qc.compose(RZGate(angle).control(1),
[c[i], a[0]], inplace=True)
if m_left:
qc.compose(A3(n - 1), [a[0], *c], inplace=True)
return qc