Therefore, by using the operation of problem C4 with ∣ki⟩ as the control bit, the desired operation can be realized by using the controlled circuit CC4 of problem C4.
import mathfrom qiskit import QuantumCircuit, QuantumRegisterdef inv_mod(a: int, L: int) -> int: def extended_euclidean(a: int, b: int) -> tuple[int, int, int]: # when b == 0: if b == 0: return a, 1, 0 # recursive step gcd, x1, y1 = extended_euclidean(b, a % b) # update x and y x = y1 y = x1 - (a // b) * y1 return gcd, x, y _, x, _ = extended_euclidean(a, L) return x % Ldef beki(n: int, a: int, L: int) -> list[int]: result = [a] for _ in range(n - 1): result.append(result[-1] ** 2 % L) return resultdef 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 qcdef mcadd(n: int, a: int, c: int) -> QuantumCircuit: qc = QuantumCircuit(n + c) qc.compose(qft(n), qubits=range(n), inplace=True) for i in range(n): theta = 2 * math.pi * a * 2**i / 2**n if c == 0: qc.p(theta, i) elif c == 1: qc.cp(theta, n, i) else: qc.mcp(theta, list(range(n, n + c)), i) qc.compose(qft(n).inverse(), qubits=range(n), inplace=True) return qcdef mcadd_mod(n: int, a: int, L: int, c: int) -> QuantumCircuit: qc = QuantumCircuit(n + 1 + c) qc.compose(mcadd(n + 1, 2**n - L + a, c), qubits=range(n + 1 + c), inplace=True) qc.x(n) qc.compose(mcadd(n, -(2**n - L + a), c + 1), qubits=range(n + 1 + c), inplace=True) qc.x(n) qc.compose(mcadd(n, 2**n - a, c + 1), qubits=range(n + 1 + c), inplace=True) qc.compose(mcadd(n + 1, a, c), qubits=range(n + 1 + c), inplace=True) return qcdef cswap(n: int) -> QuantumCircuit: qc = QuantumCircuit(2 * n + 1) for i in range(n): qc.cswap(2 * n, i, i + n) return qcdef solve(n: int, m: int, a: int, L: int) -> QuantumCircuit: x, y = QuantumRegister(n), QuantumRegister(2 * m + 1) qc = QuantumCircuit(x, y) qc.h(x) qc.x(y[0]) lst = beki(n, a, L) a_inv = inv_mod(a, L) lst_inv = beki(n, a_inv, L) lst_minus_inv = [(-v) % L for v in lst_inv] for i in range(n): b = lst[i] for j in range(m): qc.compose(mcadd_mod(m, b, L, 2), qubits=[*y[m:], x[i], y[j]], inplace=True) b = 2 * b % L qc.compose(cswap(m), qubits=[*y[: 2 * m], x[i]], inplace=True) b = lst_minus_inv[i] for j in range(m): qc.compose(mcadd_mod(m, b, L, 2), qubits=[*y[m:], x[i], y[j]], inplace=True) b = 2 * b % L return qc
Follow-up
In the original draft of the contest problems, there were the following problems, D1 and D2, at the end.
Although they were not used in the contest because of limitations in the judging system, we include the problems and their explanations here to deepen understanding of Shor’s algorithm.
Problem D1
You are given integers n, m, a, and L.
The inputs satisfy 1≤L≤2n and 0≤a<L, and a and L are coprime.
Implement, on a quantum circuit qc with n+2m+1 qubits, an operation that creates the superposition state ∣B⟩ from the zero state. Then, by measuring the leftmost n qubits, estimate the period r of akmodL.
The superposition state ∣B⟩ is defined as follows:
Although it is not completely rigorous, if we ignore the factor r1∑s=0r−1∣us⟩, we obtain
2m1k=0∑2m−1exp(2m2πi(2ms/r)k)∣k⟩
Now, if we apply the IQFT and obtain a measurement result λ, then λ≈r2ms, so that 2mλ≈rs.
Note that both r and s are unknown. However, even this information is sufficient to narrow down the candidates for r.
For example, suppose 2mλ=81923413, then, by using a continued fraction expansion, we can approximate as follows: