A controlled phase gate rotates amplitudes only when both the control and target qubits are in state 1. Because this condition is symmetric, control and target roles can be exchanged. section 7.4
Use controlled phase gates to build phase-based circuit patterns:
- Construct the QFT by applying Hadamard gates followed by controlled rotations whose angles depend on qubit positions. section 7.4
- Construct the IQFT by reversing the QFT rotation angles, using negative values. section 7.4
- Encode function values by coupling every key qubit to every value qubit with controlled rotations. section 10.1.1
Encoding a key-dependent phase
For three key qubits and two value qubits, apply qc.cp(pi / 2 ** (n_key - 1 - i), key[j], value[i]) for every key/value pair. Each 1 digit in the key contributes a phase step; applying the IQFT to the value register converts the phase pattern into the encoded output. section 10.1.1
Listing 7.6 Quantum circuits for the QFT and IQFT
def qft(qc, targets, swap=True):
for j in range(len(targets))[::-1]:
qc.h(targets[j])
for k in range(j)[::-1]:
qc.cp(pi * 2.0 ** (k - j), targets[j], targets[k])
if swap:
qc.mswap(targets)
def iqft(qc, targets, swap=True):
for j in range(len(targets))[::-1]:
qc.h(targets[j])
for k in range(j)[::-1]:
qc.cp(-pi * 2 ** (k - j), targets[j], targets[k])
if swap:
qc.mswap(targets)
class QFT(QuantumCircuit):
def __init__(self, m, reversed=False, swap=True):
super().__init__(QuantumRegister(m))
targets = range(m)
if reversed:
targets = targets[::-1]
qft(self, targets, swap)
class IQFT(QuantumCircuit):
def __init__(self, m, reversed=False, swap=True):
super().__init__(QuantumRegister(m))
targets = range(m)
if reversed:
targets = targets[::-1]
iqft(self, targets, swap)
Inspect the QFT and IQFT implementation to see how controlled phase gates are placed, parameterized, and combined with optional swaps. section 7.4
