qml.QFT¶
- QFT = <Subroutine: QFT>[source]¶
QFT(wires) Apply a quantum Fourier transform (QFT).
For the \(N\)-qubit computational basis state \(|m\rangle\), the QFT performs the transformation
\[|m\rangle \rightarrow \frac{1}{\sqrt{2^{N}}}\sum_{n=0}^{2^{N} - 1}\omega_{N}^{mn} |n\rangle,\]where \(\omega_{N} = e^{\frac{2 \pi i}{2^{N}}}\) is the \(2^{N}\)-th root of unity.
Details:
Number of wires: Any (the operation can act on any number of wires)
Number of parameters: 0
Gradient recipe: None
- Parameters:
wires (int or Iterable[Number, str]]) – the wire(s) the operation acts on
Example
The quantum Fourier transform is applied by specifying the corresponding wires:
wires = 3 dev = qml.device('default.qubit',wires=wires) @qml.qnode(dev) def circuit_qft(basis_state): qml.BasisState(basis_state, wires=range(wires)) qml.QFT(wires=range(wires)) return qml.state()
>>> circuit_qft(np.array([1.0, 0.0, 0.0])) array([ 0.3536+0.j, -0.3536+0.j, 0.3536+0.j, -0.3536+0.j, 0.3536+0.j, -0.3536+0.j, 0.3536+0.j, -0.3536+0.j])
Semiclassical Quantum Fourier transform
If the QFT is the last subroutine applied within a circuit, it can be replaced by a semiclassical Fourier transform. It makes use of mid-circuit measurements and dynamic circuit control based on the measurement values, allowing to reduce the number of two-qubit gates.
As an example, consider the following circuit implementing addition between two numbers with
n_wiresbits (modulo2**n_wires):dev = qml.device("default.qubit") @qml.qnode(dev, shots=1) def qft_add(m, k, n_wires): qml.BasisEmbedding(m, wires=range(n_wires)) qml.adjoint(qml.QFT)(wires=range(n_wires)) for j in range(n_wires): qml.RZ(-k * np.pi / (2**j), wires=j) qml.QFT(wires=range(n_wires)) return qml.sample()
>>> qft_add(7, 3, n_wires=4) array([[1, 0, 1, 0]])
The last building block of this circuit is a QFT, so we may replace it by its semiclassical counterpart:
def scFT(n_wires): '''semiclassical Fourier transform''' for w in range(n_wires-1): qml.Hadamard(w) mcm = qml.measure(w) for m in range(w + 1, n_wires): qml.cond(mcm, qml.PhaseShift)(np.pi / 2 ** (m + 1), wires=m) qml.Hadamard(n_wires-1) @qml.qnode(dev) def scFT_add(m, k, n_wires): qml.BasisEmbedding(m, wires=range(n_wires)) qml.adjoint(qml.QFT)(wires=range(n_wires)) for j in range(n_wires): qml.RZ(-k * np.pi / (2**j), wires=j) scFT(n_wires) # Revert wire order because of PL's QFT convention return qml.sample(wires=list(range(n_wires-1, -1, -1)))
>>> qml.set_shots(scFT_add, 1)(7, 3, n_wires=4) array([[1, 1, 1, 0]])