\documentclass[a4paper]{article}

%% Language and font encodings
\usepackage[english]{babel}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}

%% Sets page size and margins
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}

%% Useful packages
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{url}
\usepackage{enumitem}

\title{Tracking Multiple Objects From Partial Observations}
\author{Chinmayee Shah}
%\date{}

\newcommand{\N}{\mathcal{N}}
\newcommand{\x}{\hat{x}}
\newcommand{\X}{\hat{X}}
\newcommand{\y}{\hat{y}}
\newcommand{\Y}{\hat{Y}}
\newcommand{\dt}{\text{dt}}

\begin{document}
\maketitle

\section{Problem}

Reliable object detection, tracking, and trajectory prediction is of great
interest today, for safe autonomous navigation.
This project explores the problem of tracking multiple objects, given
noisy observed object positions.
Sensors such as lidar and radar can see what is directly in front of them,
but they cannot see occluded objects.
Lidar sensors scan their environment, and record the distance to
nearest objects, as a list of \{angle, distance\} pairs.
The recorded distance can be noisy due to sensor noise, scattering and
partial and multiple reflections.

In this project, we look at the problem of tracking objects given a set of
observed positions for objects, using Bayesian inference and maximum
likelihood.
Given a set of $M(\tau)$ observations,
$\X_\tau = \{\x^\tau_1, \x^\tau_2, \ldots, \x^\tau_{M(\tau)}\}$,
for $N(\tau)$ objects ($M(\tau) \leq N(\tau)$ because of occlusion),
for times $\tau \leq t$,
we would like to estimate $N(t)$, that is, how many objects there
really are at time $t$, and true positions of all objects at time $t$, that is,
$X_t = \{x^t_1, x^t_2, \ldots, x^t_{N(t)}\}$.
We do this by choosing the most likely association between observations and
existing objects, creating new tracks for observations that are likely from
newly entered objects, deleting tracks that have likely exited or were
spuriously created in the past, and
evolving and refining track estimates using previous estimates and new
observations, as in a hidden Markov process.

\section{Literature Review}

Typically, one must first pre-process raw lidar data to detect objects and
estimate their positions.
These observed positions can then be used to track objects.
Globally nearest neighbors,
probabilistic data association filtering (PDAF) and joint probabilistic data association
filtering (JPDAF) all assume that pre-processing is done, and final observed positions have
been computed~\cite{pdaf}.
Globally nearest neighbors (GNN) weights each observation to track association by a score,
and either locally or globally tries to maximize this weight.
PDAF assigns probabilities to all matches, and updates estimates using these probabilities
as weights -- that is, it does not pick a best association, but uses all observations to
update the estimate.
PDAF may falsely assign one observation to multiple tracks. JPDAF overcomes this by
conditioning over only valid assignments.
PDAF and JPDAF are known to be computationally expensive.
Moreover, they assume the number of tracks is known.
Markov chain Monte Carlo data association provides a polynomial randomized approximation
scheme for joint probabilistic data association~\cite{mcmcda}.
The problem model for these algorithms is slightly different from ours --
they look at clutter, where there may be false alarms from each track, so that there
may be multiple observations per track.
In our problem, we have at most one observation per track.
Multi-hypothesis is similar to globally nearest neighbors, but across multiple time
steps~\cite{mht}. It tracks multiple hypothesis (associations) in the hope that
information from future steps will provide more information.
In concept, it is similar to beam search.

End-to-end approaches~\cite{deeptracking} on the other hand, use a stack of
convolutional neural networks and recurrent neural networks to track objects
directly from sensor data.
However, this provides little insight into how the network is performing tracking,
and requires training on huge data-sets.
It is also not clear how a network trained on one kind of data set would perform on
another kind of data set.
In this project, we take a more intuitive approach of Bayesian networks,
assume we have observed positions, and look at the problem
of just estimating true positions of objects given observed positions.

\section{Data and Task}

There are many lidar point cloud data-sets publicly available.
However, we cannot directly use these data-sets -- we need to pre-process
the data to detect objects and estimate positions, which in itself is a
challenging problem.
Also, these real-world data-sets do not include true number of objects,
or true positions of objects, making evaluation and error estimation
difficult.
We generate synthetic data by evolving objects using a 2D simulation, and
record true and observed positions of each object, and whether an object
is visible or occluded.
Generating data using simulation also  lets us break the problem of object
tracking into smaller, more manageable problems.

\begin{figure}[t]
  \centering
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/input_1.png}
  \end{subfigure}~
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/input_2.png}
  \end{subfigure}
  \caption{Two frames from data generated using a simple 2D simulation.
           White shows true position for visible objects,
           light gray shows true position for occluded objects,
           dark gray shows noisy position (when an observation is used).}
  \label{fig:input}
\end{figure}

\subsection{Simulation setup}

The simulation domain is a rectangular region, with a viewer at the center
of the bottom edge, denoted by the gray square in figure~\ref{fig:input}.
White circles are objects visible to the viewer, and light gray circles
are occluded objects not visible to the viewer
(circle center gives object position).
The simulator evolves objects at each step using the equations of motion
$x_{t} = u_{t-1} \delta t + \frac{1}{2} a_{t-1} \delta t^2 $ and
$u_{t} = u_{t-1} + a_{t-1} \delta t$, where $x_t$, $u_t$ and $a_t$ denote
the position, velocity and acceleration at time $t$ and $\delta t$ is a
constant time step.
The observed position equals true position plus noise.
Acceleration and noise are independent and identically distributed random
variables, drawn from normal distributions
$\N(0, \Sigma_a)$ and $\N(0, \Sigma_r)$ respectively,
where
$\Sigma_a = \begin{bmatrix} \sigma_a^2 & 0 \\ 0 & \sigma_a^2 \end{bmatrix}$
and
$\Sigma_r = \begin{bmatrix} \sigma_r^2 & 0 \\ 0 & \sigma_r^2 \end{bmatrix}$.
Dark gray circles in figure~\ref{fig:input} denote noisy positions,
which are observed positions for visible objects.
The simulator generates a new object with a probability $p_\text{gen}$ at
each step, if the number of objects is less than $N_\text{max}$ and
greater than $\frac{N_\text{max}}{2}$, and with probability 1 if
the number of objects is less than $\frac{N_\text{max}}{2}$. The total
number of objects thus never exceeds $N_\text{max}$.
The simulator initializes a new object with a position drawn uniformly from
points along the boundary of the simulation region, and with a velocity $\mu_v$
towards the opposite edge.
Objects outside the simulation region are deleted.

At each step, the simulator records the total number of objects, object id,
the true and observed position of each object, and whether the object is
occluded or visible to the viewer at the bottom.

\subsection{Task}

Given a set of $M(\tau)$ observations,
$\X_\tau = \{\x^\tau_1, \x^\tau_2, \ldots, \x^\tau_{M(\tau)}\}$,
for $N(\tau)$ objects ($M(\tau) \leq N(\tau)$), for times $\tau \leq t$,
we want to estimate the true number of objects $N(\tau)$ and true positions $X_t$.
We assume we know the distribution for acceleration and noise, that is, they are i.i.d.,
and drawn from normal distributions $\N(0, \Sigma_a)$ and $\N(0, \Sigma_r)$, and that
objects evolve according to the equations of motion presented in the previous section.

\section{Approach}

Estimating $N(t)$ and $X_t$ given $\X_1, \X_2, \ldots, \X_t$ is difficult, because
observations are noisy, that is, they do not correspond to true positions,
we do not know which observations correspond to which objects, and
some observations might be missing and we not know how many objects there
really are -- new objects might have entered, and existing objects might have exited.
We solve the problem by looking at three smaller problems --
first, estimating true positions of objects at time $t$ given noisy positions
(observations) for all objects, including occluded objects, and association between
observations and objects till time $t$,
second, determining an association between observations and objects given all
observations
and finally, determining an association between observations and objects given
observations for only visible objects.

\subsection{Tracking objects from noisy positions given association}

The true position and velocity of each object at a time $t$ depends only on
the true position, velocity and acceleration of object at time $t-1$.
\begin{figure}[h]
  \centering
  \includegraphics[width=0.6\textwidth]{images/hmm.png}
  \caption{Future position depends only on current position and velocity,
  for each object.}
  \label{fig:HMM}
\end{figure}
We can think of position and velocity of each object as states of a hidden Markov
process, and the observed positions as the observed states of this process.
Figure~\ref{fig:HMM} illustrates this.

Given the past and current observed positions for each object, we can recursively
estimate the probabilities of unknown, hidden state using observations as they come,
using Bayesian inference.
Kalman filter recursively computes an estimate for state and its covariance at
time $t$ using state estimate at time $t-1$ (predict phase),
and then refines the estimate using observation at time $t$, given
process noise and observation noise distribution~\cite{kalman}.
Since process noise (acceleration) and observation noise are normal in our case,
these estimates yield the exact probability distributions for state estimates for
each object, and maximize posterior probability.

We use Kalman filter to estimate each object's hidden state (position and velocity)
and state covariance, given all observations, and association between observations
and objects.
The hidden state $y$ for each object comprises of position $x$ and velocity $v$,
$y = \begin{bmatrix} x & v \end{bmatrix}$.
Observed positions are denoted by $\x$, true positions by $x$, and estimated
state mean by $\y$.
The velocity $v$ is not observed, and hence, observed state equals $\x$.
For each object, Kalman filter predicts state at step $t$ as follows,
\begin{align*}
\y_{t|t-1} &= F \y_{t-1|t-1} \\
P_{t|t-1}  &= F P_{t-1|t-1} F^T + Q
\end{align*}
Here, the matrix $F$ gives how state evolves, and equals
$\begin{bmatrix} I & I \cdot \dt \\ 0 & I \end{bmatrix}$.
The matrix $Q$ denotes process noise, and is related to acceleration,
$Q = G G^T \sigma_a^2$, where
$G = \begin{bmatrix} \frac{1}{2} \cdot I \cdot \dt^2 & I \cdot \dt \end{bmatrix} ^T$.
$I$ is a $2 \times 2$ identity matrix, and $0$ is a $2 \times 2$ matrix
with all elements set to zero.
The update phase uses a new observation at time $t$, to refine the estimates as,
\begin{align*}
z_t        &= \x_t - H \y_{t|t-1} \\
S_t        &= H P_{t|t-1} H^T + R \\
K_t        &= P_{t|t-1} H^T S^{-1} \\
\y_{t|t}   &= \y_{t|t-1} + K_t z_t \\
P_{t|t}    &= (I - K_t H) P_{t|t-1}
\end{align*}
The matrix $H$, the observation matrix, transforms the hidden state $y$ to what is observed.
Since only the object position is observed, $H = \begin{bmatrix} I & 0 \end{bmatrix}$.
$R = \Sigma_r$ is the observation noise.
An actual observation $\x = H y + r$, where $r$ is a noise value and $y$ is the true state.

The estimated state $\y$ is the maximum a posteriori (MAP) estimate.
By running Kalman filter on each object, we thus get the MAP estimate for the position
and velocity of each object.

\subsection{Associating objects given all observations (no occlusion)}

