\documentclass{article}

\usepackage{graphicx}

\graphicspath{{img/}}

\title{Long term learning of compiler heuristics}

\begin{document}
\maketitle

The long term learning of heuristics is implemented into petabricks by using three classes in the compiler itself, some python scripts and some command line parameters.

The classes can be used by the programmer working on petabricks to use heuristics in their own code.
The scripts are used to perform the actual learning process.
The command line parameters can be used to tweak the functioning of the system.

\section{Overview}
\includegraphics[width=\textwidth]{heurArchitecture}

The compilation scripts take as their input a XML file structured like this:
\begin{verbatim}
<heuristics>
  <set>
    <heuristic name="thisHeuristic" formula="(foo+bar) / foobar" />
    <heuristic name="thatHeuristic" formula="if var1+var2 < 3 then 5 else 7" />
  </set>
  <set>
    <heuristic name="thisHeuristic" formula="5 * a + 8" />
  </set>
  <set>
    <heuristic name="otherHeuristic" formula="21 - a + 8*b" />
  </set>
</heuristics>
\end{verbatim}

The file includes a bunch of heuristics sets.
Every set will be used as the input for a  different instance of the compiler, generating different executable files. All the executable files will be autotuned, and the best one will be chosen.
Then, the data about the results obtained by the various files are stored in the database (\texttt{knowledge.db} in the \texttt{$\sim$/tunerout} directory).

The sets can be incomplete, not including all the required heuristics.
The missing heuristics will be automatically taken from the database or, with a given probability, from the heuristic generator. If the database is empty and the heuristic generator did not generate any new heuristic, the system will fall back to using the default heuristic specified by the programmer inside the compiler itself.

\section{Classes in petabricks}
Three C++ classes implemente this framework into Petabricks

\subsection{Heuristic}
Represents a heuristics in the compiler.

The public interface includes:
\begin{description}
 \item[formula()] return the formula representing the heuristic.
 \item[eval(ValueMap featureValues)] return the evaluation of the heuristic. ValueMap is a map name-value of the values that will be substituted to each of the features (variables) that appear in the formula. The evaluation is the number obtained by substituting the features with the values in the given map.
\end{description}

\subsection{HeuristicManager}
The heuristic manager is the main point of interaction for the compiler writer with the long term learning system.

It provides the following methods:
\begin{description}
 \item [instance()] this static method returns the singleton instance of the HeuristicManager. It can be invoked from everywhere inside the compiler itself.
 \item [getHeuristic(string name)] return a heuristic given its name. The name should be chosen to be different for heuristics having different meaning. The heuristic is taken, in order, from the input file specified on the command line, from the database (the best heuristic is taken) or from the default
 \item [registerDefault(string name, string formula)] register \texttt{formula} as the default heuristic named \texttt{name}. NB: before using \texttt{getHeuristic} on any name, a default heuristic for that name should always be registered, so that the compiler can always work properly, even without an input file and with an empty database.
\end{description}

\subsection{DBManager}
Is responsible for managing the database. It should never be used directly.

\section{Scripts}
The learning part is performed by a series of python scripts

\subsection{learningcompiler.py}
Contains all the logic dealing with the long term learning of heuristics.
It can also be used to compile a single program using a given set of heuristics.

To do this, run:

\texttt{learningcompiler.py <heuristicsFile> <program.pbcc>}

\subsection{formula.py, maximaparser.py}
They contain the python representation of formulas and the parser.

\subsection{smoketest.py, pbbenchmark.py}
The default behaviour of the scripts is unchanged.

Invoking the scripts with the \texttt{--learning} parameter activates the learning of new heuristics, starting from those already present in the database.

Invoking the scripts with the \texttt{--heuristics=<filename>} implies \texttt{--learning}, but uses first the heuristics taken from the input file.

\end{document}


\section{\texorpdfstring{Random number generators}{Random number generators}}
\vspace{5mm}
\large

\begin{definition}
	Secure RNG - even knowing complete past output, next bit is unpredictable $\Rightarrow$ statistically uniform.
\end{definition}

We have 2 type of random number generators:\\
a) PRNG: e.g. block cipher in CTR mode. Key should be changed on regular basis.\\
b) physical randomness (we have no proof such thing exists).
Examples:

