Quantum Fourier Transform¶
This tutorial creates a quantum Fourier transform by using quantum routines, or sub-circuits.
Routines allow us to define portions of circuit that we might repeat several times during the circuit generation. They behave similarly to quantum gates, meaning that you can apply operators that you would normally use on quantum gates, such as control or dagger.
Here, we will define a routine describing a Quantum Fourier Transform, giving us for free an Inverse QFT, thanks to a simple dagger operation.
Because routines are quantum gates, they have a fixed arity. Thus, we need a function that, given the number of qbits, say n
, returns a routine performing a QFT over n
qbits
from qat.lang.AQASM import QRoutine, Program, PH, H
import math
# We implement the QFT recursively
def QFT(n):
# If there is only one qbit, then the QFT is a simple H gate
qft_routine = QRoutine()
if(n == 1):
# Gates are applied using the .apply method.
# Arguments are specified by indexes.
# 0 means that the H gate must be applied
# on the first argument passed to the routine
qft_routine.apply(H, 0)
return qft_routine
# Wires can also be allocated (simpler to manage)
wires = qft_routine.new_wires(n)
qft_routine.apply(H, wires[0])
for i in range(1, n):
qft_routine.apply(PH(math.pi/pow(2.,i)).ctrl(), wires[0], wires[i])
qft_routine.apply(QFT(n-1), wires[1:])
return qft_routine
Notice that we only used application of quantum gates inside the routine. QRoutines should be seen as macros for quantum gates only. In order to ensure a consistent behavior, they must describe unitary operators (no measure, no cbits operations).
We can also easily define the inverse QFT:
def IQFT(n):
return QFT(n).dag()
Using a routine inside a proper ciruit is as simple as using a quantum gate:
prog = Program()
rout_qft_10 = QFT(10)
reg = prog.qalloc(10)
prog.apply(rout_qft_10, reg)
We can now extract our circuit and display it:
prog.to_circ().display()