did some more work

This commit is contained in:
Daniel Knüttel 2020-03-26 21:35:30 +01:00
parent b81938bdb7
commit 78ec3aa4c9
10 changed files with 145 additions and 33 deletions

View File

@ -10,10 +10,17 @@ chapters=chapters/introduction.tex \
chapters/appendix.tex
cover=cover.png
graphics=graphics/graph_high_linear_regime.png \
graphics/graph_high_linear_regime_cut.png \
graphics/graph_intermediate_regime.png \
graphics/graph_intermediate_regime_cut.png \
graphics/graph_low_linear_regime.png
other=extra_benchmark/benchmark.py
all: main.pdf
main.pdf: main.tex main.bib $(cover) $(chapters)
main.pdf: main.tex main.bib $(cover) $(chapters) $(graphics) $(other)
$(latex) main
$(bibtex) main
$(latex) main

View File

@ -66,3 +66,17 @@ code is converted to an image using
\lstinputlisting[title={Code used to Generate the Example Graphs}, language=Python, breaklines=true]{../performance/regimes/graph_intermediate_regime.py}
\subsection{Code to Benchmark \lstinline{ufunc} Gates against Python}
\label{ref:benchmark_ufunc_py}
It has been mentioned several times that the implementation using
\lstinline{ufuncs} as gates is faster than using a \lstinline{python}
implementation. To support this statement a simple benchmark can be used. The
relatively simple Pauli $X$ is used, more complicated gates like $CX$ or $H$
have worse performance when implemented in \lstinline{python}. The performance
improvement when using the \lstinline{ufunc} is around $1.7$ in this tested
case. One must however note that the tested \lstinline{python} code is not
realistic and in a possible applications there would be a significant overhead.
\lstinputlisting[title={Code to Benchmark \lstinline{ufunc} Gates against Python}, language=Python, breaklines=True]{extra_benchmark/benchmark.py}

View File

@ -101,7 +101,7 @@ a group preserving this tensor product property.
%}}}
The stabilizer formalism as introduced in \ref{ref:stab_states} has since been
generalized to normalizers of a finite abelian group over the Hilbert space
generalized to normalizers of a finite Abelian group over the Hilbert space
\cite{bermejovega_lin_vdnest2015}\cite{bermejovega_vdnest2018}\cite{vandennest2019}\cite{vandennest2018}.
This allows to simulate more classes of circuits efficiently on classical computers
including the Quantum Fourier Transforms which is often believed to be

View File

@ -41,7 +41,7 @@ classical state. The Python states also have a NumPy \lstinline{cdouble} array
that stores the quantum mechanical state. Using NumPy arrays has the advantage
that access to the data is simple and safe while operations on the states can
be implemented in \lstinline{C} \cite{numpy_ufunc} providing a considerable
speedup.
speedup \ref{ref:benchmark_ufunc_py}.
This quantum mechanical state is the component vector in integer basis
therefore it has $2^n$ components. Storing those components is acceptable in
@ -59,7 +59,7 @@ what qbits have been measured. Using ufuncs has the great advantage that
managing memory is done by NumPy and an application programmer just has to
implement the logic of the function. Because ufuncs are written in
\lstinline{C} they provide a considerable speedup compared to an implementation
in Python.
in Python \ref{ref:benchmark_ufunc_py}.
The logic of gates is usually easy to implement using the integer basis. The
example below implements the Hadamard gate \ref{ref:singleqbitgates}:
@ -166,9 +166,9 @@ Out[2]: (0.7071067811865476+0j)*|0b0>
For the graphical state $(V, E, O)$ the list of vertices $V$ can be stored implicitly
by demanding $V = \{0, ..., n - 1\}$. This leaves two components that have to be stored:
The edges $E$ and the vertex operators $O$. Storing the vertex operators is done using
a \lstinline{uint8_t} array. Every local Clifford operator is associated from $0$ to $24$,
their order is
The edges $E$ and the vertex operators $O$. Storing the vertex operators is
done using a \lstinline{uint8_t} array. Every local Clifford operator is
associated with an integer ranging from $0$ to $24$, their order is
\begin{equation}
\begin{aligned}
@ -235,7 +235,7 @@ three classes of operations.
\begin{description}
\item[\hspace{-1em}]{\lstinline{RawGraphState.apply_C_L}\\
This method implements local clifford gates. It takes the qbit index
This method implements local Clifford gates. It takes the qbit index
and the index of the local Clifford operator (ranging form $0$ to $23$).}
\item[\hspace{-1em}]{\lstinline{RawGraphState.apply_CZ}\\
Applies the $CZ$ gate to the state. The first argument is the
@ -258,7 +258,7 @@ vector state.
\subsubsection{Pure C Implementation}
Because python tends to be rather slow and might not run on any architecture
Because python tends to be rather slow \cite{benchmarkgame} and might not run on any architecture
a pure \lstinline{C} implementation of the graphical simulator is also provided.
It should be seen as a reference implementation that can be extended to the needs
of the user.

View File

@ -12,7 +12,7 @@ important class of quantum error correction strategies are stabilizer codes
faster than general quantum circuits
\cite{gottesman_aaronson2008}\cite{CHP}\cite{andersbriegel2005}.
One particularely efficient way to simulate stabilizer states is the graphical
One particularly efficient way to simulate stabilizer states is the graphical
representation \cite{andersbriegel2005} that has been studied extensively in
the context of both quantum error correction and quantum information theory
\cite{schlingenmann2001}\cite{dahlberg_ea2019}\cite{vandennest_ea2004}\cite{hein_eisert_briegel2008}.
@ -20,7 +20,7 @@ This paper describes the development of a quantum computing simulator
using both the usual dense state vector representation for a general state
and a graphical representation for stabilizer states. After giving some introduction
to quantum computing some basic properties of stabilizer states and their
dynamics are eludicated. Using this the graphical representation is introduced
dynamics are elucidated. Using this the graphical representation is introduced
and some operations on the graphical states are explained. Following is
a chapter describing the implementation of these techniques and some performance
analysis.

View File

@ -1,11 +1,16 @@
% vim: ft=tex
\section{Quantum Computing}
This chapter gives an introduction to binary quantum computing
and some basic properties of quantum systems such as measurement
and time evolution. It is based on \cite{nielsen_chuang_2010}
but introduces a notation that will often be different.
\subsection{Qbits and Gates}
\subsubsection{Single Qbits}
\begin{definition}
A qbit is a two level quantum mechanical system \cite{nielsen_chuang_2010}, i.e. it has the eigenbasis
A qbit is a two-level quantum mechanical system \cite{nielsen_chuang_2010}, i.e. it has the eigenbasis
$ \{\ket{\uparrow} \equiv \ket{1}, \ket{\downarrow} \equiv \ket{0}\} $
with $\braket{\uparrow}{\downarrow} = 0$. In the following this basis will be called
the $Z$ basis in analogy to the conventions used in spin systems ($\sigma_Z$). For some computations
@ -17,7 +22,13 @@
A gate acting on a qbit is a unitary operator $G \in U(2)$. One can show that
$\forall G \in U(2)$ $G$ can be written as a product of unitary generator matrices
\cite[Chapter 4.2]{nielsen_chuang_2010}\cite[Chapter 4.3]{kaye_ea2007}\cite[Chapter 2]{marquezino_ea_2019};
common choices for the generators are $ X, H, R_{\phi}$ or $Z, H, R_{\phi}$ with
common choices for the generators are $ X, H, R_{\phi}$ or $Z, H, R_{\phi}$
\footnote{Note that the notation in the sources is different. Instead of $R_\phi$ the
$R_Z(\alpha) = \exp(-\frac{i\alpha}{2}Z)$ and $R_Y(\alpha) = \exp(-\frac{i\alpha}{2}Y)$
rotations are used. However $R_\phi = \exp(-\frac{i\phi}{2}) R_Z(-\phi)$ and
$R_Y(\alpha) = \cos(\frac{\alpha}{2}) I - i\sin(\frac{\alpha}{2}) Y = S H R_Z H^\dagger S^\dagger$ \cite{nielsen_chuang_2010}.
}
with
\label{ref:singleqbitgates}
\begin{equation}
@ -96,7 +107,8 @@ with the normation condition
The states $\ket{i}$ for $i = 0, ..., 2^{n}-1$ are called integer states. Note
that integer states are eigenstates of the $Z$ operators.\\
The computational basis is
$\left\{\ket{i_0} \otimes ... \otimes \ket{i_{n-1}} \middle| i_0, ..., i_{n-1} = 0, 1\right\}$.
$\left\{\ket{i_0} \otimes ... \otimes \ket{i_{n-1}} \middle| i_0, ..., i_{n-1} = 0, 1\right\}$
\cite{nielsen_chuang_2010}.
\begin{definition}
For a single-qbit gate $U$ and a qbit $j = 0, 1, ..., n - 1$
@ -106,11 +118,11 @@ For a single-qbit gate $U$ and a qbit $j = 0, 1, ..., n - 1$
\otimes U
\otimes \left(\bigotimes\limits_{i = j + 1}^{n - 1} I \right)
\end{equation}
is acting on qbit $j$.
is acting on qbit $j$ \cite{kaye_ea2007}.
\end{definition}
% XXX
\newpage
%\newpage
\begin{definition}\label{def:CU}
For two qbits $i,j = 0, 1, ..., n - 1$, $i \neq j$ and a gate $U_i$ acting on $i$
@ -142,6 +154,8 @@ is acting on qbit $j$.
CZ(i, j) = \ket{0}\bra{0}_j\otimes I_i + \ket{1}\bra{1}_j \otimes Z_i .
\end{equation}
This follows the definition given in \cite{barenco_ea_1995}.
\end{definition}
In Definition \ref{def:CU} $i$ is called the act-qbit and $j$ the control-qbit. In words
@ -169,7 +183,7 @@ The matrix representation of $CX$ and $CZ$ for two qbits is given by
$$\ket{\phi_1} \otimes \ket{1}_j$$
with probability $|\alpha|^2$ and
$$\ket{\phi_0} \otimes \ket{0}_j$$
with probability $|\beta|^2$. This is called collapse of the wave function.
with probability $|\beta|^2$ \cite{nielsen_chuang_2010}. This is called collapse of the wave function.
\end{postulate}
Measuring a qbit will also yield a classical result $0$ or $1$ with the respective probabilities.
@ -182,7 +196,7 @@ $i$ $Z_i$ is measured. The $+1$ eigenvalue of $Z_i$ is $\ket{0}_i$, $\ket{1}_i$
\end{corrolary}
\begin{proof}
The measuerment is not injective: Measuring both
The measurement is not injective: Measuring both
$\ket{0}$ and $\frac{1}{\sqrt{2}}(\ket{0} + \ket{1})$ (can) map to $\ket{0}$.
Any unitary matrix $U$ has the inverse $U^\dagger \equiv U^{-1}$.
@ -190,7 +204,7 @@ $i$ $Z_i$ is measured. The $+1$ eigenvalue of $Z_i$ is $\ket{0}_i$, $\ket{1}_i$
Because a measurement is not unitary it is not a gate in the sense of the definition above.
In the following discussion the term \textit{measurement gate} will be used from time
to time as a measurement can be treated similarely while doing numerics.
to time as a measurement can be treated similarly while doing numerics.
\subsection{Quantum Circuits}
@ -237,7 +251,7 @@ Several qbits can be abbreviated by writing a slash on the qbit line:
The great hope behind quantum computing is that it will speed up some
computations exponentially using algorithms that utilize the laws of quantum
mechanics. Current algorithms are based upon quantum search and quantum fourier
transform \cite{nielsen_chuang_2010}. The latter is particular interesting for
transform \cite{nielsen_chuang_2010}. The latter is particularly interesting for
physical problems as it is a key component in the phase estimation algorithm
that can be used to analyze the spectrum of the transfer matrix:

View File

@ -106,7 +106,7 @@ its generators.
\subsubsection{Stabilizer States}
\label{ref:stab_states}
One important basic property of quantum mechanics is that hermitian operators
One important basic insight from quantum mechanics is that hermitian operators
have real eigenvalues and eigenspaces which are associated with these
eigenvalues. Finding these eigenvalues and eigenvectors is what one calls
solving a quantum mechanical system. One of the most fundamental insights of
@ -293,12 +293,12 @@ and $s=0$ are obtained with probability $\frac{1}{2}$ and after choosing a $j
\end{proof}
\subsection{The VOP-free Graph States}
\subsubsection{VOP-free Graph States}
This section will discuss the vertex operator (VOP)-free graph states. Why they
are called vertex operator-free will be clear in the following section about
graph states.
\subsubsection{VOP-free Graph States}
\begin{definition} \label{def:graph} The tuple $(V, E)$ is called a graph iff
$V$ is a set of vertices with $|V| = n \in \mathbb{N}$ elements. In the
following $V = \{0, ..., n-1\}$ will be used. $E$ is the set of edges $E
@ -560,7 +560,12 @@ states that allows the representation of an arbitrary stabilizer state. The
proof that indeed any state can be represented is purely constructive. As seen
in Theorem \ref{thm:clifford_group_approx} any $c \in C_n$ can be constructed
from $CZ$ and $C_L$. In the following discussion it will become clear that both
$C_L$ and $CZ$ can be applied to a general graph state.
$C_L$ and $CZ$ can be applied to a general graph state
\footnote{
One can show that any stabilizer state is local Clifford equivalent to
a VOP-free graph state, i.e. only tensor products of $C_L$ matrices are
required to map a stabilizer state to a VOP-free graph state \cite{andersbriegel2005}.
}.
\subsubsection{Graph States and Vertex Operators}
\label{ref:g_states_vops}
@ -577,7 +582,16 @@ $C_L$ and $CZ$ can be applied to a general graph state.
+1 \ket{G} = \left(\prod\limits_{j=1}^no_j\right) K_G^{(i)} \left(\prod\limits_{j=1}^no_j\right)^\dagger \ket{G}
\end{equation}
$o_i$ are called the vertex operators of $\ket{G}$ \cite{andersbriegel2005}.
$o_i$ are called the vertex operators of $\ket{G}$ \cite{andersbriegel2005}
\footnote{
The notation in \cite{andersbriegel2005} is different. Instead of using $(V, E, O)$
to represent any stabilizer $(V, E)$ is used to represent what is called a VOP-free
graph state in this paper. Then the state $\ket{\bar{G}}$ is extended with local Clifford
gates $c_1, ..., c_n$ to an arbitrary stabilizer state. The state is then denoted as
$\ket{\bar{G}; (c_1, ..., c_n)} \equiv \ket{\bar{G}; \vec{c}}$. This paper prefers
the notation using $(V, E, O)$ as it both emphasizes the use of stabilizers and is closer
to the representation used in the simulator.
}.
\end{definition}
Recalling the dynamics of stabilizer states the following relation follows
@ -595,7 +609,7 @@ matrices it is sufficient to store $n$ integers representing the vertex
operators:
\begin{theorem}
$C_L$ has $24$ degrees of freedom \cite{andersbriegel2005}.
$C_L$ has $24$ degrees of freedom disregarding a global phase \cite{andersbriegel2005}.
\end{theorem}
\begin{proof} It is clear that $\forall a \in C_L$ a is a group isomorphism $P
\rightarrow P$: $apa^\dagger a p' a^\dagger = a pp'a^\dagger$. Therefore
@ -611,8 +625,8 @@ $4$ degrees of freedom and a total of $24$. \end{proof}
From now on $C_L = \langle H, S \rangle$ (disregarding a global phase) will be
used. One can show (by construction) that $H, S$ generate a possible choice of
$C_L$, as is $C_L = \langle \sqrt{-iX}, \sqrt{-iZ}\rangle$ which is required in
one specific operation on graph states \cite{andersbriegel2005}.
$C_L$, as do $\sqrt{-iX}, \sqrt{-iZ}$ which is required in one specific
operation on graph states \cite{andersbriegel2005}.
\begin{equation}
S = \left(\begin{array}{cc} 1 & 0 \\ 0 & i \end{array}\right)
@ -645,7 +659,7 @@ are given by
\end{equation}
The action of a $CZ$ gate on the state $(V, E, O)$ is in most cases less
trivial. Let $i \neq j$ be two qbits, now consider the action of $CZ_{a,b}$ on
trivial. Let $a \neq b$ be two qbits, now consider the action of $CZ_{a,b}$ on
$(V, E, O)$. The cases given here follow the implementation of a $CZ$
application in \cite{pyqcs}, the respective paragraphs from
\cite{andersbriegel2005} are given in italic. Most of the discussion follows
@ -858,3 +872,4 @@ For $g_a = X_a$ one has to choose a $b \in n_a$ and the transformations are
\end{aligned}
\end{equation}
The unitaries $U$ have to be right-multiplied to the vertex operators.

View File

@ -0,0 +1,54 @@
import timeit
import numpy as np
from pyqcs.gates.gate import BuiltinGate
cl_state = np.zeros(10, dtype=np.int8)
qm_state = np.zeros(2**10, dtype=np.cdouble)
qm_state[0] = 1
gate_uf = BuiltinGate('X', 0, 0, 0.0)
print("running benchmarks ...", end="", flush=True)
time_uf = timeit.repeat("result_uf = gate_uf(qm_state, cl_state)"
, setup="import numpy as np;"
"from pyqcs.gates.gate import BuiltinGate;"
"cl_state = np.zeros(10, dtype=np.int8);"
"qm_state = np.zeros(2**10, dtype=np.cdouble);"
"qm_state[0] = 1;"
"gate_uf = BuiltinGate('X', 0, 0, 0.0);"
, repeat=5
, number=1_000_000
)
time_py = timeit.repeat("result_py = np.zeros(2**10, dtype=np.cdouble);"
"result_py[0::2] = qm_state[1::2];"
"result_py[1::2] = qm_state[0::2];"
"cl_py = np.zeros(10, dtype=np.int8)"
, setup="import numpy as np;"
"qm_state = np.zeros(2**10, dtype=np.cdouble);"
"qm_state[0] = 1;"
, repeat=5
, number=1_000_000
)
print(" done")
print("running test ...", end="", flush=True)
result_uf, cl, m = gate_uf(qm_state, cl_state);
result_py = np.zeros(2**10, dtype=np.cdouble)
cl_py = np.zeros(10, dtype=np.int8)
result_py[0::2] = qm_state[1::2]
result_py[1::2] = qm_state[0::2]
assert np.allclose(result_py, result_uf)
print(" done")
best_uf = min(time_uf) / 1_000_000
best_py = min(time_py) / 1_000_000
print("time for ufunc gate (best out of 5, 1_000_000 runs):", best_uf)
print("time for python gate (best out of 5, 1_000_000 runs):", best_py)

View File

@ -281,3 +281,9 @@
NOTE = {https://uwaterloo.ca/institute-for-quantum-computing/quantum-computing-101\#Quantum-effects-matter},
URL = {https://uwaterloo.ca/institute-for-quantum-computing/quantum-computing-101\#Quantum-effects-matter}
}
@MISC{
benchmarkgame,
author={The Computer Language Benchmarks Game Contributors},
title={The Computer Language Benchmarks Game},
note={https://benchmarksgame-team.pages.debian.net/benchmarksgame/}
}

View File

@ -1,4 +1,4 @@
\documentclass[a4paper,12pt]{scrartcl}
\documentclass[a4paper,12pt,numbers=noenddot]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{amssymb, amsthm}
@ -13,8 +13,9 @@
\usepackage{qcircuit}
\usepackage{adjustbox}
\usepackage[affil-it]{authblk}
\usepackage{tocbibind}
\usepackage[toc,page]{appendix}
%\usepackage{tocbibind}
%\usepackage[toc,page]{appendix}
\usepackage{appendix}
\usepackage{float}
@ -54,8 +55,9 @@
\include{chapters/implementation}
\include{chapters/conclusion}
\appendix
\begin{appendices}
\include{chapters/appendix}
\end{appendices}
\bibliographystyle{unsrt}
\bibliography{main}{}