\documentclass{ecnreport}
\setlength{\parindent}{0cm}

\stud{Option Robotique, Control \& Robotics master}
\topic{Advanced Robot Programming}

\def\maze{\texttt{ecn::Maze}~}

\begin{document}

\inserttitle{Advanced Robot Programming  Labs \newline C++ Programming}

\insertsubtitle{Maze generation and solving}

\newcommand{\involves}[1]{
\item {\bf C++ skills:} #1
}

\newcommand{\aitip}[1]{
\item {\bf AI tips:} #1
}

\section{Content of this lab}

In this lab you will use and modify existing code in order to generate and solve mazes. As shown in \Fig{maze2}, the goal is to generate
a maze of given dimensions (left picture) and to use a path planning algorithm to find the shortest path from the upper left to the lower right corners (right picture).

\begin{figure}[h]\centering
\includegraphics[width=.4\linewidth]{maze} \quad \quad\includegraphics[width=.4\linewidth]{maze_cell}
\caption{$51\times 75$ maze before (left) and after (right) path planning.}
\label{maze2}
\end{figure}

The lab was inspired by \link{https://www.youtube.com/watch?v=rop0W4QDOUI}{this Computerphile video}.\\

We use the classical mix of Git repository and CMake to download and compile the project:
\begin{center}
 \texttt{mkdir build} $\rightarrow$ \texttt{cd build} $\rightarrow$ \texttt{cmake ..} $\rightarrow$ \texttt{make}
\end{center}
The program can the be launched.

\section{Required work}

Four programs have to be created:
\begin{enumerate}
 \item Maze generation
 \item Maze solving through A* with motions limited to 1 cell (already quite written)
 \item Maze solving through A* with motions using straight lines
 \item Maze solving through A* with motions using corridors
\end{enumerate}

As in many practical applications, you will start from some given tools (classes and algorithm) and use them inside your own code.\\
As told during the lectures, understanding and re-using existing code is as important as being able to write something from scratch.

\section{Maze generation}

The \link{https://en.wikipedia.org/wiki/Maze_generation_algorithm}{Wikipedia page} on maze generation is quite complete
and also proposes C-code that generates a perfect maze of a given (odd) dimension. A perfect maze is a maze where there is one and only
one path between any two cells.

Create a \texttt{generator.cpp} file by copy/pasting the Wikipedia code and modify it so that:
\begin{itemize}
 \item It compiles as C++.
 \item The final maze is not displayed on the console but instead it is saved to an image file
 \item The executable takes a third argument, that is the percentage of walls that are randomly erased in order to build a non-perfect maze.
\end{itemize}
A good size is typically a few hundred pixels height / width. To debug the code, 51 x 101 gives a very readable maze.

The \maze class (\Sec{mazeClass}) should be used to save the generated maze through its \texttt{Maze::dig} method that removes a wall at a given (x,y) position.
It can also save a maze into an image file.

\section{Maze solving}

The given algorithm is described on \link{https://en.wikipedia.org/wiki/A*\_search\_algorithm\#Pseudocode}{Wikipedia}. It is basically a graph-search algorithm that
finds the shortest path and uses a heuristic function in order to get some clues about the direction to be favored.

In terms of implementation, the algorithm can deal with any \texttt{Node} class that has the following methods:
\begin{itemize}
 \item \texttt{vector<unique\_ptr<Node>> Node::children()}: returns a \texttt{vector} of smart pointers\footnote{The use of smart pointers (here \texttt{unique\_ptr}) is detailed in \Sec{smart}} to the children (or neighboors) of the considered
 element
 \item \texttt{int distToParent()}: returns the distance to the node that generated this one
 \item \texttt{bool is(const Node \&other)}: returns true if the passed argument is actually the same point
 \item \texttt{double h(const Node \&goal)}: returns the heuristic distance to the passed argument
 \item \texttt{void show(bool closed, const Node \& parent)}: used for online display of the behavior
 \item \texttt{void print(const Node \& parent)}: used for final display
\end{itemize}

While these functions highly depend on the application, in our case we consider a 2D maze so some of these functions are already implemented in, as seen in \Sec{ptClass}:
\begin{itemize}
 \item For the first exercice, only the \texttt{children} method is to write.
 \item The second one adds the \texttt{distToParent} method.
 \item The last one adds the \texttt{show} and \texttt{print} methods.
\end{itemize}

\subsection{A* with cell-based motions}

The first A* will use cell-based motions, where the algorithm can only jump 1 cell from the current one.

The file to modify is \texttt{solve\_cell.cpp}.
At the top of the file is the definition of a \texttt{Position} class
that inherits from \texttt{ecn::Point} in order not to reinvent the wheel (a point has two coordinates, it can compute the distance to
another point, etc.).

The only method to modify is \texttt{Position::children} that should generates the neighboors of the current point.
The parent node is likely to be in those neighboors, but it will be removed by the algorithm.

\subsection{A* with line-based motions}

Copy/paste the \texttt{solve\_cell.cpp} file to \texttt{solve\_line.cpp}.\\

Here the children should be generated so that a straight corridor is directly followed (ie children can only be corners, intersections or dead-ends).
A utility function \texttt{bool is\_corridor(int, int)} may be of good use.\\

The distance to the parent may not be always 1 anymore. As we know the distance when we look for the neighboor nodes, a good thing would be to store it
at the generation by using a new Constructor with signature \texttt{Position(int \_x, int \_y, int distance)}.\\

The existing \texttt{ecn::Point} class is already able to display lines between two non-adjacent points (as long as they are on the same horizontal or
vertical line). The display should thus work directly.

\subsection{A* with corridor-based motions}

Copy/paste the \texttt{solve\_line.cpp} file to \texttt{solve\_corridor.cpp}.\\

Here the children should be generated so that any corridor is directly followed (ie children can only be intersections or dead-ends, but
not simple corners).
A utility function \texttt{bool is\_corridor(int, int)} may be of good use.\\

The distance to the parent may not be always 1 anymore. As we know the distance when we look for the neighboor nodes, a good thing would be to store it
at the generation by using a new Constructor with signature \texttt{Position(int \_x, int \_y, int distance)}. \\

The existing \texttt{Point::show} and \texttt{Point::print} methods are not suited anymore for this problem. Indeed, the path from a point to its parent
may not be a straight line. Actually it will be necessary to re-search for the parent using the same approach as to generate the children.\\

For this problem, remember that by construction the nodes can only be intersections or dead-ends. Still, the starting and goal positions may
be in the middle of a corridor. It is thus necessary to check if a candidate position is the goal even if it is not the end of a corridor.

\section{Comparison}

Compare the approaches using various maze sizes and wall percentage.
If it is not the case, compile in \texttt{Release} instead of \texttt{Debug} and enjoy the speed improvement.\\

The expected behavior is that mazes with lots of walls (almost perfect mazes) should be solved must faster with the corridor, then line, then cell-based approaches.\\
With less and less walls, the line- and cell-based approaches should become faster as there are less and less corridors to follow.

\appendix

\section{Provided tools}

\subsection{The \maze class}\label{mazeClass}

This class interfaces with an image and allows easy reading / writing to the maze.

\paragraph{Methods for maze creation}
\begin{itemize}
 \item \texttt{Maze(std::string filename)}: loads the maze from the image file
 \item \texttt{Maze(int height, int width)}: build a new maze of given dimensions, with only walls
 \item \texttt{dig(int x, int y)}: write a free cell at the given position
 \item \texttt{save()}: saves the maze to \texttt{maze.png} and displays it
\end{itemize}

\paragraph{Methods for maze access}
\begin{itemize}
 \item \texttt{int height()}, \texttt{int width()}: maze dimensions
 \item \texttt{int isFree(int x, int y)}: returns true for a free cell, or false for a wall or invalid (out-of-grid) coordinates
\end{itemize}

\paragraph{Methods for maze display}
\begin{itemize}
 \item \texttt{write(int x, int y, int r, int g, int b, bool show = true)}\\
    will display the (x,y) with the (r,g,b) color and actually shows if asked
 \item \texttt{passThrough(int x, int y)}: write the final path, color will go automatically from blue to red.
 Ordering is thus important when calling this function
 \item \texttt{saveSolution(std::string suffix)}: saves the final image
\end{itemize}

\subsection{The \texttt{ecn::Point} class}\label{ptClass}

This class implements basic properties of a 2D point:

\begin{itemize}
 \item \texttt{bool is(Point)}: returns true if both points have the same x and y coordinates
 \item \texttt{double h(const Point \&goal)}: heuristic distance, may use Manhattan
 ($|x-\texttt{goal}.x| + |y-\texttt{goal}.y|$) or classical Euclidean distance.
 \item \texttt{void show(bool closed, const Point \& parent)}: draws a straight line between the point and its parent, that
 is blue if the point is in the closed set or red if it is in the open set.
 \item \texttt{void print(const Point\& parent)}: writes the final path into the maze for display, also considers a straight line
\end{itemize}
All built classes should inherit from this class. The considered maze is available through the static member variable \texttt{ecn::maze} and can thus
be accessed from the built member functions.

\section{Pointers and smart pointers}\label{smart}

During an A* algorithm, a lot of nodes are created, deleted and moved between the open and the closed set.
This makes it necessary to create the nodes on the heap and manipulate only pointers.
In our case, new nodes are created in when calling the \texttt{children()} method, while they are deleted by the algorithm
itself if needed. In order to avoid memory leaks, we will use smart pointers.\\

Assuming that a new position can be created from its coordinates, a new position may be created with:
\begin{itemize}
\item \texttt{Position p(x, y);} for an actual position
 \item \texttt{Position* p = new Position(x, y);} for a raw pointer
 \item \texttt{std::unique\_ptr<Position> p(new Position(x, y);} for a unique ptr
\end{itemize}

As the \texttt{children()} method is supposed to return a \texttt{std::vector} of pointers, the corresponding syntax may be as follows:
\begin{center}\cppstyle
\begin{lstlisting}
typedef std::unique_ptr<Position> PositionPtr;
std::vector<PositionPtr> children()
{
    std::vector<PositionPtr> generated;
    while(..)   // whatever method we use to look for children
    {

        // assuming that we found a child at (x,y)
        generated.push_back(std::make_unique<Position>(x,y)));
    }
    return generated;
}
\end{lstlisting}
\end{center}
Here the generated children are directly put inside the vector, which is returned at the end. The smart pointer keeps track
of the allocated memory and the A* algorithm can decide to keep it or not, knowing that the memory will be managed accordlingly.

\end{document}


\subsection{Iterative greedy learning}
\label{sub:learning:iterative}

% ----------------------- paths to graphics ------------------------

% ----------------------- contents from here ------------------------
%

This section presents a greedy iterative algorithm for compression learning. It uses a pattern selector (\(S\)) to greedily choose how to compress columns (\ref{sub:learning:selectors}~\nameref{sub:learning:selectors}) and the pattern detectors (\(P\)) defined in \ref{sec:pd}~\nameref{sec:pd}. The algorithm takes a breadth-first approach, thus supporting pattern detectors \(P\) that work on multiple columns (e.g. \nameref{subsec:pd:columncorrelation}). It takes as input the list of input columns (\(c_{in}\)) and builds the compression tree one level at a time.

% https://en.wikipedia.org/wiki/Iterated_function
The algorithm builds the compression tree \(T\) in an iterative process. Let \textit{add\_level(\(T\))} be an iterated function which adds 0 or more expression nodes (\(N\)) on a new level in \(T\). This function is repeatedly applied to T in an iterative process. Each call of the function uses the updated version of \(T\) that it produced in the previous iteration. The iterative process converges to the final compression tree \(T_{out}\) once no more changes are made to \(T\) in an iteration.

The learning algorithm starts with \(P_{list}\) (a list of pattern detector instances), \(S\) (a pattern selector) and \(T\) (an empty compression tree, initialized with the list of input columns \(c_{in}\)). Recall that the compression tree is actually a graph with multiple connected components where each component is a directed acyclic graph (DAG) with one or more root nodes (see \ref{ch:exprlang}~\nameref{ch:exprlang}). An additional parameter is \(it_{max}\), representing the maximum number of iterations. \(it_{max}\) also determines the maximum height of the compression tree (\(h_{max}\)), since every iteration adds a new level to \(T\).

The \textit{add\_level} function adds new compression nodes (\(N\)) to \(T\) by trying to further compress its leaf (output) columns \(c_{leaf}\). It does this in 2 steps. Step-1 pattern detection: use the pattern detectors \(P_{list}\) to generate all possibilities to compress the leaf columns, resulting in a list of expression nodes \(N_{list}\). Step-2 pattern selection: use the pattern selector \(S\) to select a subset of \(N_{list}\) (\({N_{s}}_{list}\)), representing the best way to compress each \(c_{leaf}\). Finally, the expression nodes in \({N_{s}}_{list}\) are added to as a new level. If no expression nodes (\(N\)) are selected (i.e. \({N_{s}}_{list}\) is empty), then the iterative learning algorithm converged to the final compression tree \(T\).

The algorithm is described in listings \ref{lst:learning:iterativegreedy:build_T} and \ref{lst:learning:iterativegreedy:add_level}.

\begin{lstlisting}[language=Python,
label={lst:learning:iterativegreedy:naming},
caption={Naming conventions}]
c = column
P = pattern detector
S = pattern selector
T = compression tree
N = compression node
\end{lstlisting}

\begin{lstlisting}[language=Python,
label={lst:learning:iterativegreedy:build_T},
caption={build\_T (iterative greedy)}]
def build_T(c_in_list, P_list, S)
  # initialize T with the input columns
  T = CompressionTree(c_in_list)
  # iterative process
  for it in range(0, it_max):
    add_level(T, P_list, S)
    if <no changes made to T>:
      break
  # return final compression tree
  return T
\end{lstlisting}

\begin{lstlisting}[language=Python,
label={lst:learning:iterativegreedy:add_level},
caption={add\_level (iterative greedy)}]
def add_level(T, P_list, S):
  c_leaf_list = T.c_leaf_list
  # pattern detection
  N_list = list()
  for P in P_list:
    N_p_list = P.evaluate(c_leaf_list)
    N_list.extend(N_p_list)
  # select expression nodes
  N_s_list = S.select(N_list)
  # stop if no expression nodes were selected
  if len(N_s_list) == 0:
    return
  # add selected expression nodes to T
  T.update(N_s_list)
\end{lstlisting}
\bigskip

The complexity of the algorithm is given by the total number of columns in the final compression tree multiplied by the effort spent on evaluating the pattern detectors on it and choosing the expression node that it will be compressed with:
\begin{equation}
\label{eq:learning:recursiveexhaustive}
    \mathcal{O}(c_{in} \times (b) ^ {h_{max}} \times (p + p \times \mathit{avg}(n_{p})))
\end{equation}
where:
\begin{itemize}
    \item[] \(c_{in}\) = number of input columns
    \item[] \(b\) = branching factor of the compression tree (as defined in Equation \ref{eq:optimizationproblem:b})
    \item[] \(h_{max}\) = maximum height of the compression tree
    \item[] \(p\) = number of pattern detectors
    \item[] \(n_{p}\) = number of expression nodes returned by a pattern detector
\end{itemize}
In the worst case when the maximum number of iterations is reached, \(h_{max}\) becomes \(it_{max}\), thus the complexity is bounded by \(it_{max}\).

Regardless of the nature of the pattern selector \(S\), the algorithm is greedy, as it makes irreversible locally best choices which only depend on previously made choices. The breadth-first approach allows the use of multi-column pattern detectors, representing an advantage compared to the \nameref{sub:learning:recursiveexhaustive} algorithm, which misses compression opportunities by handling each column separately. The greedy model significantly reduces the number of solutions explored, leading only to a local best solution. At the same time, the reduced dimension of the explored solution set ensures faster termination of the algorithm. The advantages of both algorithms can be combined with the \nameref{sub:learning:multistage} approach described in section \ref{sub:learning:multistage}.

% TODO-1: image describing the iterative process

% ---------------------------------------------------------------------------
% ----------------------- end of thesis sub-document ------------------------
% ---------------------------------------------------------------------------


\section{Ripples}

When SWR's are quantified for offline analysis in the literature, this is
invariably done by detecting ripples. This section describes how this is done.

\subsection{Band-pass filtering}

The wide-band voltage signal is band-pass filtered through a linear time-invariant filter. The passband is taken to be a presumed `ripple band'. Some choices made in the literature for this band are listed in \cref{tab:bands}. The type and order of the filter are rarely mentioned in methods sections. For example, when \citefull{Dutta2018} mentions ``a 25 tap finite impulse response (FIR) filter'', this is already more information than other methods sections, which mostly mention nothing more than ``the signal was band-pass filtered between xx and yy \si{\hertz}''. (But note that even in \citefull{Dutta2018} the filter design method nor filter parameters such as stopband suppression or transition width are mentioned).

\begin{table}
\begin{tabular}{@{}lllll@{}}
\toprule
Source                     & Theta (Hz) & High gamma (Hz) & Ripple (Hz)  \\
\midrule
\citefull{Csicsvari2000}   &            &                 & 80 -- 250   \\
\citefull{Behrens2005}     &            &                 & 40 -- 400   \\
\citefull{OKeefe2007}      & 6 -- 12    & 30 -- 100       & 100 -- 200  \\
\citefull{Ego-Stengel2009} &            &                 & 100 -- 400  \\
\citefull{Buzsaki2015}     & 6 -- 10    & 100+            & 110 -- 200  \\
\citefull{Colgin2016}      & 6 -- 12    & 60 -- 100       & 150 -- 200  \\
\citefull{Sadowski2016}    &            &                 & 120 -- 250  \\
\citefull{Eichenbaum2017}  & 4 -- 12    & 80 -- 140       & \\
\citefull{Olafsdottir2018} & 6 -- 12    &                 & 140 -- 250  \\
\midrule
filter.py                  & 6 -- 12    & 60 -- 140       & 140 -- 225  \\
L2 recording               & 5 -- 10    &                 & 100 -- 200  \\
\bottomrule
\end{tabular}
\captionn{Frequency bands of hippocampal LFP events}{According to different sources. When the source does not make a distinction between high and low gamma, the full gamma range is given. Note that \citefull{Behrens2005} considered artificially induced SWR's in ex-vivo hippocampus slices. `filter.py' refers to the frequency bands used in the `fklab' data-analysis software used in the Kloosterman lab.}
\label{tab:bands}
\end{table}

\subsection{Envelope estimation}

Next, the envelope $y_{e,t}$ of the band-pass filtered signal $y_t$ is estimated. This is often done simply by rectification (i.e. $y_{e,t} = \abs{y_t}$). A disadvantage of this method is that every zero-crossing in $y_t$ becomes a `dip' to zero in $\abs{y_t}$, resulting in a very jagged envelope. This is often fixed heuristically by applying a smoothing filter to $\abs{y_t}$, such as an FIR filter with a Gaussian kernel.

An alternative method, that yields naturally smooth envelopes for band-pass filtered signals, makes use of the `Hilbert transform' of $y_t$. This works as follows. The envelope $y_{e,t}$ (which is in this context often called the \emph{instantaneous amplitude}) is calculated as:
%
\begin{equation}
\label{eq:Hilbert_envelope}
y_{e,t} = \sqrt{y_t^2 + H(y_t)^2},
\end{equation}
%
where $H(y_t)$ is the discrete Hilbert transform of $y_t$.\footnote{To be precise, $H$ is a discrete approximation to the continuous Hilbert transform $\mathcal{H}$. There are multiple ways to make a discrete approximation to $\mathcal{H}$ \cite{Oppenheim2009}. Most of them make use of the discrete Fourier transform, which makes computing $H$ an efficient operation.} This transform phase shifts the signal locally by \SI{90}{\deg} (see \cref{fig:Hilbert}).\footnotemark{} From \cref{eq:Hilbert_envelope}, it can be seen that if $y_t$ is locally approximated by a sinusoid $a \cos{\omega t}$, its envelope $y_{e,t}$ will be locally approximated by a constant function, which does not dip to zero: $\sqrt{(a \cos{\omega t})^2 + (a \sin{\omega t})^2} = \abs{a}$. It should be noted that the envelopes produced in this way are only really satisfactory for narrowband signals (which is the case for $y_t$), as can be seen for example in \cref{fig:Hilbert}.

\footnotetext{To see why the Hilbert transform behaves like this, consider its definition and the shape of its impulse response. The Hilbert transform $\mathcal{H}$ of a continuous signal $x(t)$ convolves $x(t)$ with $h(t) = \frac{1}{t}$ (and scales the result by $1/\pi$). $h(t)$ has two lobes antisymmetric around the origin. They decay to zero towards $t = -\infty$ and $t = +\infty$, so the convolution takes in mostly local information from $x(t)$. The two lobes also have opposite sign: one going to $h = -\infty$ for zero lag, and the other going to $h = +\infty$. Therefore, when $x(t)$ is locally constant (as in the through or on the crest of a sinusoid), the two lobes of the convolution integrand will tend to cancel out, and the Hilbert transform will approach zero. Conversely, when a zero crossing occurs in $x(t)$, the two lobes will be of the same sign, resulting in a non-zero result.}

\begin{figure}
\img[0.6]{Hilbert_narrow.png}
\img[0.6]{Hilbert_wide.png}
\captionn{Envelope estimation using the Hilbert transform}{Blue traces: a \SI{190}{\milli\second}-long LFP segment containing two ripples. Band-pass filtered (left), and original wide-band signal (right). Orange traces: Hilbert transforms of corresponding blue traces. Note the \SI{90}{\deg} phase shift of the Hilbert-transformed signals. Green traces: envelope estimates of blue traces according to \cref{eq:Hilbert_envelope}.  Note that the envelope is only really satisfactory for the narrowband signal (left).}
\label{fig:Hilbert}
\end{figure}

\subsection{Threshold crossing}

Next, potential SWR events are inferred from this band-pass-envelope signal $y_{e,t}$. This is done by detecting threshold crossings in $y_{e,t}$, where the threshold height depends on basic statistics of the envelope. The most common threshold is $\mu + \alpha \sigma$, with $\mu$ and $\sigma$ the mean and standard deviation of $y_{e,t}$, respectively; and $\alpha$ a multiplier chosen by the experimenter.

This multiplier varies wildly: from 1 \cite{Csicsvari2000}, over 3 \cite{Dutta2018}, 4 \cite{Behrens2005}, and 5 \cite{Sadowski2016}, up until 7 \cite{Nadasdy1999}. It is clear that such different thresholds will give very different sensitivity-precision trade-offs for SWR detection (the lower thresholds yielding more false positive detections, and the higher thresholds yielding more missed true SWR events). These $\alpha$ values are not straightforward to compare however. Suppose that the filtered signal $y_t$ consists of background `noise' in the passband, and superimposed ripples. There are many factors (such as recording equipment used, electrode location, and physiological activity) that will influence the mean and variance of the envelope of the passband noise itself, and with it the mean and variance of the combined signal envelope $y_{e,t}$. Additionally, the occurence rate of ripples and their relative strength will also influence both the mean and variance of $y_{e,t}$. It is thus clear that only reporting the $\alpha$ multiplier (as is done now) is not very meaningful, without also reporting the actual $\mu$ and $\sigma$ values (or better yet, making the raw signal data available in an online repository).


\section{Type-Error Witnesses}
\label{sec:searching-witness}

% Our goal is to find concrete values that demonstrate how a
% program ``goes wrong''.

% \paragraph{Problem: Which inputs are bad?}
% %
% One approach is to randomly generate input values and use
% them to execute the program until we find one that causes
% the program to go wrong. However, to see why this approach
% is naive, consider the following example:
% %
% \begin{lstlisting}
%   let f x =
%     let y = 1 + x in
%       1. +. y
% \end{lstlisting}
% %
% What \emph{types} of inputs should we test \texttt{f} with?
% Values of type \texttt{int} and \texttt{float} are fair game,
% but values of type say, \texttt{string} or \texttt{int list}
% will cause the program to go wrong in an \emph{irrelevant}
% manner.

% \paragraph{Solution:} \RJ{STOP}

% we cannot provide \emph{completely arbitrary} inputs to
% \texttt{f}. Instead, we call \texttt{f} with a \emph{hole}, written
% \ehole{}, which is a placeholder for a value whose type we have not
% yet determined. As we execute the program, we instantiate holes with
% concrete values as demanded by the primitive operations in the
% program. For example, the hole we pass to f will be instantiated to an
% int when we reach the \lstinline{1 + x} term. Thus, y will be an int as
% well, and the program will get stuck at \lstinline{1. +. y}. \ES{this
%   reads more like overview text..}
%

% \begin{itemize}
% \item how do we run ill-typed programs?
% \item for a lang like ocaml, dynamic semantics are independent of static
%   semantics, just lambda calculus. so no problem to run ill-typed
%   program
% \item but what about functions? what type of arguments should we pass? consider
%
% \begin{lstlisting}
% let f x =
%   let y = 1 + x in
%     1. +. y
% \end{lstlisting}
%
% does \texttt{f} take an int, float, string? int and float are both
% somewhat plausible, but string or anything else is ``clearly'' bogus. so
% we cannot provide \emph{completely arbitrary} inputs to
% \texttt{f}. Instead, we call \texttt{f} with a \emph{hole}, written
% \ehole{}, which is a placeholder for a value whose type we have not
% yet determined. As we execute the program, we instantiate holes with
% concrete values as demanded by the primitive operations in the
% program. For example, the hole we pass to f will be instantiated to an
% int when we reach the \lstinline{1 + x} term. Thus, y will be an int as
% well, and the program will get stuck at \lstinline{1. +. y}. \ES{this
%   reads more like overview text..}
%
% % \item values are tagged with their types, just like ``untyped'' langs
% % \item special ``hole'' value whose type is not yet known, used for function args
% % \item on-the-fly unification to determine ``correct'' type for holes
% \end{itemize}

Next, we formalize the notion of type error witnesses as follows.
%
First, we define a core calculus within which we will work~\S~\ref{sec:syntax}.
%
Second, we develop a (non-deterministic) operational semantics
for ill-typed programs that precisely defines the notion
of a \emph{witness}~\S~\ref{sec:semantics},
%
Third, we formalize and prove a notion of \emph{generality} for
witnesses, which states, intuitively that if we find a
single witness then for \emph{every possible} type
assignment, there exist inputs that are guaranteed to make
the program ``go wrong''~\S~\ref{sec:soundness}, and finally,
%
Fourth, we refine the operational semantics into a
\emph{search procedure} that returns concrete (general)
witnesses for ill-typed programs~\S~\ref{sec:search-algorithm}.

\subsection{Syntax}
\label{sec:syntax}
\input{syntax.tex}
%
Figure~\ref{fig:syntax} describes the syntax of \lang, a simple lambda
calculus with integers and booleans.
%
As we are specifically interested in programs that \emph{do} go wrong,
we include an explicit \stuck\ state in our syntax.

\paragraph{Holes}
\label{sec:holes}
%
Recall that a key challenge in our setting is to find witnesses
that are meaningful and do not arise from choosing values from
irrelevant types.
%
We solve this problem be equipping our term language with a notion
of a \emph{hole}, written \ehole{}, which represents \emph{unconstrained}
values that may replaced with values from \emph{any} type.
%
Dually, holes may also appear in types, where they may be thought
of as type variables that we will not generalize over.
%

\paragraph{Substitutions}
%
Our semantics ensure the generality of witnesses by incrementally
\emph{refining} holes, filling in just as much information as is
needed locally to make progress (inspired by the manner in
which SmallCheck uses lazy evaluation~\cite{runciman_smallcheck_2008}).
%
We track how the holes are incrementally filled in, by using
(value) \emph{substitutions} that map holes (denoted by their index)
to values which may, in turn, contain holes.
%
The substitutions let us ensure that we instantiate each hole
with the same (partially defined) value, regardless of the multiple
contexts in which the hole appears, and hence, ensures we can
report a concrete (and general) witness for any (dynamically)
discovered type errors.

\subsection{Semantics}
\label{sec:semantics}
\input{operational.tex}
%

The evaluation relation is parameterized by a pair of functions:
called \emph{narrow} (\forcesym) and \emph{generate} (\gensym),
that ``dynamically'' perform type-checking and hole-filling
respectively.

\paragraph{Narrowing Types} The procedure $\force{e}{t}{\vsu}$ takes as
input an term \texttt{e} and refines it to have the type \texttt{t} by
yielding a pair of either the same expression and value
substitution, or yields the stuck term if no such refinement is
possible. In the case where \texttt{e} is a hole, it first checks in the
given $\vsu$ to see if the hole has already been instantiated and, if
so, returns the existing instantiation:
%
$$
\begin{array}{lcl}
%% \multicolumn{3}{l}{\forcesym \ :: \  (e, t) \rightarrow \pair{e}{\vsu}} \\
\forcesym            & ::     & (e, t, \vsu) \rightarrow \pair{e}{\vsu} \\
\force{v}{\ehole{}}{\vsu}  & \defeq & \pair{v}{\vsu} \\
\force{\ehole{i}}{t}{\vsu} & \defeq & \hspace{-1ex}
\begin{cases}
  \pair{\vsu(i)}{\vsu}        & \mbox{if}\ i \in dom(\vsu) \\
  \pair{v}{\ehole{i} \mapsto v ; \vsu}   & v = \gen{t}\\
\end{cases} \\
 % \begin{array}{l}
    % \mathtt{if}\ i \in \vsu\ \mathtt{then}\ \pair{\vsu(i)}{\vsu}\ \mathtt{else} \\
         % \elet{v}{\gen{t}}{\pair{v}{\ehole{i} \mapsto v}}
  % \end{array} \\
\force{n}{\tint}{\vsu}     & \defeq & \pair{n}{\vsu} \\
\force{v}{\tint}{\vsu}     & \defeq & \pair{\stuck}{\vsu} \\
\force{b}{\tbool}{\vsu}    & \defeq & \pair{b}{\vsu} \\
\force{v}{\tbool}{\vsu}    & \defeq & \pair{\stuck}{\vsu} \\
\force{\efun{x}{e}}{\tfun{\thole{}}{\thole{}}}{\vsu} & \defeq & \pair{\efun{x}{e}}{\vsu} \\
\force{v}{\tfun{\thole{}}{\thole{}}}{\vsu} & \defeq & \pair{\stuck}{\vsu} \\
\end{array}
$$
%
While a hole may map to a value that \emph{contains} another hole, \eg a
lambda, it may not map \emph{directly} to another hole, so in the second
case above we do not need to \forcesym\ the result of the substitution,
the sub-hole will be narrowed when the context demands it.

\paragraph{Generating Values} The (non-deterministic) procedure $\gen{t}$
takes as input a type \texttt{t} and returns a value of that type. For base
types, the procedure returns an arbitrary value. For functions, it returns
a lambda with a \emph{new} hole denoting the return value, and unconstrained
types (denoted by $\thole{}$) yield fresh, unconstrained values
(denoted by $\ehole{i}$).

$$
\begin{array}{lcll}
% \gensym       & ::      & t \rightarrow v \\
\gen{\tint}   & \defeq  & n, & \quad \text{non-deterministic} \\
\gen{\tbool}  & \defeq  & b, & \quad \text{non-deterministic} \\
\gen{\tfun{t_1}{t_2}}   & \defeq & \efun{x}{\ehole{i}}, & \quad \text{$i$ is fresh} \\
\gen{\thole{}} & \defeq & \ehole{i}, & \quad \text{$i$ is fresh} \\
\end{array}
$$

\paragraph{Steps and Traces}
%
% WRW notes that Figure 4 does not seem to handle recursion (it's not clear
% how the let rule would work for something "let rec"-y, and there's not
% function call rule). I only mention this because I can imagine a reviewer
% wondering about your ability to generate good witnesses for function
% types. This could likely be addressed in text, by a forward reference to
% Section 3.4 where higher-order functions are handled, without changing
% any of the formalisms at the last minute.
Figure~\ref{fig:operational} describes the small-step contextual
reduction semantics for \lang.
%
A \emph{closed expression} is a pair $\pair{e}{\vsu}$ of an expression $e$
and a substitution $\vsu$.
%
We write $\step{e}{\vsu}{e'}{\vsu'}$ if the closed expression $\pair{e}{\vsu}$
transitions in a \emph{small step} to $\pair{e'}{\vsu'}$.
%
A (finite) \emph{trace} $\trace$ is a sequence of closed expressions
$\pair{e_0}{\vsu_0}, \ldots, \pair{e_n}{\vsu_n}$ such that
$\forall 0 \leq i < n$, we have \step{e_i}{\vsu_i}{e_{i+1}}{\vsu_{i+1}}.
%
We write \steptr{\trace}{e}{\vsu}{e'}{\vsu'} if $\trace$ is a trace of the form
$\pair{e}{\vsu},\ldots,\pair{e'}{\vsu'}$.
%
We write \steps{e}{\vsu}{e'}{\vsu'} if \steptr{\trace}{e}{\vsu}{e'}{\vsu'}
for some trace $\trace$.

\paragraph{Primitive Reductions}
Primitive reduction steps --- addition, if-elimination, and
function application --- use \forcesym to ensure that values have the
appropriate type (and that holes are instantiated) before continuing the
computation. Importantly, beta-reduction \emph{does not} type-check its
argument, it only ensures that $v_1$ is a function.

\paragraph{Recursion}
Fixed-point operators often cannot be typed in static type systems, but
we are not concerned with \emph{assigning} types to terms, rather with
showing that \emph{no type} can be assigned. We are simply executing the
untyped $\lambda$-calculus, which has no issue handling recursion.

%% \begin{thm}
%% \label{thm:all-reduce}
%%   Every closed expression $e$ reduces to a value $v$ (which may be \stuck).
%% \ES{do we really need to state this, or is it obvious?}
%% \end{thm}

% \begin{proof}%[Proof of \autoref{thm:all-reduce}]
%   Simple induction on the evaluation relation.
% \end{proof}
%
\subsection{Generality}\label{sec:soundness}

A key technical challenge in generating witnesses is
that we have no (static) type information to rely upon. Thus, we
must avoid the trap of generating \emph{spurious} witnesses that
arise from picking irrelevant values, when instead there exist
perfectly good values of a \emph{different} type, under which
the program would not go wrong.

\paragraph{Witness Generality}
We now show that our evaluation relation instantiates holes in a
\emph{general} manner. That is, given a function $f$, if we have
$\steps{\eapp{f}{\ehole{}}}{\emptysu}{\stuck}{\su}$, then for every
possible input type $t$, we can find a value $\hastype{v}{t}$
such that $\eapp{f}{v}$ goes wrong.

\begin{thm}{\textbf{[Witness Generality]}}
\label{thm:soundness}
  For any function $f$, if \steptr{\trace}{\eapp{f}{\ehole{}}}{\emptysu}{\stuck}{\su},
  then for every inhabitable type\footnote{We exclude builtin functions that subvert the type system, \eg \texttt{Obj.magic}, and thus consider the type $\forall a b. \tfun{a}{b}$ to be uninhabitable.}  $t$ there exists $\hastype{v}{t}$ such that
  $\steps{\eapp{f}{v}}{\emptysu}{\stuck}{\su}$.
\end{thm}

We need to develop some machinery in order to prove this theorem.
First, we show how our evaluation rules encode a dynamic form of
type inference, and next, we show that the types inferred via
evaluation are indeed maximally general.

\paragraph{The Type of an Expression} The (dynamic) type of an
expression $e$ is defined as a function $\typeof{e}$ defined as:
  \[
  \begin{array}{lcll}
    \typeof{n}   & \defeq & \tint & \\
    \typeof{b}   & \defeq & \tbool & \\
    \typeof{\efun{x}{e}} & \defeq & \tfun{\thole{i}}{\typeof{e}}, & \quad \text{$i$ is fresh} \\
    \typeof{e} & \defeq & \thole{i}, & \quad \text{$i$ is fresh} \\
  \end{array}
  \]
%
Note that we approximate the type of expressions rather than
performing full type inference, for example
$\typeof{\efun{x}{\eplus{x}{1}}} = \tfun{\thole{}}{\thole{}}$,
instead of the usual $\tfun{\tint}{\tint}$.

\paragraph{Dynamic Type Inference}
We can think of the evaluation of \eapp{f}{\ehole{}} as (dynamically)
inferring a \emph{partial type} --- a type that may contain holes ---
for $f$.
%
We can extract this type from evaluation traces.
%
Formally, we say that if \steptr{\trace}{\eapp{f}{\ehole{}}}{\emptysu}{e}{\su},
then the \emph{partial type} of $f$ upto $\trace$, written \ptype{\trace}{f},
is \tfun{\typeof{\subst{\su}{\ehole{}}}}{\typeof{e}}.
%
%We will omit the subscript when we wish to refer to the final partial
%type, \ie\ at the step where the expression has been reduced to a value
%(or stuck.)

\paragraph{Type Compatibility}
Two types are compatible if one of them can be obtained by
suitably filling the holes of the other (\ie by suitably ``instantiating''
the type variables appearing in the other). Formally, a type $s$ is
\emph{compatible} with a type $t$, written \tcompat{s}{t}, if
$\exists \tsu.\ t = \subst{\tsu}{s} \lor s = \subst{\tsu}{t}$.

\paragraph{Preservation}
Given these two definitions, we show that each evaluation step
refines the partial type of $f$, \ie preserves type compatibility.
%
\begin{lem}
\label{lem:refine-partial}
If $\trace \defeq \pair{\eapp{f}{\ehole{}}}{\emptysu},\ldots$ and
$\trace' \defeq \trace, \pair{e'}{\vsu'}$ (\ie $\trace'$ is a single-step
extension of $\trace$)
%
%The partial type of $f$ upto $\trace$ is compatible
%with the partial type upto $\trace'$, \ie\
%
then \tcompat{\ptype{\trace}{f}}{\ptype{\trace'}{f}}.
\end{lem}
\begin{proof}
  By induction on the length of $\trace$ and case analysis on the evaluation rules.
  %
  Note that all rules preserve partial types with the exception of when
  \forcesym\ is called on a hole, in which case we instantiate the hole with
  a concrete value.
  %
  But $\typeof{\ehole{}} = \thole{}$, which is compatible with any type.
\end{proof}

\paragraph{Narrowing}
%
Furthermore, only a call to \forcesym can change the partial type of $f$.
%
\begin{lem}
\label{lem:force-inst}
If
$\trace \defeq \pair{\eapp{f}{\ehole{}}}{\emptysu}, \ldots,\pair{e}{\vsu}$
and
$\trace' \defeq \trace, \step{e}{\vsu}{e'}{\vsu'}$
and
$\ptype{\trace}{f} \neq \ptype{\trace'}{f}$,
then the final step $\step{e}{\vsu}{e'}{\vsu'}$ invokes \forcesym.
\end{lem}

\begin{proof}
  By case analysis on the evaluation rules.
  %
  If $\ptype{\trace}{f} \neq \ptype{\trace}{f}$ then one of the holes in $f$'s
  argument must have been instantiated with a concrete value at the last step.
  %
  An examination of the rules shows that only place this happens is
  in the first case of \forcesym.
\end{proof}

\paragraph{Incompatible Values Are Wrong}
%
\emph{Any} value that is \emph{incompatible} with
the partial type upto trace $\trace$ will cause $f$ to get stuck
in \emph{at most} $k$ steps where $k$ is the length of $\trace$.
%
\begin{lem}
\label{lem:k-stuck}
  If \steptr{\trace}{\eapp{f}{\ehole{}}}{\emptysu}{e}{\vsu} and
     \hastype{v}{t} and
     \tincompat{t}{\ptype{\trace}{f}},
  then
     \steps{\eapp{f}{v}}{\emptysu}{\stuck}{\su}.
\end{lem}
\begin{proof}
  By induction on $k$, the length of $\trace$.
  Let $\tfun{s_{\trace}}{\_} = \ptype{\trace}{f}$ and
  $\trace' = \pair{\eapp{f}{\ehole{}}}{\emptysu},...,\pair{e'}{\vsu'}$
  such that $\step{e'}{\vsu'}{e}{\vsu}$.
  Suppose \hastype{v}{\tincompat{t}{s_{\trace}}}, we
  will show that \steps{\eapp{f}{v}}{\emptysu}{\stuck}{\su'}
  in at most $k$ steps:
%
  %\begin{description}
  % \item
  [Case \tincompat{t}{s_{\trace'}}:]
    The inductive hypothesis applies.
  %\item
  [Case $\tcompat{t}{s_{\trace'}}$ but $\tincompat{t}{s_{\trace}}$:]
    By Lemma~\ref{lem:force-inst} we must have called \forcesym at step
    $k$.
    %
    Lemma~\ref{lem:refine-partial} tells us
    $\tcompat{s_{\trace'}}{s_{\trace}}$, which means we must have
    specifically narrowed $s_{\trace'}$ to a type incompatible with $t$.
    %
    A case analysis of the rules shows that \forcesym cannot have
    succeeded.
  %\end{description}
\end{proof}

\begin{proof}[\textbf{Proof of Theorem~\ref{thm:soundness}}]
%
Suppose $\trace$ witnesses that $f$ gets stuck,
and let $t = \ptype{\trace}{f}$.
We show that \emph{all} types $s$ have stuck-inducing
values by splitting cases on whether the type is
compatible with $t$. %the partial type upto $\trace$.
%
% \begin{description}
  %\item
  [Case \tcompat{s}{t}:]
   The value $\hastype{v}{t}$ suffices to demonstrate that $\eapp{f}{v}$
   gets stuck.
  %\item
  [Case \tincompat{s}{t}:]
   By Lemma~\ref{lem:k-stuck}, every \hastype{v}{t} demonstrates that
   $\eapp{f}{v}$ gets stuck.
%\end{description}
\end{proof}

\subsection{Search Algorithm}
\label{sec:search-algorithm}
%
So far, we have seen how a trace leading to a stuck configuration yields
a general witness demonstrating that the program is ill-typed (\ie\ goes
wrong for all inputs.)
In particular, we have shown how to non-deterministically find a witnesses
for a function of a \emph{single} argument.

In order to convert the semantics into a \emph{procedure} for finding
witnesses, we must address two challenges.
%
First, we must resolve the non-determinism introduced by \gensym.
%
Second, in the presence of higher-order functions and currying,
we must determine how many concrete values to generate to make
execution go wrong (as we cannot rely upon static typing to
provide this information.)

The witness generation procedure @genWitness@ is formalized in
Figure~\ref{fig:algo-gen-witness}.
%
Next, we describe its input and output, and how it
addresses the above challenges to search the space of possible
executions for general type error witnesses.

\paragraph{Inputs and Outputs}
%
The problem of generating inputs is undecidable in general.
%
Our witness generation procedure takes two inputs.
%
First, a search bound @n@ which is used to define the \emph{number} of
traces to explore. (We assume, without loss of generality, that all
traces are finite.)
%
Second, binder-expression tuples @[(f1,e1),...,(fn,en)]@
denoting the list of \emph{top-level definitions}:
%
\begin{code}
  let f1 = e1 in
  let f2 = e2 in
  ...
  let fn = en in
\end{code}
%
The witness generation procedure returns as output a list of (general)
witness expressions $e$ each of which is of the form @fn v1 ... vn@.
%
The \emph{empty} list is returned when no witness can be found after
exploring $n$ traces.
%
In what follows, we refer to @fn@ as the \emph{target} of witness generation.

\paragraph{Modeling Semantics}
%: \texttt{eval} and \texttt{isStuck}}
%
We resolve the non-determinism in the operational semantics
(\S~\ref{sec:semantics}) via the procedure:
%
\begin{mcode}
  eval :: ($e$, $\su$) -> [($v$, $\su$)]
\end{mcode}
%
Due to the non-determinism introduced by \gensym, a call \hbox{|eval($e$, $\vsu$)|}
returns the \emph{list} of possible results of the form $\pair{e'}{\vsu'}$ such
that $\steps{e}{\vsu}{e'}{\vsu'}$.
%
We determine whether a given value is stuck by using the predicate:
%
\begin{mcode}
  isStuck :: $v$ -> Bool
\end{mcode}

\paragraph{Generating Target Arguments}
%
We address the issue of currying by defining a procedure @genArgs@ such that \\
\hbox{@genArgs [(f1,e1),...,(fn,en)]@} yields a list of holes @[v1,...,vk]@
such that \hbox{@fn v1 ... vk@} \emph{does not} evaluate to a lambda.
%
This is achieved via a simple @loop@ that keeps adding holes to the
target application until @eval@uating the closed term yields a
non-lambda value.
%
The helper functions @witness@ and @close@ are used to respectively
apply the parameters to the target and close the result under the top-level
let-binders, prior to invoking \hbox{@eval@.}
%
That is, @mkApps@ creates a nested sequence of applications in
the usual left-associative style, and @mkLets@ takes a list of
binders and a body expression, and creates a sequence of nested
let-binders that close the body expression.

\begin{figure}[t]
\centering
\begin{mcode}
genArgs :: [($x$, $e$)] -> [$v$]
genArgs bs = loop []
  where
  loop vs  = case eval (close bs vs) of
               $\pair{\efun{x}{e}}{\_}$:_ -> loop ($\ehole{}$:vs)
               _        -> vs

close :: [($x$, $e$)] -> [$v$] -> ($e$, $\vsu$)
close bs vs = (e, $\emptysu$)
  where
    e       = mkLets bs (witness bs vs)

witness :: [($x$, $e$)] -> [$v$] -> $e$
witness bs vs = mkApps target vs
  where
    target    = snd (last bs)
\end{mcode}
\caption{Find number of arguments for target function}
\label{fig:algo-gen-args}
\end{figure}

\paragraph{Generating Witnesses}
% Procedure \texttt{genWitness}}
%
Finally, Figure~\ref{fig:algo-gen-witness} summarizes the overall
implementation of our search for witnesses, in the procedure @genWitness@,
which takes as input a bound @n@ and a list of top level binders, and
returns a list of witness expressions $e$ that demonstrate how the input
program gets stuck.
%
The search proceeds as follows.
%
@(1)@ we invoke @genArgs@ to determine the number of parameters required
by the (curried) target function.
%
@(2)@ we obtain a closed expression $e$ by closing the target with the
computed holes.
%
@(3)@ we take the first @n@ traces returned by @eval@ on the closed $e$
and
@(4)@ we extract the substitutions corresponding to the $\stuck$ traces,
and use them to return the list of witnesses.
%
We obtain the following corollary of Theorem~\ref{thm:soundness}:

\begin{cor}{\textbf{[Witness Generation]}}
\label{thm:generation}
  If @genWitness k [(f1,e1),...,(fn,en)]@ is non-empty,
  then for every type $t$ there exists $\hastype{v}{t}$ such that
  $\steps{\eapp{f_n}{v}}{\emptysu}{\stuck}{\su}$.
\end{cor}

\begin{figure}[t]
\centering
\begin{mcode}
genWitness :: Nat -> [($x$, $e$)] -> [$v$]
genWitness n bs
       = [witness bs ($\vsu$ vs) | $\vsu$ <- $\vsu$s]
  where
   vs  = genArgs defs []      -- (1)
   $e$    = close defs vs        -- (2)
   res = take n (eval e)      -- (3)
   $\vsu$s   = [$\vsu$ | $\pair{\stuck}{\vsu}$ <- res]  -- (4)
\end{mcode}
\caption{Generating Witnesses}
\label{fig:algo-gen-witness}
\end{figure}

%% \begin{figure}[t]
  %% \centering
  %% \begin{mcode}
  %% -- transitive small-step reduction, returning a list of results
  %% eval :: ($e$, $\su$) -> [($v$, $\su$)]
%%
  %% -- | is a value stuck?
  %% isStuck :: $v$ -> Bool
%%
  %% mkApps  :: $e$ -> [$e$] -> $e$
  %% mkLets  :: [($x$, $e$)] -> $e$ -> $e$
  %% \end{mcode}
  %% \caption{Expression API}
  %% \label{fig:expression-api}
%% \end{figure}
%% %
%% We also define a few helper functions for manipulating expressions:
%% \begin{itemize}
%% \item @subst@ applies a substitution of holes to a value,
%% \item @mkApps@ creates a nested sequence of applications in the usual
  %% left-associative style,
%% \item @mkLets@ takes a list of binders and a body expression, and
  %% creates a sequence of nested let-binders, and
%% \item @isStuck@ tests whether a value is the \stuck term.
%% \end{itemize}

%%%  \begin{figure*}[t]
  %%%  \centering
  %%%  \begin{mcode}
  %%%  check :: [($x$, $e$)] -> Result
  %%%  check bnds =
    %%%  -- (2) search for a witness
    %%%  case find (isStuck . fst) results of
      %%%  Nothing      -> Safe
      %%%  Just (_, su) -> Unsafe (mkApps f (subst su args))
    %%%  where
      %%%  (args, results) = loop []
      %%%  f               = snd (last bnds)
      %%%  build args      = mkLets bnds (mkApps f args)
%%%
      %%%  -- (1) find the correct number of arguments
      %%%  loop :: [$v$] -> ([$v$], [($v$, $\su$)])
      %%%  loop args = case eval (build args, []) of
        %%%  ($\efun{x}{e}$, _) : _ -> loop (args `snoc` $\ehole{}$)
        %%%  results      -> (args, results)
  %%%  \end{mcode}
  %%%  \caption{A procedure for generating witnesses}
    %%%  \ES{should address case where output types of successive runs dont match}
  %%%  }
  %%%  \label{fig:search-algo}
%%%  \end{figure*}
%

% !TEX root = main.tex


\documentclass[11pt,a4paper,oneside]{report}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
%\usepackage{array}
\usepackage{bbold}
%\usepackage{bm}
\usepackage[hypcap,small,hang]{caption}
%\usepackage{cite}
\usepackage{color}
\usepackage{dsfont}
%\usepackage{esint}
\usepackage{geometry}
\usepackage{graphicx}
\usepackage{wrapfig}
%\usepackage{hyperref}
%\usepackage{inputenc}
\usepackage{latexsym}
%\usepackage{listings}
\usepackage{mathrsfs}
\usepackage{mathtools}
\usepackage{microtype}
%\usepackage{marvosym}
%\usepackage{pdfpages}
%\usepackage{rotating}
%\usepackage{setspace}
\usepackage{slashed}
%\usepackage{times}
\usepackage{tikz}
%\usepackage{upgreek}
%\usepackage{url}
%\usepackage{wrapfig}
%\usepackage{showframe}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[pdftex,
            pdfauthor={Benny van Zuiden},
            pdftitle={libmd-intro},
            pdfsubject={An introduction to libmd},
            pdfkeywords={Theoretical Physics, Computational physics},
            pdfproducer={LaTeX},
            pdfcreator={Human},
            pdfborderstyle={/S/U/W 0}]{hyperref}
\usepackage{xmpincl}
 \includexmp{meta}
\usepackage{cleveref}

% New definition of square root:
% it renames \sqrt as \oldsqrt
\let\oldsqrt\sqrt
% it defines the new \sqrt in terms of the old one
\def\sqrt{\mathpalette\DHLhksqrt}
\def\DHLhksqrt#1#2{%
\setbox0=\hbox{$#1\oldsqrt{#2\,}$}\dimen0=\ht0
\advance\dimen0-0.2\ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\box0\lower0.4pt\box2}}

\renewcommand{\theequation}{\arabic{section}.\arabic{equation}}
\renewcommand{\thesection}{\arabic{section}.}
\renewcommand{\thesubsection}{\alph{subsection}.}
\newcommand{\subsect}[1]{\subsection{#1} \setcounter{equation}{0}}
\newcommand{\sect}[1]{\section{#1}  \setcounter{equation}{0}}

\renewcommand{\d}{\mathrm{d}}
\newcommand{\im}{\dot{\imath}}
\newcommand{\cs}[3]{\Gamma^{#3}_{#1 #2}}

%% TikZ related
\usetikzlibrary{calc}
\usetikzlibrary{shapes,arrows}
\tikzstyle{decision} = [diamond, draw, fill=blue!20,text width=4.5em, text badly centered, node distance=3cm, inner sep=0pt]
\tikzstyle{block} = [rectangle, draw, fill=yellow!20,text width=5em, text centered, rounded corners, minimum height=4em]
\tikzstyle{bblock} = [rectangle, draw, fill=red!20,text width=5em, text centered, rounded corners, minimum height=4em]
\tikzstyle{eblock} = [rectangle, draw, fill=green!20,text width=5em, text centered, rounded corners, minimum height=4em]
\tikzstyle{line} = [draw, -latex']
\tikzstyle{cloud} = [draw, ellipse,fill=red!20, node distance=3cm, minimum height=2em]

\begin{document}
\title{Algorithm Proposal}
\author{By Benny van Zuiden}
%\date{\today}
%\maketitle
%\thispagestyle{empty}
%\newpage
%\tableofcontents
%\newpage

\begin{center}
{\textbf{\Large{\texttt{libmd}-intro}} \\*
\large{- By Benny van Zuiden -} \\*
{April - 8 - 2014} \\* {\vspace{4pt}}
\tiny{last revised April - 8 - 2014} \\* \vspace{10pt}}
\end{center}
\normalsize
\sect{Introduction to \texttt{libmd}}
\texttt{libmd} is a molecular dynamics library optimized for theoretical soft condensed matter physics. It is developed by:
\begin{center}
Benny van Zuiden\footnote{Maintainer.} (zuiden@ilorentz.org) \\
Jayson Paulose (paulose@ilorentz.org) \\
Thomas Beuman (beuman@ilorentz.org)
\end{center}
under the supervision of Vincenzo Vitelli. \texttt{libmd} is a object-oriented library written in \texttt{C++11} using nothing but the standard libraries and is tested to work on \texttt{gcc} and \texttt{LLVM/clang}. It uses \texttt{git} as a version control system, and \texttt{GNU make} as a build system. Parallel implementations for \texttt{cpu} is underway and implementations \texttt{gpu} planned. What makes \texttt{libmd} different from all the other molecular dynamics packages is that it is designed to solve typical soft matter problems, it designed to work in arbitrary dimensions and allows, is \emph{extremely} flexible, has multiple ways to make particles interact and constrain them and it can do dynamics in curved space (Monge patches).
\sect{Introduction to molecular dynamics}
Molecular dynamics in the eyes of a theoretical softmatter physicist is nothing but the classical $N$-body problem --solved computationally. The classical $N$-body problem is basically solving Newton's equations of motion:
\begin{align}
a^{\mu}_i = \frac{1}{m_i} F^{\mu}_i
\end{align}
Here $m_i$ is the mass of particle $i$, $a^{\mu}_i$ is the geodesic equations\footnote{In flat space: $a^{\mu}_i = \ddot{x}^{\mu}_i$, in curved space it's given by: $a^{\mu}_i = \ddot{x}^{\mu}_i+\cs{\rho}{\sigma}{\mu} \dot{x}^{\rho}_i \dot{x}^{\sigma}_i$.} and $F^{\mu}_i$ is probably non-trivial and based on lots of interactions. The classical $N$ body problem was analytically solved by Sundman and Wang and is of little practical use. Fortunately, it easy to solve the problem computationally --for most cases-- as time discretized. The error remains small if symplectic integrators --integrators that conserve Lagrangian symmetries are conserved -- are used. Typical integrators in flat space are symplectic Euler or velocity Verlet. For curves space we have developed our own.
\begin{figure}
	\begin{center}
    \begin{tikzpicture}[node distance = 2cm, auto]
    \node [bblock] (init) {Initialize System};
    \node [block, right of=init, node distance=3.5cm] (identify) {Calculate Forces};
    \node [block, below of=identify, node distance=3cm] (update) {Integrate particle trajectories};
    \node [block, right of=update, node distance=3.5cm] (evaluate) {Measure};
    \node [decision, above of=evaluate, node distance=3cm] (decide) {Repeat?};
    \node [eblock, right of=decide, node distance=3.5cm] (stop) {Done!};
    \path [line] (init) -- (identify);
    \path [line] (identify) -- (update);
    \path [line] (update) -- (evaluate);
    \path [line] (evaluate) -- (decide);
    \path [line] (decide) -- node {no}(stop);
    \path [line] (decide) -- node {yes}(identify);
  \end{tikzpicture}
  \end{center}
  \caption{A very basic schematic depicting how molecular dynamics is roughly done}
  \label{fig:md}
\end{figure}
\\
As molecular dynamics is nothing less than an initial value problem, it requires initial conditions (possibly boundary conditions) and rules about how to calculate the forces. Once this is defined the integrator can calculate the particle trajectories sequentially using small time increments, called timesteps. After a bunch of timesteps one typically wants to measure a property after which the process can be repeated or terminated. This process is very schematically depicted in \cref{fig:md}.
\sect{\texttt{libmd}-specific}
\renewcommand{\theequation}{\arabic{section}.\alph{subsection}.\arabic{equation}}
In the following section we will explain how \texttt{libmd} is designed, what it can --and perhaps cannot-- do. Bear in mind that everything discussed in this is implemented regardless of dimensionality or presence of curvature --unless specifically stated otherwise.
\subsect{The simulation box}
\begin{wrapfigure}[15]{r}{0.4\textwidth}
    \begin{tikzpicture}[scale=0.5]
     \tikzstyle{every node}=[font=\tiny]
   	  \pgfmathsetmacro\lc{1.96188730425514123023821}
   	  \pgfmathsetmacro\r{0.866025403784438646763723}
   	  \pgfmathsetmacro\X{4.90471826063785307559552}
  	  \pgfmathsetmacro\Y{5.09713273454136756237537}
      \coordinate (Origin)   at (0,0);
      \coordinate (XAxisMin) at (-\X,0);
      \coordinate (XAxisMax) at (\X,0);
      \coordinate (YAxisMin) at (0,-\Y);
      \coordinate (YAxisMax) at (0,\Y);
      \coordinate (LL) at (-\X,-\Y);
      \coordinate (LR) at (\X,-\Y);
      \coordinate (TL) at (-\X,\Y);
      \coordinate (TR) at (\X,\Y);
      \draw [thin, gray,-latex] (XAxisMin) -- (XAxisMax);
      \draw [thin, gray,-latex] (YAxisMin) -- (YAxisMax);
      \draw [thick,black] (LL) -- (TL) node[left,black,midway,font=\small] {$L^y$};
      \draw [thick,black] (LR) -- (TR);
      \draw [thick,black] (LL) -- (LR) node[below,black,midway,font=\small] {$L^x$};
      \draw [thick,black] (TL) -- (TR);
    \end{tikzpicture}
    \caption{A two dimensional box with dimensions $L^x$ by $L^y$. The origin of the box is where the grey axes cross.}
    \label{fig:box}
\end{wrapfigure}
We start by building a stage we the actors --particles-- can act. The stage is called the simulation box --simbox for short-- and has a hyper volume:
\begin{align}
V = \prod_\delta^D L^{\delta}
\end{align}
where $D$ is the dimension of the system and $L^{\delta}$ is the size of the box in each component. The origin $0^{\mu}$ is placed right in the middle of the box such that the boundaries of the box are present at every $\pm \tfrac{1}{2} L^{\delta}$. A two dimensional box is depicted in \cref{fig:box}. The boundaries can have boundary conditions per dimension. Currently, the implemented boundary are \texttt{NONE}, \texttt{PERIODIC} and \texttt{HARD} boundary conditions make perfectly bounce the particles. Additionally, the box can shrink, expand and shear.
\subsect{Particles}
Particles are the actor is in the box. Particles can be added and removed dynamically from the system. Additionally they can be pinned to one point. Every particle has the following properties:
\begin{itemize} \itemsep1pt \parskip0pt
\item mass: $m$
\item position: $x^{\mu}$
\item velocity: $\dot{x}^{\mu}$
\end{itemize}
Additionally particles have:
\begin{itemize} \itemsep1pt \parskip0pt
\item type\footnote{Types will be discussed in the next subsection.}
\item fix
\item forces acting on them: $F^{\mu}$
\end{itemize}
Internally they contain additional \emph{hidden} variables for better computational performance.
\subsect{Interactions}
\emph{Without interactions life is boring}. Currently, the defined system is nothing but a box with a set of points, if we would calculate the equations of motion we would be simulating an ideal gas. To make it a bit more interesting --or realistic-- we have to define interactions. Interactions can be defined in many ways, for this part of the interaction implementation we will assume interactions are position depended and pairwise potentials. Mathematically:
\begin{align}
F^{\mu}_i=-\nabla \sum_{j>i} V(d(p_i,p_j))
\end{align}
Where $V$ is the pairwise potential and $d(p_i,p_j)$ is the distance between two particles. The potential $V$ can be any kind of potential Lennard--Jones or Yukawa for instance.
The Yukawa potential:
\begin{align}
V_Y(r)=\frac{b}{re^{\kappa r}}
\end{align}
Typical values for are $b=1$ and $\kappa=100$. Note that for these parameters $V(1) \approx 10^{-44}$  so it does not make sense to iterate over at large distances. Additionally making every particle interact with every other particle makes the algorithm at least order $N^2$ which is slow for a large number of particles. We can do better by creating some kind of cutoff radius $r_{co}$ and iterate over particles only within that cutoff vicinity, we can make the algorithm order $N log(N)$ which is typically better. In order to keep the potential continues we redefine the potential as:
\begin{align}
\tilde{V}_Y(r)=V_Y(r)-V_Y(r_{co})
\end{align}
The library can take any function $V: \mathds{R} \rightarrow \mathds{R}$ it generates the derivative automatically --without numerical errors and with the same complexity-- using a nice computational trick called \emph{automatic differentiation}.\\
Suppose you want certain particles to interact differently with other particles. A trivial way of doing this is by labeling particles with a type and then define interactions between types. Suppose I label a set of particles as type $0$ and the remaining particles as type $1$. I'll let $0$--$0$ interaction be Yukawa, $0$--$1$ interact Lennard--Jones and $1$--$1$ interact Yukawa with different parameters again. Or suppose you want to make a random spring network then you will need as many types as particles. If you don't like to think in types however, the code can translate bond lists to types for you.\\
Suppose you want to simulate dimers, trimers or polymers (or other weird objects for that matter). It can be done. We have included a structure in the code called superparticles that overrides type defined interactions if an interaction in the superparticle is assigned. This may sound a little vague so let me give an example. Take two particles of type $0$ and put them in the same superparticle, then within the super particle tie them together with a Hookean spring. The result is a dimer that interacts Yukawa with everybody else. Likewise you can create polymers and dimers.
\subsect{External forces}
Additionally there is an external forces structure that allows you to add forces like linear gravity or damping, as well as any other kind of interaction you can write a function for. You can have multiple external forces acting on each particle. You can have damped interactions, multibody interactions, random kicking etc. The implementation of such forces is, however, a little harder.
\subsect{Curvature}
Adding curvature in the form of a Monge patch is near trivial. The Monge functions can be any (external) function $f: \mathds{R}^D \rightarrow \mathds{R} : C^2$ the code are automatically differentiates them.
\end{document}


% To be compiled by XeLaTeX, preferably under TeX Live.
% LaTeX source for ``Yanqi Lake Lectures on Algebra'' Part III.
% Copyright 2019  李文威 (Wen-Wei Li).
% Permission is granted to copy, distribute and/or modify this
% document under the terms of the Creative Commons
% Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
% https://creativecommons.org/licenses/by-nc/4.0/

% To be included
\chapter*{Introduction}
\addcontentsline{toc}{chapter}{Introduction}
\markboth{Introduction}{}

In the beginning, these lecture notes were prepared for the graduate course \emph{Algebra III} (ID: 011M4002Y) in Spring 2016, University of the Chinese Academy of Sciences. For some reasons, it took place in the Yuquanlu campus instead of the Yanqi Lake campus as it should be.

The course is a sequel to Algebra I (fields, modules and representations) and II (homological algebra). The topic of this Part III is commutative algebra, or more precisely \emph{commutative ring theory}. Each ``Lecture'' in these notes took roughly one week, say approximately four hours of lecture, but the materials were only partially covered. My initial intention was to give a traditional course on commutative algebra as proposed by the syllabus prescribed by UCAS. For various reasons, my plan failed. For example, there are too few discussions on depth, regular sequences and Cohen--Macaulay modules, too few applications of completions, and the computational aspects haven't been touched. Moreover, the homological aspect of commutative algebra is almost non-existent in these notes, namely the Auslander--Buchsbaum Formula, the properties of regular local rings, etc. Last but not least, the exercises herein are scarcely sufficient.

These notes were also used for the Enhanced Program for Graduate Study held at the Beijing International Center of Mathematical Research, Peking University, during Spring 2019 (course ID: 00102057).

As the title suggests, some backgrounds from the Part I are presumed, namely the basic notions of rings, modules and their chain conditions, as well as familiarity with tensor products and some Galois theory. We occasionally presume some basic knowledge of homological algebra, such as the functors $\Tor_i$ and $\Ext^i$.

Sometimes I made free use of the language of derived categories. This was indeed covered in the preceding course \emph{Algebra II}, and it should be common sense for the future generations.

As the reader might have observed, these notes were prepared in a rush; certain paragraphs have not been proofread yet and many proofs are silly. I am very grateful to the students for various corrections and improvements, and I will try to polish these notes in the future.

\section*{Conventions}
Throughout these lectures, we consider only associative rings with unit $1$, and the rings and algebras are assumed to be commutative and nonzero unless otherwise specified. The ideal generated by elements $x_1, x_2, \ldots$ in a ring $R$ is denoted by $(x_1, x_2, \ldots)$ or sometimes $\langle x_1, x_2, \ldots \rangle$; the $R$-algebra of polynomials in variables $X, Y, \ldots$ with coefficients in $R$ is denoted by $R[X, Y, \ldots]$. We write $R^\times$ for the group of invertible elements in a ring $R$. A ring without zero-divisors except $0$ is called an integral domain, or simply a domain. The localization of a ring $R$ with respect to a multiplicative subset $S$ will be written as $R[S^{-1}]$.

For any sets $E, F$, let $E \smallsetminus F := \left\{ x \in E: x \notin F \right\}$. The cardinality of $E$ is denoted by $|E|$.

The usual logical connectives such as $\exists$, $\forall$, $\wedge$, $\vee$ and so forth will occasionally be used. Writing $A := B$ means that the expression $A$ is defined to be $B$.

We will use the standard notations $\Z, \Q, \R, \CC$ to denote the set of integers, of rational numbers, etc. Sans serif fonts are reserved for categories, such as $\cate{Ab}$ (abelian groups) and $\cate{Ring}$.

When denoting morphisms in a category by arrows, monomorphisms (resp.\ epimorphisms, isomorphisms) will be indicated $\hookrightarrow$ (resp.\ $\twoheadrightarrow, \rightiso$).

\section*{Possible references}
The reader is expected to have basic familiarity with groups, rings and modules, as covered in my lecture notes on Algebra I. We will make use of some really elementary homological algebra as our course proceeds --- so keep calm.

Our main references will be \cite{Mat80} and \cite{Eis95}. The Bourbaki volumes \cite{Bour83, Bour98} serve as our ultimate source. The readers are also encouraged to consult the relevant materials in \href{https://stacks.math.columbia.edu/}{Stacks Project}.

\vfill
\begin{figure}[h]
	\centering \includegraphics[height=180pt]{JiaoShouShengYa.jpg} \\ \vspace{1em}
	\begin{minipage}{0.7\textwidth}\begin{center}
		\small \fontspec{Noto Serif CJK SC} 《教授生涯》, 李桦, 木刻版画, 1948 年.
	\end{center}\end{minipage}
\end{figure}
\vfill


\section{Introduction}
In the first part of this report we want to present the physical concepts needed for the understanding of the performed calculations. At the end, the Split-Step Fourier method, which we used to analyze the dynamics of the different quantum systems, is introduced. \\

The Gross-Pitaevskii equation (GPE) successfully describes the dynamics of Bose-Einstein condensates. Here, we want to introduce the corresponding physical situation, along with its assumptions.

\subsection{Bose-Einstein condensation}

Bose-Einstein condensates (BECs) are states of matter of dilute boson gases cooled down to temperatures very close to absolute zero.

The most important characteristic of such system is, that a large fraction of bosons occupies the lowest quantum state.
Although one would assume that the understanding of the dynamics of a BEC is based on the microscopic, i.e. the quantum-mechanical, properties of the single bosons forming the gas, it is possible to describe Bose-Einstein condensates with one single, macroscopic wave function $\psi(\mathbf{r},t)$.

For an exact description of $N$ interacting quantum particles we would need the $N$-body wavefunction, $\psi(r_1, r_2, ...r_N , t)$, which obeys the many-body Schr\"odinger equation.
We assume the interactions between the particles to be very weak, which is well-founded in the diluteness of the gases and the weak forces between neutral atoms.
By neglecting the effects of quantum fluctuations, the many-body wave function for large particle numbers ($N \gg 1$) is replaced by an \textit{effective} single-particle wave function $\psi_{\text{eff}}(\mathbf{r},t).$

In a field-theoretical approach to the subject, one would introduce this macroscopical wave function as a complex field of the form
\begin{align}
	\psi_{\text{eff}}(\mathbf{r},t) = \sqrt{n} \cdot \exp(\frac{i}{\hbar} \ \mathcal{S}(\mathbf{r},t))\label{eqn:Field equation}
\end{align}
 with the density and phase distributions $n$ and $\mathcal{S}$ of the condensate. It is normalized to the particle number $N$, such that
 \begin{align}
 	\int \dd[3]\mathbf{r} \ \norm{\psi}^2 = N.
 \end{align}

\subsection{From the Schr\"odinger equation to the GPE}
For an ideal Bose gas, i.\,e. without interactions between the particles, the evolution of the system over time would be governed by the time-dependent Schr\"odinger equation

\begin{align}
i\hbar\ \frac{\partial\psi(\mathbf{r}, t)}{\partial t} =
\left[ -\frac{\hbar^2}{2m} \nabla^2 + V(\mathbf{r}, t)\right]\psi(\mathbf{r}, t) \label{eqn:Schroedinger}
\end{align}

with the Laplacian $\nabla^2$ and the potential
$V(\mathbf{r},t)$.

One needs to modify this equation to include the particle interactions to describe the physical situation more precisely. We assume that elastic next-neighbor interactions between two single particles due to Van-der-Waals forces dominate the interaction processes inside the gas. This allows us to describe these processes using the model of hard-sphere interactions, which yields
\begin{align}
	\mathcal{U}(\mathbf{r_1}, \mathbf{r_2}) = g_{\tiny3D}\cdot \delta_D(\mathbf{r_1} - \mathbf{r_2})
\end{align}

for the interaction potential, where the interaction strength $g_{3D}$ is defined as
\begin{align}
	g_{\tiny{3D}} = \frac{4\pi\hbar^2 a_s}{m}
\end{align}
 with the scattering length $a_s$ in the low-energy limit.

 Taking these interactions into accounts yields us to the modified, nonlinear version of the Schr\"odinger equation, the \textit{Gross-Pitaevskii equation}
\begin{align}
	i\hbar \ \frac{\partial\psi(\mathbf{r}, t)}{\partial t} = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r}, t) + g\norm{\psi}^2\right]\psi(\mathbf{r}, t).
\end{align}
All numerical calculations in this project are based on this equation. \\

\textbf{Some words on the Bogoliubov mean-field approach:} Working with field operators $\hat{\psi}$, induced by equation (\ref{eqn:Field equation}) leads us to a Hamiltonian description of the situation with the grand canonical Hamiltonian, here in one spatial dimension
\begin{align}
	\hat{\mathcal{H}} = \int \dd z \ \hat{\psi}^{\dagger}(z) \left[ -\frac{\hbar^2}{2m}\partial_z^2 + V(z) - \mu + \frac{g_{1D}}{2}\hat{\psi}^{\dagger}(z)\hat{\psi}(z)\right]\hat{\psi}(z)
\end{align}
where $g_{1D}$ is the interaction parameter for one dimension and $\mu$ is the chemical potential.

Choosing suitable parameters for the spatial grid structure, one finds solutions for the discretized version of the GPE from this approach as

\begin{align}
	\left[-\frac{\hbar^2}{2m}\partial_z^2 + V(z) - \mu + g_{1D}\ n\right]\sqrt{n} = 0.
\end{align}

 The following two sections introduce topological defects in one and two spatial dimensions, namely solitons and vortices, which are analyzed numerically later on.

\subsection{Solitons}
Solitons are non-dispersive wave solutions of the Gross-Pitaevskii equation. In the following we distinguish between bright solitons, describing attractive interactions and dark solitons for repulsive interactions. The latter ones will be the objects of interest for our studies. They are characterized by their so called \textit{greyness} $\nu = \sfrac{v_s}{c_s}$ with the Bogoliubov speed of sound $c_s = \sqrt{\sfrac{ng}{m}}$ and the velocity $v_s$ of the solitons movement inside the gas. \\
If we restrict ourselves to the case of repulsive interactions and a vanishing external potential, the analytic solution for a single solitonic excitation reads
\begin{align}
	\phi_{\nu}^{(1)}(z,t) = \sqrt{n}\left[ i\nu + \gamma^{-1}\tanh\left(\frac{z - (z^0 + \nu c_s t)}{\sqrt{2}\xi\gamma}\right) \right]\operatorname{e}^{i\mu t}\label{eqn:analytic}
\end{align}
with the Lorentz factor $\gamma^{-1} = \sqrt{1 - \nu^2}$ and the healing length $\xi = \sfrac{1}{\sqrt{mng}}$.

\begin{figure}[H]
\centering
\includegraphics[scale = 0.35]{figures/black_and_grey}
\label{fig:SolitonAnalytical}
\caption{Density profile and phase of a single black and grey soliton}
\end{figure}

Solitons are localized density minima with a maximum density depression of $\sfrac{n_{\text{min}}}{n} = \nu^2$, \\ associated with a phase jump of $\Delta\theta \leq \pi$. They are called \textit{black}, if $v_s = 0$ and \textit{gray}, if $v_s \neq 0$. The physical momentum carried by the wave function due to the presence of the soliton  is given by
\begin{align}
	p = m \int \dd z \ j(z) = -2\hbar n \nu \sqrt{1-\nu^2}
\end{align}
with the current $j(z)$. It has a maximum at $\nu \approx 0.7 $\ \cite{Erne2012}.

\subsection{Vortices}
Another interesting excitation are vortices, which are a special property of superfluids. To get a better understanding of the density structure, we use cylindrical coordinates and evaluate the GPE for
\begin{align}
	\psi(\mathbf{r}) = f(n, z)\operatorname{e}^{il\varphi}.
\end{align}
This results in an additional term, i.\,e. $ \sfrac{(\hbar l)^2}{2mn^2}$. which gives the kinetic energy resulting from its azimuthal velocity. The size of a typical vortex is about $\xi$. To visualize the density profile of a vortex we included a plot from \cite{ETH}.
\begin{figure}[H]
	\centering
	\includegraphics[scale = 0.6]{figures/vertex_density}
	\caption{Density profile of a vortex, taken from \cite{ETH} }
\end{figure}
Here, $\rho$ is the background density, $l = 1, 2$ \ is the charge of the vortex and $l=0$ \ is a situation without the presence of a vortex.

In this project, we are mainly interested in the evolution of different vortex constellations over time. This will be explained in more detail later on.

The final part of this introduction deals with the Split-Step Fourier method, our numerical approach for solving the GPE in this project.