Quantum Fourier Transform
In this notebook we present how to extend the QCircuit
to define a circuit representing the Quantum Fourier Transform (QFT) for \(n\)-qubits.
For a reminder about the QFT, one can check this medium article.
We first import the required objects.
[2]:
from mpqp.gates import *
from mpqp.execution.result import Result
from mpqp import QCircuit, Barrier
from mpqp.execution import run, IBMDevice
from math import floor
import numpy as np
We define the QFT
class, extending from QCircuit
, taking into parameter the number of qubits of the circuit, and a boolean indicating if the inverse of the QFT is needed.
[3]:
class QFT(QCircuit):
def __init__(self,n_qubits,inverse=False):
super().__init__(n_qubits, nb_cbits=n_qubits)
self.inverse = inverse
self._build()
def _build(self):
for j in range(self.nb_qubits):
self.add(H(j))
self.add([CRk(i+1, i, j) for i in range(j+1, self.nb_qubits)])
self.add(Barrier())
self.add([SWAP(i, self.nb_qubits-1-i) for i in range(int(floor(self.nb_qubits / 2)))])
if self.inverse == True:
self.inverse()
As a matter, we generate and print the Quantum Fourier Transform for 5-qubit systems.
[4]:
qft_5 = QFT(n_qubits=5)
print(qft_5)
┌───┐ ░ »
q_0: ┤ H ├─■────────■────────■────────■─────────░────────────────────────»
└───┘ │P(π/2) │ │ │ ░ ┌───┐ »
q_1: ──────■────────┼────────┼────────┼─────────░─┤ H ├─■────────■───────»
│P(π/4) │ │ ░ └───┘ │P(π/4) │ »
q_2: ───────────────■────────┼────────┼─────────░───────■────────┼───────»
│P(π/8) │ ░ │P(π/8) »
q_3: ────────────────────────■────────┼─────────░────────────────■───────»
│P(π/16) ░ »
q_4: ─────────────────────────────────■─────────░────────────────────────»
░ »
c: 5/════════════════════════════════════════════════════════════════════»
»
« ░ ░ ░ ░
«q_0: ───────────░──────────────────────────░─────────────────░───────░──X────
« ░ ░ ░ ░ │
«q_1: ─■─────────░──────────────────────────░─────────────────░───────░──┼──X─
« │ ░ ┌───┐ ░ ░ ░ │ │
«q_2: ─┼─────────░─┤ H ├─■────────■─────────░─────────────────░───────░──┼──┼─
« │ ░ └───┘ │P(π/8) │ ░ ┌───┐ ░ ░ │ │
«q_3: ─┼─────────░───────■────────┼─────────░─┤ H ├─■─────────░───────░──┼──X─
« │P(π/16) ░ │P(π/16) ░ └───┘ │P(π/16) ░ ┌───┐ ░ │
«q_4: ─■─────────░────────────────■─────────░───────■─────────░─┤ H ├─░──X────
« ░ ░ ░ └───┘ ░
«c: 5/════════════════════════════════════════════════════════════════════════
«
When applied on the basis state \(|0\rangle^{\otimes n}\), we retrieve as expected the fully-parallelized state \(|+\rangle^{\otimes n}\).
[5]:
result = run(qft_5, IBMDevice.AER_SIMULATOR_STATEVECTOR)
if isinstance(result, Result):
print(result.amplitudes)
[0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j 0.1767767+0.j
0.1767767+0.j 0.1767767+0.j]
We then give a couple of example of application of the QFT, when appended at the end of a circuit defining a state.
[6]:
qc1 = QCircuit([H(1)]) + QFT(2)
print(qc1)
result1 = run(qc1, IBMDevice.AER_SIMULATOR_STATEVECTOR)
if isinstance(result1, Result):
print(result1.amplitudes)
┌───┐ ░ ░
q_0: ┤ H ├─■────────░───────░──X─
├───┤ │P(π/2) ░ ┌───┐ ░ │
q_1: ┤ H ├─■────────░─┤ H ├─░──X─
└───┘ ░ └───┘ ░
[0.70710678-4.32978028e-17j 0.35355339+3.53553391e-01j
0. +4.32978028e-17j 0.35355339-3.53553391e-01j]
[7]:
W_circuit = QCircuit([Ry(2*np.arccos(1/np.sqrt(3)),0),Ry(-np.pi/4,1),CZ(0,1),Ry(np.pi/4,1),CNOT(1,2),CNOT(0,1),X(0)])
qc2 = W_circuit + QFT(3)
print(qc2)
result2 = run(qc2, IBMDevice.AER_SIMULATOR_STATEVECTOR)
if isinstance(result2, Result):
print(result2.amplitudes)
┌────────────┐ ┌───┐┌───┐ ░ »
q_0: ┤ Ry(1.9106) ├─■───────────────────■──┤ X ├┤ H ├─■────────■────────░──────»
└┬──────────┬┘ │ ┌─────────┐ ┌─┴─┐└───┘└───┘ │P(π/2) │ ░ ┌───┐»
q_1: ─┤ Ry(-π/4) ├──■─┤ Ry(π/4) ├──■──┤ X ├───────────■────────┼────────░─┤ H ├»
└──────────┘ └─────────┘┌─┴─┐└───┘ │P(π/4) ░ └───┘»
q_2: ────────────────────────────┤ X ├─────────────────────────■────────░──────»
└───┘ ░ »
« ░ ░
«q_0: ──────────░───────░──X─
« ░ ░ │
«q_1: ─■────────░───────░──┼─
« │P(π/4) ░ ┌───┐ ░ │
«q_2: ─■────────░─┤ H ├─░──X─
« ░ └───┘ ░
[ 0.61237244-7.49939943e-17j -0.05978658+3.48461713e-01j
0.14433757+1.44337567e-01j -0.20412415+4.09474745e-17j
0.20412415-2.49979981e-17j -0.34846171+5.97865779e-02j
-0.14433757-1.44337567e-01j -0.20412415-4.08248290e-01j]