Once we have associations between object tracks and observations, we can use Kalman
filter to estimate the true positions of objects.
But we only have a set of observed positions and we need to determine the association
between observations and tracks first.
In this part, we assume that we have exactly one noisy observation for every object.
With this setup, we know that the number of object tracks must be equal to the number
of observations, that is $N(t) = M(t)$.
One approach is to match the nearest objects and observations.
However, greedily matching nearest object to an observation may not be optimal globally,
as there might be clusters of nearby objects.
Also, the greedy approach cannot be extended to the case when observations might be
missing due to occlusion.
Finally, even though $N(t)$ equals $M(t)$, $M(t)$ does not necessarily equal $M(t-1)$
as tracks enter and leave the domain.
We compute a penalty/loss for each object-observation match, and for unmatched tracks
and observations, and select the association that gives the least total loss.
To limit the search
(there would be more than $N(t)!$ associations if we were to include all possible
matches with tracks entering and leaving),
we include only those tracks that are within a small distance from an observation
(gate tracks), when determining a track to match.
We experimented with 2 different loss functions --
the distance between track position and observation, and
negative log of the probability that an observation is from a track,
assuming the estimated track position is the true position.
The ideas of gating and computing scores for association are inspired by
globally nearest neighbors and multi-hypothesis tracking~\cite{mht}.
We choose the best association unlike JPDAF which uses all observations weighted by
probability, to evolve a track, because in our problem, we assume there
is no clutter, and each track has at most one observation (no false alarms).

\subsubsection{Distance based loss}
For an object-observation pair, the loss equals the Euclidean distance between them.
For an unmatched observation pair, we assume that it must be a new track, and take
the least distance to the boundary as the loss, thus heavily penalizing unmatched
observations near the center. Unmatched observations near the boundary are penalized
less. Similarly, for an unmatched track, we assume it must have left the domain,
and take the least distance to boundary as the loss.

\subsubsection{Maximum likelihood formulation}
For an object-observation pair, the loss in this case equals negative of log of
probability that the observation is from a track, assuming the current estimate of
track as the actual position.
We discretize the PDF and approximate probabilities as $\text{PDF} \times \Delta$,
to approximate the probability for new and leaving tracks.
For an observation-track pair, this translates to
$-\log(P_\N(x_{t|t-1}, \Sigma_r, \x_t)) \Delta$,
where $x_{t|t-1}$ is our MAP estimate of position at time $t$ given previous
observations, that is,
$H \y_{t|t-1}$,
$\Sigma_r$ is observation noise, $\x_t$ is observation at time $t$,
$P_\N(\mu, \Sigma, x))$ is normal PDF with mean $\mu$,
covariance $\Sigma$, evaluated at $x$, and $\Delta$ is size of discretization.
For an unmatched observation, the loss equals
$- \sum_{x'} \log(P_\N(x', \Sigma_r, \x_t)) \Delta$, where the sum is over
points $x'$ outside the rectangular region.
We limit the sum till $4\sigma_r$ on each side of $x_{t|t-1}$.
Similarly, for an unmatched track, the loss equals
$- \sum_{x'} \log(P_\N(x_{t|t-1}, \Sigma_r, x')) \Delta$.

\subsubsection{Algorithm}
The algorithm for estimating positions given a set of noisy positions, but
no missing objects, looks as follows:
\begin{enumerate}[itemsep=0mm]
\item Predict position for tracks at time $t$, using estimated positions at time $t-1$.
\item For each observation, find tracks that are within a small region around the
observation
(an axis aligned box $10 (\sigma_a + \sigma_r)$ long in each dimension,
centered at the observation, in our experiments)
\item Search for the association that gives the least loss (penalty).
Total loss for an association =
  $\Sigma_{a \in A}$ loss for matching $a.$track and $a.$observation +
  $\Sigma_{c \in C}$ penalty for creating a new track for observation $c$ +
  $\Sigma_{d \in D}$ penalty for deleting track $d$.
$A$ is the set of matched observation-track pairs, $C$ is unmatched observations, and
$D$ is unmatched tracks.
\item Use the association from previous step to update the estimate for each track in $A$, create new tracks for observations in $C$ and delete tracks in $D$.
\end{enumerate}

\subsection{Handling missing observations and occlusion}

In this part, we look at the case when observations for occluded objects are missing.
Here, $N(t)$ is not necessarily equal to $M(t)$. We extend the maximum likelihood
formulation in the previous section, so that an unmatched track may either be occluded,
or may be outside the rectangular region (and should be deleted).
When a track is unmatched, but is occluded, we use the predict equations of Kalman filter
to evolve the object track, and skip the update part, where an observation is used to
refine the estimate.

\subsubsection{Maximum likelihood formulation}
Loss for object-observation pair and unmatched observation is same as the unoccluded case.
Loss for unmatched track now has two components --
outside points and occluded points, \\
$- \sum_{x' \in \text{outside}} \log(P_\N(x', \Sigma_r, \x_t)) \Delta - \sum_{x' \in \text{occluded}} \log(P_\N(x', \Sigma_r, \x_t)) \Delta$, \\
where outside is points outside the rectangular region,
and occluded is points that seem occluded to the viewer.
Points that seem occluded to the viewer are not the same as points that are actually
occluded, as observed positions are noisy.
We compute observed occluded region for every step by tracing rays from viewer to each
point in the domain, and checking if the ray crossed an observed object
(assuming objects are circular with some finite radius).

A more complete formulation should also consider the prior probability distribution
on track estimates.
This can be computed using the state mean and covariance from Kalman filter.
We experimented with this formulation too, and got similar results, but the formulation
is computationally more expensive -- we can compute and cache discretized
probabilities $P_\N(0, \Sigma_r, x-\mu)$ for the former case,
but we need to compute the probabilities in the latter case every time.

\subsubsection{Deleting spurious tracks}
We noticed that sometimes, we have falsely created tracks, especially at the boundary
when objects are just entering, and when the probability that an observation corresponds
to a new track is high. That is, we falsely get multiple tracks for just one object.
These clusters of false tracks keep moving through the domain, even though there is really
just one object.
We delete tracks that are in visible region, but do not match to any observation for some
number of consecutive frames, to avoid such spurious tracks.
We did not face this issue in the previous problem where we had all observations, because
we knew $N(t)$ then, and limited search to cases where number of tracks equals number of observations.

\subsubsection{Algorithm}

The final algorithm for tracking objects from partial observations is:
\begin{enumerate}[itemsep=0mm]
\item Predict position for tracks at time $t$, using estimated positions at time $t-1$.
\item For each observation, gate tracks to a small region around the observation as before.
\item Search for association that gives least total loss, where the total loss now includes
the probability that an unmatched track is occluded and hence not observed.
\item Create new tracks for unmatched observations, and delete tracks outside the domain,
and those that seem spurious.
\item Update estimates for tracks that have a matching observation.
\end{enumerate}

\section{Implementation and Results}
We have implemented the simulation and all discussed algorithms in python, our code is
available at \url{https://github.com/schinmayee/bayesian-object-tracking}.
We have also included the code and results in a codalab worksheet at
\url{https://worksheets.codalab.org/worksheets/0xee9369450dfa40f8a006a2f54da38876/}.
Estimated positions are saved as images such as images here, in results
folder for each run, on the codalab sheet.

\begin{figure}[h]
  \centering
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/kalman_1.png}
  \end{subfigure}~
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/kalman_2.png}
  \end{subfigure}
  \caption{Estimates using Kalman filter, given association.}
  \label{fig:kalman}
  \vspace{-2pt}
\end{figure}
\begin{figure}[h]
  \centering
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/nearest_1.png}
  \end{subfigure}~
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/nearest_2.png}
  \end{subfigure}
  \caption{Estimates using Euclidean distance as loss.}
  \label{fig:nearest}
  \vspace{-2pt}
\end{figure}

Figure~\ref{fig:kalman} shows results for 2 frames for the first part,
estimating position using Kalman filter, when all observations are available,
and the association is also given.
Light gray and white circle centers give true positions, and dark gray circle
centers give observed positions. Dark gray squares are the estimated positions.
Kalman filter seems to work quite well, even when observations are very noisy,
such as the circle in the middle on the left, in the left figure -- the estimate
lies in the white region, even when the gray region (noise) is almost outside
the white region.
Kalman filter gives the MAP estimate, and uses previous estimate of the state
to effectively reduce the observation noise.

Figure~\ref{fig:nearest} shows results for the same frames for second part,
determining association between objects and observations and estimating
positions, given all observations.
It uses Euclidean distance between observation and track estimate as loss function.
The estimates seem to be very close to estimates given by Kalman filter.
Figure~\ref{fig:unoccluded_ml} shows results for the same setup, with
negative log probability as the loss function. These results look similar
to the distance based loss function.
However, this algorithm falsely creates, in the second frame, a new track for
the circle at top right -- bigger squares denote newly created tracks and
smaller squares denote old tracks.
The probability that the observation is a new track and the old track has left
seems to be more than the probability that the observation is from an old track.
The distance loss function also runs into this problem, but less often.
\begin{figure}[h]
  \centering
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/unoccluded_ml_1.png}
  \end{subfigure}~
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/unoccluded_ml_2.png}
  \end{subfigure}
  \caption{Estimates using negative log probability as loss.}
  \label{fig:unoccluded_ml}
  \vspace{-2pt}
\end{figure}

Figure~\ref{fig:occluded_ml} shows results for the final part, where
observations for occluded objects are missing, and association is unknown.
Light gray circles denote occluded objects.
The frame on right shows some spurious tracks created near the boundary --
there are two false tracks in the left corner, and one falsely created new
track resulting in one stray track along the right edge.
However, the algorithm does seem to track occluded objects correctly in
most cases, particularly in the interior.
\begin{figure}[h]
  \centering
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/occluded_ml_1.png}
  \end{subfigure}~
  \begin{subfigure}{0.48\textwidth}
  \centering
  \includegraphics[width=0.6\textwidth]{images/occluded_ml_2.png}
  \end{subfigure}
  \caption{Estimates when observations for occluded objects are missing}
  \label{fig:occluded_ml}
  \vspace{-2pt}
\end{figure}

For the cases where association information is not available, we find that
false new tracks are sometimes created near the boundary, as in
figure~\ref{fig:unoccluded_ml} and figure~\ref{fig:occluded_ml}.
As objects move closer to the center, they are tracked more accurately, even
in the occluded object case, as the penalty for creating new tracks in the
interior is high.
\begin{figure}[h]
  \centering
  \includegraphics[width=0.6\textwidth]{images/position_error.png}
  \caption{Error in position, averaged over 100 frames.}
  \label{fig:errors}
\end{figure}
Figure~\ref{fig:errors} shows error in estimated position for 4 cases.
The first bar, baseline-basic is the observation error, if observations for
all objects are available, and we use the observed position as the position estimate.
The second one, kalman-basic, gives the estimation error for Kalman
filter, given all observations and association. Kalman filter reduces error over
baseline by 1.4x. The next two bars give errors when all observations are
available, but association information is not. As expected, both errors are more
than kalman-basic. Somewhat surprisingly, both errors are still less than
baseline-basic, even without the association information, and the error for
the probabilistic formulation is more than the one with distance based loss.

We think that we get more false tracks with the probabilistic formulation,
as compared to distance as the loss function, because,
with the probabilistic formulation, we have more false tracks at the boundaries,
when it is likely that an observation is from a new
track, as a result of which the estimation error equals observation error at
the boundaries.
The probabilistic formulation adds up probability for a new track,
from all points on and outside the boundary, while the distance based loss
only takes the least distance to boundary as loss.
This means it is better to create new tracks at the boundary, in the probabilistic
formulation.
Moreover, since we use Euclidean distance rather than squared Euclidean distance
for distance loss, small distances from the boundary get a larger penalty, compared
to negative log probability, which will have squared distance in the numerator
since the probability is for a normal distribution.
If we factored in the probability that there is a new object at the boundary
(using the average rate at which new objects are created), then the formulation
would be more complete, and probably give better results,
as the probability of a new track would become smaller, and the corresponding
negative log would become larger.
This argument also extends to the case with occlusion, when observations are missing.

Finally, we do not have an error bar for the last case, where observations
are missing, as estimation error no longer makes sense when we have false
tracks. Instead, we have the results for 40 frames, on Codalab, that shows
estimated track positions.

\section{Discussion, Conclusion, Future Directions}

The problem of multiple object tracking has rich literature, with
techniques such as multi-hypothesis tracking, probabilistic data association
filter, and joint probabilistic data association filter.
However, many of these formulations assume that the number of tracks is known.
End-to-end deep tracking is a novel approach that uses a stack of convolutional
neural networks and recurrent neural networks to perform tracking using sensor
data~\cite{deeptracking}.
We tried a different approach in this project, using Bayesian networks.
While the results look great without occlusion, we get some false tracks at
boundaries.
We think if we factor in the probability of new objects, the rate at which
we get false tracks should go down.
Even with the current formulation, tracking is robust in the interior.
In a realistic case, an observer is probably at the center, with a $360^o$
view, and making a few errors for tracks far away, that are just entering the
field of view, is probably not bad.

Our approach requires assumptions about the distribution of process and
observation noise, and how system evolves.
As an interesting future direction,
it might be possible to learn some of this so that we can make fewer
assumptions about distribution of observation noise, process noise,
and even how the system evolves.
This might be useful in scenarios such as road intersections, round-abouts,
curved roads, where traffic tends to move in a certain way.

\pagebreak

\bibliography{paper}{}
\bibliographystyle{plain}

\end{document}


As concluded in Chapter \ref{ch:litReview}, with the rapid development of mobile devices and mobile computing, the literature review has showed the potential of combining different information sources, such as mobile sensors and social media, in a crowd monitoring approach. In our framework, the context data layer is designed to fulfill this objective and serves as the input for the other layers down the stack.

The context data layer collects information about the context, which is the mass gathering event. In the development of a domain ontology for mass gathering, \citet{DelirHaghighi2013a} has summarised a set of related features that might have the effect on the safety of an event, such as environmental factors, event type, crowd size and venue. These knowledge can be retrieved from different sources. For this crowd monitoring framework, we propose three main sources:
\begin{inparaenum}[i)]
\item event information;
\item mobile sensing;
\item social media
\end{inparaenum}, each of which will be discussed in detail in the following sections.

\subsection{Event Information}
Event information includes information about the venue, expected number of participants or crowd size, and the type of event. This information is static and not required to be collected in real time, hence it can be prepared in the pre-event phase of the emergency management. Ideally, it can be either crawled from the events' homepages or provided by the event organizers and gathered at a centralized system for the monitoring phase.

One of the important features of a mass gathering in the context of emergency management is crowd density, which is the key factor leading to trampling and crushing incidents \citet{Lee2005}. This information can be estimated by using collected data above, namely the estimated crowd size, the venue capacity and the size of venue following below formula.

\[
crowd\_density = crowd\_size / venue\_size
\]
where, \(crowd\_density\) is the estimated crowd density, \(crowd\_size\) is the number of participants or the venue capacity and \(venue\_size\) is the area of the venue holding the event.

\subsection{Mobile Sensing}

Mobile sensing paradigm has become an emerging topic among recent studies in mobile and context aware computing. It leverages the power of sensor-enhanced mobile devices to acquire information about the context \citep{guo2014participatory}. The mobile devices include modern smart-phones and devices, which are integrated with a wide range of sensors such as GPS receivers, accelerometers and ambient light sensors.

Using the built-in GPS receiver in mobile phones to collect information for crowd monitoring has been proposed in a related works proposed by \citet{Wirz2012}. As mentioned in the literature review, in this study, GPS is used to obtain the current location of the phone bearer. The continuous sampling of the location can be used to estimate the movement of the crowd and the crowd density.

Another integrated sensor in mobile phones that can be used to gather context data is the accelerometer. Accelerometer is often used for the purpose of activity recognition \citep{ravi2005activity, kwapisz2011activity}. In our context of crowd monitoring, the literature review has noted a related work from \citet{Roggen2011}, where several crowd activities can be determined by analysing the pattern of accelerometer's data.

Interestingly, the microphone in mobile phones can also act as a sensor to count the number of devices in a crowd \citep{Kannan2012, Xu2013}, thus can be eventually used to roughly estimate the number of participants. Table \ref{table:mobileSensingCrowdFeature} summarises the possible sensing sources that can be integrated into our framework and the knowledge about a crowd that can be inferred from these sensors.

\begin{table}
\caption{Mobile sensors and Crowd features}
\label{table:mobileSensingCrowdFeature}
\centering
\begin{tabular}{|l|l|}
\hline
\textbf{Mobile sensor} & \textbf{Crowd features} \\
\hline
GPS receiver & Movement and density \\
\hline
Accelerometer & Activity \\
\hline
Microphone & Density \\
\hline
\end{tabular}
\end{table}

The role of mobile sensing in our crowd monitoring framework is to provide the real-time data about a mass gathering event. As mentioned in the previous chapter, the during event phase in emergency management requires real-time decision making, which requires continuously updated intelligence from the crowd monitoring system. The reason for this requirement is that, according to \citet{Berlonghi1995}, a particular crowd can change from one type to another type during the event. This dynamic nature of a crowd is the key factor that we want to address in our approach by integrating the mobile sensing as one of the sources of context data.

\subsection{Social Media}

Social media is another source of information that is capable of providing real-time data. In a related work, social media is considered as a special ``soft sensor'' in the mobile sensing techniques used in crowd monitoring \citep{Ramesh2014}. Social media is a generic term referring to a wide range of Internet-based tools that enable users to create and share content. These tools include social network sites, such as Twitter and Facebook, Internet forums and channels. Among those tools, Twitter is by far the most commonly utilized social media in research because of the huge volume of user base and the availability of the API which makes the data highly accessible.

Studies show that during emergency situation, there is significant use of social media to report about the incident. One of the most well known research is the potential of earthquake detection by Twitter by \citet{Sakaki2010}. In the context of crowd monitoring, \citet{DelirHaghighi2013} has also proposed an approach to analyse tweets and capture the bipolar crowd mood. This has proven the feasibility of probing the social media to detect emergency situation.

In our proposed framework, social media is also integrated as one of the input for contextual data. If mobile sensing mentioned in the previous section can be considered as a pro-active mechanism where data is continuously sampling and analysed to detect critical crowd condition, social media provides us a reactive channel where we can capture a crowd incident as soon as it is reported by the Internet user.

\section{Crowd Model}

The next layer in the crowd monitoring framework is the crowd model, which consists of a crowd typology and a set of crowd attributes for classification a crowd into a specific type.

\subsection{Comparison of different Crowd Models}
As mentioned in the literature review, there has been a very limited work on crowd modelling. From the perspective of emergency planning, Berlonghi's model is among the most widely adopted by emergency management bureaus worldwide \citep{FEMA2005, EMA1999}. Our literature also highlights several notable works in other disciplines that attempt to classify and describe different crowd types. Interestingly, in spite of having different disciplinary views, there are similarities and overlaps can be observed between those works and the model proposed by Berlonghi. Berlonghi has proposed the most number of crowd types and his eleven crowd types can be mapped into the crowd types mentioned in other studies and vice versa. Hence, in our approach, we will employ Berlonghi's model as the baseline to make distinction of different crowds.

Table \ref{table:crowdModelComparison} presents our chosen crowd types based on Berlonghi's work and compares each crowd type with the crowd types defined in the related works. From these related works, the definition and description of each crowd type are collected and gathered to construct a more detailed explanation of the crowd type.

\subsection{Crowd Types}
Explain each type
\begin{itemize}
\item Ambulatory crowd
\item Limited movement crowd
\item Crowd of spectators
\item Participatory crowd
\item Expressive crowd
\item Aggressive crowd
\item Crowd of demonstrator
\item Escaping crowd
\item Looting crowd
\item Rushing crowd
\item Violent crowd
\end{itemize}

\subsection{Crowd Attributes}
Explain why we need to add attribute. because the definition is not sufficient to classify. need human judgement. the need for a systematic approach.

Discuss each attribute
\begin{itemize}
\item Level of Density
\item Level of Movement
\item Crowd Activities
\item Motivating Emotions
\end{itemize}

Table showing the crowd type and the attributes

Among those attributes, we focus on the motivating emotions and discuss further in the subsections

\subsubsection{Human Basic Emotion}
List work on human basic emotions
8 emotions
6 emotions
4 emotions
\subsubsection{Emotion and Collective Behaviour}
\citet{Lofland1985} and \citet{Smelser1998} identify joy, fear and anger can motivate the formation of collective behaviour.

\subsubsection{Mapping from Emotions to Crowd Types}
Insert the table here

\subsubsection{Social Media Analysis and Emotion Capture}
By probing social media, we can capture the emotion

\section{Crowd Monitoring}


\haddockmoduleheading{ForSyDe.Atom.Skeleton}
\label{module:ForSyDe.Atom.Skeleton}
\haddockbeginheader
{\haddockverb\begin{verbatim}
module ForSyDe.Atom.Skeleton (
    Skeleton((=.=), (=*=), (=\=), (=<<=), first, last),  farm22,  reduce,
    reducei,  pipe,  pipe2
  ) where\end{verbatim}}
\haddockendheader

This module exports a type class with the interfaces for the
 Skeleton layer atoms. It does \emph{NOT} export any implementation of
 atoms not any constructor as composition of atoms.\par
\begin{mdframed}[style=reminder,frametitle=Reminder]Make sure to consult naming conventions in  \cref{sec:forsyde-atom:naming-convention} in order to interpret the names and type signatures correctly.\end{mdframed}\par

