Introduction

In the second part of this series I talked about the Haskell implementation of Qubits. There are two more articles about the library and after that I will start posting about algorithms. In this article we will define some Quantum Gates that we will use in our algorithms, even if in the first article I wrote a little about this topic and I presented some matrices.

Background

As we already know computers are built using logic gates and in a similar way quantum computation also use logic gates that can be designed by considering unitary transformation of the qubits. In conclusion, we can construct infinitely many quantum logic gates with the constraint that they must be reversible.

In the first article from this series I already presented some gates but we didn’t see their symbol or truth table.

1 qubit gates

Pauli X-Gate or NOT gate

Symbol: Matrix:

Transformation:

$\newcommand{\ket}{\left|{#1}\right\rangle}$ $\newcommand{\bra}{\left\langle{#1}\right|}$ $X\ket{0}=\ket{1}, X\ket{1}=\ket{0}$

Pauli Y-Gate

Symbol: Matrix:

Transformation:

Pauli Z-Gate

Symbol: Matrix:

Transformation:

Symbol: Matrix:

Transformation:

Controlled Quantum Gates

Controlled Quantum Gates are useful for implementing IF-THEN-ELSE type operations. In this article we will only present CNOT.

Controlled-NOT (CNOT)

Symbol: Truth Table:

x y x $(x\oplus y)$
0 0 0 0
0 1 0 1
1 0 1 1
1 1 1 0

Implementation

Having the background now, let’s start implementing those gates in Haskell. First, let’s define a new data named Gate.

data Gate=
Gate {
gateMatrix::(Matrix C)
} deriving (Eq,Show)


Our data Gate has a constructor Gate with one parameter, gateMatrix, of type ** complex matrx, Matrix C. Let’s see the code in **GHCI:

ghci>:t Gate
Gate :: Matrix C -> Gate
ghci>let g= Gate ((2><2) [1,0,0,-1]::Matrix C)
ghci>g
Gate {gateMatrix = (2><2)
[ 1.0 :+ 0.0,       0.0 :+ 0.0
, 0.0 :+ 0.0, (-1.0) :+ (-0.0) ]}
ghci>>gateMatrix g
(2><2)
[ 1.0 :+ 0.0,       0.0 :+ 0.0
, 0.0 :+ 0.0, (-1.0) :+ (-0.0) ]


In the above example we created a Pauli Z-Gate. We will proceed like for Qubit and we will define some functions that will return a Gate. We will implement the Pauli X-Gate, Y-Gate, Z-Gate, Hadamard Gate, CNOT-Gate, and Controlled Phase Shift Gate ( we will need in Grover’s Algorithm).

xGate::Gate
xGate=Gate ((2><2)[0,1,1,0]::Matrix C)

yGate::Gate
yGate=Gate ((2><2) [0.0,0.0:+(-1.0),0.0:+1.0,0.0]::Matrix C)

zGate::Gate
zGate=Gate ((2><2) [1,0,0,-1]::Matrix C)

hGate::Gate
hGate=Gate ((2><2) [1/sqrt 2,1/sqrt 2,1/sqrt 2,(-1)/sqrt 2]::Matrix C)

cNotGate::Gate
cNotGate=Gate ((4><4)[1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0]::Matrix C)

cPhaseShifGate::Gate
cPhaseShifGate=Gate ((4><4)[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,-1]::Matrix C)


Now, in GHCI, if we call, for example zGate we will see that the output is the same with the one from the previous example:

ghci>zGate
Gate {gateMatrix = (2><2)
[ 1.0 :+ 0.0,       0.0 :+ 0.0
, 0.0 :+ 0.0, (-1.0) :+ (-0.0) ]}
ghci>:t zGate
zGate :: Gate


Conclusions

In this article we implemented some 1-qubit Gates and some Controlled-Gate. In next articles we will define some functions to apply those gate on qubits and also to create gates, starting from 1-qubit ones, that apply on multiple qubits. New ideas, features, issues are welcomed and I encourage every reader to submit them on Github or ask questions using Disquss.