Skip to content

Commit

Permalink
Finish Simulator Section of report
Browse files Browse the repository at this point in the history
  • Loading branch information
adamisntdead committed Jan 5, 2017
1 parent 8a8e668 commit 14a3d0b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
11 changes: 3 additions & 8 deletions Code/Simulator/QuSim.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,9 @@ def applyGate(self, gate, qubit1, qubit2=-1):
raise ValueError(
'Cannot Apply Gate to a Measured Quantum Register')
else:
if gate == 'CNOT':
gateMatrix = gates.generateGate(
gate, self.numQubits, qubit1, qubit2)
self.amplitudes = np.dot(self.amplitudes, gateMatrix)
else:
# Qubit 1 is the target
gateMatrix = gates.generateGate(gate, self.numQubits, qubit1)
self.amplitudes = np.dot(self.amplitudes, gateMatrix)
gateMatrix = gates.generateGate(
gate, self.numQubits, qubit1, qubit2)
self.amplitudes = np.dot(self.amplitudes, gateMatrix)

def measure(self):
if self.measured:
Expand Down
7 changes: 4 additions & 3 deletions Report/appedix/controlledGates.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
\begin{document}

One method of creating 'Controlled Unitary-2x2 Gates',
that involves a new number \(c\), or the control value.
When working with this value, it has all of the properties of a real number (\(\mathbb{R}\)), except that the kronecker product of any matrix \(M\), and \(c\) is:
that involves a new value \(c\), or the control value. It is a fairly "Hacky" Solution but it works.

When working with this value, c, it has all of the properties of a real number (\(\mathbb{R}\)), except that the product of any matrix \(M\), and \(c\) is:
\begin{equation}
c \otimes M = c \cdot Id
c \cdot M = c \cdot Id
\end{equation}
With \(Id\) Being a 2x2 Identity matrix. \\
Now with a control matrix, \(C = \begin{bmatrix} c & 0 \\ 0 & 1\end{bmatrix}\), You can create any controlled matrix \(CG_{control, target, n}\) (With \(G\) being the 2x2 matrix you want to apply, \(control\) being the number of the qubit controlling the opperation, \(target\) being the number of the qubit you want to apply \(G\) to conditionally, and \(n\) being the total number of qubits in the register) with this equation:
Expand Down
3 changes: 1 addition & 2 deletions Report/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@
]{biblatex}
\addbibresource{sections/ref.bib}

\title{Designing a High Level Programming Language for Quantum Computing}
\subtitle{For the implementation and simulation of Classical and Quantum Algorithms}
\title{Implementing a High Level Programming Language and Simulator for Quantum Computing}
\author{Adam Kelly}
\date{January 2017}

Expand Down
37 changes: 33 additions & 4 deletions Report/sections/simulation.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
When thinking of simulating a Quantum Computer, there are a number of possible ways to implement it, depending on what you want from your simulator.
Regardless of what method, it will always get exponentially slower as you add more Qubits to simulate, as the number of amplitudes you need to store is \(2^n\).
To get the most accurate simulation, you need to also simulate 'Decoherence', which is where the system will loose information due to measurements by the outside environment, although the simulator detailed here is called an 'Ideal' Simulator, as it doesn't also simulate Decoherence.
In this project, the simulator will be built upon vector-matrix opperations.
In this project, the simulator will be built upon vector-matrix operations.

\subsection{Quantum Register}
When you start the simulator, you have to have a new Quantum Register. When a new Quantum Register is created, it creates a new \(2^n\) dimensional vector of zero, and then it sets the first 0 to 1. This is the same as representing an n Qubit state, and setting all n Qubits to the state \(\lvert0\rangle\). Remember:
Expand Down Expand Up @@ -126,7 +126,7 @@ \subsubsection{Writing the Gate Generator}
\begin{itemize}
\item \emph{gate}: The gate to be applied (i.e. X)
\item \emph{numQubits}: The number of qubits in the register the gate will be applied to.
\item \emph{qubit1}: The main qubit. In the case of a single qubit gate, it will be the qubit the gate is to be applied on. In the case of a Controled gate (CNOT), it is the target
\item \emph{qubit1}: The main qubit. In the case of a single qubit gate, it will be the qubit the gate is to be applied on. In the case of a Controlled gate (CNOT), it is the target
\item \emph{qubit2}: In the case that its a controlled gate being applied (CNOT), then this would be the target qubit. It has a default value of 1, and doesn't need to be used if its not a CNOT
\end{itemize}

Expand All @@ -136,7 +136,7 @@ \subsubsection{Writing the Gate Generator}
\begin{lstlisting}[language=Python]
def generateGate(gate, numQubits, qubit1, qubit2=1):
else:
# Put these here for handyness
# Put these here for handiness
identity = gates.singleQubitGates['Id']
mainGate = gates.singleQubitGates[gate]

Expand All @@ -151,10 +151,39 @@ \subsubsection{Writing the Gate Generator}
return reduce(np.kron, gateOrder)
\end{lstlisting}

So that code works if you want to generate a gate that only acts on one qubit, but we have to do something else if we want to use a CNOT gate. The way this function works is based on the "Formula" in the Appendix, and the finished Gate Generation function is this:
So that code works if you want to generate a gate that only acts on one qubit,
but we have to do something else if we want to use a CNOT gate.
The way this part of the function works is based on the "Formula" in the Appendix,
and the finished Gate Generation function is this:

\lstinputlisting[language=Python,firstline=63,lastline=106]{../Code/Simulator/QuSim.py}

\subsubsection{Applying the Gates to the Register}

After the gates have been generated, they can now be applied to the register.
This function first checks if the register has been measured, as you cannot apply a gate to a register that has been measured.
The function, \emph{applyGate}, takes the same inputs as generateGate() but after getting the generated gates, then is multiplies the Amplitude vector by the new gate, which applies it.

\lstinputlisting[language=Python,firstline=123,lastline=130]{../Code/Simulator/QuSim.py}

\subsubsection{Taking Measurements}
So at this point the simulator can:
\begin{enumerate}
\item Create a Qubit Register
\item Generate Gates that can be applied to that register
\item Apply that gate to the register
\end{enumerate}
Now all that is left to implement is the Measurement function.

You should recall that the probability of measuring one of the basis states is the amplitude squared.
With this in mind, I will implement the measurement function just like a weighted number picker.

First of all, the measurement function uses a \emph{for} loop to loop through all of the amplitudes in the register. The absolute value of each amplitude is squared and then its added to a list of all the probablilities.
Then, these probabilities are used to generate the list index. when a choice is made, then it is converted to its binary form, which would be what the state is. (for example, if it chose the 7th list item, then that would be \(\lvert 111 \rangle \)).
The code is:
\lstinputlisting[language=Python,firstline=132,lastline=157]{../Code/Simulator/QuSim.py}

So thats the simulator complete! You can see the finished source code in the Appendix.
\end{document}


0 comments on commit 14a3d0b

Please sign in to comment.