\begin{itemize}
	\item Thermal noise or resister/diode
	\item Radioactive decay (count \# of particles)
	\item Radio noise
	\item Lava lamp (chaotic movement)
	\item Ring oscillator (attacker can observer)
	\item Precise timings of keystrokes, mouse movements or network packages (attacker can record or flood packages)
\end{itemize}

\begin{note}
	Entropy in physical processes is not as high as we can expect.
	Therefore, a combination of PRNG and physical randomness is the best choice.
\end{note}

Problem with PRGN + rekey: if a key or state of the PRNG is compromised, adding 1 bit or physical entropy does not help. Attacher can try both options (guess) and track the state. Therefore entropy should be mixed in large batches.

\subsection{Fortuna RNG}
\begin{definition}
	Fortuna RGN has a \emph{Generator} and \emph{Accumulator}.

	Generator is based on block cipher (AES) which encrypts a 128-bit counter (never overflows). After $2^{16}$ block we rekey and using the next 2 blocks as key.

	Trick: do not reset the counter to avoid short cycles.

	Accumulator: gets entropy from other sources and resets Generator periodically.
	Has $p_0, ..., p_{31}$ pods of entropy. External RNG is mixed to the pods in Round-Robin order: assign RNG to $p_i$, move to the next.
	Such process distributes RNG among the pods.

	After 100ms we mix pods into Generator. In the $j$-th mixing only selected pods are used, e.g. with index $2^j/i$.
\end{definition}

Assume that $\rho = $ rate of input entropy, measured in bits per 100ms.
If $\rho \geq 128 * 32 \Rightarrow p_0$ is enough for recovery. As at least 128 bit of entropy were put in $p_0$.
If $ \rho \geq 128 * 32/2^i \Rightarrow p_i$ is enough to recover.

To conclude, for any given rate of entropy Fortuna can recover after some time. Speed of recovery depends on entropy rate.

\subsection{Secure channel}
We use symmetric encryption to establish secure channel. Assume Alice and Bob share unique random key $k$.
Alice sends $\{ m_i \}_0^n$ sequence of messages, Bob receives a subsequence and he is still able to know which one he got.
On the other hand, attacker have no such info, except for length of the sequence.

We use
\begin{itemize}
	\item Random IV for every message (public).
	\item AES in CTR mode for encryption (alternatively ChaCha20).
	\item MAC after encrypt.
	\item Sequence numbers (inside MAC).
	\item Key derivation function which generates encryption and MAC keys for both directions.
		\[ h(k | id) \]
\end{itemize}


\chapter{Skill Perks}\label{ch:skillPerks}
Skills are perks that represent a character's training in a certain area of ability and/or knowledge.
They allow that character to add their level to a check related to that area.
Higher levels in a perk allow them to add +1d4, +2d4 and +3d4 respectively.
Skills are not bound to one certain activity, instead including knowledge about the topic and activities that relate to that area.\\
The costs of Skill Perks are based on the amount of levels that the character already has in skill levels.
To calculate the costs of the next level in a skill, sum up the amount of levels that the character already has in in skill perks.\\
\\
Level Progression: \textbf{Cost} = New total Skill Levels * 20 + Cost of previous levels\\
\\
This means that the progression for the first 28 levels is as follows:\\
\\
\begin{minipage}{0.25\textwidth}
    \rowcolors{2}{lightgray}{white}
    \begin{tabular}{l | l}
        Level & Cost\\ \hline
        I & 20\\
        II & 60\\
        III & 120\\
        IV & 200\\
        V & 300\\
        VI & 420\\
        VII & 560\\
    \end{tabular}
\end{minipage}
\begin{minipage}{0.25\textwidth}
    \rowcolors{2}{lightgray}{white}
    \begin{tabular}{l | l}
        Level & Cost\\ \hline
        VIII & 720\\
        IX & 900\\
        X & 1,100\\
        XII & 1,340\\
        XIII & 1,600\\
        XIV & 1,880\\
    \end{tabular}
\end{minipage}
\begin{minipage}{0.25\textwidth}
    \rowcolors{2}{lightgray}{white}
    \begin{tabular}{l | l}
        Level & Cost\\ \hline
        XV & 2,180\\
        XVI & 2,500\\
        XVII & 2,840\\
        XVIII & 3,200\\
        XIX & 3,580\\
        XX & 3,980\\
        XXI & 4,400\\
    \end{tabular}
\end{minipage}
\begin{minipage}{0.25\textwidth}
    \rowcolors{2}{lightgray}{white}
    \begin{tabular}{l | l}
        Level & Cost\\ \hline
        XXII & 4,840\\
        XXIII & 5,300\\
        XXIV & 5,780\\
        XXV & 6,280\\
        XXVI & 6,800\\
        XXVII & 7,340\\
        XXVIII & 7,900\\
    \end{tabular}
\end{minipage}

\input{./perks/skills/animalHandling.tex}

\input{./perks/skills/balancing.tex}

\input{./perks/skills/climbing.tex}

\input{./perks/skills/deception.tex}

\input{./perks/skills/examination.tex}

\input{./perks/skills/forgery.tex}

\input{./perks/skills/intimidation.tex}

\input{./perks/skills/jumping.tex}

\input{./perks/skills/lockPicking.tex}

\input{./perks/skills/lore.tex}

\input{./perks/skills/masquerade.tex}

\input{./perks/skills/medicine.tex}

\input{./perks/skills/negotiation.tex}

\input{./perks/skills/performance.tex}

\input{./perks/skills/pickpocket.tex}

\input{./perks/skills/research.tex}

\input{./perks/skills/ropeHandling.tex}

\input{./perks/skills/seduction.tex}

\input{./perks/skills/stealth.tex}

\input{./perks/skills/survival.tex}

\input{./perks/skills/swimming.tex}

\input{./perks/skills/trapHandling.tex}


% !TeX root = ../Main.tex

\section{Hadoop}
\marginnote{Sauce!}\hadoop{} is an open-source framework for computation and storage, distributed over an \marginnote{almost?}(almost) arbitrary number of machines. It contains the \hdfs{}, a distributed file system built for high throughput and reliability, and specifically designed to run on commodity hardware. These properties allow for large clusters of relatively cheap hardware.

\hadoop{} also provides an API for distributed computing, named Hadoop MapReduce, based on the MapReduce algorithm by Dean and Ghemawat in \cite{dean2008mapreduce}. In this algorithm the underlying transformation of data is abstracted into two general steps, Map and Reduce. With $K,L,V,W$ being sets the Map function implements
\[\mathtt{Map}: K\times{}V\to{}(L\times{}W)^*\]
Thus it maps a key-value pair to a list of key-value pairs of arbitrary length \cite{wiki:mapreduce}. The resulting list of key-value pairs acts as intermediate values. The Reduce function aggregates those intermediate values with
\[\mathtt{Reduce}: L\times{}W^*\to{}\] huh...
The programmer in question needs to understand this concept and divide their code into those two steps.


\section{Preliminary Results}\label{section:results}

As a criteria of the project is to compare the performance of different frameworks against the performance of ROOT based \texttt{HistFactory} benchmarking of the different backends was carried out.
As a preliminary benchmark of the frameworks a one point $\text{CL}_{s}$ test\footnote{$\text{CL}_{s}$ is defined as the ratio of the signal + background hypothesis $p$-value to $1$ minus the background only hypothesis $p$-value: $\text{CL}_{s} = p_{s+b}/\left(1-p_{b}\right)$.~\cite{Cowan:2010js}} was performed, in which the $p$-values of test statistics from the data and the ``Asimov'' data set are compared given the parameter of interest.~\cite{Cowan:2010js}
The model used is a simple one in which every bin has the same content to ensure that the fit will complete.
In lieu of model complexity large numbers of bins are given to simulate difficult conditions for the fit as each bin is uncorrelated and so represents an additional nuisance parameter.
The results are shown against each other in Figure~\ref{fig:benchmark_backends}.
As a pure MXNet optimizer has not been fully implemented in pyhf at this time it has not yet been benchmarked, and so only backends that do have language specific optimizers have been compared to ROOT based \texttt{HistFactory}.\\

The preliminary results show that the computational backends that support automatic differentiation and built in parallelism show promising scaling behavior as the nature of the statistical fits becomes more computational difficult, as seen in Figure~\ref{fig:relative_time}.
The optimizer for the NumPy pyhf backend is based on optimizers in SciPy, and while the NumPy backend optimizer does not currently have automatic differentiation support it does show very good timing for lower computational difficulty problems.
Given that pyhf allows for fluidity in the choice of backend, this demonstrates a possible use case for automatically switching from the low overhead NumPy backend to a graph based backend as computational difficulty rises.

\begin{figure}
 \centering
 \includegraphics[width=0.9\linewidth]{benchmark_times.pdf}
 \caption{Comparison of the mean time needed to complete a one point $\text{CL}_{s}$ test for ROOT \texttt{HistFactory} and the NumPy, TensorFlow, and PyTorch pyhf backends vs. the number of bins in the associated fit.
  The binning choices (number of nuisance parameters) used are $n_{\text{bins}} \in \left\{1, 10, 50, 100, 200, 500, 800, 1000\right\}$.
  For each binning choice the fit is repeated 5 times.
  For ROOT \texttt{HistFactory} only binning choices up to 200 are used as runtime became too long afterwards.
  The minimum and maximum run times time for each binning choice are shown as open shapes corresponding to the shapes of the markers for each backend, and an uncertainty bar corresponding to 1 standard deviation is drawn (though it may be obscured by the markers).
 }\label{fig:benchmark_backends}
\end{figure}

\begin{figure}[htbp]
 \centering
 \subfigure[ROOT \texttt{HistFactory}]{%
  \includegraphics[width=0.5\textwidth]{relative_times_root_log.eps}\label{fig:relative_time_root_HF}%
 }\hfil
 \subfigure[NumPy backend]{%
  \includegraphics[width=0.5\textwidth]{relative_times_numpy_log.eps}\label{fig:relative_time_numpy}%
 }
 \subfigure[TensorFlow backend]{%
  \includegraphics[width=0.5\textwidth]{relative_times_tensorflow_log.eps}\label{fig:relative_time_tensorflow}%
 }\hfil
 \subfigure[PyTorch backend]{%
  \includegraphics[width=0.5\textwidth]{relative_times_pytorch_log.eps}\label{fig:relative_time_pytorch}%
 }
 \caption{Comparison of the mean time needed to complete a one point $\text{CL}_{s}$ test for ROOT \texttt{HistFactory} and the pyhf backends for a number of bins in the associated fit relative to the time for a single bin.
  The binning choices (number of nuisance parameters) used are $n_{\text{bins}} \in \left\{1, 10, 50, 100, 200, 500, 800, 1000\right\}$.
  For ROOT \texttt{HistFactory} only binning choices up to 200 are used as runtime became too long afterwards.
 }\label{fig:relative_time}
\end{figure}


\section{Points, lines and planes}


\documentclass{article}
\usepackage{graphicx}

\begin{document}

\title{High Level Modelling}
\maketitle

\section{Abstracting the implementation detail}

\subsection{Abstract Data Type}
\begin{verbatim}
KeyId : Type (* Abstract Type *)
Fingerprint : Type (* Abstract Type *)
Identity : Type (* Abstract Type *)
Token : Type (* Abstract Type *)
(* Key is record data type *)
Key : Type = Record {
  keyId : KeyId
  fingerprint : Fingerprint
  identities : Identity set}

\end{verbatim}

I am slightly confused between \textbf{sealed trait} and
\textbf{case class}
\begin{itemize}
\item case class Identity(email: String)
\item case class Token(uuid: UUID)
\end{itemize}

\subsection{Maps as Function Type}
\begin{verbatim}
keys keys' : Fingerprint -> Key
uploaded uploaded'  : UToken -> Fingerprint
pending pending' : VToken -> (Fingerprint, Identity)
confirmed confirmed' : Identity -> Fingerprint
managed managed' : MToken -> Fingerprint
\end{verbatim}

\subsection{Function Definition}
\begin{verbatim}

byFingerprint (f : Fingerprint) :=
   ( In f (dom keys) -> Exists (v : Key), Some v /\ v = keys f) /\
   (~In f (dom keys) -> None)

byKeyId (keyId : KeyId) :=
  Exists (l : List[Key]), (forall (x : Key), In x l ->
     Exists (f : Fingerprint), keys f = x) /\
     (forall (f : Fingerprint), (keys f).keyId = keyId -> In (keys f) l)

upload (key : Key) :=
  Forall fingerprint, fingerprint = key.fingerprint ->
  (In key.fingerprint (dom keys) ->
        keys (key.fingerprint) = key  /\ Exists (token : UToken),
        fresh token  /\ keys' = keys [fingerprint := key]  /\
        uploaded' = uploaded [token := key.fingerprint]) /\
  (~In key.fingerprint (dom keys) -> keys' = key /\ uploaded' = uploaded)

requestVerify (from : UToken) (identities : Identity set) :=
  (In from (dom uploaded) ->
      Forall fingerprint key, fingerprint = uploaded from ->
        key = keys fingerprint ->
        (Subset identities key.identities -> Exists (f : Identity -> VToken),
           injective f /\ pending' =   pending
           \Union {(f h, (fingerprint, h)) | h \In identities}) /\
        (~Subset s key.identities -> pending' = pending)) /\
 (~In from (dom uploaded) -> pending' = pending)

verify (token : VToken) :=
  (In token (dom pending) -> Forall fingerprint identity,
       (fingerprint, identity) = pending token ->
           pending'   = pending - token /\
           confirmed' = confirmed [identity := fingerprint]) /\
  (~In token (dom pending) -> pending' = pending /\ confirmed' = confirmed)

requestManage (id : Identity) :=
  (In id (dom confirmed) -> Exists fingerprint token,
         fresh token /\  fingerprint = confirmed id /\
         managed' = managed [token := fingerprint]) /\
  (~In id (dom managed) -> managed' = managed)

revoke (token : MToken) (identities : Identity set) :=
  (In token (dom managed) ->  Forall fingerprint key,
    fingerprint = managed token -> key = keys fingerprint ->
     ( Subset identities key.identities ->
            confirmed' = confirmed -- identities) /\
     (~Subset identities key.identities ->
            confirmed' = confirmed)) /\
  (~In token (dom managed) -> confirmed' = confirmed)

ms -- ks
The map containing all mappings of ms except for any mapping with a key in ks.
dubMinus (ms ks) :=
  Exists tf, forall x, In x (dom tf) -> _

\end{verbatim}

\end{document}


% From Robert_Harper@terrier.fox.cs.cmu.edu  Wed Jun 19 00:07:29 1996
%Return-Path: Robert_Harper@terrier.fox.cs.cmu.edu
%To: tofte@diku.dk
%Subject: revised appendix 5 (tex source, no references)
%Date: Tue, 18 Jun 1996 18:07:12 -0400
%From: Robert Harper <Robert_Harper@terrier.fox.cs.cmu.edu>
%
\section{Appendix: The Development of ML}
\label{story-app}

This Appendix records the main stages in the development of ML, and the people
principally involved.  The main emphasis is upon the design of the language;
there is also a section devoted to implementation. On the other hand, no
attempt is made to record work on applications of the language.
\note{\thenewpreface}{This appendix has been revised and extended in
several ways. A detailed list of changes is not available.}
\subsection*{Origins}

ML and its semantic description have evolved over a period of about
twenty years.  It is a fusion of many ideas from many people;  in this
appendix we try to record and to acknowledge the important precursors
of its ideas, the important influences upon it, and the important
contributions to its design, implementation and semantic description.

ML, which stands for {\em meta language}, was conceived as a medium for
finding and performing proofs in a formal logical system.  This application
was the focus of the initial design effort, by Robin Milner in collaboration
first with Malcolm Newey and Lockwood Morris, then with Michael Gordon and
Christopher Wadsworth~\cite{GMMNW}. The intended application to proof affected
the design considerably.  Higher order functions in full generality seemed
necessary for programming proof tactics and strategies, and also a robust type
system (see below).  At the same time, imperative features were important for
practical reasons; no-one had experience of large useful programs written in a
pure functional style. In particular, an exception-raising mechanism was
highly desirable for the natural presentation of tactics.

The full definition of this first version of ML was included in a
book~\cite{GMW} which describes LCF, the proof system which ML was designed to
support.  The details of how the proof application exerted an influence on
design is reported by Milner~\cite{Mil2}.  Other early influences were the
applicative languages already in use in Artificial Intelligence, principally
LISP~\cite{McC}, ISWIM~\cite{Lan} and POP2~\cite{BP}.

\subsection*{Polymorphic types}

The polymorphic type discipline and the associated type-assignment algorithm
were\linebreak
 prompted by the need for security;  it is vital to know that when
a program produces an object which it claims to be a theorem, then it
is indeed a theorem.  A type discipline provides the security, but a
polymorphic discipline also permits considerable flexibility.

The key ideas of the type discipline were evolved in combinatory logic by
Haskell Curry and Roger Hindley, who arrived at different but equivalent
algorithms for computing principal type schemes.  Curry's~\cite{Cur} algorithm
was by equation-solving; Hindley~\cite{Hin} used the unification algorithm of
Alan Robinson~\cite{Rob} and also presented the precursor of our type
inference system.  James Morris~\cite{Mor} independently gave an
equation-solving algorithm very similar to Curry's.  The idea of an algorithm
for finding principal type schemes is very natural and may well have been
known earlier. Roger Hindley has pointed out that Carew
Meredith's inference rule for propositional logic called Condensed Detachment,
defined in the early 1950s, clearly suggests that he knew such an algorithm
\cite{Mer}.

Milner~\cite{Mil1}, during the design of ML, rediscovered principal types and
their calculation by unification, for a language (slightly richer than
combinatory logic) containing local declarations.  He and Damas~\cite{DM}
presented the ML type inference systems following Hindley's style.  Damas
\cite{Dam}, using ideas from Michael Gordon, also devised the first
mathematical treatment of polymorphism in the presence of references and
assignment.  Tofte~\cite{Tof-a} produced a different scheme employing
so-called {\em imperative types}, which was adopted in the original version of
the language.  This approach has been superseded in the present language by a
simpler scheme, suggested by Tofte~\cite{Tof-a}, Andrew Wright~\cite{wright95}, and
Xavier Leroy~\cite{Ler1}, according to which polymorphic bindings are
restricted to non-expansive expressions.

\subsection*{Refinement of the Core Language}

Two movements led to the re-design of ML.  One was the work of Rod
Burstall and his group on specifications, crystallised in the specification
language CLEAR~\cite{BG} and in the functional programming language HOPE
\cite{BMS};  the latter was for expressing executable specifications.  The
outcome of this work which is relevant here was twofold.  First, there were
elegant programming features in HOPE, particularly pattern matching and
clausal function definitions; second, there were ideas on modular construction
of specifications, using signatures in the interfaces.  A smaller but
significant movement was by Luca Cardelli, who extended the data-type
repertoire in ML by adding named records and variant types.

In 1983, Milner (prompted by Bernard Sufrin) wrote the first draft of a
standard form of ML attempting to unite these ideas; over the next three years
it evolved into the Standard ML core language.  Notable here was the harmony
found among polymorphism, HOPE patterns and Cardelli records, and the nice
generalisations of ML exceptions due to ideas from Alan Mycroft, Brian Monahan
and Don Sannella.  A simple stream-based I/O mechanism was developed from
ideas of Cardelli by Milner and Harper.  The Standard ML core language is
described in detail in a composite report~\cite{HMM} which also contains a
description of the I/O mechanism and MacQueen's proposal for program modules
(see later for discussion of this). Since then only few changes to the core
language have occurred.  Milner proposed equality types, and these were added,
together with a few minor adjustments~\cite{Mil3}.  The
last development before the 1990 Definition was in the exception mechanism, by MacQueen using an idea
from Burstall~\cite{AMMT}; it harmonized the ideas of exception and data type
construction.

\subsection*{Modules}

Besides contributory ideas to the core language, HOPE~\cite{BMS} contained a
simple notion of program module.  The most important and original feature of
ML modules, however, stems from the work on parameterised specifications in
CLEAR~\cite{BG}.  MacQueen, who was a member of Burstall's group at the time,
designed~\cite{Mac} a new parametric module feature for HOPE inspired by the
CLEAR work.  He later extended the parameterisation ideas by a novel method of
specifying sharing of components among the structure parameters of a functor,
and produced a draft design which accommodated features already present in ML
-- in particular the polymorphic type system.  This design was discussed in
detail at Edinburgh, leading to MacQueen's first report on modules~\cite{HMM}.

Thereafter, the design came under close scrutiny through a draft operational
static semantics and prototype implementation of it by Harper, through Kevin
Mitchell's implementation of the evaluation, through a denotational semantics
written by Don Sannella, and then through further work on operational
semantics by Harper, Milner, and Tofte.  (More is said about this in the later
section on Semantics.)  In all of this work the central ideas withstood
scrutiny, while it also became clear that there were gaps in the design and
ambiguities in interpretation.  (An example of a gap was the inability to
specify sharing between a functor argument structure and its result structure;
an example of an ambiguity was the question of whether sharing exists in a
structure over and above what is specified in the signature expression which
accompanies its declaration.)

Much discussion ensued; it was possible for a wider group to comment on
modules through using Harper's prototype implementation, while Harper, Milner
and Tofte gained understanding during development of this semantics.  In
parallel, Sannella and Tarlecki explored the implications of modules for the
methodology of program development~\cite{ST}.  Tofte, in his thesis
\cite{tofte88}, proved several technical properties of modules in a skeletal
language, which generated considerable confidence in this design. A key point
in this development was the proof of the existence of principal signatures,
and, in the careful distinction between the notion of {\it enrichment} of
structures, which allows more polymorphism and more components, and {\it
realisation} which allows more sharing.

At a meeting in Edinburgh in 1987 a choice of two designs was presented,
hinging upon whether or not a functor application should coerce its actual
argument to its argument signature.  The meeting chose coercion, and
thereafter the production of Section~\ref{statmod-sec} of this report -- the
static semantics of modules -- was a matter of detailed care.  That section is
undoubtedly the most original and demanding part of this semantics, just as
the ideas of MacQueen upon which it is based are the most far-reaching
extension to the original design of ML.

Considerable experience was gained in implementing, programming with, and
teaching the language during the nearly ten years since the definition was
first published.  Based on this experience a number of design decisions were
revisited at a meeting of the authors in Cambridge at the end of 1995.  At
this meeting it was decided to make several modest, but significant, changes
to the language in order to simplify the semantics and to correct some
shortcomings that had come to light.  The most important of these changes was
the replacement of the imperative type discipline by the so-called value
restriction (discussed above), the elimination of structure sharing as a
separate concept from type sharing, and the introduction of the closely
connected mechanisms of opaque signature matching and type abbreviations in
signatures.  An important impetus for these changes to the modules language
was the work of Leroy~\cite{leroy94}, and Harper and
Lillibridge~\cite{HL} on the type-theoretic interpretation of
modules (described below).

\subsection*{Implementation}

The first implementation of ML was by Malcolm Newey, Lockwood Morris and Robin
Milner in 1974, for the DEC10.  Later Mike Gordon and Chris Wadsworth joined;
their work was mainly in specialising ML towards machine-assisted reasoning.
Around 1980 Luca Cardelli implemented a version on VAX; his work was later
extended by Alan Mycroft, Kevin Mitchell and John Scott.  This version
contained one or two new data-type features, and was based upon the {\em
Functional Abstract Machine (FAM)}, a virtual machine which has been a
considerable stimulus to later implementation.  By providing a reasonably
efficient implementation, this work enabled the language to be taught to
students; this, in turn, prompted the idea that it could become a useful
general purpose language.

In Gothenburg, an implementation was developed by Lennart Augustsson and
Thomas Johnsson in 1982, using lazy evaluation rather than call-by-value; the
result was called {\em Lazy ML} and is described in~\cite{Aug}.  This work is
part of continuing research in many places on implementation of lazy
evaluation in pure functional languages.  But for ML, which includes
exceptions and assignment, the emphasis has been mainly upon strict evaluation
(call-by-value).

In Cambridge, in the early 1980s, Larry Paulson made considerable improvements
to the Edinburgh ML compiler, as part of his wider programme of improving {\em
Edinburgh LCF} to become {\em Cambridge LCF}~\cite{Pau}.  This system has
supported larger proofs than the Edinburgh system, and with greater
convenience; in particular, the compiled ML code ran four to five times
faster.

Around the same time G\'{e}rard Huet at INRIA (Versailles) adapted ML to
Maclisp on Multics, again for use in machine-assisted proof.  There was close
collaboration between INRIA and Cambridge in this period.  ML has undergone a
separate development in the group at INRIA on the {\em CAML}
language~\cite{CCM}.  Work on {\em CAML} included the development of several
extensions to the core language, notably updatable fields in record types,
values with dynamic types, support for lazy evaluation, and handling of
embedded languages with user-defined syntax.  It did not, however, include
modules.

The first implementation of the Standard ML core language was by Mitchell,
Mycroft and Scott at Edinburgh, around 1984.  The prototype implementation of
modules, before that part of the language settled down, was done in 1985-6;
Mitchell dealt with evaluation, while Harper tackled the elaboration (or
`signature checking') which raised problems of a kind not previously
encountered.  Harper's implementation employed a form of unification that was
later adopted in the static semantics of modules.

At around the same time the {\em Poly/ML} implementation began with a
suggestion from Mike Gordon that an interesting application of Matthews' Poly
language would be to implement Standard ML.  Important experience was gained
through Matthews' early implementation of the core language, followed by
several versions of the modules language as they were devised.  {\em Poly/ML}
features arbitrary precision arithmetic, a process package, and a windowing
system.  Considerable experience has been gained with the compiler, notably by
Larry Paulson at Cambridge and by Abstract Hardware Limited (AHL).

  The {\em Standard ML of New Jersey (SML/NJ)} system has been in active development
  since 1986~\cite{am87,am91}.
  Initially started by David MacQueen at Bell Laboratories and Andrew Appel at Princeton University,
  the project has also benefited from significant contributions
  by Matthias Blume, Emden Gansner, Lal George, John Reppy and Zhong Shao.
  {\em SML/NJ} is a robust and complete environment for Standard ML that supports
  the implementation of large software systems and generates efficient code for a
  number of different hardware and software platforms.  {\em SML/NJ} also serves as
  a laboratory for compiler research: in implementations of module systems for ML;
  code optimization based on continuation-passing style; efficient pattern matching;
  and very fast heap allocation and garbage collection.  Dozens of researchers
  have contributed to the development of the compiler, in such areas as
  efficient closure representations, first-class continuations, type-directed
  compilation, concurrent programming, portable code generators, separate
  compilation, and register allocation.
  {\em SML/NJ} has also been widely used to explore extending SML with
  concurrency features.

%In 1986 Andrew Appel and David MacQueen began work on the {\em Standard ML of
%New Jersey (SML/NJ)} compiler~\cite{am87}.  {\em SML/NJ} is a robust and
%complete environment for Standard ML that supports the implementation of large
%software systems and generates efficient code for a number of different
%hardware and software platforms.  {\em SML/NJ} also serves as a laboratory for
%compiler research: in implementations of module systems for ML; code
%optimization based on continuation-passing style; efficient pattern matching;
%and very fast heap allocation and garbage collection.  Dozens of researchers
%have contributed to the development of the compiler, in such areas as
%efficient closure representations, first-class continuations, type-directed
%compilation, concurrent programming, portable code generators, separate
%compilation, and register allocation.

In 1989, Mads Tofte, Nick Rothwell and David N. Turner started work on the
{\em ML Kit Compiler} in Edinburgh. The {\em ML Kit} is a direct translation
of the 1990 Definition into a collection of Standard ML modules, emphasis being
on clarity rather than efficiency. During 1992 and 1993, Version~1 of the {\em
ML Kit} was completed, mostly through the work of Nick Rothwell at Edinburgh
and Lars Birkedal at DIKU\cite{BRTT}. In 1994, region inference was added to
the {\em ML Kit}, by Mads Tofte. Lars Birkedal wrote a region-based C-code
generator and a runtime system in C.  In 1995, Martin Elsman and Niels
Hallenberg extended this work to generate native code for the HP PA-RISC
architecture.

Harlequin Ltd. began the implementation of a commercial compiler in 1990.  The
{\em MLWorks} system is a fully-featured graphical programming environment,
including an interactive debugger, inspector, browser, extensive profiling
facilities, separate compilation and delivery, a foreign-language interface,
and libraries for threads and windowing systems.
%Harlequin was a major
%partner in the effort to standardize the revised Standard ML basis library.

{\em Caml Light}, a lightweight reimplementation of {\em CAML} released in
1991, added a simple module system in the style of Modula-2, targeted towards
separate compilation of modules: structures and signatures are identified with
files, functors and multiple views of a structure are not supported.  These
were added in the {\em Caml Special Light} implementation in 1995, while
preserving the support for separate compilation. {\em Caml Special Light} and
the present version of Standard ML share several important simplifications,
such as the value restriction on polymorphism, type definitions in signatures,
and the lack of support for structure sharing.  The static semantics for {\em
Caml Special Light} is based on the type-theoretic properties of dependent
function types (functor signatures) and manifest types (type definitions in
signatures)~\cite{leroy94}.

{\em Moscow ML} is an implementation of core Standard ML, created in 1994 by
Sergei Romanenko in Moscow and Peter Sestoft in Copenhagen.  The {\em Caml
Light} system was used to implement the dynamic semantics, and the ML Kit
guided the implementation of the static semantics.  The result is a compact
and robust implementation, suitable for teaching.

The {\em TIL (Typed Intermediate Languages)} compiler developed at Carnegie
Mellon
University by Greg Morrisett, David Tarditi, Perry Cheng, Chris Stone,
Robert Harper,
and Peter Lee demonstrates the use of
types in compilation.  All but the last few stages of {\em TIL} are expressed
as type-directed and type-preserving transforms.  Types are used at run time
to support unboxed, untagged data representations and natural calling
conventions in the presence of variable types and garbage collection.  {\em
TIL} employs a wide variety of conventional functional language optimizations
found in other SML compilers, as well as a set of loop-oriented optimizations.
A description of the compiler and an analysis of its performance appears
in~\cite{Tar}.

Other currently active implementations are by Michael Hedlund at the
Rutherford-Appleton Laboratory, by Robert Duncan, Simon Nichols and Aaron
Sloman at the University of Sussex ({\em POPLOG}) and by Malcolm Newey and his
group at the Australian National University.

\subsection*{Semantics}

The description of the first version of ML~\cite{GMW} was informal, and in an
operational style; around the same time a denotational semantics was written,
but never published, by Mike Gordon and Robin Milner.  Meanwhile structured
operational semantics, presented as an inference system, was gaining credence
as a tractable medium.  This originates with the reduction rules of
$\lambda$-calculus, but was developed more widely through the work of Plotkin
\cite{Plo}, and also by Milner.  This was at first only used for dynamic
semantics, but later the benefit of using inference systems for both static
and dynamic semantics became apparent.  This advantage was realised when
Gilles Kahn and his group at INRIA were able to execute early versions of both
forms of semantics for the ML core language using their Typol system
\cite{Des}.  The static and dynamic semantics of the core language reached a
final form mostly through work by Tofte and Milner.

The modules of ML presented little difficulty as far as dynamic semantics is
concerned, but the static semantics of modules was a concerted effort by
several people.  MacQueen's original informal description~\cite{HMM} was the
starting point; Sannella wrote a denotational semantics for several versions,
which showed that several issues had not been settled by the informal
description.  Robert Harper, while writing the first implementation of
modules, made the first draft of the static semantics.  Harper's version made
clear the importance of structure names; work by Milner and Tofte introduced
further ideas including realisation; thereafter a concerted effort by all
three led to several suggestions for modification of the language, and a small
range of alternative interpretations; these were assessed in discussion with
MacQueen, and more widely with the principal users of the language, and an
agreed form was reached.

Concurrently with the formulation of the Definition of Standard ML, Harper and
Mitchell took up the challenge adumbrated by MacQueen~\cite{Mac2} to find
a type-theoretic interpretation of Standard ML~\cite{HM}.  This work led to
the formulation of the XML language, an explicitly-typed $\lambda$-calculus
that captured many aspects of Standard ML.  Although incomplete, their
approach formed the basis for a number of subsequent studies, including the
work of Harper and Lillibridge~\cite{HL} and Leroy~\cite{leroy94} on the
type-theoretic interpretation of modules.  This work influenced the decision
to revise the language, and culminated in a type-theoretic interpretation of
the present language by Harper and Stone~\cite{SH}.  The TIL/ML compiler
(described above) is based directly on this interpretation.

There is no doubt that the interaction between design and semantic description
of modules has been one of the most striking phases in the entire language
development, leading (in the opinion of those involved) to a high degree of
confidence both in the language and in the semantics.

\subsection*{Program Libraries}
%During 1989-1991, Dave Berry produced the first program library for
%Standard ML\cite{mllib91,berry93}. Subsequently, a partnership between
%the originators of {\em SML/NJ}, {\em MLWorks} and
%{\em Moscow ML} was formed, with the goal of creating an industrial strength
%initial basis for Standard ML. The resulting SML Basis
%Library\cite{mllib96} is a much improved and extended
%replacement of the initial basis defined in the 1990 Definition of
%Standard ML.
 During 1989-1991, Dave Berry produced the first program library for
 Standard ML\cite{mllib91,berry93}.
 The {\em SML/NJ} system is distributed with a rich library organised by
 Emden Gansner and John Reppy; this library was the starting point for
 the SML Basis Library~.
 The {\em SML Basis Library\/}\cite{mllib96} has been developed
 over the past three years in a
 partnership between the SML/NJ effort, {\em MLWorks}, and {\em Moscow ML}.
 The resulting library is a much improved and extended
 replacement of the initial basis defined in the 1990 Definition of
 Standard ML.


\chapter{Conclusion \& Perspectives}         % ne pas numéroter
%\phantomsection\addcontentsline{toc}{chapter}{Conclusion \& Perspectives} % dans TdM

\section{General conclusions}
The objectives of the present thesis were, first, to deploy the infrared thermography technique in the procedure of maintaining the ``cold food chain'', especially in insulated vehicles of ATP standards. The application of infrared thermography aims to identify thermal insulation anomalies, which the standard ATP test cannot localize.

The preliminary work focused on mapping the heat flux on the external surface of an insulated roll-container using the Infrared thermography technique. The ATP standard measurement was performed to obtain the experimental results, meanwhile IR images of the roll-container were obtained when the steady condition was reached, in order to analyze and compute the corresponding heat flux on the entire surface. A simple thermal resistance model was applied to conduct the computation. Final temperature figures showed a good uniform distribution, and several defects in the structure such as thermal bridges or air leakages were identified. A reference zone of the external wall was measured by a thermal flux meter, then with that reference the entire surface heat flux map was determined. In addition, for a better view of the heat flux map, the homography, one of the computer vision techniques, was performed in the raw images by applying a bilinear interpolation with the projective transformation matrix. The final corrected heat flux map was demonstrated for each surface, in which the right surface showed a smaller value than the others.  Due to the air streaming, temperatures in the lateral surfaces were a little smaller than other surfaces, thus this lead to the smaller heat flux values.

When implemented into the internal surface of the insulated vehicle, a panoramic view was needed, since the field of view (FOV) of the infrared camera could not capture the entire surface of insulated vehicle. With the help of an infrared camera mounted on a pan-tilt head and automatically driven by a suitable software, a series of thermal images of the inner walls of the vehicle under steady condition have been captured. Proper computer vision techniques such as inverse spherical projection and stitching images by translation helped to generate the final panorama. The same thermal resistance model was utilized to compute the corresponding heat flux map. Results demonstrated a good performance of the algorithm, though the manual creation of the panoramic view required more time for completion. Compared with the standard ATP test, the final K-value obtained by infrared thermography showed a good accuracy (0.87\% of error).

Then based on the previous favorable results, the second aspect of this project was to explore cold approaches (such as compressed air, liquid nitrogen, etc.) in infrared thermography for Non-Destructive Testing \& Evaluation. The first interesting idea of detection of insulation flaws and thermal bridges in insulated truck box panels then emerged. As it is not convenient to heat the entire vehicle panels for the detection, cooling them by compressed air therefore can be a better solution. The study then focused on the cooling approach for the truck box panels inspection by infrared thermography. Both heating and cooling methods were applied by lamp and compressed air respectively. Numerical simulations under COMSOL Multiphysics{\textregistered} platform were conducted as well. For a comprehensive analysis, passive thermography detection in computational models has been presented at the same time. Results demonstrate that the compressed air spray is more rapid than the traditional heating method in providing successful detection.

A consideration of replacing compressed air by liquid nitrogen was then explored in more detail. Thus a study was performed, in which a steel specimen was used to test three different stimulations for thermal images and also Receiver Operating Characteristic (ROC) analysis comparison. Results showed that all techniques highlighted part of the flaws in the sample, whereas the liquid nitrogen technique represented the defects only at the beginning; this may be due to the high conductivity of steel. In thermal results, the PCT post-processing method displayed better results for all procedures. More defects were exhibited in Flash stimulation with PCT processing. ROC curve analysis has elucidated a straightforward classification comparison, in which the best curve was obtained using the Flash technique with PCT processing.

\section{Future perspectives}
Generally, the infrared thermography technique has been applied with promising results in ATP standard insulated vehicle tests, for the goal of maintaining the ``cold food chain". The results have demonstrated that the benefits of time-saving and the accuracy in the determination of the K-value could be applied for assessment at a commercial level.  For the panoramic view of the insulated vehicle internal surface, due to the repeated structure on the internal surface of vehicle, algorithms of automatic creation which have better feature detection and comparison remain to be explored.  A suitable software package may be created to simplify the post-processing of thermal images. This will facilitate the computation of the K-value.

On the other hand, the exploration of cold approaches in infrared thermography for Non-Destructive Testing and Evaluation has also shown several advantages. Compressed air cooling can be a good replacement of heating in the detection of insulation flaws for truck box panels. The strategy of heating one side and cooling another side can be deployed in practice, since ideal cases in simulation show favorable results.

The use of ROC curves to compare the different methods in infrared thermography is an interesting approach. This technique would benefit from more complete application and discussion, which would favor a more harmonious implementation in traditional techniques of NDT.


\documentclass[../../main]{subfiles}
\graphicspath{{images/rubiks-exp/}}

\begin{document}

This project is a continuation of the previous experiment described in Section \ref{subsec:sudoku_experiment}. Ideas developed for Sudoku were extrapolated on a Rubik's cube face detection problem as they are assumed to be similar in some sense \cite{rubiks_cube_zakharov}.

\subsubsection{Contour and corner detection}

Contour detection was covered in the previous step but in this case there were some issues to be solved. From the beginning, it was an issue that edges of the cube are not very clear thus face extraction with the biggest contour is not an option. On the contrary, small contours of face pieces were detected with higher success rate. Therefore, they were used for face detection. So as the next step, the closed contours with proper approximation of 4 corners were picked. These contours were supposed to be diffused square pieces of cube's face. The mentioned operations still were not able to filter all duplicates. They occur from time to time if \ac{OpenCV} detects a couple of different contours for the same object. To reject unnecessary contours, all of those with almost the same center of mass were removed but one. In order to find a face it is not enough to find contours. Diagonal of these small contours were computed and if 9 diagonals exist and located at the same angle to horizon their contours assumed to be face's pieces. The following action is to find the extremums or top-left, top-right, bottom-left, bottom-right points. The found extremums are expected to be the face's corners.

\subsubsection{Extraction}

The corner detection is covered in the previous subsection thus at this point 4 detected corners should to be passed to the next stage to apply linear transformation. As a result, plane image of the face will be stored.
This approach has the limitation for an input. It is not possible to detect the face corners if an image or a video quality is poor or contours are broken. These circumstances will fail face extraction. However, if the source quality is sufficient then this algorithm performs well because of its simplicity and performance.

\subsubsection{Transforming Image}

At this stage the same approach as in the Sudoku experiment was used. The same set of equations was used to transform the image. The system of equations from figure \ref{eq:persptransform} makes mapping of points from distorted image to a flat square image possible. To achieve this \ac{OpenCV}'s $GetPerspectiveTransform$ and $WarpPerspective$ methods were used for applying perspective transformation to the source.

\subsubsection{Identifying unique faces}

There are many possible options to check images for similarities like feature matching, color histograms, cross correlation, euclidean distance. Looking at a cube it is clear that there are no specific features on it, only colored pieces. The other case is the observation problem, the cube can be shown in different orientations. From the observations made, color histograms was chosen as a best choice to distinguish faces.
All uniquely detected faces were stored in the list and compared with every newly detected face. In order to achieve this images were converted to \ac{HSV} to calculate the histogram and normalize the results. To compare images correlation was used and performed well. For example, if the correlation is more than 0.6 it is assumed that faces are too similar thus the new one has to be rejected as already found.
This algorithm is a simple one however the empirical research showed that it works as expected.

\subsubsection{Color detection}

Color detection is nearly the easiest part of the program. In order to detect \ac{RGB} color representation for each piece of a cube face it should be segmented into $n$ equal squares, since the 3 by 3 Rubik's cube was used. The segmentation operation produces nine pieces and this approach cannot handle larger cubes.
After the piece of the face is cut out, the center pixel \ac{RGB} data and intensity are taken. The extracted data is collected into specific data structure and this is the end of the process. Extracted \ac{RGB} colors are mapped to the new data structure in order to convert it to the Rubik's cube 3D model for solving and rendering purposes.

\subsubsection{Conclusion}

This project was a continuation of the Sudoku ideas projected onto the Rubik's cube. At this stage single faces were extracted correctly but some faces extraction might fail due to illumination conditions. In fact, cube's surface may be different and it means that when the light falls on the surface it may be reprojected and create color distortions thus it brakes edge detection. Under the good illumination conditions corners of faces and pieces colors are extracted correctly.  From the figure \ref{fig:rubiks_cube_face_detected} it is clearly seen that this approach is applicable for the given problem.

\begin{figure} [ht]
    \begin{center}
        \includegraphics[width=150pt]{detected_face}
        \includegraphics[width=150pt]{extracted_face}
        \caption{Detected and extracted face sample with distorted colors.}
        \label{fig:rubiks_cube_face_detected}
    \end{center}
\end{figure}

\end{document}


\chapter{Simple BSP-based model to predict CUDA kernels}\label{chap:BSPmodel}
Models are useful to represent abstractions of software and hardware processes. The Bulk Synchronous Parallel (BSP) is a bridging model for parallel computation that allows algorithmic analysis of programs on parallel computers using performance modeling. The main idea of the BSP model is the treatment of communication and computation as abstractions of a parallel system.

In this chapter, we present a simple and intuitive BSP-based model for predicting the CUDA application execution times on GPUs. The model is based on the number of computations and memory accesses of the GPU, with additional information from profiling. Scalability, divergence, effect of optimizations and differences of architectures are adjusted by a single parameter.

The structure of this chapter is organized as follow,  in Section~\ref{sec:BackgroundModel} we mention the most important parallel models of the literature, in Section \ref{sec:proposeModel}, we describe the propose parallel BSP-based model to predict execution time of GPU applications, in Section~\ref{sec:methodModel} we describe the methodology and the use cases, in Section~\ref{sec:resultModel} we show some experimental results and  finally in Section~\ref{sec:relatedModel} we show the main relate works of this model.

\input{sections/models.tex}
\input{sections/bsp-gpu-model.tex}
\input{sections/method-model.tex}
\input{sections/result-model.tex}
\input{sections/related-works-model.tex}


\documentclass[twocolumn,12pt]{scrartcl}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Text formatting %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\setkomafont{disposition}{\normalfont\bfseries}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Includes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\usepackage{amsmath, amsfonts, amsbsy, amssymb}
\usepackage{lipsum}
\usepackage{paralist}
\input{Qcircuit.tex}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Title %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\title{An Introduction to Quantum Circuits and Shor's Algorithm}
\subtitle{A literature survey}
\author{Ben Hamlin}
\date{}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\mat}[2][ccccccccccccccccccccccccccccccccccc]{\left[
  \begin{array}{#1}
  #2\\
  \end{array}
\right]}

\newcommand{\rot}{\frac{1}{\sqrt{2}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Document %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\maketitle

\section{Introduction}
\label{sec:intro}

Quantum computing systems are nothing more than a collection of
Turing-equivalent programming systems. They differ from classical programming
systems, however, in that they rely on the features of quantum mechanics to
perform computations. It's an open question whether this gives them a
fundamental advantage in complexity over classical methods (a more than
polynomial speedup over ``physically realizable'' classical machines), but
there's enough evidence to make studying them worthwhile.

In order to take take advantage of --- or, put another way, to model --- quantum
mechanics, a system must have some way to represent all of the following
\cite{pit00}: \begin{compactenum}
\item {\it probabilistic states:} A closed quantum system is characterized by
      the probability that it will be in each of a set of observable states when
      it is measured;
\item {\it change in state:} The probabilities that characterize a state can be
      manipulated to change over time, making computation possible. This is
      frequently called {\it time evolution} in the literature;
\item {\it measurement:} When a quantum system is measured, its state resolves
      into a particular observable outcome. This effect is distinct from time
      evolution;
\item {\it interference:} The probabilities associated with each component of
      a closed quantum system can affect or ``interfere'' with the probabilities
      associated with other components. This results in the two components
      having non-independent distributions.
\end{compactenum} A variety of systems with these properties have been proposed.
Bernstein and Vazirani have suggested a quantum analog of the classical Turing
machine \cite{ber97}, and quantum cellular automata, proposed by Richard
Feynmann, have been formalized more recently by Delgado and others \cite{del07}.
Quantum circuits remain the most popular system for representing quantum
algorithms, however, and those are what this paper will cover.

The goal of this paper is to introduce the reader to quantum circuits from the
perspective of computational theory. In the process, I'll survey some of the
literature on this topic and walk through some examples of how quantum circuits
can be applied. In sections \ref{sec:qubits} and \ref{sec:ensembles}, I'll
introduce the basic abstractions in the quantum circuit model: qubits and qubit
ensembles. I'll also introduce the concept of ``mixed'' or ``entangled'' states,
which is one of the principle ways in which quantum computation differs from
classical computation. Next, in section \ref{sec:operations} I'll talk about the
operations that can be applied to qubits and ensembles, and with these
preliminaries out of the way, I'll describe the system of quantum circuits and
how they differ from classical boolean circuits. In sections \ref{sec:simon} and
\ref{sec:shor}, I'll describe some algorithms that can be expressed using
quantum circuits, including --- to the limited degree to which I understand it
--- Shor's famous integer factorization algorithm.

I began writing this paper in the hopes of answering the question of whether
quantum algorithms allow a fundamental speedup over classical algorithms, in
contradiction of the strong form of the Church-Turing thesis, and if so, what
this speedup entails. In section \ref{sec:conclusion}, I'll briefly sum up my
answer to this question, to the extent that I've succeded in finding one.

\section{Qubits}
\label{sec:qubits}

Qubits are the basic unit of quantum information, whether you're working with
QTMs, quantum circuits, or even the bloch sphere representation used in quantum
physics. That is to say, they're not specific to quantum circuits. Nonetheless,
qubits and their canonical representation as column or ``ket'' vectors are
central to understanding quantum circuits.

A qubit represents a single bit of classical information. When measured, it will
be observed to be a zero or a one. However between measurements, a qubit exists
in a ``superposition'' of classical states. That is, when measured, it will be
a zero with probability $P(0)$ and a one with probability $P(1)$. Obviously,
$P(0) + P(1) = 1$ in a single qubit system.

Rather than express the state of our system using $P(0)$ and $P(1)$ themselves,
it's useful to think of the one-state and the zero-state as having signed
{\it amplitudes} whose squares represent their respective probabilities. I.e.,
\[P(0) = a_0^2\] \[P(1) = a_1^2\] This means that \[\mat{a_0\\a_1}\]
is a unit vector. As it turns out, letting $a_0,a_1 \in \mathbb{C}$ allows
us to accurately model the kinds of time evolution we can perform on quantum
systems. For complex-valued amplitudes, \[P(0) = |a_0|^2 = |x_0 + iy_0|^2 =
x_0^2 + y_0^2\] and similarly for $P(1)$.

The standard notation for a qubit in the classical state zero is \[\ket{0}\] The
implication here is that, even though the qubit happens to be in a classical
state, it still has amplitudes: \[\ket{0} = 1\ket{0} + 0\ket{1}\] More
generally, a qubit is always in the state \[a_0\ket{0} + a_1\ket{1}\] where
$a_0$ and $a_1$ are amplitudes, as before. This is called Dirac notation, and
the symbol $\ket{n}$ is called a {\it ket}\footnote{There's also a ``bra'',
hence together they're ``bra-ket'' notation. A bra, written $\bra{n}$, is
just a row vector, the complex transpose of a ket.}.

This notation avoids some messy typesetting, but at first glance, it hides an
important fact: A ket is nothing more than a column vector. That is, \[\ket{0} =
\mat{1\\0}\] \[\ket{1} = \mat{0\\1}\]. More generally, you'll see when we
talk about ensembles of qubits that $\ket{b}$, where $b \in \{0, 1\}^n$ is the
binary representation of the number $B$, is the n-dimensional column vector in
which the $B$th element is a one, and the rest are zeroes. Thus \[a_0\ket{0} +
a_1\ket{1} = a_0\mat{1\\0} + a_1\mat{0\\1}\] \[= \mat{a_0\\0} + \mat{0\\a_1} =
\mat{a_0\\a_1}\] which is identical to our unit vector representation above.

The ket vectors $\ket{0}$ and $\ket{1}$ are called {\it bases} --- in linear
algebra terms, orthonormal basis vectors. It's worth noting that they're not
unique. These particular bases --- called the computational bases in the
literature --- are useful because their amplitudes correspond to the
probabilities of observing the classical states when measured. Nonetheless, we
could as easily express the state of our system using any set of orthonormal
bases. For example, \[\ket{+} = \mat{1\\1}\] \[\ket{-} = \mat{1\\-1}\] are
called the Bell bases.

We can derive a Bell representation of a qubit using the following
identities: \[\ket{0} = \frac{\ket{+} + \ket{-}}{\sqrt{2}}\] \[\ket{1} =
\frac{\ket{+} - \ket{-}}{\sqrt{2}}\] As we'll see in section
\ref{sec:operations}, viewing a quantum system in terms of the Bell bases can
make the effects of some quantum operations seem less mystifying\footnote{
In fact from a physical perspective, we could even {\it measure} the qubit with
respect to these bases. That is, we could measure the qubit $\ket{\phi} =
a_+\ket{+} + a_-\ket{-}$ in such a way that we would see a $\ket{+}$ with
probability $|a_+|^2$ and a $\ket{-}$ with probability $|a_-|^2$. This would
tell us nothing about whether the qubit was a $\ket{0}$ or a $\ket{1}$
\cite{nie00}. For the purposes of quantum computation, all measurement happens
with respect to the computational bases.}.

\section{Ensembles of Qubits}
\label{sec:ensembles}

One of the principle notions in quantum computation --- called interference ---
is that the amplitudes of one qubit can affect the amplitudes of another qubit
in the same closed system before they are measured. This results in qubits whose
probability distributions are intertwined. Put in the terminology of quantum
mechanics, they are {\it entangled,} or in a {\it mixed} as opposed to a
{\it pure} state. The upshot of this is that being able to represent qubits in
isolation isn't enough. We need to be able to represent groups or
{\it ensembles} of qubits.

The computational bases for qubit ensembles are analogous to the ones used for
individual qubits. That is, \[\ket{...000} = \mat{1\\0\\0\\.\\.\\.} ,
\ket{...001} = \mat{0\\1\\0\\.\\.\\.} , ...\] More precisely, the states of an
ensemble's component qubits are combined using the tensor product ($\otimes$),
defined as \[\mat{a_0\\a_1\\.\\.\\.} \otimes \mat{b_0\\b_1\\.\\.\\.} =
\mat{a_0 \times b_0\\a_0 \times b_1\\a_1 \times b_0\\.\\.\\.}\] Note that tensor
distributes over addition, so that \[a \otimes (b + c) = a \otimes b + a
\otimes c\]

If we have two qubits $\ket{\phi_a} = a_0\ket{0} + a_1\ket{1}$ and $\ket{\phi_b}
= b_0\ket{0} + b_1\ket{1}$, the ensemble $\ket{\phi_0} \otimes \ket{\phi_1}$,
often expressed as $\ket{\phi_0}\ket{\phi_1}$, or even $\ket{\phi_0\phi_1}$, is
\[a_0b_0\ket{00} + a_0b_1\ket{01} + a_1b_0\ket{10} + a_1b_1\ket{11}\] \[=
\mat{a_0b_0\\a_0b_1\\a_1b_0\\a_1b_1}\] Thus an ensemble with $n$ qubits will
be represented using $2^n$ basis vectors and amplitudes. Again, the square of
the amplitude of each state corresponds to the probability of observing that
state when the system is measured. That is $P(00) = |a_0b_0|^2$, etc.

It's also possible to measure just one qubit of an ensemble \cite{nie00}. Given
the ensemble \[a_{00}\ket{00} + a_{01}\ket{01} + a_{10}\ket{10} +
a_{11}\ket{11}\] measuring just the first qubit gives us \[P(0) = |a_{00} +
a_{01}|^2 \] \[P(1) = |a_{10}|^2 + |a_{11}|^2\] and assuming the outcome of our
measurement was $X$, the new state of the ensemble is \[\frac{a_{X0}\ket{X0} +
a_{X1}\ket{X1}}{\sqrt{P(X)}}\]

A simple example of an entangled state is $\frac{\ket{00} +
\ket{11}}{\sqrt{2}}$, sometimes called the Bell state. Say we measure the first
qubit in an ensemble in the Bell state and, with probability $\frac{1}{2}$, we
observe a $\ket{0}$. The new state of the ensemble is
\[\frac{\rot\ket{00}}{\rot} = \ket{00}\] so the second qubit must be a
$\ket{0}$. On the other hand, if we observe the first qubit to be a $\ket{1}$,
the second qubit must also be a $\ket{1}$. Measuring the first qubit changes the
probabilities associated with the second. There is no way to represent this
with single-qubit ket vectors.

It's important to note that increasing the number of qubits in the ensemble by
one multiplies the number of amplitudes by two. This makes quantum circuits ---
and quantum mechanics in general --- difficult to simulate with a classical
computer. It also hints at the power of quantum computing: An ensemble of $n$
qubits seems to contain $2^n$ complex-valued amplitudes --- significantly more
than $n$ bits of information. This information isn't immediately useful, since
measuring the qubit resolves the ensemble into a classical state, and $n$ bits
of information are lost. Quantum algorithm design is an exercise in trying to
use interference to perform calculations using this extra information before
the system is measured.

\section{Operations and Gates}
\label{sec:operations}

Ensembles of qubits allow us to represent the probabilistic state of a quantum
computational system at a single moment in time. In addition, we need to be able
to represent the way the system changes over time --- its so-called ``time
evolution.'' In fact, in order to perform computations, we need to be able to
execute these changes. Since we're representing qubits and ensembles with
$2^n$-dimensional unit vectors, it's natural to represent operations as
dimension-preserving linear transformations, that is, by left-multiplying our
state vectors by $2^n\times2^n$ matrices.

The laws of probability and physics place some limits on the kinds of operations
we can perform. The laws of thermodynamics demand that we only perform
reversible transformations. That is, we can only multiply our state vectors by
invertible matrices. Fortunately, any classical computation can be made
reversible with only a constant increase in time complexity \cite{sim97}. In
addition, it would make no sense if the probabilities associated with the
observable outcomes of our system didn't add up to one. Thus we are limited to
operations that can be described by unitary matrices. Since state vectors have
elements in $\mathbb{C}$, our operations must be unitary in the complex-valued
sense that $P^{-1} = P^\dagger$, where $P^\dagger$ is the adjoint\footnote{
``Adjoint'' is just a quantum mechanical term for conjugate transpose.} of $P$.
In quantum circuits, operations are often refered to as ``gates''. From here on,
I'll use the terms interchangably.

Any $2^n\times2^n$ unitary matrix over $\mathbb{C}$ is a valid transformation on
an $n$-bit ensemble. This provides us with an infinite number of possible
operations --- an undesirable state if we ever hope to implement a quantum
computer. A wide variety of sets of ``universal'' operations have been proposed
to deal with this problem --- ``universal'' in the sense that in combination,
they can approximate any quantum operation to an arbitrary degree of accuracy.
The most influential approach seems to be the one taken by Barenco, et al.
\cite{bar95}, who show that the set of one qubit ``rotations'', which they
simulate using five one-qubit operations, along with a single two-qubit
operation, form a universal set.

The choice of operations is important because although any universal set of
quantum operations can be combined to approximate any other quantum operation,
they may not be able to do so efficiently. In fact, it is conjectured that
``almost all'' operations require a number of applications of the universal
gates that is exponential in the number of input qubits. The choice of a
universal set thus determines which operations can be efficiently approximated.
In practice, it seems to be possible to implement useful circuits using a
relatively small --- efficiently approximable --- set of operations. This is
discussed more fully in \cite{bar95} and \cite{nie00}.

Only one one-qubit gate has an obvious analog in classical computation:
the ``not'' or $X$ gate. This has the effect of swapping the amplitudes of
the computational bases. The corresponding matrix representation is \[X =
\mat{0&1\\1&0}\] The effect this has on the classical states is \[X\ket{0} =
\ket{1}\] \[X\ket{1} = \ket{0}\] Note that the interpretation of $X$ as ``not''
only makes sense as long as we intend to measure in the computational bases,
since \[X\ket{+} = \frac{\ket{0} + \ket{1}}{\sqrt{2}} = \ket{+}\] \[X\ket{-} =
X\frac{\ket{0} - \ket{1}}{\sqrt{2}} = \frac{\ket{1} - \ket{0}}{\sqrt{2}} =
-1\ket{-}\] So $X\ket{+} \not= \ket{-}$, and vice versa.

The other one-qubit gates used in the circuits described below are the Hadamard
or $H$ gate and the $T$ gate. The $H$ gate takes a qubit in one of the
computational base states and places it reversibly into a ``uniform'' state ---
a state that has equal probability of resolving to a $\ket{0}$ or a $\ket{1}$ on
measurement. The matrix for $H$ is \[\rot\mat{1&1\\1&-1}\] and its effect is
\[H\ket{0} = \frac{\ket{0} + \ket{1}}{\sqrt{2}}\] \[H\ket{1} = \frac{\ket{0} -
\ket{1}}{\sqrt{2}}\] It is its own inverse, so its effects can be reversed
simply by applying it a second time. It's interesting to note that \[H\ket{0} =
\ket{+}\] \[H\ket{1} = \ket{-}\] \[H\ket{+} = \ket{0}\] \[H\ket{-} = \ket{1}\]
So another way to characterize the Hadamard gate is that it converts between
the computational and Bell bases.

The effects of the $T$ gate are harder to describe in an intuitive way. If the
complex-valued amplitudes of a qubit are taken to represent angles of the form
\[a = cos(\theta) + i sin(\theta)\] then the $T$ gate rotates $\theta$ in the
$\ket{1}$ amplitude of the qubit $45^\circ$ counterclockwise\footnote{This
relates to a representation of qubits called the Bloch sphere, which can be
useful, but which I won't talk about further here.}. Its only application in the
algorithms discussed in this paper is to perform the quantum Fourier transform
as part of Shor's algorithm.

In order to model interference --- the property of quantum mechanical systems
that the amplitudes of one qubit can affect the amplitudes of another before
measurement occurs --- we need multi-qubit gates. As discussed by \cite{bar95}
and others, it suffices to talk about two qubit gates, since they can be used to
construct gates over an arbitrary number of qubits.

In particular, we can construct arbitrary n-qubit gates using single-qubit gates
and the two-qubit gate ``controlled-not,'' or $CNOT$. $CNOT$ has a control qubit
and a target qubit, and its effect is to perform $X$ on the target qubit if the
control qubit is a $\ket{1}$, and do nothing otherwise. Assuming the first qubit
in a two-qubit ensemble is the control and the second is the target, its matrix
representation is \[CNOT = \mat{1&0&0&0\\0&1&0&0\\0&0&0&1\\0&0&1&0}\]

Now that we have introduced all of the components of a quantum circuit, we can
start talking about the circuits themselves. Quantum circuits, also called
quantum gate arrays, were introduced by D. Deutsch in \cite{deu85}. They are
analogous to classical boolean circuits, and analogously, they can be used to
judge the time complexity of an algorithm. The time complexity of a quantum
circuit is the number of gates it contains as a function of its input size. In
addition, we require that a family of circuits describing the algorithm for
arbitrary input sizes be constructible by a Turing machine. This allows us to
rule out circuit families that solve uncomputable problems.

Graphically, a quantum circuit looks much like a classical boolean circuit. In
the circuit \[\Qcircuit @R=.8em {
  & \gate{H} & \ctrl{1} & \gate{T} & \qw \\
  & \gate{H} &\targ     &\qw       & \qw
}\]
the gates applied are $H$, $CNOT$ with the upper qubit as control and the lower
as target, and $T$, in that order. Time proceeds left to right along the x-axis.
Sometimes, like the Hadamards in the above diagram, gates will be applied to
multiple wires at the same ``time''. This is strictly for convenience of
representation. They both count toward the complexity of the overall circuit.
Also, many operations require extra scratch, or ``ancilla'' qubits that are not
part of the input and that start in a known state. These to not count toward the
input size. A comprehensive coverage of quantum circuit complexity is provided
in \cite{deu85}.

Quantum circuits are lacking some features of classical circuits. In particular
fanout is impossible. The number of wires is constant throughout the circuit.
Even using scratch qubits, it's impossible to copy the value of a qubit.
Consider a circuit of the form \[\Qcircuit @R=.8em {
  \lstick{\ket{x}} & \multigate{1}{CLONE} & \rstick{\ket{x}} \qw \\
  \lstick{\ket{y}} & \ghost{CLONE}        & \rstick{\ket{x}} \qw
}\] The value of $y$ is lost, so this gate is not invertible. On the other hand,
this circuit is realizable \[\Qcircuit @R=.8em {
  \lstick{\ket{x}} & \multigate{1}{CLONE} & \rstick{\ket{x}} \qw \\
  \lstick{\ket{y}} & \ghost{CLONE}        & \rstick{\ket{y \oplus x}} \qw
}\] and as long as we make sure that $y$ is $\ket{0}$ to start out with, this
has the same effect.

Similarly, there is no way to implement an exact analog of classical $and$. On
the other hand, we can do this \[\Qcircuit @R=.8em {
  \lstick{\ket{x}} & \multigate{2}{AND} & \rstick{\ket{x}} \qw \\
  \lstick{\ket{y}} & \ghost{AND}        & \rstick{\ket{y}} \qw \\
  \lstick{\ket{0}} & \ghost{AND}        & \rstick{\ket{x \land y}} \qw \\
}\] This is called a Toffoli gate, and it can be implemented using $CNOT$s as
follows: \[\Qcircuit @R=.8em {
  & \ctrl{1} & \targ     & \ctrl{1} & \ctrl{2} & \qw \\
  & \targ    & \ctrl{-1} & \targ    & \qw      & \qw \\
  & \qw      & \qw       & \qw      & \targ    & \qw
}\] An $or$ gate can be constructed similarly, and along with $X$ ($not$) and
$CNOT$ ($xor$), these can be used to construct any classical circuit. On the
other hand, every $and$ in a classical circuit requires a scratch qubit in a
quantum circuit. This could result in an unbounded increase in the number of
qubits required for a computation, so quantum algorithms have to be carefully
designed to reset their scratch qubits to $\ket{0}$ between calculations so they
can be reused. This is frequently accomplished by performing the computation and
then performing its inverse, as in \cite{sho97}.

Finally, it's worthwhile to note a possibly counterintuitive property of $CNOT$:
\[\Qcircuit @R=.8em {
  & \gate{H} & \ctrl{1} & \gate{H} & \qw \\
  & \gate{H} & \targ    & \gate{H} & \qw
} \equiv \Qcircuit @R=.8em {
  & \targ     & \qw \\
  & \ctrl{-1} & \qw \\
}\] This is unexpected, because our description of $CNOT$ entails that it leaves
the control qubit unchanged. This characterization applies to ensembles in
classical states, however ($\ket{00}$, $\ket{01}$, ...). Remember that the
effect of Hadamard is to make a qubit undetermined with respect to the
computational bases but determined with respect to the Bell bases. The effect of
$CNOT$ on an ensemble represented with respect to the Bell bases is
\[CNOT\ket{++} = \ket{++}\] \[CNOT\ket{+-} = \ket{--}\] \[CNOT\ket{-+} =
\ket{-+}\] \[CNOT\ket{--} = \ket{+-}\] In other words, its effect is to change
the first qubit when the second qubit is a $\ket{-}$ and do nothing otherwise,
the exact opposite of what it does when the qubit is determined with respect to
the computational bases.

\section{An Example: Simon's Problem}
\label{sec:simon}

Simon's problem is a relatively simple example of the power of quantum
computing. In fact, it was published with the express interest of demonstrating
the potential of quantum algorithms \cite{sim97}. The problem it solves is of
less practical interest than integer factorization or discrete logarithm.
Nonetheless, it is thought not to be in $BPP$, whereas the quantum-computational
solution runs in expected polynomial time.

The problem is the following: Let \[f:\{0,1\}^n \rightarrow \{0,1\}^m\] such
that for some constant $c$ \[\forall x \not= y, f(x) = f(y) \text{ iff } x = c
\oplus y\] We wish to find $c$. Note that $f$ is an injection in the case that
$c = 0$. Otherwise, each output of $f$ corresponds to exactly two inputs, $x$
and $x \oplus c$.

The corresponding decision problem --- whether the $c$ value for $f$ is within a
specified range --- is clearly in $NP$. The $c$ value acts as the certificate,
and because we are guaranteed that $c$ exists, the verifier can simply
\begin{compactenum}
\item Select some $x$,
\item Calculate $a = f(x)$ and $b = f(x \otimes c)$,
\item Return true iff $a = b$.
\end{compactenum} which runs in polynomial time assuming $f$ runs in polynomial
time.

On the other hand, there is no known decider for the problem in $P$. The naive
algorithm would be \begin{compactitem}
\vspace{10pt}
  \item[] for $x$ from $0$ to $2^n$ \begin{compactitem}
    \item[] for $y$ from $0$ to $2^n$ \begin{compactitem}
      \item[] if $x \not= y$ \begin{compactitem}
        \item[] $a \leftarrow f(x)$
        \item[] $b \leftarrow f(y)$
        \item[] if $a = b$ return $x \oplus y$
      \end{compactitem}
    \end{compactitem}
  \end{compactitem}
  \item[] return $0$
\vspace{10pt}
\end{compactitem}

Assuming $c$ is non-zero, the likelyhood that $a = b$ at each
comparison is \[\frac{1}{2^{2n} - 2^n - ((x + 1)(y + 1))}\] and it can can be
shown that no classical probabilistic Turing machine that runs $f$ fewer than
$2^\frac{1}{4}$ times can correctly guess even whether $c$ is zero or non-zero
ith greater than $\frac{1}{2} + 2^{-\frac{n}{2}}$ probability \cite{sim97}.

The quantum circuit for Simon's problem looks as follows, where $U_f$ finds
$a_0,a_1,...,a_m = f(x)$ on the first $n$ qubits of the ensemble and sets
each $b_i$ of the last $m$ qubits to $b_i = b_i \oplus a_i$:
\[\Qcircuit @R=.8em @C=.7em {
  \lstick{\ket{0}_{1}}   & \gate{H} & \qw & \multigate{7}{U_f} & \qw & \gate{H} & \qw \\
  \lstick{\ket{0}_{2}}   & \gate{H} & \qw & \ghost{U_f}        & \qw & \gate{H} & \qw \\
  \dots                  &          &     &                    &     &          & \\
  \lstick{\ket{0}_{n}}   & \gate{H} & \qw & \ghost{U_f}        & \qw & \gate{H} & \qw \\
  \lstick{\ket{0}_{n+1}} & \qw      & \qw & \ghost{U_f}        & \qw & \qw      & \qw \\
  \lstick{\ket{0}_{n+1}} & \qw      & \qw & \ghost{U_f}        & \qw & \qw      & \qw \\
  \dots                  &          &     &                    &     &          & \\
  \lstick{\ket{0}_{n+m}} & \qw      & \qw & \ghost{U_f}        & \qw & \qw      & \qw \\
}\] Only the upper $n$ qubits are measured. I provide examples below, but the
gist is that after the second Hadamard, assuming $c \not= 0$, the upper $n$
qubits will contain, with equal likelyhood, exactly one of the two inputs
corresponding to each output\footnote{E.g., if $f(00) = f(01) = 00$ and $f(10) =
f(11) = 11$, the upper $n$ bits will contain a superposition of $\ket{00}$ and
$\ket{10}$}. On the other hand if $c = 0$, the upper $n$ bits will be uniformly
distributed over $2^n$. Sampling $k$ times and solving the resulting set of
linear equations will give us $c$. A detailed statistical analysis of this,
including a proof that the number of samples required is polynomial, can be
found in \cite{sim97}.

In broad strokes, the technique here is a common approach in quantum algorithms:
\begin{compactenum}
\item Put a set of qubits into a uniform superposition.
\item Run some function on them and store the output, generating a uniform
      superposition of pairs of the form $(x,f(x))$ for all possible input
      values, $x$.
\end{compactenum} This is sometimes called ``quantum parallelism''. Note that
this does let us obtain all possible $(x,f(x))$ pairs using a single run of $f$.
If we measure our ensemble at this point, we'll see a single such pair, which we
could have obtained by simply running $f$ classically. The tricky part is using
this uniform superposition to give us some information about the function.

To take a minimal one-bit example, say \[f(0) = 1\] \[f(1) = 0\] In this case,
$c = 0$. The circuit implementing Simon's algorithm for this problem description
is simply \[\Qcircuit @R=.8em {
  \lstick{\ket{0}} & \gate{H} & \ctrl{1} & \gate{H} & \qw \\
  \lstick{\ket{0}} & \qw      & \targ    & \qw      & \qw \\
}\] After the first Hadamard gate, we have \[\frac{\ket{00} + \ket{10}}{\sqrt{2}}\]
The $CNOT$ takes this to \[\frac{\ket{00} + \ket{11}}{\sqrt{2}}\] And the final
Hadamard gives us \[\frac{\ket{00} + \ket{10} + \ket{01} - \ket{11}}{2}\] Since
each input to $f$ maps to a different output, nothing cancels, and measuring the
first qubit gives us $\ket{0}$ or $\ket{1}$ with equal probability.

On the other hand, say $c = 1$, for example, our function might be
\[f(0) = f(1) = 1\] The circuit to implement Simon's algorithm would be
\[\Qcircuit @R=.8em {
  \lstick{\ket{0}} & \gate{H} & \qw      & \gate{H} & \qw \\
  \lstick{\ket{0}} & \qw      & \gate{X} & \qw      & \qw \\
}\] After the final Hadamard, our ensemble is in the state \[\frac{\ket{01} +
\ket{11} + \ket{01} - \ket{11}}{2} = \ket{01}\] Because an output value was
repeated, one of our input values canceled out, and the only possible value for
the first qubit is $\ket{0}$. This can be used to find $c$.

In this simple case, the outcome may seem trivial. After all, $H$ is its own
identity, so of course $HH\ket{0} = \ket{0}$. Nonetheless, this generalizes to
functions with inputs of arbitrary size. Moreover, it illustrates a feature that
\cite{sim97} uses to characterize why quantum machines seem to be more powerful
--- in a complexity sense --- than classical probabilistic machines:

The computation of a classical probabilistic machine can be characterized by a
tree in which each node is a configuration. The probability of it being in
configuration $a$ at step $n + 1$ is determined by its configuration at step $n$
and the input it sees. Configurations can be duplicated at the $n + 1$st
level of the tree if they are reachable from more than one configuration at step
$n$. For each leaf, the probability of ending at that leaf is the product of the
probabilities along the path to that leaf, and if a configuration is duplicated
in more than one leaf, the probability of ending in that configuration is the
sum of those leaves' probabilities. All of the probabilities are, of course,
positive.

A quantum computation can be described by a similar tree of configurations. The
difference is that, until measurement is taken, each node is assigned
amplitudes, not probabilities, and these amplitudes can be negative. If a
configuration is duplicated, the probability of arriving at that leaf is the
{\it square of the sums} of their amplitudes. This means that if one of leaf
representing configuration $c$ has amplitude $\rot$ and another has amplitude
$^-\rot$, they cancel out, and the configuration is unreachable. In other words,
the amplitudes interfere with each other before they resolve to probabilities.
It's interesting to note that, if one were to measure the system after each
step, collapsing the amplitudes to probabilities, the result would have no more
power than a classical probabilistic machine.

\section{Shor's Algorithm}
\label{sec:shor}

Shor's algorithm is the most famous quantum algorithm. It factors integers, a
problem that is not only believed not to be in $P$, but whose hardness is the
basis for RSA. Nonetheless, integer factorization is not $NP$ complete, and from
the perspective of computational complexity, its solution is no more surprising
than the solution to Simon's problem. I'll cover Shor's algorithm in
significantly less depth than I did Simon's problem, without circuit diagrams or
examples. This is in part because the circuits involved in Shor's algorithm are
quite complex, but also because the final step in Shor's algorithm involves an
element of Fourier analysis that I have yet to fully understand. Nonetheless,
the general thrust of Shor's algorithm isn't hard to grasp, and is in fact
quite similar to the algorithm for Simon's problem.

In \cite{sho97}, Shor presents a solution not just to integer factorization, but
also to the discrete logarithm problem, which is the hard problem behind the
Diffie-Hellman cryptographic key exchange algorithm. In fact, the problem Shor
solves is neither of these, directly, but order-finding: determining the
smallest $r$ such that $x^r \equiv 1 (\text{mod }n)$. Such an $r$ for a
uniformly chosen $x$ can be used to find a prime factor of $n$ with probability
greater than $\frac{1}{3}$, and since the number of factors of $n$ is polynomial
in $log(n)$, a polynomial time algorithm for order-finding equates to a
polynomial time algorithm for integer factorization: All we need to do is choose
values for $x$ and find their order until the prime factors derived can be
multiplied together to get $n$. A complete coverage of the number-theoretic
foundations of this can be found in \cite{sho97}, but an order-finding approach
is not unique to Shor's algorithm. It is the basis for classical factoring
algorithms as well.

Shor's algorithm can be broken up into two basic parts, one of which could
easily be performed by a classical computer. The other two require quantum
computation. The first of these is merely a quantum version of fast
exponentiation. The algorithm is fully described in \cite{sho97}, but it is
identical in most respects to the classical algorithm for performing the same
task. We calculate $x^y (\text{mod }n)$, where $y$ is treated as input, and $x$
is hard-wired into the circuit\footnote{Thus for each new value of $x$ whose
order we wish to find, we must create a new circuit.}.

Once we have a circuit that calculates $f(y) = x^y (\text{mod }n)$ on $log(n)$
qubits and sets the next $log(n)$ qubits to their original value $xor$ the
result, we do the following: \begin{compactenum}
\item Prepare an ensemble of $2log(n)$ qubits plus scratch qubits to $\ket{0}$
\item Use Hadamard gates to bring the first $log(n)$ qubits into the uniform
      state
\item Apply $f$ with the first $log(n)$ qubits as control and the next $log(n)$
      qubits as target
\end{compactenum} Our ensemble is now in the state
\[\sum_{i = 0}^n\frac{\ket{i}\ket{x^i (\text{mod }n)}}{n^{\frac{1}{2}}}\] This
very similar to the approach taken in the algorithm for Simon's problem. Every
pair of the form $(y,f(y))$ is now stored in our ensemble with equal amplitude.
If we attempt to measure it at this stage, however, the amplitudes collapse to
give us just one of these pairs --- no more than we could have gotten with
classical fast exponentiation. We need some way to tease out only those values
for which $f(y) = 1$.

The solution to this --- and the part of the algorithm I have yet to understand
--- involves performing quantum Fourier transform (QFT). The classical Fourier
transform takes as input a list of numbers representing outputs to a function
$f$ and produces a list of coefficients to $sine$ and $cosine$ functions whose
sum approximates $f$. This can then be used to find the periodicity of $f$. QFT
does exactly the same thing, but the list taken as input and used as output is
the list of amplitudes to a qubit ensemble. That is, each amplitude of the
resulting ensemble is a coefficient to a $sine$ or $cosine$ function, which
together approximate the function described by the original coefficients. The
final part of the algorithm, which can be performed by a classical computer, is
to perform statistical analysis on a polynomial number of runs of the quantum
algorithm. The results of this are used to find the order of $x$ mod $n$ with
probability greater than $\frac{2}{3}$. More detail on this process can be found
in \cite{sho97}.

\section{Conclusion}
\label{sec:conclusion}

I'm a little disappointed that I failed to fully understand fully Shor's
algorithm. I feel like I learned a lot in the attempt, though. In general, I
think the answer to my original question, ``To what extent does quantum
computation allow a more-than-polynomial speedup over classical algorithms, and
what does that speedup entail,'' can be summed up as follows:
\begin{compactitem}
\item There is evidence, albeit inconclusive, that quantum algorithms provide
      a fundamental algorithmic speedup in some cases.
\item To the extent that such a speedup exists, it can be explained by
      interference phenomena and so-called ``quantum parallelism''. In other
      words, it stems from the fact that at a quantum mechanical level, it seems
      to be possible to execute a function on an exponential\footnote{That is,
      exponential in the number of qubits.} number of inputs at once and then
      cause the outputs of those executions to affect the amplitudes of qubits
      in a limited way.
\end{compactitem}

\begin{thebibliography}{10}
\label{sec:ref}

\bibitem{bar95}
A. Barenco, C. Bennett, R. Cleve, D. DiVincenzo, N. Margolus, P. Shor, T.
  Sleater, J. Smolin, and H. Weinfurter.
"Elementary Gates for Quantum Computing."
In {\it Physical Review A.}
March, 1995.

\bibitem{ber97}
E. Bernstein and U. Vazirani.
``Quantum complexity theory.''
In {\it Siam Journal on Computing} 26(5).
1997.

\bibitem{del07}
C. Delgado and D. Cheung.
``Local unitary quantum cellular automata.''
In {\it Physical Review A} 76(3A).
2007.

\bibitem{deu85}
D. Deutsch.
``Quantum theory, the Church-Turing principle and the universal quantum
  computer''
In {\it Proceedings of the Royal Society of London A} 400, pages 97--117.
1985.

\bibitem{nie00}
M. Nielsen and I. Chuang.
{\it Quantum Computation and Quantum Information.}
Cambridge, UK, 2000.

\bibitem{pit00}
A. Pittenger.
{\it An Introduction to Quantum Computing Algrithms.}
Birkhauser, Boston, MA, 2000.

\bibitem{sho97}
P. Shor.
``Polynomial time algorithms for prime factorization and discrete logarithm on a
  quantum computer.''
In {\it SIAM Journal of Computing 26.}
1997.

\bibitem{sim97}
D. Simon.
``On the power of quantum computation.''
In {\it SIAM Journal on Computing} 26(5).
1997.

\end{thebibliography}

\end{document}

%%% End %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\section{Introduction}
The fact that \gls{FRE} is uncorrelated with \gls{TRE} is well established
\cite{fitzpatrick2009}. In spite of this, many students and users of clinical guidance systems struggle to
correctly interpret \gls{FRE} and residual errors in general.
\fred (Fiducial Registration Educational Demonstrator)
 \cite{stephen_thompson_2021_4462897} was developed using the
\sksurgery \cite{PMID:32436132} libraries to probe the causes of misconceptions
about \gls{FRE} and \gls{TRE}. \fred supports online learning and provides tools to enable
research into user interface design for image guidance systems.

Faced with the need to deliver teaching and research remotely during 2020's {SARS-CoV-2}\cite{PMID:32123347}
travel restrictions, we
developed a new online tutorial\footnote{\href{https://mphy0026.readthedocs.io/en/latest/summerschool/registration_demo.html}{https://mphy0026.readthedocs.io/en/latest/summerschool/registration{\textunderscore}demo.html}}
on fiducial based registration. The tutorial utilises \fred which is now implemented as a browser based web-app.
\fred can be accessed on-line\footnote{\href{https://scikit-surgeryfred.ew.r.appspot.com/}{https://scikit-surgeryfred.ew.r.appspot.com/}} or deployed locally.
Rather than simply telling the students that \gls{FRE} is uncorrelated with \gls{TRE}
we decided it would be more effective to use divergent questioning strategies\cite{Tofade155} within the application, analysis, synthesis and
evaluation levels of Bloom's taxonomy \cite{blooms_tax}: hence the question posed within the title of this paper.

We also took the opportunity to develop a serious game based on \fredns.
Serious games are games designed to be engaging to play, whilst setting out to achieve an objective
beyond pure entertainment. In the case of \fredns, the objective is to gather data on how clinical
decision making might be influenced by the communication of registration errors.
Serious games have significant potential
as a training tool for clinicians \cite{PMID:28133947, serious-needle}. Serious games have also been shown to be
useful in assessing the usability of human computer interfaces \cite{hci_games}, which is of particular
relevance to computer aided surgery. The results of the game indicate that the choice of error statistic shown can affect clinical decision making.

In this paper we introduce the \fred application and show how it can
be used as an educational tool and to perform studies to measure registration and
ablation performance. By default \fred
implements \gls{FLE} as an isotropic, normally distributed, independent variable.
In this paper we show how \fred can be modified to implement anisotropic and
systematic errors, and present the results of these modifications.
It is our plan to build on
the software to perform larger studies; to investigate more realistic models of \gls{FLE};
to investigate other registration approaches; and other ways of communicating registration error.
\fred is entirely open
source software and we encourage researchers and educators to use and contribute to it.


\section{Results for SWR detection}
\label{sec:RNN-results}

The first GRU network that we analyzed used all 16 input LFP channels, had 2 layers of 40 hidden units each, and was trained on a target function $y_t$ that is $1$ during the entire duration of each reference SWR segment, and $0$ elsewhere. \Cref{fig:validloss} shows the evolution of the validation loss while training this RNN. \Cref{fig:RNN-envelopes} shows example output envelopes $n_t$.

\begin{figure}
\img[0.6]{575_4--576_0}
\img[0.6]{589_8--590_4}
\captionn{RNN output envelopes}{Output of a trained GRU-RNN that uses all input channels and that has two hidden layers of 40 hidden units each. See \cref{fig:BPF-outputs} for legend.}
\label{fig:RNN-envelopes}
\end{figure}

We notice that the RNN output matches the target block-shaped function $y_t$ relatively well. Together with the validation loss curve, it seems that the target function was relatively well learnable.

Secondly, the RNN clearly uses more information than the ripple oscillation only to generate its output. In the right panel of \cref{fig:RNN-envelopes}, the RNN outputs a positive with high confidence. The low frequency LFP over all channels indeed has the profile of an SWR; but the ripple is almost non-existent, as can be seen in the band-pass and GEVec filter outputs. This detection of the RNN is thus classified as a false positive. Additional examples of this phenomenon are shown in \cref{fig:RNN-profile}.

% The fact that the trained RNN seemingly uses the low frequency spatiotemporal pattern of SWR's leads to a correct and early detection in the left panel of \cref{fig:RNN-envelopes}, but a correct and relatively late detection in the right panel; this might be because the negative sharp wave only starts after the ripple oscillation has already begun.

This phenomenon, where the RNN seemingly uses the low frequency spatiotemporal pattern of SWR's but does not require clear ripples, leads to a low precision for the RNN detector, under our evaluation scheme. \Cref{fig:RNN-PR} compares the precision-recall curve of this RNN detector with those of previous online SWR detectors, as well as comparing their detection latencies.

\begin{figure}
\img[0.9]{PR_full_fullrect}\\[2.5em]
\img[0.9]{PR_fullrect}
\captionn{Online SWR detection performance of an RNN}{See \cref{fig:BPF-performance} for legend. \Top: Full PR-curve. \Bottom: zoom-in on high-recall/high-precision region. Same net as \cref{fig:RNN-envelopes}.}
\label{fig:RNN-PR}
\end{figure}

The detection thresholds in \cref{fig:RNN-envelopes} are chosen at the maximal $F_1$ point for each output envelope. Because of the relatively low precision (high false-positive rate) of the RNN, this threshold is set high for the RNN envelope. This leads often to relatively late detections; see e.g. the rightmost detection in \cref{fig:RNN-envelopes}.

To investigate the influence of input channels, we trained a GRU-RNN that only used a single input channel (namely the pyramidal cell layer channel that is also used as input for the band-pass filters). The resulting RNN behaves very much like the band-pass filter (\cref{fig:RNN-pyr-envelopes}). It does not show the non-ripple false positive detections of the all-channel RNN. Its detection performance approaches, but is not as good as the baseline online band-pass filter (\cref{fig:RNN-PR-pyr}).

A second net was trained on this single channel input, this time with only one hidden layer, of 25 hidden units. Its performance was slightly worse than the two-layer, 40 hidden units per layer RNN (\cref{fig:RNN-PR-pyr}).

Finally, we experimented with a different target function; Namely a $y_t$ that is $1$ only around the start of reference SWR segments. This did not result in good performance for all-channel, two-layer, 40 hidden unit RNN's (\cref{fig:RNN-PR-startblocks}).