Author: Anubhav Vardhan (anubhavvardhan@gmail.com)
For more information about QuTiP see http://qutip.org
In [1]:
%pylab inline
In [2]:
from IPython.display import Image
In [3]:
from qutip import *
In quantum computing and specifically the quantum circuit model of computation, a quantum gate (or quantum logic gate) is a basic quantum circuit operating on a small number of qubits. They are the building blocks of quantum circuits, like classical logic gates are for conventional digital circuits.
Unlike many classical logic gates, quantum logic gates are reversible. However, classical computing can be performed using only reversible gates. For example, the reversible Toffoli gate can implement all Boolean functions. This gate has a direct quantum equivalent, showing that quantum circuits can perform all operations performed by classical circuits.
In [4]:
cphase(pi/2)
Out[4]:
In [5]:
Image(filename='images/cphase.png')
Out[5]:
In [6]:
rx(pi/2)
Out[6]:
In [7]:
Image(filename='images/rx.png')
Out[7]:
In [8]:
ry(pi/2)
Out[8]:
In [9]:
Image(filename='images/ry.png')
Out[9]:
In [10]:
rz(pi/2)
Out[10]:
In [11]:
Image(filename='images/rz.png')
Out[11]:
In [12]:
cnot()
Out[12]:
In [13]:
Image(filename='/home/anubhav/Images/cnot.png')
Out[13]:
In [14]:
csign()
Out[14]:
In [15]:
Image(filename='images/csign.png')
Out[15]:
In [16]:
berkeley()
Out[16]:
In [17]:
Image(filename='images/berkeley.png')
Out[17]:
In [18]:
swapalpha(pi/2)
Out[18]:
In [19]:
Image(filename='images/swapalpha.png')
Out[19]:
In [20]:
fredkin()
Out[20]:
In [21]:
Image(filename='images/fredkin.png')
Out[21]:
In [22]:
toffoli()
Out[22]:
In [23]:
Image(filename='images/toffoli.png')
Out[23]:
In [24]:
swap()
Out[24]:
In [25]:
Image(filename='images/swap.png')
Out[25]:
In [26]:
iswap()
Out[26]:
In [27]:
Image(filename='images/iswap.png')
Out[27]:
In [28]:
sqrtiswap()
Out[28]:
In [29]:
Image(filename='images/sqrtiswap.png')
Out[29]:
In [30]:
sqrtswap()
Out[30]:
In [31]:
Image(filename='images/sqrtswap.png')
Out[31]:
In [32]:
sqrtnot()
Out[32]:
In [33]:
Image(filename='images/sqrtnot.png')
Out[33]:
In [34]:
snot()
Out[34]:
In [35]:
Image(filename='images/snot.png')
Out[35]:
In [36]:
phasegate(pi/2)
Out[36]:
In [37]:
Image(filename='images/phasegate.png')
Out[37]:
In [38]:
globalphase(pi/2)
Out[38]:
In [39]:
Image(filename='images/globalphase.png')
Out[39]:
The example above show how to generate matrice representations of the gates implemented in QuTiP, in their minimal qubit requirements. If the same gates is to be represented in a qubit register of size $N$, the optional keywork argument N
can be specified when calling the gate function. For example, to generate the matrix for the CNOT gate for a $N=3$ bit register:
In [40]:
cnot(N=3)
Out[40]:
In [41]:
Image(filename='images/cnot310.png')
Out[41]:
Furthermore, the control and target qubits (when applicable) can also be similarly specified using keyword arguments control
and target
(or in some cases controls
or targets
):
In [42]:
cnot(N=3, control=2, target=0)
Out[42]:
In [43]:
Image(filename='images/cnot302.png')
Out[43]:
The gates implemented in QuTiP can be used to build any qubit circuit using the class QubitCircuit. The output can be obtained in the form of a unitary matrix or a latex representation.
In the following example, we take a SWAP gate. It is known that a swap gate is equivalent to three CNOT gates applied in the given format.
In [44]:
N = 2
qc0 = QubitCircuit(N)
qc0.add_gate("SWAP", [0, 1], None)
qc0.png
Out[44]:
In [45]:
U_list0 = qc0.propagators()
U0 = gate_sequence_product(U_list0)
U0
Out[45]:
In [46]:
qc1 = QubitCircuit(N)
qc1.add_gate("CNOT", 0, 1)
qc1.add_gate("CNOT", 1, 0)
qc1.add_gate("CNOT", 0, 1)
qc1.png
Out[46]:
In [47]:
U_list1 = qc1.propagators()
U1 = gate_sequence_product(U_list1)
U1
Out[47]:
In place of manually converting the SWAP gate to CNOTs, it can be automatically converted using an inbuilt function in QubitCircuit
In [48]:
qc2 = qc0.resolve_gates("CNOT")
qc2.png
Out[48]:
In [49]:
U_list2 = qc2.propagators()
U2 = gate_sequence_product(U_list2)
U2
Out[49]:
In [50]:
qc3 = QubitCircuit(3)
qc3.add_gate("CNOT", 1, 0)
qc3.add_gate("RX", 0, None, pi/2, r"\pi/2")
qc3.add_gate("RY", 1, None, pi/2, r"\pi/2")
qc3.add_gate("RZ", 2, None, pi/2, r"\pi/2")
qc3.add_gate("ISWAP", [1, 2])
qc3.png
Out[50]:
In [51]:
U3 = gate_sequence_product(qc3.propagators())
U3
Out[51]:
In [52]:
qc4 = qc3.resolve_gates("CNOT")
qc4.png
Out[52]:
In [53]:
U4 = gate_sequence_product(qc4.propagators())
U4
Out[53]:
In [54]:
qc5 = qc3.resolve_gates("ISWAP")
qc5.png
Out[54]:
In [55]:
U5 = gate_sequence_product(qc5.propagators())
U5
Out[55]:
In [56]:
qc6 = qc3.resolve_gates(["ISWAP", "RX", "RY"])
qc6.png
Out[56]:
In [57]:
U6 = gate_sequence_product(qc6.propagators())
U6
Out[57]:
In [58]:
qc7 = qc3.resolve_gates(["CNOT", "RZ", "RX"])
qc7.png
Out[58]:
In [59]:
U7 = gate_sequence_product(qc7.propagators())
U7
Out[59]:
Interactions between non-adjacent qubits can be resolved by QubitCircuit to a series of adjacent interactions, which is useful for systems such as spin chain models.
In [60]:
qc8 = QubitCircuit(3)
qc8.add_gate("CNOT", 2, 0)
qc8.png
Out[60]:
In [61]:
U8 = gate_sequence_product(qc8.propagators())
U8
Out[61]:
In [62]:
qc9 = qc8.adjacent_gates()
qc9.png
Out[62]:
In [63]:
U9 = gate_sequence_product(qc9.propagators())
U9
Out[63]:
In [64]:
qc10 = qc9.resolve_gates("CNOT")
qc10.png
Out[64]:
In [65]:
U10 = gate_sequence_product(qc10.propagators())
U10
Out[65]:
In [66]:
from qutip.ipynbtools import version_table
version_table()
Out[66]: