B3: Controlled Constant Addition

Time Limit: 3 sec

Memory Limit: 512 MiB

Score: 300

Writer: PSL

Editorial

Quantum Fourier Transform (QFT\mathrm{QFT}) is defined as follows:

An nn-qubit quantum oracle that satisfies the following transition for any integer with 0j<2n0 \leq j < 2^n.

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

Therefore, you can solve this problem by using QFT\mathrm{QFT}, the operation in Problem B2 (controlled phase shift) and inversed QFT (IQFT\mathrm{IQFT}).

knc1QFT12nj=02n1exp(2πijk2n)jnc1B212nj=02n1exp(2πi(k+ca)j2n)jnc1IQFT(k+ca)mod2nnc1\begin{align} \ket{k}_n\ket{c}_1 &\xrightarrow{\mathrm{QFT}} \sqrt{\frac{1}{2^n}} \sum_{j=0}^{2^n-1} \exp{\left(\frac{2\pi i j k}{2^n}\right)} \ket{j}_n\ket{c}_1 \nonumber\\ &\xrightarrow{\mathrm{B2}} \sqrt{\frac{1}{2^n}} \sum_{j=0}^{2^n-1} \exp{\left(\frac{2\pi i(k + ca)j}{2^n}\right)} \ket{j}_n\ket{c}_1 \nonumber\\ &\xrightarrow{\mathrm{IQFT}} \ket{(k + ca) \bmod 2^n}_n \ket{c}_1 \end{align}

You don't have to make QFT\mathrm{QFT} and IQFT\mathrm{IQFT} as controlled gates. The circuit depth is O(n)O(n).

Sample Code

Below is a sample program:

import math
 
from qiskit import QuantumCircuit
 
 
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
 
 
# B2
def crot(n: int, a: int) -> QuantumCircuit:
    qc = QuantumCircuit(n + 1)
 
    for i in range(n):
        theta = 2 * math.pi * a * 2**i / 2**n
        qc.cp(theta, n, i)
 
    return qc
 
 
def solve(n: int, a: int) -> QuantumCircuit:
    k, c = QuantumRegister(n), QuantumRegister(1)
    qc = QuantumCircuit(k, c)
 
    qc.compose(qft(n), qubits=k, inplace=True)
    qc.compose(crot(n, a), qubits=[*k, *c], inplace=True)
    qc.compose(qft(n).inverse(), qubits=k, inplace=True)
 
    return qc