Some work here
This commit is contained in:
parent
d03c076c8e
commit
f5c7fe824d
|
@ -232,20 +232,20 @@ implemented in \lstinline{C} and are exported to python3 in the class
|
||||||
\lstinline{RawGraphState}. This class has three main methods to implement the
|
\lstinline{RawGraphState}. This class has three main methods to implement the
|
||||||
three classes of operations.
|
three classes of operations.
|
||||||
|
|
||||||
%\begin{description}
|
\begin{description}
|
||||||
% \item[\lstinline{RawGraphState.apply_C_L}]{This method
|
\item[\lstinline{RawGraphState.apply_C_L}]{This method
|
||||||
% implements local clifford gates. It takes the qbit index and the index
|
implements local clifford gates. It takes the qbit index and the index
|
||||||
% of the local Clifford operator (ranging form $0$ to $23$).}
|
of the local Clifford operator (ranging form $0$ to $23$).}
|
||||||
% \item[\lstinline{RawGraphState.apply_CZ}]{Applies the $CZ$ gate to the
|
\item[\lstinline{RawGraphState.apply_CZ}]{Applies the $CZ$ gate to the
|
||||||
% state. The first argument is the act-qbit, the second the control
|
state. The first argument is the act-qbit, the second the control
|
||||||
% qbit (note that this is just for consistency to the $CX$ gate).}
|
qbit (note that this is just for consistency to the $CX$ gate).}
|
||||||
% \item[\lstinline{RawGraphState.measure}]{Using this method one can
|
\item[\lstinline{RawGraphState.measure}]{Using this method one can
|
||||||
% measure a qbit. It takes the qbit index as first argument and
|
measure a qbit. It takes the qbit index as first argument and
|
||||||
% a floating point (double precision) random number as second
|
a floating point (double precision) random number as second
|
||||||
% argument. This random number is used to decide the measurement outcome
|
argument. This random number is used to decide the measurement outcome
|
||||||
% in non-deterministic measurements. This method returns either $1$ or $0$ as
|
in non-deterministic measurements. This method returns either $1$ or $0$ as
|
||||||
% a measurement result.}
|
a measurement result.}
|
||||||
%\end{description}
|
\end{description}
|
||||||
|
|
||||||
Because this way of modifying the state is rather unconvenient and might lead to many
|
Because this way of modifying the state is rather unconvenient and might lead to many
|
||||||
errors the \lstinline{RawGraphState} is wrapped by the pure python class
|
errors the \lstinline{RawGraphState} is wrapped by the pure python class
|
||||||
|
@ -253,7 +253,7 @@ errors the \lstinline{RawGraphState} is wrapped by the pure python class
|
||||||
in \ref{ref:pyqcs_circuits} and provides the method \lstinline{GraphState.to_naive_state}
|
in \ref{ref:pyqcs_circuits} and provides the method \lstinline{GraphState.to_naive_state}
|
||||||
to convert the graphical state to a dense vector state.
|
to convert the graphical state to a dense vector state.
|
||||||
|
|
||||||
\subsubsection{Pure \lstinline{C} Implementation}
|
\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 and might not run on any architecture
|
||||||
a pure \lstinline{C} implementation of the graphical simulator is also provided.
|
a pure \lstinline{C} implementation of the graphical simulator is also provided.
|
||||||
|
@ -273,8 +273,162 @@ always done in three steps:
|
||||||
|
|
||||||
\subsection{Utilities}
|
\subsection{Utilities}
|
||||||
|
|
||||||
TODO
|
To make both using the simulators more convenient and to help with using them in
|
||||||
|
as scientific or educational context several utilities have been written. This chapter
|
||||||
|
explains some of them.
|
||||||
|
|
||||||
|
\subsubsection{Sampling and Circuit Generation}
|
||||||
|
|
||||||
|
The function \lstinline{pyqcs.sample} provides a simple way to sample from a state.
|
||||||
|
Copies of the state are made when necessary and the results are returned
|
||||||
|
in a \lstinline{collections.Counter} object. Several qbits can be sampled at once; they can be passed
|
||||||
|
to the function either as an integer which will be interpreted as a bit mask and the
|
||||||
|
least significant bit will be sampled first. When passing the qbits to sample as a list
|
||||||
|
of integers the integers are interpreted as qbit indices and are measured in the order
|
||||||
|
they appear.
|
||||||
|
|
||||||
|
If the keyword argument \lstinline{keep_states} is \lstinline{True} the sampling
|
||||||
|
function will include the resulting states in the result. At the moment this works
|
||||||
|
for dense vectors only. Checking for equality on graphical states has yet to be implemented
|
||||||
|
but can be done in polynomial time \cite{dahlberg_ea2019}.
|
||||||
|
|
||||||
|
Writing circuits out by hand can be rather painful. The function \lstinline{pyqcs.list_to_circuit}
|
||||||
|
Converts a list of circuits to a circuit. This is particularely helpful in combination
|
||||||
|
with python's \lstinline{listcomp}:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
circuit_H = list_to_circuit([H(i) for i in range(nqbits)])
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
The module \lstinline{pyqcs.util.random_circuits} provides the method described in \ref{ref:performance}
|
||||||
|
to generate random circuits for both graphical and dense vector simulation. Using the module
|
||||||
|
\lstinline{pyqcs.util.random_graphs} one can generate random graphical states which is more performant
|
||||||
|
than using random circuits.
|
||||||
|
|
||||||
|
\subsubsection{Exporting Circuits, Graphical States}
|
||||||
|
|
||||||
|
|
||||||
\subsection{Performance}
|
\subsection{Performance}
|
||||||
|
\label{ref:performance}
|
||||||
|
|
||||||
|
To test the performance and compare it to the dense vector simulator the python
|
||||||
|
module is used. Although the pure \lstinline{C} implementation has potential
|
||||||
|
for better performance the python module is better comparable to the dense
|
||||||
|
vector simulator which is a python module as well.
|
||||||
|
|
||||||
|
For performance tests (and for tests against the dense vector simulator) random
|
||||||
|
circuits are used. Length $m$ circuits are generated from the probability space
|
||||||
|
|
||||||
|
|
||||||
|
\begin{equation}
|
||||||
|
\Omega = \left(\{1, ..., 4n\} \otimes \{1, ..., n-1\} \otimes [0, 2\pi)\right)^{\otimes m}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
with the uniform distribution. The continous part $[0, 2\pi)$ is unused when
|
||||||
|
generating random circuits for the graphical simulator; when generating random
|
||||||
|
circuits for dense vector simulations this is the argument $\phi$ of the
|
||||||
|
$R_\phi$ gate.
|
||||||
|
|
||||||
|
For $m=1$ an outcome is mapped to a gate using
|
||||||
|
|
||||||
|
\begin{equation}
|
||||||
|
\begin{aligned}
|
||||||
|
F(i, k, x) = \left\{\begin{array}{cc} X(i - 1) & \mbox{, if } i \le n \\
|
||||||
|
H(i - n - 1) & \mbox{, if } i \le 2n\\
|
||||||
|
S(i - 2n - 1) & \mbox{, if } i \le 3n\\
|
||||||
|
CZ(i - 3n - 1, k - 1) & \mbox{, if } k \le i - 3n - 1 \\
|
||||||
|
CZ(i - 3n - 1, k) & \mbox{, if } k > i - 3n - 1\\
|
||||||
|
\end{array}\right.
|
||||||
|
.
|
||||||
|
\end{aligned}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
This method provides equal probability for $X, H, S$ and $CZ$ gate. For the
|
||||||
|
dense vector simulator $S$ can be replaced by $R_\phi$ with the parameter $x$.
|
||||||
|
|
||||||
|
Using this method circuits are generated and applied both to graphical and
|
||||||
|
dense vector states and the time required to execute the operations
|
||||||
|
\cite{timeit} is measured. The resulting graph can be seen in
|
||||||
|
\ref{fig:scaling_qbits_linear} and \ref{fig:scaling_qbits_log}. Note in both cases the length of the circuits
|
||||||
|
have been scaled linearely with the amount of qbits and the measured time was
|
||||||
|
divided by the number of qbits:
|
||||||
|
|
||||||
|
\begin{equation}
|
||||||
|
\begin{aligned}
|
||||||
|
L_{\mbox{circuit}} &= \alpha n \\
|
||||||
|
T_{\mbox{rescaled}} &= \frac{T_{\mbox{execution}}(L_{\mbox{circuit}})}{n}\\
|
||||||
|
\end{aligned}
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
\begin{figure}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{../performance/scaling_qbits_linear.png}
|
||||||
|
\caption[Runtime Behaviour for Scaling Qbit Number]{Runtime Behaviour for Scaling Qbit Number}
|
||||||
|
\label{fig:scaling_qbits_linear}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{../performance/scaling_qbits_log.png}
|
||||||
|
\caption[Runtime Behaviour for Scaling Qbit Number (Logarithmic Scale)]{Runtime Behaviour for Scaling Qbit Number (Logarithmic Scale)}
|
||||||
|
\label{fig:scaling_qbits_log}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
The reason for this scaling will be clear later; one can observe that the
|
||||||
|
performance of the graphical simulator increases in some cases with growing
|
||||||
|
number of qbits when the circuit length is constant.
|
||||||
|
|
||||||
|
As described by \cite{andersbriegel2005} the graphical simulator is exponentially
|
||||||
|
faster than the dense vector simulator. According to \cite{andersbriegel2005} it
|
||||||
|
is considerably faster than a simulator using the straight forward approach simulating
|
||||||
|
the stabilizer tableaux like CHP \cite{CHP}.
|
||||||
|
|
||||||
|
One should be aware that the gate execution time (the time required to apply a gate
|
||||||
|
to the state) highly depends on the state it is applied to. For the dense vector
|
||||||
|
simulator and CHP this is not true: Gate execution time is constant for all gates
|
||||||
|
and states. Because the graphical simulator has to toggle neighbourhoods the
|
||||||
|
gate execution time of the $CZ$ gate varies greatly. The plot \ref{fig:scaling_circuits_linear}
|
||||||
|
shows the circuit execution time for two different numbers of qbits. One can observe three
|
||||||
|
regimes:
|
||||||
|
|
||||||
|
\begin{figure}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{../performance/regimes/scaling_circuits_linear.png}
|
||||||
|
\caption[Circuit Execution Time for Scaling Circuit Length]{Circuit Execution Time for Scaling Circuit Length}
|
||||||
|
\label{fig:scaling_circuits_linear}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[Low-Linear Regime] {Here the circuit execution time scales approximately linearely
|
||||||
|
with the number of gates in the circuit (i.e. the $CZ$ gate execution time is approximately constant).
|
||||||
|
}
|
||||||
|
\item[Intermediate Regime]{The circuit execution time has a nonlinear dependence on the circuit length.}
|
||||||
|
\item[High-Linear Regime]{This regime shows a linear dependence on the circuit length; the slope is
|
||||||
|
higher than in the low-linear regime.}
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
\begin{figure}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{../performance/regimes/graph_low_linear_regime.png}
|
||||||
|
\caption[Typical Graphical State in the Low-Linear Regime]{Typical Graphical State in the Low-Linear Regime}
|
||||||
|
\label{fig:graph_low_linear_regime}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=\linewidth]{../performance/regimes/graph_high_linear_regime.png}
|
||||||
|
\caption[Typical Graphical State in the High-Linear Regime]{Typical Graphical State in the High-Linear Regime}
|
||||||
|
\label{fig:graph_high_linear_regime}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
These two regimes can be explained when considering the graphical states that typical live in these
|
||||||
|
regimes. With increased circuit length the amount of edges increases which makes toggling neighbourhoods
|
||||||
|
harder. Two graphs from the low-linear and high-linear regime can be seen in \ref{fig:graph_low_linear_regime}
|
||||||
|
and \ref{fig:graph_high_linear_regime}. The latter is hardly visible; this is due to the great amount of
|
||||||
|
edges in this regime. Further these two regimes are only visibly for $n>30$ qbits so choosing smaller graphs is
|
||||||
|
not possible.
|
||||||
|
|
||||||
|
Because states with more qbits reach the intermediate regime at higher circuit lengths it is important to
|
||||||
|
account for this virtual performance boost when comparing with other simulation methods. This explains
|
||||||
|
why the circuit length in \ref{fig:scaling_qbits_linear} had to be scaled with the qbit number.
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
|
@ -166,3 +166,11 @@
|
||||||
note={Unpublished Work}
|
note={Unpublished Work}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@online{
|
||||||
|
timeit,
|
||||||
|
title={timeit — Measure execution time of small code snippets},
|
||||||
|
url={https://docs.python.org/3.5/library/timeit.html},
|
||||||
|
urldate={13.03.2020},
|
||||||
|
year=2020,
|
||||||
|
note={https://docs.python.org/3.5/library/timeit.html}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user