\subsection{Atoms}
\begin{haddockdesc}
\item[\begin{tabular}{@{}l}
class\ Functor\ c\ =>\ Skeleton\ c\ where
\end{tabular}]\haddockbegindoc
Class containing all the Skeleton layer atoms.\par
This class is instantiated by a set of categorical types,
 i.e. types which describe an inherent potential for being evaluated
 in parallel. Skeletons are patterns from this layer. When skeletons
 take as arguments entities from the MoC layer (i.e. processes), the
 results themselves are parallel process networks which describe
 systems with an inherent potential to be implemented on parallel
 platforms. All skeletons can be described as composition of the
 three atoms below (\haddockid{=<<=} being just a specific instantiation of
 \haddockid{={\char '134}=}). This possible due to an existing theorem in the categorical
 type theory, also called the Bird-Merteens formalism
 \cite{Bird97}:\par
\par
\begin{description}
\item[factorization] A function on a categorical type is an algorithmic
 skeleton (i.e. catamorphism) \emph{iff} it can be represented in a
 factorized form, i.e. as a \emph{map} composed with a \emph{reduce}.
\end{description}Consequently, most of the skeletons for the implemented categorical
 types are described in their factorized form, taking as arguments
 either:\par
                 \begin{itemize}
                 \item
                 type constructors or functions derived from type constructors\par

                 \item
                 processes, i.e. MoC layer entities\par

                 \end{itemize}
                 Most of the ground-work on algorithmic skeletons on which this
 module is founded has been laid in \cite{Bird97},
 \cite{Skillicorn05} and it founds many
 of the frameworks collected in \cite{Gorlatch03}.\par

\haddockpremethods{}\textbf{Methods}
\begin{haddockdesc}
\item[\begin{tabular}{@{}l}\haddockid{(=.=)}\ ::\ (a\ ->\ b)\ ->\ c\ a\ ->\ c\ b\ \end{tabular}]
\haddockbegindoc
Atom which maps a function on each element of a structure (i.e. categorical type), defined as:\haddockeq{fig/eqs-skel-atom-dot.pdf}\haddockid{=.=} together with \haddockid{=*=} form the map pattern.\par

\item[\begin{tabular}{@{}l}\haddockid{(=*=)}\ ::\ c\ (a\ ->\ b)\ ->\ c\ a\ ->\ c\ b\ \end{tabular}]
\haddockbegindoc
Atom which applies the functions contained by as structure (i.e. categorical type), on the elements of another structure, defined as:\haddockeq{fig/eqs-skel-atom-star.pdf}\haddockid{=.=} together with \haddockid{=*=} form the map pattern.\par

\item[\begin{tabular}{@{}l}\haddockid{(=\textbackslash=)}\ ::\ (a\ ->\ a\ ->\ a)\ ->\ c\ a\ ->\ a\ \end{tabular}]
\haddockbegindoc
Atom which reduces a structure to an element based on an \emph{associative} function, defined as:\haddockeq{fig/eqs-skel-atom-red.pdf}\par

\item[\begin{tabular}{@{}l}\haddockid{(=<<=)}\ \end{tabular}]
\haddockbegindoc
Skeleton which \emph{pipes} an element through all the functions contained by a structure. N.B.: this is not an atom. It has an implicit definition which might be augmented by instances of this class to include edge cases.\haddockeq{fig/eqs-skel-pattern-pipe.pdf}As the composition operation is not associative, we cannot treat pipe as a true reduction. Alas, it can still be exploited in parallel since it exposes another type of parallelism: time parallelism.\par

\item[\begin{tabular}{@{}l}\haddockid{first}\ ::\ c\ a\ ->\ a\ \end{tabular}]
\haddockbegindoc
Returns the first element in a structure.N.B.: this is not an atom. It has an implicit definition which might be replaced by instances of this class with a more efficient implementation.\haddockeq{fig/eqs-skel-pattern-first.pdf}\par

\item[\begin{tabular}{@{}l}\haddockid{last}\ ::\ c\ a\ ->\ a\ \end{tabular}]
\haddockbegindoc
Returns the last element in a structure.N.B.: this is not an atom. It has an implicit definition which might be replaced by instances of this class with a more efficient implementation.\haddockeq{fig/eqs-skel-pattern-last.pdf}\par

\end{haddockdesc}

\item[\begin{tabular}{@{}l}
instance\ Skeleton\ Vector
\end{tabular}]\haddockbegindoc
Ensures that \haddockid{Vector} is a structure associated with the Skeleton Layer.\par

\end{haddockdesc}

\subsection{Skeleton constructors}
Patterns of in the skeleton layer are provided, like all other
 patterns in ForSyDe-Atom, as constructors. If the layer below
 this one is the \haddockid{MoC} layer, i.e. the functions
 taken as arguments are processes, then these skeletons can be
 regarded as process network constructors, as the structures
 created are process networks with inherent potential for parallel
 implementation.\par

\begin{haddockdesc}
\item[\begin{tabular}{@{}l}
farm22\ ::\ Skeleton\ c\ =>\\\ \ \ \ \ \ \ \ \ \ (a1\ ->\ a2\ ->\ (b1,\ b2))\ ->\ c\ a1\ ->\ c\ a2\ ->\ (c\ b1,\ c\ b2)
\end{tabular}]\haddockbegindoc
\haddocktt{farm} maps a function on a vector. It is the embodiment of the
 \haddocktt{map} homomorphism, and its naming is inspired from the pattern
 predominant in HPC. Indeed, if we consider the layer below as being
 the \haddockid{MoC} layer (i.e. the passed functions are
 processes), the resulting structure could be regarded as a "farm of
 data-parallel processes".\par
Constructors: \haddocktt{farm{\char 91}1-8{\char 93}{\char 91}1-4{\char 93}}.\par
\haddockeq{fig/eqs-skel-pattern-farm.pdf}
 \haddockfig{fig/skel-pattern-farm.pdf}\par

\item[\begin{tabular}{@{}l}
reduce
\end{tabular}]\haddockbegindoc
\haddockbeginargs
\haddockdecltt{::} & Skeleton c \\
                     \haddockdecltt{=>} & \haddockdecltt{(a
                                                          -> a
                                                             -> a)} & associative function (*) \\
                                                                      \haddockdecltt{->} & \haddockdecltt{c a} & structure \\
                                                                                \haddockdecltt{->} & \haddockdecltt{a} & reduced element \\
\end{tabulary}\par
Infix name for the \haddockid{={\char '134}=} atom operator.\par
(*) if the operation is not associative then the network can be
 treated like a pipeline.\par

\item[\begin{tabular}{@{}l}
reducei
\end{tabular}]\haddockbegindoc
\haddockbeginargs
\haddockdecltt{::} & Skeleton c \\
                     \haddockdecltt{=>} & \haddockdecltt{(a
                                                          -> a
                                                             -> a)} & associative function (*) \\
                                                                      \haddockdecltt{->} & \haddockdecltt{a} & initial element of structure \\
                                                                                \haddockdecltt{->} & \haddockdecltt{c a} & structure \\
                                                                                \haddockdecltt{->} & \haddockdecltt{a} & reduced element \\
\end{tabulary}\par
\haddockid{reducei} is special case of \haddockid{reduce} where an initial element is
 specified outside the reduced vector. It is implemented as a
 \haddockid{pipe} with switched arguments, and the reduction function is
 constrained to be associative. It is semantically equivalent to the
 pattern depicted below.\par
(*) if the operation is not associative then the network is
 semantically equivalent to \haddocktt{pipe1} (see \haddockid{pipe2}).\par
\haddockeq{fig/eqs-skel-pattern-reducei.pdf}
 \haddockfig{fig/skel-pattern-reducei.pdf}\par

\item[\begin{tabular}{@{}l}
pipe
\end{tabular}]\haddockbegindoc
\haddockbeginargs
\haddockdecltt{::} & Skeleton c \\
                     \haddockdecltt{=>} & \haddockdecltt{c (a
                                                            -> a)} & vector of functions \\
                                                                     \haddockdecltt{->} & \haddockdecltt{a} & kernel element \\
                                                                                \haddockdecltt{->} & \haddockdecltt{a} & result  \\
\end{tabulary}\par
Infix name for the \haddockid{=<<=} skeleton operator.\par

\item[\begin{tabular}{@{}l}
pipe2\ ::\ Skeleton\ c\ =>\\\ \ \ \ \ \ \ \ \ (a1\ ->\ a2\ ->\ a\ ->\ a)\ ->\ c\ a1\ ->\ c\ a2\ ->\ a\ ->\ a
\end{tabular}]\haddockbegindoc
The \haddocktt{pipe} constructors are a more generic form of the \haddockid{=<<=}
 (\haddockid{pipe}) skeleton apt for successive partial application and create
 more robust parameterizable pipeline networks.\par
Constructors: \haddocktt{comb{\char 91}1-8{\char 93}}.\par
\haddockeq{fig/eqs-skel-pattern-pipe1.pdf}
 \haddockfig{fig/skel-pattern-pipe1.pdf}\par

\end{haddockdesc}


\section{Circuit Basics}
\input{Ch2/circuit_basics}

\section{Half and Full Adders}
\input{Ch2/adder}


\documentclass[paper-main.tex]{subfiles}

\begin{document}

A continuous gravitational-wave signal may wander slowly (and randomly) in frequency over time, due to stochastic internal processes in the superfluid interior of isolated neutron stars, or variable accretion from a stellar companion for neutron stars in binaries such as LMXBs (see Ref.~\cite{SuvorovaEtAl:2017} and references therein).
Although continuous gravitational waves are nearly monochromatic, the long observing times ($\sim 1\,{\rm yr}$) mean that searches can be impacted by very small frequency drifts.
A typical observation involves $1 \times 10^{10}$ wave cycles, and a coherent search must track the phase to better than half a cycle over the full observation.
Here we consider the audio analog of a tone that wanders in frequency.

A Fourier transform applied to the whole dataset (as in Section~\ref{sec:single_tone}) is not well suited to the wandering frequency case as the signal is spread across multiple frequency bins.
In continuous-wave searches, the wandering frequency problem is solved using the Viterbi algorithm,\cite{Viterbi:1967} which can track the signal's frequency over time.
The analysis described and presented in this section is directly inspired by real continuous-wave search methods,~\cite{SuvorovaEtAl:2017} yet is pitched at a level appropriate for an undergraduate laboratory setting.
In Section~\ref{sec:realCWSearches}, we briefly review the analysis method used by LIGO and Virgo; in Section~\ref{sec:viterbi}, we describe the methods as applied in this work; and in Section~\ref{sec:wanderingResults}, we show results for recovering a wandering frequency signal using the table-top interferometer.

\subsection{Continuous wave analysis with real data}
\label{sec:realCWSearches}

The methods used here are inspired by LIGO and Virgo continuous-wave searches.
For further details on these methods and continuous-wave searches, we refer the reader to the references in the Supplementary Material.

Continuous-wave searches are performed on long datasets, months to years in duration.
The frequency of the signal can wander significantly over the observation period.
In this context, ``significantly'' means across multiple frequency bins, where the typical width of a frequency bin is the reciprocal of the total observation time.\cite{JKS:1998,ScoX1O2Viterbi:2019}

A ``hidden Markov model'' can be used to search for continuous gravitational waves.\cite{SuvorovaEtAl:2017}
In a Markov process, the current state depends only on the previous state (in this case the ``state'' is the frequency of the signal).
In a hidden Markov model, the frequency state of the signal is unknown (hidden) and can undergo transitions at discrete times.
The transitions are Markovian in that the hidden state (i.e.\ frequency) of the system at any time depends solely on its state at the previous time.

A detection statistic relates the observed data to the hidden state and quantifies the likelihood of a signal being present in the data at each frequency and time bin.
This likelihood is also called the emission probability in gravitational-wave literature.
In gravitational-wave data analysis, the detection statistic gives the likelihood of a signal given the antenna beam pattern of the detector, which varies as the Earth rotates and orbits the Sun.\cite{JKS:1998}
When searching for continuous waves from a neutron star in a binary (such as an LMXB), the Doppler modulation of the source also needs to be taken into account and a different detection statistic is used.\cite{SuvorovaEtAl:2017}

In continuous-wave searches, a physical model of the target informs how far the frequency of the signal can wander over time.
This is called the transition probability matrix.
For example, in LMXB searches, the transition matrix allows the signal frequency to (i) stay in the same frequency bin, (ii) move up a single frequency bin, or (iii) move down a frequency bin in each time step.\cite{ScoX1O2Viterbi:2019}
In supernova remnant searches, source frequency is expected to decrease over time, therefore the allowable transitions are to (i) remain in the same frequency bin, or (ii) move down one frequency bin (see the Supplementary Material for LMXB and supernova remnant search references).

The Viterbi algorithm~\cite{Viterbi:1967} is used to find the most probable sequence of hidden frequency states given the sequence of observables.
In the next section, we describe our application of the Viterbi method and our choice of detection statistic.

\subsection{The hidden Markov model and Viterbi algorithm}
\label{sec:viterbi}

\begin{figure}
\begin{center}
\includegraphics[width=0.48\textwidth]{figures/viterbiDiagramSizes.pdf}
\caption{\label{fig:viterbi}
Schematic diagram of the Viterbi algorithm.
The circular nodes represent elements in a time-frequency grid, labeled $t_0$ to $t_{N_t}$ (left to right) in time and $f_0$ to $f_{N_f}$ (bottom to top) in frequency.
The size of the nodes represents the likelihood of a signal being present in each time-frequency element.
The small to large sizing corresponds to low to high likelihood values in arbitrary units for this schematic.
The objective is to find the most probable path of a signal through the grid from left to right.
All possible paths are shown by the lines.
The black lines show the best path to each node and the gray lines show rejected paths.
Some routes through the grid result in dead-ends with respect to optimally reaching the other side, such as the path ending at $t_1$ marked (a).
At $t=t_{N_t}$ the algorithm chooses the terminating frequency node which has the highest value given by Eqn.~\ref{eqn:pathprobability}, marked (b).
The Viterbi path is the path leading to this node, highlighted by the thick-black lines, from (b) to the start at (c).
}
\end{center}
\end{figure}

First, we split the timeseries data from the interferometer into segments.
Then, we take the discrete Fourier transform of each timeseries segment to form a grid in time and frequency (a spectrogram) with the Fourier amplitude $F(t_i,f_j)$ at frequency $f_j$ and time $t_i$, as the detection statistic (this is the emission probability).
Assuming Gaussian noise, this detection statistic maximizes the likelihood of detecting a sinusoidal signal as described in Appendix~\ref{app:sinusoid_likelihood}.
The detection statistic is normalized for convenience by dividing each value by the maximum Fourier amplitude in the grid (such that $\max_{i,j} F(t_i,f_j) = 1$).

Fig.~\ref{fig:viterbi} represents a spectrogram with $N_t$ time bins and $N_f$ frequency bins.
The circular nodes represent the elements of the time and frequency grid, which are labelled as
$t_i$ and $f_j$, respectively, where $i=0,1,2,\mathellipsis,N_t$ and $j=0,1,2,\mathellipsis,N_f$.
The shading of the nodes represents the detection statistic $F(t_i,f_j)$ (the observable) at each grid point, where dark corresponds to lower values and light to higher values.

The objective is to find the most likely path through the grid, given the observed data and any probabilistic constraints on how the frequency of the signal can wander from $t_i$ to $t_{i+1}$.
The transition probability matrix, $A(f_k,f_m)$, describes the probability of the system transitioning from state $f_k$ at $t_i$ to a state $f_{m}$ at $t_{i+1}$.
Here, we allow the frequency of the signal to either (i) stay in the same bin, (ii) move up by a single frequency bin, or (iii) move down by a single frequency bin at each transition.
We assign these three transitions equal probability, i.e.\ $A(f_k,f_m)=1/3$ for $k=m+1,m,m-1$ and $A(f_k,f_m)=0$ otherwise.
All possible transitions are shown as lines in Fig.~\ref{fig:viterbi}.
The different line colors are explained below.

Before we begin analyzing the data, we have no prior knowledge as to which frequency bin the signal starts in (i.e. the prior is flat between the minimum and maximum frequency bins).
At the first stage of the analysis, we define the probability of the system having frequency $f_j$ at the initial time $t_0$ to be equal to the (normalized) detection statistic of that state (i.e.\  ${\rm Pr}[f(t_0) = f_j] = F[t_0,f_j]$).
A specific path (which may not be optimal) is written as $f(t_0), f(t_1),\mathellipsis, f(t_n)$.
The probability of a specific path given the data is
\begin{eqnarray}
{\rm Pr}[ f(t_0), f(t_1),&&\mathellipsis, f(t_n) | {\rm data}] \nonumber\\
          && =F[t_n,f(t_n)] A[f(t_n),f(t_{n-1})] \nonumber \\
          && \times\mathellipsis\times A[f(t_1),f(t_0)] F[t_0,f(t_0)] \,.
\label{eqn:pathprobability}
\end{eqnarray}
The path $f^\ast(t_0),\mathellipsis,f^\ast(t_n)$ that maximises ${\rm Pr}[ f(t_0), f(t_1),\mathellipsis, f(t_n) | {\rm data}]$ is the optimal path terminating in the frequency bin $f^\ast(t_n)$.
We note that the left-hand-side and right-hand-side of Eqn.~\ref{eqn:pathprobability} are both evaluated for a specific path and then we maximize over all such paths to find the optimal Viterbi path.

The Viterbi algorithm provides a computationally efficient method for finding the optimal path.
At every $t_i$ all but $N_f$ possible paths are eliminated.
Here we describe the algorithm while referring to the schematic in Fig.~\ref{fig:viterbi}.
The implementation used in this work is available online (see Appendix~\ref{app:code}) and we provide further information (including pseudocode) in Appendix~\ref{app:viterbi}.
\begin{enumerate}
\item Starting at time $t_1$, each $f_j$ node (circles in Fig~\ref{fig:viterbi}) can originate from three prior nodes at time $t_0$ (except for the edge cases $f_0$ and $f_{N_f}$ which only have two).
The paths between these nodes are indicated by the lines in Fig.~\ref{fig:viterbi}.
At each $f_j$ node, we select the path with the highest $A[f(t_0),f(t_1)] {\rm Pr}[f(t_0)]$ value as the most probable path.
These choices are highlighted using the black lines in Fig.~\ref{fig:viterbi} while the gray lines show the rejected paths.
For example, the most probable connection to the node labeled (a) is the one directly behind it (i.e., $f_4$).
Therefore, this path is selected as the best path from $t_0$ to $t_1$ for $f_4$.
To allow backtracking at the end, the index of the most probable connection to a node along with the value of the best path to that node is stored, for each node.

\item Moving to time $t_2$, again we select the path which maximizes Eqn.~\ref{eqn:pathprobability} for each $f_j$.
These paths are again shown by the solid black lines between the nodes at $t_1$ and $t_2$ in Fig.~\ref{fig:viterbi}.
Rejected paths are again shown by gray lines.

\item Step 2 is repeated until the end of the grid ($t=t_{N_t}$) is reached with only the best paths being stored at each iteration.

\item We have now found the most probable path to each $f_j$ at $t=t_{N_t}$ and its probability (Eqn.~\ref{eqn:pathprobability}).
We select the terminating frequency bin $f(t_{N_t})$ with the highest probability labeled as (b) in Fig.~\ref{fig:viterbi}.

\item The final step is to find the Viterbi path (the overall best path that terminates in the frequency bin with the highest probability in step 4).
The Viterbi path is found by backtracking along the stored best connections at each $t_i$ (see also Appendix~\ref{app:viterbi}).
In Fig.~\ref{fig:viterbi}, it is the path ending at (b) that started at (c) highlighted by the thick-black lines.
\end{enumerate}

In continuous gravitational wave searches, the signal amplitude is expected to be small in comparison to the noise and its frequency can change unpredictably over time. % how to hyphenate ``continuous gravitational wave searches''?
The Viterbi algorithm's strength lies in its ability to track such signals through the data even in the presence of comparatively loud noise fluctuations in the time-frequency bins.
In the following section, we present the results of using the Viterbi algorithm with the table-top interferometer data.

\subsection{Wandering frequency signal results}
\label{sec:wanderingResults}

\begin{figure*}
	\includegraphics[width=\textwidth]{figures/expt_overlay_2_viterbi_test_webcam.pdf}
	\caption{\label{fig:viterbi_overlay}
Recovery of a wandering tone using the Viterbi algorithm.
The spectrogram (heat-map) coloring indicates the value of the detection statistic (here, the logarithm of the absolute value of the discrete Fourier transform) in each time-frequency bin -- with brighter colors indicating higher values.
The overlaid pink-dot and white-cross markers show the injected signal and recovered Viterbi path, respectively.
On the left, before $\sim 15\,{\rm s}$, the signal changes frequency too quickly for the Viterbi algorithm to recover, given that the algorithm is restricted to only change by one frequency bin per time bin.
At $150\,{\rm s}$, the data appears anomalous, which may be due to some transient background noise. }
\end{figure*}

We simulate a slowly wandering signal by modulating the frequency sinusoidally with a modulation amplitude that decays with time.
We use the same apparatus as shown in Fig.~\ref{fig:ifo_schematic_webcam} and the output interference pattern is recorded via webcam as in Section~\ref{sec:single_tone}.
In this section, we test the Viterbi algorithm’s ability to recover the wandering signal.
Note that we implicitly approximate the noise at the webcam as white (uniform in frequency) in this implementation of the Viterbi algorithm.
This approximation ignores the increase in noise at low frequencies (below 1~Hz) shown in Fig.~\ref{fig:webcam_spectrum}.
However, white noise is a reasonable approximation for the narrow frequency range (around $3$--$11\,{\rm Hz}$) we use in this analysis.

The results are shown in Fig.~\ref{fig:viterbi_overlay}, where the heat-map shows the spectrogram of the observed signal (similar to that represented by the schematic in Fig.~\ref{fig:viterbi}).
In this demonstration we use a signal that can easily be identified in the spectrogram; however, we expect real continuous-wave signals to have far lower signal-to-noise ratios at each time step.
The overlaid pink dots in Fig.~\ref{fig:viterbi_overlay} show the injected signal and the white crosses show the recovered Viterbi path.
The recovered Viterbi path is within one frequency bin ($\sim 0.3\,{\rm Hz}$) of the injected signal for $94\%$ of the time. We also compute the root-mean-square (RMS) fractional error $E_{\rm rms}$ along the path, which is defined as
\begin{equation}
E_{\rm rms} = \left[ \frac{1}{N_t+1} \sum_{i=0}^{N_t} \frac{(I_i - R_i)^2}{{I_i}^2} \right] ^{1/2}\,,
\end{equation}
where $I_i$ and $R_i$ are the injected and recovered (Viterbi) frequencies at time $t_i$, respectively.
For the result shown in Fig.~\ref{fig:viterbi_overlay}, we find that $E_{\rm rms} = 0.082$, which indicates fair but not total recovery of the injected signal.

This may be explained by two anomalies in the recovered path. Initially, the injected signal wanders by more than one frequency bin per time bin (i.e.\ faster than our choice of $A(f_k,f_m)$ allows), thus leading to a discrepancy between the injected and recovered paths for $t\lesssim 10\,{\rm s}$.
If we remove the first four time bins from the $E_{\rm rms}$ calculation, we find a slight improvement in recovery with $E_{\rm rms} = 0.044$.
One may be tempted to increase the allowed frequency wander in the algorithm; however, this leads to an overall decrease in the above statistics, as the algorithm is prone to jump briefly to nearby spots of noise.
There is also an anomaly at $150\,{\rm s}$, which is likely due to a local disturbance, e.g. someone walking past the interferometer.
As shown in Fig.~\ref{fig:viterbi_overlay}, the Viterbi algorithm can recover and continue to track the signal after the disturbance.

\end{document}


% Copyright © 2017 Eric Griffis <dedbox@gmail.com>
%
% This software may be modified and distributed under the terms of the MIT
% license. See the LICENSE file for details.

\chapter{Formal semantics}

\newcommand\newId[2]{\newcommand{#1}{\ensuremath{{\tt #2}}}}

\newenvironment{Grammar}
{
  \begin{tabular*}{\linewidth}{
    >{$}l<{$}
    >{$}c<{$}
    >{$}l<{$}
    @{\extracolsep{\fill}}
    r}
}{
  \end{tabular*}
}

\newcommand\OR{\ensuremath{~\big|~}}

\newId{\Start}{start}
\newId{\Wait}{wait}
\newId{\Stop}{stop}
\newId{\Kill}{kill}
\newId{\Quit}{quit}
\newId{\Die}{die}
\newId{\Yield}{yield}
\newId{\Filter}{filter}
\newId{\Give}{give}
\newId{\Take}{take}
\newId{\Emit}{emit}
\newId{\Recv}{recv}
\newId{\Commanded}{commanded}
\newId{\Command}{command}
\newId{\Bind}{bind}
\newId{\Codec}{codec}
\newId{\Encode}{encode}
\newId{\Decode}{decode}
\newId{\Serve}{serve}
\newId{\Connect}{connect}

\begin{center}
  \begin{Grammar}
    t
    &::=& \Start~t~t~t \OR \Wait~t \OR \Stop~t \OR \Kill~t \OR \Quit \OR \Die \OR \Yield \OR & concurrent \\
    &   & \Filter~t~t~t \OR \Give~t~t \OR \Take \OR \Emit~t \OR \Recv~t \OR & message \\
    &   & \Commanded~t~t \OR \Command~t~t \OR \Bind~t \OR & processing \\
    &   & \Codec~t~t \OR \Encode~t~t \OR \Decode~t~t \OR & serial \\
    &   & \Serve~t~t~t \OR \Connect~t~t & communication \\[1ex]
    v
    &::=& \pi \OR a \\
  \end{Grammar}
\end{center}

\subsection*{Concurrency}

%\Pi, \Phi, \Sigma, \Gamma, \Delta |- \Process~t_1~t_2~t_3

\begin{mathpar}
  \Pi = \{\pi_i |-> (t_{start}, t_{stop}, t_{die})\}_{i < \Len{\Pi}}
\end{mathpar}

\begin{mathpar}
  \Infer[Start]{
    \text{choose } \pi \notin \Dom(\Pi)
  }{
    \Pi, \pi_0 |- \Start~t_1~t_2~t_3 --> [\pi |-> (t_1, t_2, t_3)]\Pi, \pi_0 |- \pi
  }

  \Infer[End]{
    \Pi(\pi_0) = (v_1, t_2, t_3) \\
    t_2 \ne \Void
  }{
    \Pi, \pi_0 |- v_1 --> \Pi, \pi_0 |- \Quit
  }

  \Infer[Quit]{
    \Pi(\pi_0) = (\Quit, t_2, t_3)
  }{
    \Pi, \pi_0 |- \Quit --> [\pi_0 |-> (t_2, \Void, t_3)]\Pi, \pi_0 |- t_2
  }

  \Infer[Quited]{
    \Pi(\pi_0) = (v_1, \Void, t_3) \\
    t_3 \ne \Void
  }{
    \Pi, \pi_0 |- v_1 --> \Pi, \pi_0 |- \Die
  }

  \Infer[Die]{
    \Pi(\pi_0) = (\Die, \cdot, t_3)
  }{
    \Pi, \pi_0 |- \Die --> [\pi_0 |-> (t_3, \Void, \Void)]\Pi, \pi_0 |- t_3
  }

  \Infer[Died]{
    \Pi(\pi_k) = (v_{1k}, \Void, \Void) \\\\
    \Pi(\pi_j) = (t_{1j}, \Any, \Any) \\
    \pi_j \ne \pi_k
  }{
    \Pi, \pi_k |- v_{1k} --> \Pi \setminus \pi_k, \pi_j |- t_{1j}
  }

  \Infer[Yield]{
    \Pi(\pi_j) = (t_{1j}, \Any, \Any) \\
    \pi_j \ne \pi_k
  }{
    \Pi, \pi_k |- \Yield --> \Pi, \pi_j |- t_{1j}
  }

  \Infer[Wait]{
    \pi \in \Dom(\Pi)
  }{
    \Pi, \pi_0 |- \Wait~\pi --> \Pi, \pi_0 |- \Wait~\pi
  }

  \Infer[Waited]{
    \pi \notin \Dom(\Pi)
  }{
    \Pi, \pi_0 |- \Wait~\pi --> \Pi, \pi_0 |- \Void
  }

  \Infer[Stop]{
    \Pi(\pi) = (\Any, t_2, t_3)
  }{
    \Pi, \pi_0 |- \Stop~\pi --> [\pi |-> (\Quit, t_2, t_3)]\Pi, \pi_0 |- \Wait~\pi
  }

  \Infer[Kill]{
    \Pi(\pi) = (\Any, \Any, t_3)
  }{
    \Pi, \pi_0 |- \Kill~\pi --> [\pi |-> (\Die, \Void, t_3)]\Pi, \pi_0 |- \Wait~\pi
  }
\end{mathpar}

%%% Local Variables:
%%% TeX-master: "master"
%%% End:


\section{Coursework}

\denseouterlist{
\entrylabeled[--]{\textbf{CFD}: Computational Fluid Dynamics \& Heat Transfer, Computational Methods for Viscous Flows, Reduced Order Models for Fluids}
\entrylabeled[--]{\textbf{Math}: Perturbations, Advanced Dynamics, Chaos \& Nonlinear Dynamics, Mathematical Fluid Dynamics, Complex Analysis, Partial Differential Equations}
\entrylabeled[--]{\textbf{Fluids}: Ideal Flow, Turbulence, Applied Fluid Mechanics, Continuum Mechanics, Science Guided Machine Learning}
}


\section{Action}


%
% CMPT 454: Database Systems II - A Course Overview
% Section: Indexed File Structure
%
% Author: Jeffrey Leung
%

\section{Indexed File Structure}
	\label{sec:indexing}

\subsection{Introduction}
	\label{subsec:indexing-introduction}
\begin{easylist}

& \textbf{Indexed file structure:} File organization structure where records are organized and searchable by certain configured search keys
	&& Designed to be efficient for value-based searches

& Structure of an index:

	&& \textbf{Search key:} Field(s) on which a file/record is organized for searchability
		&&& Not guaranteed to be unique
		&&& Creating an index associates each record with a corresponding search key
		&&& \textbf{Composite search key:} Search key composed of multiple fields
			&&&& Sorting by a composite key sorts by its fields in order

	&& \textbf{Data entry:} Single search key and IDs of all records which contain/match it
		&&& Notation: Given search key value $k$, the index emits a set of data entries $k*$
		&&& Always sorted by the search key $k$
		&&& Possible formats:
			&&&& $\langle k \textrm{, data record} \rangle$
				&&&&& DB cannot have any other indices
			&&&& $\langle k \textrm{, RID} \rangle$
			&&&& $\langle k \textrm{, list of RIDs} \rangle$

\end{easylist}
\subsection{Types of Indices}
	\label{subsec:types-of-indices}
\begin{easylist}

& Methods of indexing:
	&& \textbf{Sorted file structure:} Indexed file structure where records are sorted by search key (generally using a tree)
		&&& Efficient for equality/range searches

	&& \textbf{Hashed file structure:} Indexed file structure where records are grouped in buckets by a hashed search key
		&&& Efficient for equality searches
		&&& Types: Static hashing, extendible hashing, linear hashing

& \textbf{Unique index:} Index format where the search key contains a candidate key
	&& \textbf{(Candidate) Key:} Set of fields which uniquely defines a record
	&& I.e. Searching the index using a candidate key returns either 0 or 1 result

& \textbf{Clustered index:} Index for which the data records are sorted by $k$ (in addition to the data entries sorted by $k$)
	&& Maximum of 1 clustered index per file
	&& Records are sequential on the page, though the pages may have pointers to the next page rather than be sequential
	&& Diagram: See figure~\ref{img:clustered-index}

	\begin{figure}[!htb]
		\centering
		\includegraphics[width=.8\linewidth]{indexed-file-structure/clustered-index}
		\caption{A clustered index and its records}
		\label{img:clustered-index}
	\end{figure}

	&& \textit{Unclustered index:} Index for which the data records are not sorted by $k$
		&&& Diagram: See figure~\ref{img:unclustered-index}

		\begin{figure}[!htb]
			\centering
			\includegraphics[width=.8\linewidth]{indexed-file-structure/unclustered-index}
			\caption{An un clustered index and its records}
			\label{img:unclustered-index}
		\end{figure}

	&& Data entry format $\langle k \textrm{, data record} \rangle$ is always clustered by the single index
	&& Search process for a given data range in a clustered index:
		&&& Use the data entry to find the page with the first value to read
		&&& Read through all data records in order until reaching a value greater than the end

& \textbf{Dense index:} Index where, for every search key $k$, there are one or more data entries $k*$
	&& Data entry format $\langle k \textrm{, data record} \rangle$ is always dense
	&& \textbf{Sparse index:} Index where there is at least one search key $k$ which does not map to any data entries
		&&& In a sparse index, data entries are always clustered for efficient scanning

\clearpage
\end{easylist}
\subsection{Tree-Structured Indexes}
	\label{subsec:tree-structured-indexes}
\begin{easylist}

& \textbf{Index search tree:} Search structure where index pages branch out to primary leaf pages which contain data entries
	&& Root and index pages consist of splitting keys and ordered pointers to trees containing values greater/less than the splitting keys
	&& Common components:
		&&& \textbf{Index pages:} Index search tree node which contains pivots for the search key values and pointers to index/leaf pages
			&&&& Does not directly contain data entries
			&&&& \textbf{Splitting key:} Index page value which acts as a pivot value for partitioned subtrees
			&&&& Root: Top node of an index search tree which contains a single pivot value and pointers to index pages
		&&& \textbf{Primary leaf page:} Index search tree leaf node which contains a set of data entries with pointers to data records
			&&&& Will not be deallocated even if empty

\clearpage
\end{easylist}
\subsubsection{ISAM Trees}
	\label{subsubsec:isam-trees}
\begin{easylist}

& \textbf{Indexed sequential access method (ISAM):} Index search tree where index pages are static and leaf pages contain optional overflow pages
	&& \textbf{Overflow page:} Linked list starting from a primary leaf page, which contains additional search key values
		&&& Allocated/deallocated as required; all other nodes in the tree are not affected during insert/delete operations
		&&& Can degrade performance

& Diagram: See figure~\ref{img:isam-tree}

\begin{figure}[!htb]
	\centering
	\includegraphics[width=.8\linewidth]{indexed-file-structure/isam-tree}
	\caption{An ISAM Tree}
	\label{img:isam-tree}
\end{figure}

& Search process:
	&& Follow the search from the root through the index pages to the matching primary leaf page
	&& Search the leaf page
	&& Search any linked overflow pages until a result is found
& Rebalanced during system maintenance

\clearpage
\end{easylist}
\subsubsection{B+ Trees}
	\label{subsubsec:b+-trees}
\begin{easylist}

& \textbf{B+ tree:} Index search tree which dynamically rebalances nodes and children during operation

& Diagram: See figure~\ref{img:bplus-tree}

\begin{figure}[!htb]
	\centering
	\includegraphics[width=.8\linewidth]{indexed-file-structure/bplus-tree}
	\caption{A B+ Tree}
	\label{img:bplus-tree}
\end{figure}

& \textbf{Order:} Minimum and maximum splitting key capacity of a B+ tree (which can differ for index and leaf nodes)
	&& Denoted by $d$
	&& Each B+ tree node must have between $d$ and $2d$ search keys (inclusive), except for the root (minimum 1)
	&& \textit{Fanout:} Branching factor of a B+ tree
		&&& Denoted by $F$
		&&& Fanout of root: $2$ to $2d+1$
		&&& Fanout of index nodes: $d+1$ to $2d+1$
		&&& Fanout of leaf nodes: $d$ to $2d$

& Ensures insert/delete/search operations are $\log_{F} N$ where $N = $ number of leaf nodes

& Operations:
	&& \textbf{Copying up:} B+ tree operation where a search key in a leaf is copied to the parent index node
		&&& Used when splitting a leaf in two

	&& \textbf{Pushing up:} B+ tree operation where a splitting key in an index node is moved to the parent index node, and removed from the original
		&&& Used when splitting an index node in two

	&& Insertion into a full leaf node:
		&&& Split leaf $L$ into two nodes, $L$ and $L2$
		&&& Redistribute entries evenly
		&&& Copy up the middle key to the parent to create a new partition
		&&& Link $L2$ to the parent
		&&& If the parent index node is not being split, the process is repeated recursively but with pushing-up instead of copying-up

	&& Deletion:
		&&& Search for and remove the entry
		&&& If the leaf node which contained the entry has only $d-1$ entries remaining:
			&&&& If the sibling node has more than $d-1$ entries, then re-balance entries with the sibling so both have at least $d-1$ entries
			&&&& Else, merge the node and its sibling (with $d$ entries) to create a node of $2d-1$ entries
				&&&&& Delete the key pointing to the deleted leaf node
				&&&&& Propagate merge upwards recursively

	&& \textbf{Bulk loading:} Initialization of a B+ tree with a number of records, which avoids constant rebalancing through standard insertion
		&&& Process:
			&&&& Sort data entries by search key
			&&&& Allocate data entries on the disk
			&&&& Create parent nodes for data entry leaf pages from left to right
			&&&& If the parent of the current index node has more slots available, split index nodes into siblings
			&&&& If the parent of the current index node has no slots available, split the parent node

\clearpage
\end{easylist}
\subsection{Hash-Based Indices}
	\label{subsec:hash-based-indices}
\begin{easylist}

& \textbf{Hash-based index:} Search structure where primary pages, each identified by a hashed search key, point to data entry pages
	&& Optimized for equality search; does not support range search
	&& Vulnerable to skewed hash distributions

& Common components:
	&& Hash function: Function which hashes a search key to a value
		&&& Denoted by $h(k)$ for a given data entry with search key $k$
		&&& Bucket to store the entry is chosen from $N$ buckets by calculating $h(k) \textrm{ mod } N$
	&& \textbf{Primary (bucket) page:} Hash-based index page identified by a hashed search key and containing/linking to a bucket with data entries
		&&& Always allocated sequentially for speed of access
	&& \textbf{Directory:} Collection of primary pages
		&&& Not in all types of hash indices
	&& \textbf{Overflow page:} Hash index page containing data entries, linked to from a primary page
		&&& Not in all types of hash indices
		&&& Allocated and de-allocated as required

\clearpage
\end{easylist}
\subsubsection{Static Hashing}
	\label{subsubsec:static-hashing}
\begin{easylist}

& \textbf{Static hashing:} Hash-based index method where the primary pages are never modified or deallocated
	&& Uses overflow pages to hold additional data entries
		&&& May create overflow chains when there are too many records, or hashes skew towards several values

& Diagram: See figure~\ref{img:static-hashing}
\begin{figure}[!htb]
	\centering
	\includegraphics[width=.8\linewidth]{indexed-file-structure/static-hashing}
	\caption{A Static Hash Index}
	\label{img:static-hashing}
\end{figure}

\clearpage
\end{easylist}
\subsubsection{Extendible Hashing}
	\label{subsubsec:extendible-hashing}
\begin{easylist}

& \textbf{Extendible hashing:} Hash-based index method which splits overflowing buckets and dynamically increases the directory
	&& Does not use overflow pages
	&& When a bucket overflows, its contents are split into a new bucket which is added to the directory
	&& Requires accessing a directory page to look up an entry page
	&& Bucket access is approximately 1.2 page accesses amortized (due to overflows)

& \textbf{Global depth:} Value on an extendible hashing directory which tracks the number of bits in the current directory size
& \textbf{Local depth:} Value on an extendible hashing bucket which (approximately) tracks the number of buckets matching the same hash
	&& If local depth is less than global depth, then the bucket can be split without increasing directory size
	&& If local depth equals the global depth, then splitting the bucket will require doubling the directory

& Diagram: See figure~\ref{img:extendible-hashing}

\begin{figure}[!htb]
	\centering
	\includegraphics[width=.8\linewidth]{indexed-file-structure/extendible-hashing}
	\caption{An Extendible Hash Index}
	\label{img:extendible-hashing}
\end{figure}

\clearpage
& Operations:

	&& Insertion:
		&&& When a bucket overflows, split its contents into a new bucket of the same hash
		&&& Increment the local depth of both buckets
		&&& If the directory has no space for a new bucket of the same hash (i.e. the global depth is less than the new local depth), the directory is increased to accommodate hashing the new bucket:
			&&&& Double the directory (adding a new leftmost bit to the directory index)
			&&&& Increment the global depth
			&&&& Point the newly created directory indices to the existing buckets with the same hash values
		&&& Link the new duplicate hash value in the directory to the new bucket

		&&& Diagram: See figure~\ref{img:extendible-hashing-splitting}
		\begin{figure}[!htb]
			\centering
			\includegraphics[width=.8\linewidth]{indexed-file-structure/extendible-hashing-splitting}
			\caption{Splitting an Extendible Hash Bucket}
			\label{img:extendible-hashing-splitting}
		\end{figure}

	&& Deletion:
		&&& Remove the data entry from the corresponding bucket
		&&& If the bucket has no more entries, deallocate it and point the key in the directory to the matching bucket
		&&& If half or more of the buckets of all hashes are empty/deallocated, the directory can be halved

\clearpage
\end{easylist}
\subsubsection{Linear Hashing}
	\label{subsubsec:linear-hashing}
\begin{easylist}

& \textbf{Linear hashing:} Hash-based index method which uses overflow pages, splits buckets using a round-robin strategy, and dynamically doubles the buckets
	&& Has no directory; does not require directory page lookup before accessing an entry page
	&& Splits a bucket into two (chosen by round-robin strategy) whenever any overflow page is created
		&&& Every bucket is kept split evenly, rather than focusing on splitting heavy-use buckets
	&& Bucket access is approximately 1.2 page accesses amortized (due to overflows)

& Components:

	&& \textbf{Overflow page (linear hashing):} Data bucket which holds additional data entries matching the index, which have not yet been split into new buckets

	&& Uses two hash algorithms at any given time; when the buckets are doubled, the old one is discarded and a new hash algorithm is added

	&& \textbf{Level:} Index of the hash algorithms currently being used, and the number of times the buckets have been doubled
		&&& Begins at 0; increments without limit
		&&& Hash algorithm of a certain level $x$ is denoted by $h_x$

	&& \textbf{Next:} Beginning index of buckets in a linear hashing index which have not yet been split
		&&& Begins at 0; increments when a bucket is split; reset to 0 after splitting all buckets once
		&&& All buckets before \textrm{next} have been split in the current round-robin implementation
			&&&& All buckets after or including \textrm{next} have not yet been split in the current round-robin implementation

& Diagram: See figure~\ref{img:linear-hashing}
\begin{figure}[!htb]
	\centering
	\includegraphics[width=.8\linewidth]{indexed-file-structure/linear-hashing}
	\caption{A Linear Hash Index}
	\label{img:linear-hashing}
\end{figure}

& Operations:

	&& Search:
		&&& Use $h_\textrm{level}$ to find the index of the bucket where the value belongs
			&&&& If the index is less than \textrm{next}, the search key belongs in the index found by $h_\textrm{level+1}$ (as the bucket has been split)
			&&&& If the index is greater than or equal to \textrm{next}, the search key belongs in this (as the bucket has not yet been split)
		&&& Search the selected bucket and any linked overflow pages

	&& Insertion:
		&&& Apply the search process above to find the bucket to insert the data entry
		&&& Add the value to the bucket, creating an overflow page if necessary

		&&& If an overflow page is created:
			&&&& Split the bucket at index \textrm{next}
			&&&& Index the new bucket at the bottom of the others
			&&&& Use $h_\textrm{level+1}$ to redistribute the values between the old and new buckets
			&&&& Increment \textrm{next}

		&&& If \textrm{next} has looped through all buckets once (not including the newly split buckets):
			&&&& Discard hash algorithm $h_\textrm{level}$
			&&&& Increment \textrm{level}
			&&&& Create a new hash algorithm $h_\textrm{level+1}$
			&&&& Reset \textrm{next} to 0

\end{easylist}
\clearpage


\chapter{Introduction}

In recent years, the interface between neuroscience and machine learning has been an active area of research. By combining large amounts of neuroscientific data with recent advances in machine learning, interesting insights into the human brain have been obtained \cite{neuro_ml, amoroso_multiplex_age, amoroso_multiplex_ad}. Another fruitful approach has been to apply the framework of graph theory in neuroscience, where the human brain is represented as a graph, and analysed using graph theoretic techniques \cite{chan, braph}. In this project, we have combined these approaches by applying graph-based machine learning models on neuroscientific data in order to understand healthy ageing, and differences between sexes, in the human brain. The motivation for this study is twofold; generally, to understand how the human brain potentially differs with age and sex, but also specifically since understanding the healthy ageing of the human brain may aid in identifying unhealthy ageing, perhaps due to underlying neurodegenerative disease \cite{kaufmann}.

\section{Neuroscience of human brain connectivity}

The human brain can be analysed by studying how the connections between various parts of the brain differ with sex and age. These connections can either be structural or functional. Structural connections refer to different parts of the brain being anatomically connected, whilst functional connections are slightly more abstract in that two brain regions are considered connected if their activation is correlated in time \cite{sporns}. The structural connections of the brain can be obtained through methods such as \acrshort{mri} and \acrshort{dti}, whereas functional connections are studied through functional-\acrshort{mri} (\acrshort{fmri}), \acrshort{pet}, \acrshort{eeg} and \acrshort{meg} \cite{hirsch}. Mapping these connections throughout the brain yield structural and functional brain networks, respectively. The functional networks can further be grouped together to form specialised networks. The largest of these is the default-mode network, which is primarily active when the brain experiences no external stimuli and for example considered to be responsible for mind wandering \cite{alves_dmn}.

Functional brain networks can be derived from either task-specific or resting-state \acrshort{fmri} (\acrshort{rs-fmri}), depending on the state of the subject when the measurement is carried out. Task-specific networks are mapped whilst the subject is engaged in some activity, for instance memory tasks \cite{grady}. In contrast, resting-state functional networks are mapped when the subject is not exposed to any external stimuli, i.e., is in a resting state. In Biswal et. al. \cite{biswal}, it was observed that such resting-state functional networks are affected by sex and age, and that these effects where observed to be consistent across a large group of subjects.

\section{Machine learning and graph theory in neuroscience}

One possible framework for analysing functional brain networks is graph theory. The networks are interpreted as graphs, and properties of these graphs can then be extracted using graph measures. This approach has previously been applied on functional brain networks with promising results. In Chan et al. \cite{chan}, graph measures where used to analyse the functional connections between various specialised brain networks, with the graph theoretical measure of segregation among the specialised networks being correlated to ageing. However, there still exists a need for more complex analysis to further understand the functioning of the human brain with regards to age and sex. For instance, it has been observed that patients suffering from neurodegenerative diseases such as dementia exhibit gaps in their estimated brain age compared to their actual age \cite{kaufmann}. Thus, if one could develop efficient methodologies for estimating brain age, such methods could be used to identify and analyse unhealthy ageing due to underlying neurodegenerative disease.

Inspired by recent advances in machine learning, \acrlong{ann}s (\acrshort{ann}) have previously been utilised to obtain accurate and complex models for predicting sex and brain age \cite{amoroso_multiplex_age, stankeviciute, arslan}. \acrshort{ann}s typically excel at finding complex patterns in large data sets. However, classical \acrshort{ann}s are heavily dependent on the input data forming ordered tensors. This is not the case for graph structured data, since graphs by definition are node order invariant. Thus, if one wants to combine \acrshort{ann}s with the promising approach of analysing functional brain networks as graphs, one could turn to a class of \acrshort{ann}s known as \acrlong{gnn}s (\acrshort{gnn}) which operate directly on the graph structure. \acrlong{gcn}s (\acrshort{gcn}) are a subclass of \acrshort{gnn}s which generalise the concept of convolutions to the graph domain. \acrshort{gcn}s have shown promising results when applied to graph data in general \cite{kipf_semi_supervised, kipf_vae, wu_review}, and specifically for the task of predicting neurodegenerative disease in human brains based on graphs derived from structural-MRI data \cite{jansson_sandstrom}. Motivated by these results, \acrshort{gcn}s applied on large \acrshort{fmri} data sets could be used to develop accurate models for predicting sex and brain age, which in turn could be analysed to gain further insight into the functioning of the human brain.

% \todo{Få in explainable AI -- från att analysera vad nätverken lär sig får vi in explainable AI.}

\section{Aim of the project}
The aim of this thesis is to investigate which resting-state functional brain networks are important for age and sex prediction. To this end, machine learning models based on GCNs are developed and analysed using saliency mapping techniques. A saliency map determines the importance of, for instance, individual pixels in an image or nodes in a graph, and will in this thesis reveal which functional brain networks are important for the predictions.

\subsection{Demarcations}
Since both neuroscience and machine learning are two large and active fields of research, some demarcations must be set for this thesis. Regarding the data to be analysed, one such demarcation is that only \acrshort{rs-fmri} data will be investigated, which is a delimitation both in the sense that task-specific \acrshort{fmri} will not be included, but also that other data modalities such as \acrshort{mri} will not be utilised. Another demarcation is that in the data used in this thesis, the connections defined by correlations from the \acrshort{fmri} scans are aggregated into graphs with 21 connected nodes, where each node represents a smaller functional network of brain regions. This is a delimitation since using data with other dimensionalities could perhaps be beneificial.

A demarcation regarding the machine learning is that only models based on \acrshort{gcn}s, with the exception of a baseline model for comparison, will be considered. There exist other types of models and architectures that could be investigated for the aim of the thesis. For instance other GNNs, including \acrlong{gat}s (\acrshort{gat}) \cite{gat} and \acrlong{gin}s (\acrshort{gin}) \cite{gin}. More generally, one could also  study the usage of other kinds of machine learning models such as \acrlong{svm}s (\acrshort{svm}) \cite{neuro_ml}.

\section{Structure of the report}
The first chapter will include an overview of general graph theory and \acrlong{gcn}s, as well as the theoretical foundation for a saliency mapping technique. In the second chapter, all models used in the thesis will be presented, together with other necessary methods that have been developed, for instance to preprocess the data and be able to train the networks. Thereafter, the results will be presented, including model performance and saliency maps. Lastly, the thesis will be concluded with a discussion, conclusion and outlook.


    \filetitle{zerodb}{Create model-specific zero-deviation database}{model/zerodb}

	\paragraph{Syntax}\label{syntax}

\begin{verbatim}
[D,IsDev] = zerodb(M,Range)
[D,IsDev] = zerodb(M,Range,NCol)
\end{verbatim}

\paragraph{Input arguments}\label{input-arguments}

\begin{itemize}
\item
  \texttt{M} {[} model {]} - Model object for which the zero database
  will be created.
\item
  \texttt{Range} {[} numeric {]} - Intended simulation range; the zero
  database will be created on a range that also automatically includes
  all the necessary lags.
\item
  \texttt{NCol} {[} numeric {]} - Number of columns for each variable;
  the input argument \texttt{NCol} can be only used on models with one
  parameterisation.
\end{itemize}

\paragraph{Output arguments}\label{output-arguments}

\begin{itemize}
\item
  \texttt{D} {[} struct {]} - Database with a tseries object filled with
  zeros for each linearised variable, a tseries object filled with ones
  for each log-linearised variables, and a scalar or vector of the
  currently assigned values for each model parameter.
\item
  \texttt{IsDev} {[} \texttt{true} {]} - The second output argument is
  always \texttt{true}, and can be used to set the option
  \texttt{'deviation='} in
  \href{model/simulate}{\texttt{model/simulate}}.
\end{itemize}

\paragraph{Description}\label{description}

\paragraph{Example}\label{example}


\chapter{Algebraic Loops}
\label{chp:algebraicLoop}

\Fref{fig:blockDiagramAlgLoop} which is causing the algebraic loop.
\begin{figure}[!htb]
    \def\svgwidth{0.8\textwidth}
    \input{appendix/fig/blockDiagramAlgLoop.pdf_tex}
    \caption{Block diagram that describes the algebraic loop example}
    \label{fig:blockDiagramAlgLoop}
\end{figure}

.. in Listing \ref{lst:server} for the server and in ..

\mylisting[label=lst:server]{server.c}


\section{Proof Structure}\label{gua:sec:proof-structure}

The proofs for the cutoff results, new and original,
are based on two lemmas, Monotonicity and Bounding~\cite{Emerson00}.
When combined together, the lemmas give a cutoff.
We state the lemmas, and discuss them in the context of deadlock detection and fairness.
The detailed proofs are in Sections~\ref{gua:sec:proofs-disj} and \ref{gua:sec:proofs-conj}.
Note that we only consider properties of the form $h(A,B^{(1)})$---the
proof ideas extend to general properties $h(A,B^{(k)})$ without difficulty.
Similarly, in most cases the proof ideas extend to open systems
without major difficulties---mainly because when we construct a simulating
run, we have the freedom to choose the input that is needed.
% AK: in the main text of the paper no difficulties are seen
Only for the case of deadlock detection we have to handle open systems explicitly.

\smallskip
\noindent
{\bf 1) Monotonicity lemma:} if a behavior is possible in a (conjunctive or disjunctive) system with $n \in \Nat$ copies of $B$,
then it is also possible in a (conjunctive or disjunctive resp.) system with one additional process:
\[
\largesys \models \pexists h(A,B^{(1)})
~\implies~
(A,B)^{(1, n+1)} \models \pexists h(A,B^{(1)}),
\]
and if a deadlock is possible in $(A,B)^{(1, n)}$, then it is possible in $(A,B)^{(1, n+1)}$.
%

\parit{Discussion}
The lemma is easy to prove for properties
$\pexists h(A,B^{(1)})$ in both disjunctive and conjunctive systems, by letting the
additional process stay in its initial state $\init_B$ forever (see~\cite{Emerson00}).
This cannot disable transitions with disjunctive guards, as
these check for \emph{existence} of a local state in another process (and we
do not remove any processes), and it cannot disable conjunctive guards since
they contain $\init_B$ by assumption.
However, this construction violates fairness, since the new process
never moves. This can be resolved in the disjunctive case by letting the
additional process mimic all transitions of an existing process. But in
general this does not work in conjunctive systems (due to the non-reflexive
interpretation of guards).
For this case and for deadlock detection, the proof is not
trivial and may only work for $n \geq c$, for some lower bound $c \in \Nat$.
The following sections provide the details.

\smallskip
\noindent
{\bf 2) Bounding lemma:} there exists a number $c \in \Nat$ such that
a behavior is possible in a system with $c$ copies of $B$ if it is possible in a system with
$n \geq c$ copies of process $B$:
\[
(A,B)^{(1, c)} \models \pexists h(A,B^{(1)})
~\impliedby~
(A,B)^{(1, n)} \models \pexists h(A,B^{(1)})
,
\]
and a deadlock is possible in \cutoffsys if it is possible in \largesys.

\parit{Discussion}
For disjunctive systems,
the main difficulty is that removing processes
might falsify guards of the local transitions of $A$ or $B_1$ in a given run.
To address this,
Emerson and Kahlon~\cite{Emerson00} came up with so-called flooding construction (described later).
For conjunctive systems,
removing processes from a run is easy for the case of infinite runs,
since a transition that was enabled before cannot become disabled.
Here, the difficulty is in preserving deadlocks,
because removing processes may enable processes that were deadlocked before.
The next sections explain how to address this.

\parbf{Tightness}
Recall from Section~\ref{gua:sec:paramsynt} that
$c$ is a tight cutoff iff $c$ is a cutoff and there are templates $(A,B)$ and a property $\Phi$,
such that
$$\sys{c-1} \not\models \Phi \textit{ and } \sys{c} \models \Phi.$$
For deadlock detection this is equivalent to:
$\sys{c-1}$ does not have a deadlock but $\sys{c}$ does.
%For properties of the form $\E h(A,B^{(1)})$ and $\A h(A,B^{(1)})$,
%due to the equivalence ``$\sys(n) \models \E h$'' $\equiv$ ``$\sys{n} \not\models \A\neg h$'',
%this is equivalent to having:
%$\sys{c-1} \not\models \E h(A,B^{(1)})$ and $\sys{c} \models \E h(A,B^{(1)})$.
To prove tightness, we provide a template $(A,B)$ and a property.

The next sections contains all the proofs of the results in the table.
For each row and column, we prove monotonicity and bounding lemmas,
as well as tightness.
Note that for simplicity the proofs are for the case of $h(A,B_1)$,
while the generalization to the case $h(A,B^{(k)})$ follows.


\section{Moments of statistics}


\section{Directed graphs}