%SourceDoc ../YourName-Dissertation.tex
% \vspace*{-80mm}
\chapter{Background} \label{chapter1:Background}

\section{\sloppy Gaussian Processes}

Consider a \emph{spatial stochastic process}~\cite{gelfand2010handbook} $\{Y(\bm{s}): \bm{s} \in \mathcal{D} \subseteq \mathbb{R}^d\}$ that varies over some continuous spatial domain $\mathcal{D}$. We will focus on the most common case for spatial statistics, where the dimension is $d = 2$, although the methods presented here are valid for any $d$.  For a finite collection of spatial locations $\{\bm{s}_1, \dots, \bm{s}_n\} \subset \mathcal{D}$, $\bm{Y} = (Y(\bm{s}_1), \dots, Y(\bm{s}_n))^T$ is a random vector where each element is associated with one location. The multivariate distribution of $\bm{Y}$ contains information about the spatial dependencies between all $n$ locations.

The distribution of the process $\{Y(\bm{s})\}$ may be described through its finite-dimensional joint distributions
\begin{equation} \label{eq:joint}
F(y_1, \dots, y_n; \bm{s}_1, \dots, \bm{s}_n) = P(Y(\bm{s}_1) \leq y_1, \dots, Y(\bm{s}_n) \leq y_n)
\end{equation}
for every value of $n$ and every set of $n$ spatial locations in $\mathcal{D}$. A \emph{Gaussian process} is a special case in which every distribution in \eqref{eq:joint} is multivariate normal~\cite{gelfand2010handbook}. As a result, the distributions are all completely characterized by their means and covariance matrices, which makes Gaussian processes much easier to work with than non-Gaussian spatial stochastic processes.

% section gaussian_processes (end)

\section{Stationarity and Isotropy} % (fold)
\label{sec:stationarity_and_isotropy}

Throughout this work we will be making two key assumptions:  \emph{stationarity} and \emph{isotropy}. A stationary Gaussian process is one that does not vary with spatial shifts. That is, for any lag vector $\bm{h} \in \mathbb{R}^d$,
\[
E[Y(\bm{s})] = E[Y(\bm{s} + \bm{h})] = \bm{\mu}
\]
and
\[
\textrm{Cov}(Y(\bm{s}), Y(\bm{s} + \bm{h})) = \textrm{Cov}(Y(\bm{0}), Y(\bm{h})) = C(\bm{h}).
\]
Here $C(\bm{h})$ is called the \emph{covariance function}.

For isotropic Gaussian processes, the covariance function depends on $\bm{h}$ only through its magnitude $||\bm{h}||$. In this setting, we can express the covariance function simply as $C: [0, \infty) \to \mathbb{R}$. If we assume without loss of generality that the process is standardized, we can further stipulate that $C(0) = 1$ and $E[Y(\bm{s})] = 0$ for all $\bm{s} \in \mathcal{D}$.

% Define $\mathcal{C}_d$ as the set of all continuous isotropic covariance functions in $d$ dimensions. Further define $\mathcal{C}_\infty = \bigcap_{d=1}^\infty \mathcal{C}_d$ as the set of all functions that are valid isotropic covariance functions in \emph{all} dimensions. It can be shown~\cite{Stein1999}~\cite{schoenberg1938metric} that
% \[
% 	\mathcal{C}_1 \supseteq \mathcal{C}_2 \supseteq \cdots \supseteq \mathcal{C}_\infty
% \]
% and that a function $C(h)$ is in $\mathcal{C}_\infty$ if and only if it can be written in the form
% \[
% 	C(h) = \int_0^\infty \exp(-h^2u^2) \; dG(u)
% \]
% for some $G$ bounded and non-decreasing on $[0, \infty)$~\cite{Stein1999}.

% section stationarity_and_isotropy (end)

\section{Covariance Function Estimation} % (fold)
\label{sec:covariance_function_estimation}

Because Gaussian processes are completely characterized by their mean and covariance functions, estimating $C$ given a collection of observations $\{y_1, \dots, y_n\}$ is a topic of great interest~\cite{ver1993multivariable}~\cite{banerjee2014hierarchical}. The problem of estimating $C$ differs from the general problem function estimation because only a restricted class of functions will produce a valid Gaussian process. In particular, $C$ must belong to the class of \emph{positive definite functions}, which is defined as the set of all functions $C$ such that
\[
  \sum_{i=1}^n \sum_{j=1}^n a_i a_j C(\bm{s_i}\bm{s}_j) > 0
\]
for any $n$, any $\{\bm{s}_1, \dots, \bm{s}_n\} \in \mathcal{D}$, and any $a_1, \ldots, a_n \in \mathbb{R}$. This condition guarantees that the joint distribution of any finite collection of observations $\{Y(\bm{s}_1), \ldots, Y(\bm{s}_n)\}$ has a positive definite covariance matrix. This turns out to be a strong restriction, and it is very difficult in general to directly estimate $C$ in such a way that forces positive definiteness.

The classical approach to overcoming this difficulty is to select a parametric family of covariance functions that is known to be positive definite for a given range of the parameters, and to estimate the parameters using moment- or likelihood-based methods\cite{gelfand2010handbook}. A popular choice of parametric families is the \emph{Mat\'{e}rn} class of functions~\cite{handcock1994approach}, which take the form
\begin{equation} \label{eq:matern}
C(h) = \frac{\sigma^2}{2^{\nu - 1}\Gamma(\nu)} \left( \frac{2\nu^{1/2}h}{\rho} \right)^{\nu} \mathcal{K}_{\nu} \left( \frac{2\nu^{1/2}h}{\rho} \right), \qquad \sigma^2, \nu, \rho > 0,
\end{equation}
where $\mathcal{K}_\nu$ is a modified Bessel function of the third kind. This is a three-parameter family, with $\sigma$ controlling the marginal variance, $\rho$ controlling the range of correlation, and $\nu$ controlling the smoothness of the sample paths. All functions in this class are positive definite for observations in any dimension~\cite{Stein1999}. Some examples of Mat\'ern covariance functions are shown in Figure~\ref{fig:matern_examples}.

\begin{figure}[!htb]
	\centering
	\includegraphics[width=0.95\textwidth]{matern_examples.pdf}
	\caption{\small The Mat\'ern isotropic covariance function \eqref{eq:matern} for various choices of $\nu$ and $\rho$, each with $\sigma^2 = 1$.}
	\label{fig:matern_examples}
\end{figure}

Another positive definite family, which we will use in examples below, is the \emph{exponentially damped cosine} class,
\begin{equation} \label{eq:dampedcos}
	C(h) = \sigma^2 \exp \left( -\tau \frac{h}{\lambda} \right) \cos \left( \frac{h}{\lambda} \right), \qquad \tau \geq \frac{1}{\tan \frac{\pi}{2d}}, \quad \sigma^2,\lambda > 0.
\end{equation}
Unlike the Mat\'ern class, the damped cosine class allows for negative correlations at certain distances. This non-monotonic behavior is known in geostatistical applications as a \emph{hole effect}~\cite{Ye2015}, and is shown in Figure~\ref{fig:dampedcos_examples}. The restriction on $\tau$ that depends on $d$ is necessary for functions of this form to be positive definite. %Note, however, that $\tan(\pi/2d) \to 0$ as $d \to \infty$, so this set of functions is not a member of $\mathcal{C}_\infty$.
The damped cosine family is not nearly as commonly used as the Mat\'ern family, but it is useful in some applications because allows for stochastically periodic behavior as well as negative correlations, which a Mat\'ern family cannot capture. However, it does not share the attractive feature of the Mat\'ern family that the smoothness of the process (i.e. the degree of differentiability) is controlled by a parameter that can be estimated from the data. The smoothness is closely related to the local behavior of the process, which crucial to obtaining good performance when interpolating the process at unobserved locations~\cite{Stein1999}.

\begin{figure}[!htb]
	\centering
	\includegraphics[width=0.95\textwidth]{dampedcos_examples.eps}
	\caption{\small The damped cosine isotropic covariance function \eqref{eq:dampedcos} for $\tau = 1$, $\lambda = 1$, and $\sigma^2=1$. Notice that $C(h) < 0$ for certain values of $h$.}
	\label{fig:dampedcos_examples}
\end{figure}

The strategy of fitting the data to a parametric family of covariance functions can produce a good estimate if the true covariance structure is close to the structure assumed by the choice of parametric family. However, there is no guarantee that this will be the case. For instance, if the true covariance contains a hole effect, there is no way for a Mat\'ern model to capture it since $C(h) > 0$ for all $h$. More preferable would be a flexible method that allows the spatial dependence in the data itself, rather than the choice of parametric family, to determine the shape of $C$.

% subsection estimating_the_covariance_function (end)

\section{The Spectral Domain and Bochner's Theorem} % (fold)
\label{sec:bochner_s_theorem}

The method proposed in this work takes advantage of the result from Bochner~\cite{bochner1955harmonic} which says that a real-valued continuous function $C$ is positive definite if and only if it is the Fourier transform of a symmetric, non-negative, finite measure $F$ on $\mathbb{R}^d$. That is, $C$ is positive definite if and only if
\begin{equation} \label{eq:bochner}
C(\bm{h}) = \int_{\mathbb{R}^d} \exp(i \bm{h}^T \bm{\omega}) \; dF(\bm{\omega}),
\end{equation}
In most circumstances, the measure $F$ has a Lebesgue density, $f(\bm{\omega})$, which is referred to as the \emph{spectral density}~\cite{gelfand2010handbook}.  Furthermore, because we are assuming that the Gaussian process described by $C$ is isotropic, $C$ is a function of a scalar $h$, so that
\begin{equation} \label{eq:bochner2}
C(h) = \int_{\mathbb{R}} \cos(h\omega) \; f(\omega) \; d\omega.
\end{equation}
Stein~\cite{Stein1999} argues that for Gaussian process covariance functions to be realistic models for spatial phenomena, spectral densities $f(\omega)$ must be heavy tailed.

The relationship between the covariance function and the spectral density given in \eqref{eq:bochner2} suggests us an alternative way to estimate the covariance function $C(h)$. If we can estimate the the symmetric spectral density $f(\omega)$, then we are assured that the corresponding covariance function $C(h)$ is positive definite.  Flexibly modeling $C(h)$ directly is difficult because of the restriction of positive definiteness, but flexibly modeling $f(\omega) $ is easy because it can be any symmetric density.

There have been previous approaches for non- and semi-parametric methods that estimate $C(h)$ using the spectral domain. Most closely related to our approach is that of Im, Stein, and Zhu~\cite{IM2007}, who estimate the spectral density using a combination of cubic B-splines with an explicitly specified algebraically decaying tail.   Constraints are placed on the spline coefficients to ensure that the spectral density is non-negative, thereby resulting in a covariance function is positive definite.  Im, Stein, and Zhu use the fact that when under isotropy, \eqref{eq:bochner} can be written as an integral over only one dimension,
\[
	C(h) = 2^{(d-2)/2}\Gamma(d/2) \int_0^\infty (hu)^{-(d-2)/2} J_{(d-2)/2}(hu) \; dG(u),
\]
where $J_\nu(\cdot)$ is the Bessel function of the first kind of order $\nu$. The spline-based spectral density is transformed into a covariance function using numerical integration, which is then used to construct the likelihood of the spline coefficients given the data.  This likelihood is be maximized over the constrained set of spline coefficients to produce $d\hat{G}(u)$, and hence $\hat{C}(h)$.  Our method follows this same concept, with some notable differences outlined in Chapter~\ref{chapter2:Procedure}.

Another, earlier method was put forth by Hall, Fisher and Hoffmann~\cite{Hall1994}. They proposed a multistep process which begins with a kernel estimate of the covariogram. Because the kernel estimate is not necessarily positive definite, they numerically compute its Fourier transform, set all frequencies beyond the first negative value to zero, and then numerically Fourier transform it back to the spatial domain. In the simulation study in Chapter~\ref{chapter3:Simulation-Study}, we compare our method to the one from Hall et al., as well as to the Mat\'ern model fit by maximum likelihood.

In Chapter~\ref{chapter4:Data-Application}, we apply our method to data from a paper by Singh et al. \cite{Singh2014}, where we model the thickness of a thin film semiconductor in a photovoltaic cell as a Gaussian process. The results are discussed in Chapter~\ref{chapter5:Conclusions}, as well as possibilities for improvements and future directions for this work.

% section bochner_s_theorem (end)


\section{Language models}

\paragraph{Language model}
A language model is the probability distribution
of a sequence of words, it can be used for all sort
of applications.
$$p(w_1, w_2, \dots, w_n)$$

\paragraph{Examples}
This probability could be used to predict the next word
given a sequence
$$p(w_n | w_1, w_2, \dots, w_{n-1})$$
Another usage is to predict a feature given the sequence,
for instance find the author from the text
$$p(\mathit{author} | w_1, w_2, \dots, w_n)$$

\paragraph{Bases and evaluation}
The goal of language modeling is to build a computational model of the
language of an entity $X$, that can be any entity in a domain.

Language models are entirely \emph{data-driven}. In other terms,
we need to train models on the right data. One of the disadvantages of
this fact is that instead of modeling the language of $X$, we are modelling
the language of the \emph{documents about X}.

\subsection{N-grams models}
The easier way to estimate a sequence probability is to count
frequencies, but that could be unfeasible. We discussed a similar approach
in Section \vref{problangmodel} in \emph{Computing a sentence probability}.

\paragraph{Unigram models}
A first approach is to use word frequencies,
the idea is to find the relative frequency of a word, by simply counting
it in the corpus and use it to estimate
the probability of a sequence.
$$p(w_n, w_{n-1}\dots, w_1) = p(w_n)p(w_{n-1})\dots p(w_1)$$
Note that this approach does not take into consideration the sequence in
any way, this is a \emph{Unigram model} .

These models might be useful to compare two documents, where we
need to compare the probability of seeing a given word,
or to find how much relevant is a given word for a document.
We can do that by comparing the word probability in all the dataset and in the
single document.

\paragraph{Pointwise Mutual Information}
$$\mathit{pmi}(a,b) = \log\frac{p(a,b)}{p(a)p(b)} = \log \frac{p(a | b)}{p(a)} = \log\frac{p(b|a)}{p(b)}$$
We can set the two variables to the event of extracting the document $C$ from
the corpus and the probability $w$ of extracting a given word.
$$\mathit{pmi}(w, C) = \log\frac{p(w, C)}{p(w)p(C)}$$
By computing the \emph{pmi} for the same word and two different documents,
we can compare the difference of relevance of a word for the two
documents.

\paragraph{Chain rule}
We now want to consider the sequence instead of taking words independently
as in the unigram model.
$$p(w_k | w_1, \dots, w_{k-1}) =
\frac{\mathit{count}(w_1, \dots, w_{k-1}, w_k)}{\sum_w \mathit{count}(w_1, \dots, w_{k-1}, w)}$$
Basically to compute the probability of finding a given word
after a sequence, we count how many times we observe the sequence with
that word, over the count of all other words after the sequence.

In practice, we can reduce a long sequence to a shorter one, for instance
of two or three words, to potentially have enough data to estimate the probability.

\subsection{Evaluation}

There are basically two ways of evaluating a language model:
\begin{itemize}
    \item \emph{Extrinsic evaluation} : embed the system in a real applications
    and measure improvement
    \item \emph{intrinsic evaluation} : define a metric and evaluate the
    model independent from any application, this requires a training set and
    a testing set, where the second must be different but consistent
    with the language learned by the model
\end{itemize}

\paragraph{Perplexity}
In the case of intrinsic evaluation, the main idea
 is to check if the model fits the test data.
This measure is called perplexity.
$$\mathit{pp}(T) = p(w_1, \dots, w_n)^{-\frac{1}{n}}$$
For a two-gram model the measure becomes:
$$\mathit{pp}(T)= \sqrt[n]{\prod_{i=1}^n \frac{1}{p(w_i\;|\;w_{i-1})}}$$

\paragraph{Generalization and zero probabilities}
Language models have an issue when a word is present in the test set
but not in the training set, this becomes unknown with no null probability.

To fix this we apply smoothing, for instance \emph{Laplace smoothing}, i.e.
adding one to each word count, or a parameter k.

\paragraph{Backoff and interpolation}
Another way to deal with null probabilities
is to apply \emph{backoff and interpolation}. Basically to estimate
a $n$-gram frequency, if we do not have enough evidence, we use the $(n-1)$-gram
frequency, until we have just a unigram.
An example can be:
$$p(\mathit{New\;York\;City}) = p(\mathit{City}\;|\;\mathit{York})\;p(\mathit{York}\;|\;\mathit{New}) $$

\emph{Interpolation} means computing a weighted sum over an $n$-gram levels,
this way, even if we only observe the last word of a $n$-gram, we do not
have zero probability.

\subsection{Word-Context models}
The problem of data sparsity is mitigated by the n-gram models, but not
solved completely.

\paragraph{Skip-gram model}
The main of the model is to fix the cases where two sentences
are really similar, i.e. they give the same information, but they do
not have any common n-gram.

We introduce the concept of \emph{word context},
basically we take a n-gram by skipping at most $k$ words,
this leads to skip noisy terms.
By doing so, we could potentially match two sentences
that differs for a few words but that do not share commons
grams.

\paragraph{Continuous Bag of Words}
The idea of this model is to take the context of a word,
for instance a collection of 2-grams, and predict a word.

\paragraph{Word context matrix}
We can think of a word context matrix, where we
store information about appearance of a word $w$
within $t$ other words.

Taking into account the word order depends on the focus of
the model, in language the order is important, in semantics
it is less relevant.

The context matrix stores in $c_{i, j}$ for each word $w_i$
how many times the word $w_j$ occurs in its context.
If we consider the row of that matrix as a vector, two words
are close in that space if they have a similar context.

After computing the matrix, we can factorize it with singular value
decomposition to obtain a more compact representation.
A problem is that such a factorization has many zero terms, to
fix it we can \emph{weighted matrix factorization}.

\subsection{Word embeddings}

\paragraph{Words as vectors}
Representing words as vectors, as we did with models previously,
is a very efficient way to compute words similarity and
represent documents as regions in the vector space.
An example of word as vectors can be found in the context matrix.

The goal is to obtain \emph{dense word vectors}, so with small dimensionality
and with the absence of sparsity.

\paragraph{Distributional hypothesis}
In a real world scenario a word has a meaning, which is related
to the object, or the concept it represent, in our case there is
no such thing, so we must find a way to deal with this.

We can assume that words that appear in the same
context have the same meaning.

\subsubsection{Neural network models}

A first example of using a neural network is
to take as input an $n$-gram of a word $w$ and
as output the probability distribution over the next word.

We saw this concept in the previous section when talking about
\emph{Continuous Bag of Words}.

Basically what the network is doing is to compute
this function
$$f(w_t, \dots, w_{t-n+1}) = P(w_t \; | \; w_1, \dots, w_{t-1})$$

\paragraph{Decomposition}
The idea used by the model is to decompose the function in
two parts:
\begin{itemize}
    \item A mapping from any word $w_i \in V$ to a vector $w_i \in \mathbb{R}^m$ dimensions,
    this creates a matrix $W \in \mathbb{R}^{V \times m}$, where $V$ is the number of words
    \item A probability function over words, that takes in input
    a sequence of vectors of $d$ dimensions, obtained via the previous
    mapping, and produces a vector $g$ in the original $V$ space.
\end{itemize}

\paragraph{Why is this relevant for word embeddings?}
The mapping to a $d$ dimensional space could be the word
embedding we want to obtain, we are not interested
in the network output.

We are assuming that the embedding made by the network
correspond to the real meaning of the word, as such a
mapping is obtained minimizing the objective function.

In other words, if the network is able to perform well, that should
be a good embedding.

\paragraph{Word2vec}
The idea is to train the neural network with positive couples of
words and negative ones, with the hope the network will learn
to output good words sequences.

The structure of the network in this implementation
has an input and output layer of dimensions $V \times V$,
and a middle layer of $V \times m$, initialized with random values.

After training we discard the output layer and keep the
middle one, as discussed in the previous section.
The main principle is that similar vectors in the hidden
layer corresponds to words with similar context.

This is due to the fact that two words with the same context
should have similar consequent predictions, thus, the weights in
the middle layer for this two words must be close, as the
prediction made by the network must be more o less the same for
the twos.

\begin{figure}[h]
    \centering
    \includegraphics[width=0.8\textwidth]{images/nn-words.png}
    \caption{Word2vec implementation of Neural Network embedding}
\end{figure}

\subsubsection{Using embeddings}

\paragraph{Adding information}
We can use the word embeddings obtained in some way to improve
retrieval, for instance by applying query expansion.

\paragraph{Similarity}
We can also compute similarity among group of words,
as we have a vector space where for instance cosine similarity is
applicable.


\section{Conclusion}

This article illustrated the verification method equational reasoning by example. We proved that the monoid law known as left identity holds for a given function definition.

The type class laws provide a specification for the verification process. In addition, we can rely on properties of existing type class instances to prove further properties.

Type classes allow us to generalize definitions. A proof for the generalization is valid for all specializations. Hence, the proof is reusable.

The examination of the topic improved my comprehension for the advantages of a purely functional language. The reason why verification in a purely functional language like Haskell is easier then in imperative language is because functions are just equalities. We can reason about Haskell code in the same way we reason about mathematical equations. The definitions are stateless. This fact does not apply to mainstream languages. A function definition of an imperative language is allowed to change the context. These definitions are stateful.

Personally, I found the process of proving the left identity law for the given definition tedious and difficult. The proof requires creativity and a strong mathematical background. The verification process would be too cumbersome and expensive to apply it to every piece of software. Although equational reasoning  is not suitable for software with a short life cycle, I think it is important to know the difference between testing and verification by proof.


%%%%%%%%%%%%%%%%%%%%%%%%% Shortest Paths %%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Shortest Paths}

\begin{frame}
  \frametitle{Shortest paths}

  \textcolor{purple}{Different editions of shortest paths problems:}
  \begin{enumerate}
    \item shortest(longest) path in DAG  \\
      \emph{\textcolor{blue}{Dynamic Programming}}
    \item single-source shortest paths
      \begin{itemize}
        \item No negative edges. \\
          \emph{\textcolor{blue}{Dijkstra algorithm.}}
        \item With negative edges (No negative cycle). \\
          \emph{\textcolor{gray}{Bellman-Ford algorithm.}}
      \end{itemize}
    \item all pairs shortest paths \\
      \emph{\textcolor{blue}{Floyd-Warshall algorithm.}}
  \end{enumerate}

\end{frame}

%\begin{frame}
%  \frametitle{Shortest paths}
%
%  \textcolor{purple}{To better understand these problems and algorithms:}
%  \vspace{0.40cm}
%
%  \begin{enumerate}
%    \setlength{\itemsep}{0.30cm}
%    \item Why the algorithm works for this problem ?
%    \item Does the algorithm also work for another problem ?
%  \end{enumerate}
%
%\end{frame}

\begin{frame}
  \frametitle{Shortest paths}

  \textcolor{purple}{DAG can be topologically sorted, so \emph{DP} works.}

  \begin{figure}
    \begin{center}
      \includegraphics[scale=0.30]{figure/bfs_dfs/daglinear}
      \caption{{\scriptsize A dag and its topological sorting.}}
      \label{fig:daglinear}
    \end{center}
  \end{figure}

  \[
    dist(D) = \min \lbrace dist(B)+1, dist(C)+3 \rbrace.
  \]

\end{frame}

\begin{frame}
  \frametitle{Shortest paths}

  \textcolor{purple}{Shortest path without negative edges : \emph{Dijkstra algorithm}}

  \begin{figure}
    \begin{center}
      \includegraphics[scale=0.40]{figure/bfs_dfs/dijkstra}
      \caption{{\scriptsize Property of shortest paths.}}
      \label{fig:dijkstra}
    \end{center}
  \end{figure}

\end{frame}

\begin{frame}
  \frametitle{Priority queue implementations}

  \textcolor{purple}{Complexity of Dijkstra algorithm:}
  \begin{enumerate}
    \item makequeue, $\lvert V \rvert \cdot insert$
    \item $\lvert V \rvert \cdot deletemin$
    \item $\lvert E \rvert \cdot descreaseKey$
  \end{enumerate}

  \pause
  \vspace{0.50cm}

  \textcolor{purple}{Different implementations of priority queue:}

  {\scriptsize

    \begin{tabular}{|c||c|c|c|}
      \hline
      Implementation     & deletemin        & insert, decreaseKey       & total                 \\ \hline \hline
      Array              & $O(V)$           & $O(1)$                    & $O(V^2)$              \\ \hline
      Binary heap        & $O(\log{V})$     & $O(\log{V})$              & $O((V+E) \log {V})$   \\ \hline
      Fibonacci heap     & $O(\log{V})$     & $O(1)$                    & O$(V \log {V} + E)$   \\
      \hline
    \end{tabular}
  }

\end{frame}

\begin{frame}
  \frametitle{Shortest path with negative edges: \emph{Bellman-Ford algorithm}}

  \begin{figure}
    \begin{center}
      \includegraphics[scale=0.40]{figure/bfs_dfs/dijkstranegative}
      \caption{{\scriptsize Dijkstra algorithm fails if there are negative edges ([\textcolor{blue}{$P_{418}$ 8.14}]).}}
      \label{fig:dijkstranegative}
    \end{center}
  \end{figure}

\end{frame}

\begin{frame}
  \frametitle{All pairs of shortest paths: \emph{Floyd-Warshall algorithm}}

  \begin{figure}
    \begin{center}
      \includegraphics[scale=0.40]{figure/bfs_dfs/warshall}
      \label{fig:warshall}
    \end{center}
  \end{figure}

  \pause
  \vspace{0.40cm}
  \textcolor{red}{Assumption: No negative cycles.}

\end{frame}

\begin{frame}
  \frametitle{All pairs of shortest paths: \emph{Floyd-Warshall algorithm}}

  \begin{itemize}
    \item Routing table for all-pair shortest path ([\textcolor{blue}{$P_{448}$ 9.10}]).
    \item Length of shortest cycle in digraph ([\textcolor{blue}{$P_{448}$ 9.12}]).
  \end{itemize}

\end{frame}

\begin{frame}
  \frametitle{All pairs of shortest paths: \emph{Floyd-Warshall algorithm}}

  \begin{itemize}
    \item Routing table for all-pair shortest path ([\textcolor{blue}{$P_{448}$ 9.10}]).
    \vspace{0.50cm}

      \begin{figure}
        \begin{center}
          \includegraphics[scale=0.35]{figure/shortest_paths/route0}
          \caption{{\scriptsize Construction of routing table.}}
          \label{fig:route0}
        \end{center}
      \end{figure}
    \end{itemize}

\end{frame}

\begin{frame}
  \frametitle{All pairs of shortest paths: \emph{Floyd-Warshall algorithm}}

  \begin{itemize}
    \item Length of shortest cycle in digraph ([\textcolor{blue}{$P_{448}$ 9.12}]).
    \[
      path \lbrack i \rbrack \lbrack i \rbrack
    \]
    \[
      path \lbrack i \rbrack \lbrack i \rbrack < 0 ?
    \]
    \textcolor{red}{Fail for undirected graph:}
    \[
      \lbrace v, w \rbrace \to (v,w,v).
    \]
  \end{itemize}

\end{frame}

\begin{frame}
  \begin{figure}
    \begin{center}
      \includegraphics[scale=0.60]{figure/thank}
      \label{fig:thank}
    \end{center}
  \end{figure}
\end{frame}


The \eslmod{stats} module is the foundation of a set of statistics
modules. It contains special functions like $\Gamma(x)$ and $\Psi(x)$,
and elementary statistics routines such as linear regression fitting
and $\chi^2$ testing. Table~\ref{tbl:stats_api} lists the functions in
the \eslmod{stats} API.

\begin{table}[hbp]
\begin{center}
{\small
\begin{tabular}{|ll|}\hline
\hyperlink{func:esl_stats_DMean()}{\ccode{esl\_stats\_\{D,F,I\}Mean()}} & Calculates mean and $\sigma^2$ for samples $x_i$.\\
\hyperlink{func:esl_stats_LogGamma()}{\ccode{esl\_stats\_LogGamma()}} & Calculates $\log \Gamma(x)$.\\
\hyperlink{func:esl_stats_Psi()}{\ccode{esl\_stats\_Psi()}} & Calculates $\Psi(x)$ (the digamma function).\\
\hyperlink{func:esl_stats_IncompleteGamma()}{\ccode{esl\_stats\_IncompleteGamma()}} & Calculates the incomplete Gamma function.
\\
\hyperlink{func:esl_stats_ChiSquaredTest()}{\ccode{esl\_stats\_ChiSquaredTest()}} & Calculates a $\chi^2$ P-value.\\
\hyperlink{func:esl_stats_LinearRegression()}{\ccode{esl\_stats\_LinearRegression()}} & Fit data to a straight line.\\
\hline
\end{tabular}
}
\end{center}
\caption{The \eslmod{stats} API.}
\label{tbl:stats_api}
\end{table}

\subsection{An example of using the stats API}

Figure~\ref{fig:stats_example} shows an example of using one of the
routines in the \eslmod{stats} module, linear regression fitting. It
generates a set of $n$ points dispersed around a line, $y_i = a + bx +
N(\sigma)$ with Gaussian noise $N(\sigma)$, then fits the data to a
line to obtain estimates $\hat{a}$ and $\hat{b}$.

\begin{figure}
\input{cexcerpts/stats_example}
\caption{An example of using the \eslmod{stats} module.}
\label{fig:stats_example}
\end{figure}


\chapter[Markov Chains]{Markov Chains}\label{chp:markov_chains}

% Introduction
\chapterinitial{M}{any} real world situations have some level of
unpredictability through randomness: the flip of a coin, the number of orders of
coffee in a shop, the winning numbers of the lottery. However, mathematics can
in fact let us make predictions about what can be expected to happen. One tool
used to understand randomness is Markov chains, an area of mathematics sitting
at the intersection of probability and linear algebra.

\section{Problem}\label{sec:markov_chains_problem}

Consider a barber shop. The shop owners have noticed that customers will not
wait if there is no room in their waiting room and will choose to take their
business elsewhere. The barber shop would like to make an investment so as to
avoid this situation. They know the following information:

\begin{itemize}
    \item They currently have 2 barber chairs (and 2 barbers);
    \item they have waiting room for 4 people;
    \item they usually have 10 customers arrive per hour;
    \item each barber takes about 15 minutes to serve a customer so they can
        serve 4 customers an hour.
\end{itemize}

This is represented diagrammatically in Figure~\ref{fig:barber-shop}.

\begin{figure}[!hbtp]
    \begin{center}
    \includestandalone[width=.75\textwidth]{./assets/barber-shop/main}
    \end{center}
    \caption{Diagrammatic representation of the barber shop as a queuing system.}
    \label{fig:barber-shop}
\end{figure}

They are planning on
reconfiguring space to either have 2 extra waiting chairs or
another barber's chair and barber.

The mathematical tool used here to model this situation is a Markov
chain\index{Markov chain}.

\section{Theory}\label{sec:markov_chains_theory}

A Markov chain is a model of a sequence of random events\index{random events}
that is defined by a collection of \textbf{states} and rules that define how to
move between these states.

For example, in the barber shop a single number is sufficient to describe the
status of the shop: the number of customers present.
If that number is 1 this implies that 1 customer is
currently having their hair cut. If that number is 5 this implies that 2
customers are being served and 3 are waiting. The entire set of values that this
value can take is a finite set of integers from 0 to 6, this set, in general, is
called the \textit{state space}.
If the system is full (all barbers and waiting room occupied) then the Markov
chain is in state 6 and if there is no one at the
shop then it is in state 0. This is denoted mathematically as:

\begin{equation}
    S = \{0, 1, 2, 3, 4, 5, 6\}
    \label{eqn:barber_shop_state_space}
\end{equation}

The state increases when people arrive and this happens at a rate of change of
10 per unit time. The state decrease when people are served and this happens at
a rate of 4 per active server per unit time. In both cases it is assumed that no
2 events can occur at the same time.

In general, the rules that govern how to move between these states can be
defined in 2 ways:

\begin{itemize}
    \item Using probabilities\index{probability} of changing state (or not) in a
          well defined time interval. This is called a discrete time Markov
          chain\index{discrete time Markov chain}.
    \item Using rates of change\index{rate of change} from one state to another.
          This is called a continuous time Markov chain\index{continuous time Markov chain}.
\end{itemize}

The barber shop will be considered as a continuous time Markov chain as shown
in Figure~\ref{fig:barber-shop-continuous-markov-process}

\begin{figure}[!hbtp]
    \begin{center}
    \includestandalone[width=.6\textwidth]{./assets/barber-shop-continuous-markov-process/main}
    \end{center}
    \caption{Diagrammatic representation of the state space and the transition
    rates}
    \label{fig:barber-shop-continuous-markov-process}
\end{figure}

Note that a Markov chain assumes the rates follow an exponential
distribution\index{exponential distribution}.
One interesting property of this distribution is that it is considered
memoryless which means the probability of a customer finishing service
within the next 5 minutes does not change if they have been
having their hair cut for 3 minutes already.

These states and rates can be represented mathematically using a transition
matrix\index{transition matrix}\index{matrix} \(Q\) where \(Q_{ij}\) represents the rate
of going from state \(i\) to
state \(j\). In this case:

\begin{equation}
Q =
\begin{pmatrix}
-10 &  10 &   0 &   0 &   0 &   0 &   0\\
  4 & -14 &  10 &   0 &   0 &   0 &   0\\
  0 &   8 & -18 &  10 &   0 &   0 &   0\\
  0 &   0 &   8 & -18 &  10 &   0 &   0\\
  0 &   0 &   0 &   8 & -18 &  10 &   0\\
  0 &   0 &   0 &   0 &   8 & -18 &  10\\
  0 &   0 &   0 &   0 &   0 &   8 &  -8\\
 \end{pmatrix}
 \label{eqn:barber_shop_transition_matrix}
\end{equation}

You will see that \(Q_{ii}\) are negative and ensure the rows of \(Q\) sum to 0.
This gives the total rate of change leaving state \(i\).

The matrix \(Q\) can be used to understand the probability of being in a given
state after \(t\) time unis. This can be represented mathematically using a
matrix \(P_{t}\) where \((P_{t})_{ij}\) is the probability of being in state \(j\)
after \(t\) time units having started in state \(i\). Using a mathematical tool
called the matrix exponential\footnote{Chapter 9 of~\cite{van1996matrix}
gives a description of how to compute the matrix
exponential\index{matrix exponential} numerically and~\cite{moler1978nineteen,
moler2003nineteen} give a review of 19 algorithms that can be used.} the value
of \(P_{t}\) can be calculated numerically.

\begin{equation}
    P_t = e^{Qt}
    \label{eqn:continuous_time_markov_process_matrix_exponential}
\end{equation}

What is also useful is understanding the long run behaviour of the
system. This allows us to answer questions such as ``what state is the system most
likely to be in on average?'' or ``what is the probability of being in the last
state on average?''.

This long run probability distribution\index{long run probability distribution}
over the states can be represented using a vector\index{vector} \(\pi\) where
\(\pi_i\) represents the probability of being in state \(i\). This vector is in
fact the solution to the following matrix equation\index{matrix equation}:

\begin{equation}
    \pi Q = 0
    \label{eqn:continuous_time_markov_process_steady_state}
\end{equation}

with the following constraint:

\begin{equation}
    \sum_{i=1}^{n}\pi_i = 1
\end{equation}

In the upcoming sections all of the above concepts will be demonstrated and used
to understand what is the best course of action for the barber shop.

\section{Solving with Python}\label{sec:markov_chains_solving-with-python}

The first step is to write a function to obtain the transition
rates between 2 given states:

\begin{pyin}
def get_transition_rate(
    in_state,
    out_state,
    waiting_room=4,
    num_barbers=2,
):
    """Return the transition rate for 2 given states.

    Args:
        in_state: an integer
        out_state: an integer
        waiting_room: an integer (default: 4)
        num_barbers:  an integer (default: 2)

    Returns:
        A real.
    """
    arrival_rate = 10
    service_rate = 4
    capacity = waiting_room + num_barbers
    delta = out_state - in_state

    if delta == 1:
        return arrival_rate

    if delta == -1:
        return min(in_state, num_barbers) * service_rate

    return 0
\end{pyin}

Next, a function that creates an entire transition rate matrix \(Q\) for a given
problem is written. The Numpy\index{Numpy}~\cite{harris2020array} library will
be used to handle all the linear algebra\index{linear algebra} and the
Itertools\index{Itertools} library for some iterations:

\begin{pyin}
import itertools
import numpy as np

def get_transition_rate_matrix(waiting_room=4, num_barbers=2):
    """Return the transition matrix Q.

    Args:
        waiting_room: an integer (default: 4)
        num_barbers: an integer (default: 2)

    Returns:
        A matrix.
    """
    capacity = waiting_room + num_barbers
    state_pairs = itertools.product(range(capacity + 1), repeat=2)
    flat_transition_rates = [
        get_transition_rate(
            in_state=in_state,
            out_state=out_state,
            waiting_room=waiting_room,
            num_barbers=num_barbers,
        )
        for in_state, out_state in state_pairs
    ]
    transition_rates = np.reshape(
        flat_transition_rates, (capacity + 1, capacity + 1)
    )
    np.fill_diagonal(
        transition_rates, -transition_rates.sum(axis=1)
    )

    return transition_rates
\end{pyin}

Using this the matrix \(Q\) for the default system can be obtained:

\begin{pyin}
Q = get_transition_rate_matrix()
print(Q)
\end{pyin}

which gives:

\begin{pyout}
[[-10  10   0   0   0   0   0]
 [  4 -14  10   0   0   0   0]
 [  0   8 -18  10   0   0   0]
 [  0   0   8 -18  10   0   0]
 [  0   0   0   8 -18  10   0]
 [  0   0   0   0   8 -18  10]
 [  0   0   0   0   0   8  -8]]
\end{pyout}

Here, the matrix exponential will be used as
discussed above, using the SciPy\index{SciPy}~\cite{2020SciPy-NMeth}
library. To see what would happen after 0.5 time units:

\begin{pyin}
import scipy.linalg

print(scipy.linalg.expm(Q * 0.5).round(5))
\end{pyin}

which gives:

\begin{pyout}
[[0.10492 0.21254 0.20377 0.17142 0.13021 0.09564 0.0815 ]
 [0.08501 0.18292 0.18666 0.1708  0.14377 0.1189  0.11194]
 [0.06521 0.14933 0.16338 0.16478 0.15633 0.14751 0.15346]
 [0.04388 0.10931 0.13183 0.15181 0.16777 0.18398 0.21142]
 [0.02667 0.07361 0.10005 0.13422 0.17393 0.2189  0.27262]
 [0.01567 0.0487  0.07552 0.11775 0.17512 0.24484 0.32239]
 [0.01068 0.03668 0.06286 0.10824 0.17448 0.25791 0.34914]]
\end{pyout}

To see what would happen after 500 time units:

\begin{pyin}
print(scipy.linalg.expm(Q * 500).round(5))
\end{pyin}

which gives:

\begin{pyout}
[[0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
 [0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]]
\end{pyout}

After 500 time units, the probability of ending up in each state (column) is
the same regardless of the state the system began in (row).

The analysis can in fact be stopped here
however the choice of 500 time units was arbitrary and might not be the correct
amount for all possible scenarios, as such the
underlying equation~\ref{eqn:continuous_time_markov_process_steady_state}
can be solved directly in order to get a solution where
equilibrium\index{equilibrium} is guaranteed.

The underlying linear system will be solved using a numerically efficient
algorithm called least squares optimisation\index{least squares optimisation}
(available from the Numpy library):

\begin{pyin}
def get_steady_state_vector(Q):
    """Return the steady state vector of any given continuous time
    transition rate matrix.

    Args:
       Q: a transition rate matrix

    Returns:
        A vector
    """
    state_space_size, _ = Q.shape
    A = np.vstack((Q.T, np.ones(state_space_size)))
    b = np.append(np.zeros(state_space_size), 1)
    x, _, _, _ = np.linalg.lstsq(A, b, rcond=None)
    return x
\end{pyin}

The steady state vector for the default system is given by:

\begin{pyin}
print(get_steady_state_vector(Q).round(5))
\end{pyin}

giving:

\begin{pyout}
[0.03431 0.08577 0.10722 0.13402 0.16752 0.2094  0.26176]
\end{pyout}

This shows that the shop is expected to be empty approximately 3.4\% of the time
and full 26.2\% of the time.

The final function written is one that uses all of
the above to return the probability of the shop being full.

\begin{pyin}
def get_probability_of_full_shop(waiting_room=4, num_barbers=2):
    """Return the probability of the barber shop being full.

    Args:
        waiting_room: an integer (default: 4)
        num_barbers: an integer (default: 2)

    Returns:
        A real.
    """
    Q = get_transition_rate_matrix(
        waiting_room=waiting_room,
        num_barbers=num_barbers,
    )
    pi = get_steady_state_vector(Q)
    return pi[-1]
\end{pyin}

This can now confirm the previous calculated probability of the shop
being full:

\begin{pyin}
print(round(get_probability_of_full_shop(), 6))
\end{pyin}

which gives:

\begin{pyout}
0.261756
\end{pyout}

Now that the models have been defined, they will be used to compare the 2
possible scenarios.

Having 2 extra space in the waiting room corresponds to:

\begin{pyin}
print(round(get_probability_of_full_shop(waiting_room=6), 6))
\end{pyin}

which gives:

\begin{pyout}
0.23557
\end{pyout}

This is a slight improvement however, increasing the number of barbers has a
substantial effect:

\begin{pyin}
print(round(get_probability_of_full_shop(num_barbers=3), 6))
\end{pyin}

\begin{pyout}
0.078636
\end{pyout}

Therefore, it would be better to increase the number of barbers by 1
than to increase the waiting room capacity by 2.

\section{Solving with R}\label{sec:markov_chains_solving-with-R}

The first step taken is to write a function to obtain the transition rates
between 2 given states:

\begin{Rin}
#' Return the transition rate for 2 given states.
#'
#' @param in_state an integer
#' @param out_state an integer
#' @param waiting_room an integer (default: 4)
#' @param num_barbers an integer  (default: 2)
#'
#' @return A real
get_transition_rate <- function(in_state,
                                out_state,
                                waiting_room = 4,
                                num_barbers = 2) {
  arrival_rate <- 10
  service_rate <- 4
  capacity <- waiting_room + num_barbers
  delta <- out_state - in_state

  if (delta == 1) {
    return(arrival_rate)
  }
  if (delta == -1) {
    return(min(in_state, num_barbers) * service_rate)
  }
  return(0)
}
\end{Rin}

This actual function will not be used but instead a vectorized
version\footnote{
A vectorized\index{vectorized} calculation refers to the manner in which an
instruction is given to a computer. When vectorized: a single instruction with
multiple data are given at the same time
which corresponds to ``Single instruction, multiple data'' (SIMD) as defined in
Flynn's taxonomy~\cite{flynn1966very}. This is a type of parallelisation
that can be done at the central processing unit level of the computer. }
of this makes calculations more efficient:

\begin{Rin}
vectorized_get_transition_rate <- Vectorize(
  get_transition_rate,
  vectorize.args = c("in_state", "out_state")
)
\end{Rin}

This function can now take a vector of inputs for the \mintinline{R}{in_state}
and \mintinline{R}{out_state} variables which will allow us to simplify the
following code that creates the matrices:

\begin{Rin}
#' Return the transition rate matrix Q
#'
#' @param waiting_room an integer (default: 4)
#' @param num_barbers an integer (default: 2)
#'
#' @return A matrix
get_transition_rate_matrix <- function(waiting_room = 4,
                                       num_barbers = 2){
  max_state <- waiting_room + num_barbers

  Q <- outer(
    0:max_state,
    0:max_state,
    vectorized_get_transition_rate,
    waiting_room = waiting_room,
    num_barbers = num_barbers
  )
  row_sums <- rowSums(Q)
  diag(Q) <- -row_sums
  Q
}
\end{Rin}

Using this the matrix \(Q\) for the default system can be used:

\begin{Rin}
Q <- get_transition_rate_matrix()
print(Q)
\end{Rin}

which gives:

\begin{Rout}
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]  -10   10    0    0    0    0    0
[2,]    4  -14   10    0    0    0    0
[3,]    0    8  -18   10    0    0    0
[4,]    0    0    8  -18   10    0    0
[5,]    0    0    0    8  -18   10    0
[6,]    0    0    0    0    8  -18   10
[7,]    0    0    0    0    0    8   -8
\end{Rout}

One immediate thing that can be done with this matrix is to take the
matrix exponential discussed above. To do this, an R library called
expm\index{expm}~\cite{goulet2021expm} will be used.
To be able to make use of the nice \mintinline{R}{%>%} ``pipe'' operator the
magrittr\index{magrittr}~\cite{bache2020magrittr} library will be loaded. Now to
see what would happen after 0.5 time units:

\begin{Rin}
library(expm, warn.conflicts = FALSE, quietly = TRUE)
library(magrittr, warn.conflicts = FALSE, quietly = TRUE)

print( (Q * 0.5) %>% expm() %>% round(5))
\end{Rin}

which gives:

\begin{Rout}
        [,1]    [,2]    [,3]    [,4]    [,5]    [,6]    [,7]
[1,] 0.10492 0.21254 0.20377 0.17142 0.13021 0.09564 0.08150
[2,] 0.08501 0.18292 0.18666 0.17080 0.14377 0.11890 0.11194
[3,] 0.06521 0.14933 0.16338 0.16478 0.15633 0.14751 0.15346
[4,] 0.04388 0.10931 0.13183 0.15181 0.16777 0.18398 0.21142
[5,] 0.02667 0.07361 0.10005 0.13422 0.17393 0.21890 0.27262
[6,] 0.01567 0.04870 0.07552 0.11775 0.17512 0.24484 0.32239
[7,] 0.01068 0.03668 0.06286 0.10824 0.17448 0.25791 0.34914
\end{Rout}

After 500 time units:

\begin{Rin}
print( (Q * 500) %>% expm() %>% round(5))
\end{Rin}

which gives:

\begin{Rout}
        [,1]    [,2]    [,3]    [,4]    [,5]   [,6]    [,7]
[1,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[2,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[3,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[4,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[5,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[6,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
[7,] 0.03431 0.08577 0.10722 0.13402 0.16752 0.2094 0.26176
\end{Rout}

After 500 time units, the probability of ending up in each state (columns) is
the same regardless of the state the system began in (row).

The analysis can in fact be stopped here
however the choice of 500 time units was arbitrary and might not be the correct
amount for all possible scenarios, as such the
underlying equation~\ref{eqn:continuous_time_markov_process_steady_state}
needs to be solved directly.

To be able to do this, the versatile pracma\index{pracma}~\cite{borchers2021pracma}
package will be used which includes a number of numerical analysis functions for
efficient computations.

\begin{Rin}
library(pracma, warn.conflicts = FALSE, quietly = TRUE)

#' Return the steady state vector of any given continuous time
#' transition rate matrix
#'
#' @param Q a transition rate matrix
#'
#' @return A vector
get_steady_state_vector <- function(Q){
  state_space_size <- dim(Q)[1]
  A <- rbind(t(Q), 1)
  b <- c(integer(state_space_size), 1)
  mldivide(A, b)
}
\end{Rin}

This is making use of pracma's \mintinline{R}{mldivide} function
which chooses the best numerical algorithm to find the solution to a given
matrix equation \(Ax=b\).

The steady state vector for the default system is now given by:

\begin{Rin}
print(get_steady_state_vector(Q))
\end{Rin}

giving:

\begin{Rout}
           [,1]
[1,] 0.03430888
[2,] 0.08577220
[3,] 0.10721525
[4,] 0.13401906
[5,] 0.16752383
[6,] 0.20940479
[7,] 0.26175598
\end{Rout}

The shop is expected to be empty approximately 3.4\% of the time
and full 26.2\% of the time.

The final piece of this puzzle is to create a single function that uses all of
the above to return the probability of the shop being full.

\begin{Rin}
#' Return the probability of the barber shop being full
#'
#' @param waiting_room (default: 4)
#' @param num_barbers (default: 2)
#'
#' @return A real
get_probability_of_full_shop <- function(waiting_room = 4,
                                         num_barbers = 2){
  arrival_rate <- 10
  service_rate <- 4
  pi <- get_transition_rate_matrix(
    waiting_room = waiting_room,
    num_barbers = num_barbers
    ) %>%
    get_steady_state_vector()

  capacity <- waiting_room + num_barbers
  pi[capacity + 1]
}
\end{Rin}

This confirms the previous calculated probability of the shop
being full:

\begin{Rin}
print(get_probability_of_full_shop())
\end{Rin}

which gives:

\begin{Rout}
[1] 0.261756
\end{Rout}

Now that the models have been defined, they will be used to compare the 2
possible scenarios.

Adding 2 extra spaces in the waiting rooms corresponds to:

\begin{Rin}
print(get_probability_of_full_shop(waiting_room = 6))
\end{Rin}

which decreases the probability of a full shop to:

\begin{Rout}
[1] 0.2355699
\end{Rout}

but adding another barber and chair:

\begin{Rin}
print(get_probability_of_full_shop(num_barbers = 3))
\end{Rin}

gives:

\begin{Rout}
[1] 0.0786359
\end{Rout}

Therefore, it would be better to increase the number of barbers by 1
than to increase the waiting room capacity by 2.

\section{Wider context}\label{sec:markov_chains_wider_context}

The overview of Markov chains given here has mainly concentrated on calculation
of steady state\index{steady state} probabilities. There are in fact many more
theoretic and applied aspects of Markov chain models. Some examples of this
include the calculation of sojourn times\index{sojourn time} which is how long a
system spends in a given state as well as considering models with
absorption\index{absorption}: where the system arrives at a state that it no
longer leaves. For a good overview of these the following textbook is
recommended:~\cite{stewart2009probability}.

In~\cite{tan1997markov, stewart1996monopoly}, Markov chains are used to model
board games\index{board games}. In~\cite{tan1997markov} a model of the battles
that take place on a Risk board is used to understand the probabilities of
invasion of territories based on troop numbers. This is done using an
absorbing Markov chain. In~\cite{stewart1996monopoly} a standard model is used
to identify the properties that are most likely to be landed on in Monopoly.
This is done through calculation of steady state probabilities. These are both
examples of discrete time Markov chains.

A common application of Markov chains is in queueing\index{queueing} systems and
specifically queueing systems applied to healthcare\index{healthcare}.
In~\cite{griffiths2013modelling} a model of a neurological rehabilitation unit
is built and used to help better staff the unit.  This is accomplished using the
steady state probabilities and calculating various performance measures. This is
an application of a continuous time Markov chain.

An extension of Markov chains are Markov decision
processes\index{Markov decision process}. This is a particular mathematical
model that identifies the optimal decision made within a Markov chain.
Instead of building multiple Markov models for different decisions, in Markov
decision processes decisions can be made at each state of the underlying chain.
A policy can be identified giving the optimal decision at each state.
In~\cite{white1993survey} a literature review is given showing a wide
ranging application of these decision processes from agriculture to motor
insurance claims as well as sports.


\subsection{The value function}

\subsubsection{State payoffs}

An agent gets a payoff which depends on the current state. We now have:

\begin{itemize}
\item \(S\) - the state space
\item \(s_1\) - the initial state
\item \(P\) - the transition model
\item \(R\) - the reward distribution
\end{itemize}

\subsubsection{Discounting}

We maximise the reward function using discounting.

\(E[\sum_{t=1}^\infty \gamma^{t-1}r_t|s_1]\)


%*******************************************************************************
%***********************************    Background   *****************************
%*******************************************************************************
%!TEX root = 0.main.tex

\setcounter{page}{1}

%********************************** %First Section  **************************************
\section {Introduction and general background}

\subsection{Introduction}

Neural Networks (NNs) are popular algorithms for regression and classification tasks. Taking as example classification tasks of mapping the image $I$ into its correct label $C_I$, neural networks perform multiple combinations of linear and non-linear transformations of the image $I$ to assign it a label in $\mathcal C$.  The first \textit{layer} of a neural network transforms the input image $I$ in a vector $\mathbf f_1$ through a function $\phi_1$. $\mathbf f_1$ is used as input of the following layer that transforms it in a second vector $\mathbf f_2$ through a second function $\phi_2$, and so on, until the original image $I$ is mapped into a label $C_I$ by the last, $n$-th layer of the neural network:
$$C_I = \phi_n \circ \phi_{n-1}\circ ... \phi_2\circ\phi_1 (I)$$
 Given a large \textit{training set} of labeled images, a neural network is capable of learning the optimal transformations $\phi_i$ that let it map the input image to its correct label. Since the functions $\phi_i$ have many degrees of freedom - even millions - a neural network is able to learn very complex transformations. This characteristic makes NNs the optimal tool for complex tasks such as image classification, image segmentation, speech recognition and natural language processing.\\

Convolutional Neural Networks (CNNs) are a specific class of neural networks whose layer structure has been specifically designed for image recognition and segmentation. For this purpose, they don't have all the degrees of freedom of a normal, \textit{fully connected} neural network described above: each layer of a CNN has been constrained to only learn transformations of the input that are \textit{invariant} to translation of the input. This means that if used in an image classification task, a translation of the input image will not result in a change of class. The function $\phi_i$ of a CNN are \textit{convolutions} with some kernel that was learned during the training phase. Thanks to their design, training of CNNs is faster - thanks to the smaller number of parameters to be learned compared to a fully connected NN -, it is easier -since there's no need of artificially \textit{augmenting} the dataset with translated copies of the same image -, and leads to very accurate results.\\

Spherical convolutional neural networks (SCNNs) are NNs that have been specifically designed to deal with spherical data, whose layer design makes them \textit{equivariant to rotations of the input}.  Examples of tasks where data is naturally represented on a sphere are (i) climate science, where data is sampled on the surface of the Earth, (ii) cosmology, where observations are naturally projected on a sphere centered around the observer (see Figure \ref{fig:cosmicradiation}), and (iii) virtual reality, where the images are represented on a sphere centered around the player. Being able to come up with designs that are equivariant to rotations brings with it all the advantages that traditional CNNs have brought for traditional (euclidean) image classification tasks: training is faster, easier and results are very accurate. The transformations $\phi_i$ that each layer of a SCNN performs is a \textit{spherical convolution} of the input vector with a kernel learned during the training phase.

\begin{figure}
	\centering
	\caption{\label{fig:cosmicradiation} Cosmic microwave background map, the oldest electromagnetic radiation in the universe. Source: Wikipedia}
	\includegraphics[width=0.4\textwidth]{figs/literaturereview/WMAP.png}
\end{figure}
One of the main issues with traditional SCNNs is the computational complexity of computing at each layer the Spherical Harmonic Transform (SHT) of the data to perform the convolution in the spectral domain. Perraudin et al. \cite{DeepSphere} proposed a Graph Convolutional Neural Network (GCNN) that is almost equivariant to rotations, replacing the SHT with a more efficient Graph Convolution.

In this Chapter we start by presenting fundamental concepts of spectral theory on the sphere and we present classical ways of building rotation equivariant neural networks through the use of the SHT.  We present then some basics of Graph Spectral Theory useful to introduce the work of Perraudin et al. DeepSphere \cite{DeepSphere}. We present then a well suited way to build a graph to approximate the Laplace-Beltrami operator on a manifold, the Heat Kernel Graph Laplacian (HKGL) together with some convergence results. In Chapter 2 we study the spectral properties of the graph Laplacian matrix $\mathbf L$ used by Perraudin et al. and we show a way to build a graph $G'$ such that the corresponding graph Laplacian matrix $\mathbf L'$ shows better spectral properties. In Chapter 3 we investigate other different methods of building the matrix $\mathbf L$ better suited to non uniform sampling measures. In particular, we study the Finite Element Method approximation of the Laplace-Beltrami operator on the sphere. We compare the FEM and the graph Laplacian on different samplings of the sphere. We finish by discussing the general problem of how to incorporate geometrical informations about the sphere in the graph, a purely topological object.

\subsection{Fourier Transforms and Convolutions on the 2-Sphere}
[Review of \textit{Computing Fourier Transforms and Convolutions on the 2-Sphere}]
If we find a basis of minimal subspaces invariant (a vector space of functions on the sphere is invariant if all of the operators $\Lambda(g), g\in SO(3)$ take each function in the space back into the space) under all the rotations of $SO(3)$, then we simplify a lot the analysis of rotation-invariant operators.
\paragraph{Things to keep in mind from section 2, "Preliminaries"}
\begin{enumerate}
	\item any rotation $g\in SO(3)$ can be written in the well-known Euler angle decomposition: $g = u(\phi)a(\theta)u(\psi)$ determined uniquely for almost all $g$. Remember that any point on the sphere
	\item $\omega(\theta, \phi) = \left(\cos\phi\sin\theta, \sin\phi\sin\theta, \cos\theta\right)$. In fact, the 2-sphere is a quotient of the rotation group $SO(3)$ and inherits its natural coordinate system from that of the group.
	\item $\Lambda(g)f(\omega) = f(g^{-1}\omega)$
	\item invariant volume measure on $SO(3)$ is $dg=\sin\theta\ d\theta\ d\phi\ d\psi$, invariant volume measure on the sphere is $d\omega = \sin\theta\ d\theta\ d\phi$
	\item The invariant subspace of degree $l$ harmonic polynomials restricted to the sphere is called the space of \textit{spherical harmonics of degree l}. Spherical harmonics of different degree are orthogonal to one another
	\item In coordinates,
	$$Y_l^m(\theta, \phi) =(-1)^m\sqrt{\frac{(2l+1)(l-m)!}{4\pi(l+m)!}}P_l^m(\cos\theta)e^{im\phi}$$
	where $P_l^m$ are Legendre functions.
	\begin{figure}
		\centering
		\includegraphics[width=0.6\textwidth]{../codes/03.FEM_laplacian/HEALPix/img/linear_FEM_8_eigenvectors.png}
		\label{fig:spherical harmonics}
		\caption{The first 16 spherical harmonics}
	\end{figure}

	\item Of all the possible basis for $L^2(S^2)$ the spherical harmonics uniquely exploit the symmetries of the sphere. Under a rotation $g$, each spherical harmonic of degree $l$ is transformed into a linear combination of only those spherical harmonics of same degree $l$.
	Thus the effect of a rotation on a function expressed in the basis of the spherical harmonics is a multiplication by a semi-infinite block-diagonal matrix with the $(2l+1)\times(2l+1)$ blocks for each $l \geq 0$ given by $$D^{(l)}(g) = \left(D^{(l)}_{m,n}\right) (g) =  \left(D^{(l)}_{m,n}\right)(u(\phi)a(\theta)u(\psi)) = e^{-im\psi}d^{(l)}_{m,n}(\cos \theta) e^{-in\phi}$$
	The effect of all of this is to block-diagonalize rotationally invariant operators; namely, convolution operators obtained as weighted averages of the rotation operators by functions or kernels. For example the Laplace-Beltrami operator, that acts diagonally on the spherical harmonic basis.
	\item \begin{definition}{[\textit{Left Convolution}]}\\
		$k\star f(\omega) = \left(\int_{g\in SO(3)}dg\ k(g\eta)\Lambda(g)\right)f(\omega) = \int_{g\in SO(3)}k(g\eta)f(g^{-1}\omega)dg$
		where $\eta$ is the north pole.
	\end{definition}
	Since the convolution is a linear combination of rotation operators $\Lambda(g)$, it follows that also the convolution must be block diagonalized. Indeed,
	$$\hat {(f \star h)}(l,m) = 2\pi \sqrt{\frac{4\pi}{2l+1}}\hat f(l,m) \hat h(l,0) $$

\end{enumerate}

\subsection{Spherical Convolutional Neural Networks}
[Review of \textit{Spherical CNNs}]
\subsection{Graph Spectral Theory} \label{sec:Chapter1: Spectral Graph Theory}
[Review of \textit{The emerging field of Graph Signal Processing}]
\subsection{Deep Sphere V1.0}
[Review of \textit{Deep Sphere}]
\subsection{Belkin's trinity}
[Review of \textit{the Belkin's trinity}]

\subsubsection{Towards a theoretical foundation of Laplacian-based manifold methods}
In this paper they present two results: a pointwise probabilistic convergence of \textbf{the extension of the graph Laplacian}
\begin{definition}{Graph Laplacian}
	$$ \left(\mathbf L_n^t\right)_{ij}=\begin{cases}
	-w_{ij}, & i\neq j\\
	\sum_{k}w_{ik}, & i=j
	\end{cases}$$
\end{definition}
\begin{definition}{Point cloud Laplace operator}
	$$L_n^t:\quad(L_n^tf)(y) = \frac{1}{n}f(y)\sum_i e^{-\frac{||x_i-y||^2}{4t}}-\frac{1}{n}\sum_ie^{-\frac{||x_i-y||^2}{4t}}f(x_i)$$
\end{definition}
\begin{definition}{Functional approximation to the Laplace-Beltrami operator} \label{eq:L^t}
	$$L^tf(p) :=  \frac{1}{ (4\pi t)^{\frac{k+2}{2}}} \int_\mathcal Me^{-\frac{||p-x||^2}{4t}}\left(f(x)-f(p)\right)d\mu(x)$$
\end{definition}

\begin{theorem}{Pointwise convergence}
	$$\forall f \in C^\infty(\mathcal M)\quad  C\frac{(4\pi t_n)^{-\frac{k+2}{2}}}{n} L_n^t f(\bf x) \xrightarrow{n\to\infty}\triangle_\mathcal M f(\bf x)$$
\end{theorem}

and a uniform (pointwise convergence of the operator) one
\begin{theorem}{uniform convergence}
	$$\sup_{x\in\mathcal M, f\in \mathcal F_C}\left| C\frac{(4\pi t_n)^{-\frac{k+2}{2}}}{n} L_n^t f(\bf x) - \triangle_\mathcal M f(\bf x) \right|\xrightarrow{n\to\infty}0
	, \quad \mathcal F_C = \left\{f\in C^\infty(\mathcal M), f^{(i)}(x)\leq M, i=1,2,3\right\}$$
\end{theorem}

here nothing is said about convergence of the spectra, plus there's nothing written about the relationship between $\mathbf{Eig} L_n^t$ (the eigenfunctions and eigenvalues of the extension of the graph Laplacian) and $\mathbf {Eig} \mathbf {L}_n^t$ (the eigenvectors and eigenvalues of the matrix Laplacian).

Theorem 1 is proven by simple analysis arguments and by Hoeffding's formula (probability).
First, by the simple law of large numbers, we have that for a fixed $t>0$, a fixed function $f$ and a fixed point $p\in\mathcal M$
\begin{equation}\label{eq:pointwise convergence of laplacian discrete approximation}
	\lim_{n\to\infty}\frac{1}{tn}\frac{1}{ (4\pi t)^{\frac{k}{2}}}L_n^tf(p)= L^tf(p)
\end{equation}

To prove the convergence of $L^t$ to $\triangle_\mathcal M$, then we need three steps, that we can recycle completely. They use the fact that thanks to the exponential map the heat kernel centered on $p$ on any manifold can be approximated by a Gaussian in the ambient Euclidean space in a small neighborhood of $p$, and the relationship between Euclidean distances and geodesic distances.

Theorem 2 is proven with arguments of Functional Analysis: Ascoli-Arzelà, compact convergence in Sobolev spaces, etc.etc...

\subsubsection{Consistency of Spectral Clustering}
$$ \mathbf{Eig} \mathbf{L}^t_n \xrightarrow[a.s.]{n\to\infty} \mathbf{Eig} L^t $$
It aims at proving the convergence of eigenvalues and eigenvectors of random graph Laplacian matrices for growing sample size. They present two results: one for the normalized Laplacian and one for the unnormalized Laplacian. Since the matrix eigenvectors grow in dimension as the sample size increases, standard convergence arguments can not be applied. However, they show that there exists a function $f\in C(\mathcal M)$ such that the difference between the eigenvector $v_n$ and the restriction of $f$ to the sample converges to $0$

$$||v_n-\rho_nf||\rightarrow 0$$

To do so they see the eigenvector $v_n$ as the restriction to the sample of a continuous eigenfunction $f_n$ of some continuous operator $U'_n$ that acts on the space $C(\mathcal M)$. Then they use the fact that

$$||v_n-\rho_nf||_\infty = ||\rho_nf_n-\rho_nf||_\infty\leq ||f_n-f||_\infty$$

So, it will just be necessary to show that  $$||f_n-f||_\infty\rightarrow 0$$
\textbf{compact convergence} of both matrices towards $L^t$ (where $\mathcal M$ is a compact metric space) in the Banach space of the continuous functions $(C, ||\cdot||_\infty)$.

Compact convergence ensures convergence of spectral properties in the following sense: for isolated eigenvalues of the limit operator $\triangle_\mathcal M$ with finite multiplicity we have convergence of eigenvalues and eigenspaces but not convergence of eigenfunctions. for isolated simple eigenvalues of the limit operator we have also convergence of the eigenfunctions!

The proof consists in three steps:
\paragraph{Step 1} Construct a bounded operator $U'_n$ on the Banach space $(C(\mathcal M), ||\cdot||_\infty)$ such that restricted on the sampled values behaves like $\mathbf{L}'_n$. Then, construct an operator $U'$ such that for the law of large numbers for a fixed $f$ and for a fixed $x$, $U'_nf(x) \xrightarrow U'f(x) $
\paragraph{Step 2} Here they establishes the connection between the spectra of $L'_n$ and $U'_n$. In particular, they prove a one-to-one correspondence between the eigenfunctions and eigenvalues of $U'_n$ and the eigenvectors and eigenvalues of $L'_n$, provided that satisfy $\lambda\notin \{1\}=\sigma_{ess}(U'_n)= \sigma_{ess}(U')$.
\paragraph{Step 3} Here we prove compact convergence:

$$U'_n \xrightarrow[n\to\infty]{c,\ a.s.}U'$$

At the light of compact convergence and on the analysis of the essential spectrum of $U'_n, U'$ and the one-to-one correspondence of the spectra done in step 2, given Proposition 6 \textit{Perturbation results for compact convergence} we get to the following result

\begin{theorem}
	Let $\lambda\neq 1 $ be an eigenvalue of $U'$ and $M\subset \mathbb C$ an open neighborhood of $\lambda$ such that $\sigma(U')\cap M=\{\lambda\}$. Then:
	\begin{enumerate}
		\item Convergence of eigenvalues: The eigenvalues in$\sigma(L'_n)\cap M$ converge to $\lambda$ in the sense that every sequence $(\lambda_n)_{n\in\mathbb N}$ with $\lambda_n\in\sigma(L'_n)\cap M$ satisfies $\lambda_n\rightarrow \lambda$ almost surely.
		\item Convergence of spectral projections: There exists some $N\in\mathbb N$ such that for $n>N$, the sets $\sigma(U'_n)\cap M$ are isolated in $\sigma(U'_n)$. For $n>N$, let $Pr'_n$ be the spectral projection of $U'_n$ corresponding to $\sigma(U'_n)\cap M$, and $Pr$ the spectral projection of $U$ for $\lambda$. Then $Pr'_n\xrightarrow p Pr a.s.$
		\item Convergence of eigenvectors: if $\lambda$ is a single eigenvalue, then the eigenvectors of $L'_n$ converge a.s. up to a change of sign: if $v_n$ is the eigenvector
		of $L'_n$ with eigenvalue $\lambda_n$, $v_{n,i}$ its i-th coordinate, and $f$ the eigenfunction of eigenvalue $\lambda$, then there exists a sequence $(a_n)_{n\in\mathbb N}$ with $a_i \in \{+1,-1\}$ such that $\sup_{i=1,...,n} |a_nv_{n,i} - f(X_i)| \rightarrow 0$ a.s. In particular, for all $b \in\mathbb R$, the sets $\{a_nf_n > b\}$ and $\{f > b\}$ converge, that is, their symmetric difference satisfies $P(\{f > b\}\triangle\{a_nf_n > b\}) \rightarrow 0$.
	\end{enumerate}
\end{theorem}

A similar theorem is stated also for non-normalized Laplacian matrix, although the arguments stay the same.
\subsubsection{Convergence of Laplacian Eigenmaps}
Here all the pieces are put together.

$$ \mathbf{Eig} \mathbf{ L}^t_n \xrightarrow[a.s.]{n\to\infty} \mathbf{Eig} L^t \xrightarrow{t\to0} \mathbf{Eig} \triangle_\mathcal M $$

\begin{theorem}
	Let $\lambda_{n,i}^t$ be the ith eigenvalue of $\hat L_n^t$ and $e^t_{n,i}$ be the corresponding eigenfunction (which for each fixed i will be shown to exist for t sufficiently small). Let $\lambda_{i}$ be the ith eigenvalue of $\triangle_\mathcal M$ and $e_{i}$ be the corresponding eigenfunction. Then there exists a sequence $t_n\rightarrow 0$ such that

	$$\lim_{n\rightarrow\infty} \lambda_{n,i}^{t_n}=\lambda_i$$
	$$\lim_{n\rightarrow\infty}||e_{n,i}^{t_n}(x) - e_i(x)||_2 = 0$$

	where the limits are in probability.

\end{theorem}

\paragraph{Step 1: Spectral convergence of the empirical approximation $\mathbf{ L}_n^t$ to $L^t$}
Recycle the work of \textbf{Consistency of Spectral Clustering} with the analysis of the essential spectrum of the limit operator $\sigma_{ess}(L^t)$.
\paragraph{Step 2: Spectral convergence of the functional approximation $L^t$ to $\triangle$}
Really hard. Uniform operator convergence does not hold, however spectral convergence is still assured in theorem 4.1 of the paper. This part, although really hard, will stay the same!
sub


\documentclass[../../main.tex]{subfiles}
\begin{document}
\subsubsection{Timeunit To Number of Seconds}

The operation $toSeconds$ will return the number of seconds corresponding to the input $Timeunit$
\begin{zed}
  Timeunit ::= second ~| ~ minute ~| ~hour ~| ~day ~| ~week ~| ~month ~| ~year
\end{zed}
such that the following schema defines $toSeconds$
\begin{schema}{ToSeconds[Timeunit]}
  t? : Timeunit \\
  toSeconds~\_ : Timeunit \pfun \nat
  \where
  toSeconds(t?) = 1 \iff t? = second \\
  toSeconds(t?) = 60 \iff t? = minute \\
  toSeconds(t?) = 3600 \iff t? = hour \\
  toSeconds(t?) = 86400 \iff t? = day \\
  toSeconds(t?) = 604800 \iff t? = week \\
  toSeconds(t?) = 2629743 \iff t? = month \\
  toSeconds(t?) = 31556926 \iff t? = year
\end{schema}
\end{document}


\providecommand{\main}{../..}
\documentclass[\main/thesis.tex]{subfiles}
\begin{document}

\section{Continuous Systems}\label{continuous}

We say a numeral system is \textit{continuous} if there are no gaps in the number
line and we can always find a successor after each numeral.
In other words, a system is continuous if every numeral is \textit{incrementable}.

\begin{lstlisting}
Continuous : ∀ b d o → Set
Continuous b d o = (xs : Numeral b d o) → Incrementable xs
\end{lstlisting}

Bounded systems are deemed to be incontinuous because there are no successor
after the maximum numeral.

\begin{lstlisting}
Bounded⇒¬Continuous : ∀ {b d o}
    → Bounded b d o
    → ¬ (Continuous b d o)
Bounded⇒¬Continuous (xs , max) claim
    = contradiction (claim xs) (Maximum⇒¬Incrementable xs max)
\end{lstlisting}

Since systems of \lstinline|NullBase| and \lstinline|AllZeros| are all bounded,
they cannot be continuous. We will only be concerning ourselves with systems of
\lstinline|Proper| in the rest of the section.

Suppose we want to determine if a system of \lstinline|Proper| is continuous,
we can examine \textit{every} numeral of that system with the view function
\lstinline|nextView|.
If \textit{all} numerals are sorted as \lstinline|Interval| and
\lstinline|UngappedEndpoint|, then the system is continuous;
if \textit{any} numeral is sorted as \lstinline|GappedEndpoint|,
then the system must not be continuous.

But it is impossible to go through every numeral because we know that systems
of \lstinline|Proper| are non-exhaustive.
Therefore we need another way of deciding the continuity of a system.

\subsection{Look no further than the Gaps}

In the section~\ref{next}, we have propositions for describing gaps.

\begin{lstlisting}
Gapped#0 : ∀ b d o → Set
Gapped#0 b d o = suc d < carry o * suc b

Gapped#N : ∀ b d o
    → (xs : Numeral (suc b) (suc d) o)
    → (proper : 2 ≤ suc (d + o))
    → Set
Gapped#N b d o xs proper
    = suc d < (⟦ next-numeral-Proper xs proper ⟧ ∸ ⟦ xs ⟧) * suc b

Gapped : ∀ {b d o}
    → (xs : Numeral (suc b) (suc d) o)
    → (proper : 2 ≤ suc (d + o))
    → Set
Gapped {b} {d} {o} (x ∙)    proper = Gapped#0 b d o
Gapped {b} {d} {o} (x ∷ xs) proper = Gapped#N b d o xs proper
\end{lstlisting}

\lstinline|Gapped#0| describes the first gap of a system, whereas
\lstinline|Gapped#N| covers the rest.
Compared to \lstinline|Gapped#N|, the definition of \lstinline|Gapped#0| is much
less demanding because it only depends on the three indices, making it really
easy to be determined.

\subsection{When the First Gap is Open}

Let's start with the easier case, we can know for sure that when the first gap
\lstinline|Gapped#0| is open, the system must not be continuous.

\begin{center}
    \begin{adjustbox}{max width=\textwidth}
        \begin{tikzpicture}
            % the frame
            \path[clip] (0, -2) rectangle (16, 2);
            % the spine
            \draw[ultra thick] (0,0) -- (16,0);
            % the body

            \foreach \i in {1,...,7} {
                \draw[ultra thick, fill=white] ({\i+0.05}, -0.2) rectangle ({\i+0.95}, +0.2);
            };
            \draw[ultra thick, fill=black] (8.05, -0.2) rectangle (8.95, +0.2);

            \foreach \i in {12,...,16} {
                \draw[ultra thick, fill=white] ({\i+0.05}, -0.2) rectangle ({\i+0.95}, +0.2);
            };
            \draw[->, ultra thick] (8.5,1) -- (8.5,0.5)
                node at (8.5, 1.3) {the first endpoint};

            % gap
            \draw[ultra thick, loosely dotted] (9, -0.2) -- (9,-1);
            \draw[ultra thick, loosely dotted] (12,-0.2) -- (12,-1);
            \draw[ultra thick, decoration={brace,mirror},decorate]
                (9, -1) -- (12,-1);
            \node at (10.5, -1.3) {the first gap};
        \end{tikzpicture}
    \end{adjustbox}
\end{center}

We construct the first endpoint with the greatest digit.

\begin{lstlisting}
first-endpoint : ∀ b d o → Numeral (suc b) (suc d) o
first-endpoint b d o = greatest-digit d ∙
\end{lstlisting}

The first endpoint is proven to be not incrementable.

\begin{lstlisting}
first-endpoint-¬Incrementable : ∀ {b d o}
    → (proper : 2 ≤ suc (d + o))
    → (gapped : Gapped#0 b d o)
    → ¬ (Incrementable (first-endpoint b d o))
first-endpoint-¬Incrementable {b} {d} {o} proper gapped
    with nextView (first-endpoint b d o) proper
first-endpoint-¬Incrementable proper gapped
    | Interval b d o ¬greatest
    = contradiction (greatest-digit-is-the-Greatest d) ¬greatest
first-endpoint-¬Incrementable proper gapped
    | GappedEndpoint b d o greatest _
    = GappedEndpoint⇒¬Incrementable
        (first-endpoint b d o) greatest proper gapped
first-endpoint-¬Incrementable proper gapped
    | UngappedEndpoint b d o greatest ¬gapped
    = contradiction gapped ¬gapped
\end{lstlisting}

The first endpoint can then be used as an counter example of the continuity of
the system.

\begin{lstlisting}
Gapped#0⇒¬Continuous : ∀ {b d o}
    → (proper : 2 ≤ suc (d + o))
    → (gapped : Gapped#0 b d o)
    → ¬ (Continuous (suc b) (suc d) o)
Gapped#0⇒¬Continuous {b} {d} {o} proper gapped cont
    = contradiction
        (cont (first-endpoint b d o))
        (first-endpoint-¬Incrementable proper gapped)
\end{lstlisting}

Now we can see if a system is incontiuous just by checking the first gap.

\begin{lstlisting}
Continuous-Proper : ∀ b d o
    → (proper : 2 ≤ suc (d + o))
    → Dec (Continuous (suc b) (suc d) o)
Continuous-Proper b d o proper with Gapped#0? b d o
Continuous-Proper b d o proper | yes gapped#0
    = no (Gapped#0⇒¬Continuous proper gapped#0)
Continuous-Proper b d o proper | no ¬gapped#0
    = ?
\end{lstlisting}

However, when the first gap is closed, it is uncertain whether the given system
will be continuous.

\subsection{When the First Gap is Closed}

If we can prove that \lstinline|Gapped#N| \textbf{implies} \lstinline|Gapped#0|,
then by contraposition, we can know that all gap of a system are closed if the
first gap is also closed.

\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
Gapped#N⇒Gapped#0 : ∀ {b d o}
    → (xs : Numeral (suc b) (suc d) o)
    → (proper : 2 ≤ suc (d + o))
    → Gapped#N b d o xs proper
    → Gapped#0 b d o
Gapped#N⇒Gapped#0 xs proper gapped#N with nextView xs proper
Gapped#N⇒Gapped#0 xs proper gapped#N | Interval b d o ¬greatest =
    start
        suc (suc d)
    ≤⟨ gapped#N ⟩
        (⟦ next-numeral-Proper-Interval xs ¬greatest proper ⟧ ∸ ⟦ xs ⟧) * suc b
    ≤⟨ *n-mono (suc b) (...next-numeral-Proper-Interval-lemma xs ¬greatest...) ⟩
        (suc zero ⊔ o) * suc b
    □)
Gapped#N⇒Gapped#0 (x ∙)    proper _ | GappedEndpoint b d o greatest gapped#0
    = gapped#0
Gapped#N⇒Gapped#0 (x ∷ xs) proper _ | GappedEndpoint b d o greatest gapped#N
    = Gapped#N⇒Gapped#0 xs proper gapped#N
Gapped#N⇒Gapped#0 xs proper gapped#N | UngappedEndpoint b d o greatest ¬gapped =
    start
        suc (suc d)
    ≤⟨ gapped#N ⟩
        (⟦ next-numeral-Proper-UngappedEndpoint xs greatest proper ¬gapped ⟧
            ∸ ⟦ xs ⟧) * suc b
    ≤⟨ *n-mono (suc b) (... next-numeral-Proper-UngappedEndpoint-lemma ...) ⟩
        (suc zero ⊔ o) * suc b
    □)
\end{lstlisting}

We can prove that, if the first gap is closed, then so do the rest of the gaps,
by contraposition.

\begin{lstlisting}
¬Gapped#0⇒¬Gapped : ∀ {b d o}
    → (xs : Numeral (suc b) (suc d) o)
    → (proper : 2 ≤ suc (d + o))
    → ¬ (Gapped#0 b d o)
    → ¬ (Gapped xs proper)
¬Gapped#0⇒¬Gapped (x ∙)    proper ¬Gapped#0 = ¬Gapped#0
¬Gapped#0⇒¬Gapped (x ∷ xs) proper ¬Gapped#0 = contraposition
    (Gapped#N⇒Gapped#0 xs proper)
    ¬Gapped#0
\end{lstlisting}

We can conclude that, if all gaps are closed,
then all numerals should be incrementable, therefore the system is continuous.

\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
¬Gapped#0⇒Continuous : ∀ {b d o}
    → (proper : 2 ≤ suc (d + o))
    → (¬gapped : ¬ (Gapped#0 b d o))
    → Continuous (suc b) (suc d) o
¬Gapped#0⇒Continuous proper ¬gapped#0 xs with Incrementable? xs
¬Gapped#0⇒Continuous proper ¬gapped#0 xs | yes incr = incr
¬Gapped#0⇒Continuous proper ¬gapped#0 xs | no ¬incr = contradiction
    (¬Gapped⇒Incrementable xs proper (¬Gapped#0⇒¬Gapped xs proper ¬gapped#0))
    ¬incr
\end{lstlisting}

\subsection{Determining Continuity}

Finally, we can decide if a system is continuous.

\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
Continuous-Proper : ∀ b d o
    → (proper : 2 ≤ suc (d + o))
    → Dec (Continuous (suc b) (suc d) o)
Continuous-Proper b d o proper with Gapped#0? b d o
Continuous-Proper b d o proper | yes gapped#0
    = no (Gapped#0⇒¬Continuous proper gapped#0)
Continuous-Proper b d o proper | no ¬gapped#0
    = yes (¬Gapped#0⇒Continuous proper ¬gapped#0)

Continuous? : ∀ b d o → Dec (Continuous b d o)
Continuous? b d o with numView b d o
Continuous? _ _ _ | NullBase d o = no (Bounded⇒¬Continuous (Bounded-NullBase d o))
Continuous? _ _ _ | NoDigits b o = yes (λ xs → NoDigits-explode xs)
Continuous? _ _ _ | AllZeros b = no (Bounded⇒¬Continuous (Bounded-AllZeros b))
Continuous? _ _ _ | Proper b d o proper = Continuous-Proper b d o proper
\end{lstlisting}

\subsection{Successor Function}

Since the proof of \lstinline|Continuous| is essentially a successor function,
we can use it to increment a numeral.

\begin{lstlisting}
1+ : ∀ {b d o}
    → {cont : True (Continuous? b d o)}
    → (xs : Numeral b d o)
    → Numeral b d o
1+ {cont = cont} xs = proj₁ (toWitness cont xs)
\end{lstlisting}

A numeral taking these two routes should result in the same {{\lstinline|ℕ|}}.

\begin{center}
    \begin{tikzpicture}
        \matrix (m) [matrix of nodes,row sep=6em,column sep=8em,minimum width=4em]
            {
                {\lstinline|Numeral b d o|} & {\lstinline|Numeral b d o|} \\
                {\lstinline|ℕ|} & {\lstinline|ℕ|} \\
            };
      \path[-stealth]
            (m-1-1)
                edge node [left] {{\lstinline|⟦_⟧|}} (m-2-1)
                edge node [above] {{\lstinline|+1|}} (m-1-2)
            (m-2-1.east|-m-2-2)
                edge node [below] {{\lstinline|suc|}} (m-2-2)
            (m-1-2)
                edge node [right] {{\lstinline|⟦_⟧|}} (m-2-2);
    \end{tikzpicture}
\end{center}

The proof also comes for free from \lstinline|Continuous| as part of its
definition.

\begin{lstlisting}
1+-toℕ : ∀ {b d o}
    → {cont : True (Continuous? b d o)}
    → (xs : Numeral b d o)
    → ⟦ 1+ {cont = cont} xs ⟧ ≡ suc ⟦ xs ⟧
1+-toℕ {cont = cont} xs = proj₂ (toWitness cont xs)
\end{lstlisting}

% \subsection{Observations}
%
% \lstinline|Numeral 4 3 0| is a quaternary (base-4) system with only 3 digits:
% $0, 1, 2$.
% Suppose we plot all values of numerals of \lstinline|Numeral 4 3 0| onto a number
% line, it would have a series of gaps that are ever widening as shown in the figure below.
%
% \begin{center}
%     \begin{adjustbox}{max width=\textwidth}
%         \begin{tikzpicture}[spy using outlines]
%
%             \foreach \j in {0,...,2} {
%                 \foreach \i in {0,...,2} {
%                     \draw[fill=black] ({\j*4 + \i}, 0.5) rectangle ({\j*4 + \i + 0.75}, 0.75);
%                 };
%             };
%
%             \draw[ultra thick] (0, 0) -- (16, 0);
%
%             % ticks
%             \foreach \i in {0, ..., 64} {
%                 \draw[thick] ({\i*0.25},0) -- ({\i*0.25},-0.2);
%             };
%             \foreach \i in {0, ..., 16} {
%                 \pgfmathsetmacro{\j}{int(\i * 4)}
%                 \draw[thick] (\i,0) -- (\i,-0.3)
%                     node[below, scale=0.8] {\j};
%             };
%
%             % spies
%             \spy[rectangle,lens={scale=8}, size=5cm, connect spies]
%                 on (0.875,0.75) in node [left] at (5.25,5);
%             \spy[rectangle,lens={scale=2}, size=5cm, connect spies]
%                 on (3.375,0.75) in node [left] at (10.5,5);
%
%             % gaps
%             \draw[ultra thick, loosely dotted] (1.75,5) -- (1.75,6);
%             \draw[ultra thick, loosely dotted] (3.75,5) -- (3.75,6);
%             \draw[ultra thick, decoration={brace,mirror},decorate]
%                 (3.75, 6) -- (1.75, 6);
%             \node at (2.75, 6.5) {$1$};
%             \draw[ultra thick, loosely dotted] (6.75,5) -- (6.75,6);
%             \draw[ultra thick, loosely dotted] (9.25,5) -- (9.25,6);
%             \draw[ultra thick, decoration={brace,mirror},decorate]
%                 (9.25, 6) -- (6.75,6);
%             \node at (8, 6.5) {$5$};
%             \draw[ultra thick, loosely dotted] (10.75, 0.5) -- (10.75,6);
%             \draw[ultra thick, loosely dotted] (16,0.5) -- (16,6);
%             \draw[ultra thick, decoration={brace,mirror},decorate]
%                 (16, 6) -- (10.75,6);
%             \node at (13.375, 6.5) {$21$};
%
%         \end{tikzpicture}
%     \end{adjustbox}
% \end{center}
%
% \subsection{The Relation between Gaps}
%
% In the section~\ref{next}, we have propositions for describing these gaps.
%
% \begin{lstlisting}
% Gapped#0 : ∀ b d o → Set
% Gapped#0 b d o = suc d < carry o * suc b
%
% Gapped#N : ∀ b d o
%     → (xs : Numeral (suc b) (suc d) o)
%     → (proper : 2 ≤ suc (d + o))
%     → Set
% Gapped#N b d o xs proper
%     = suc d < (⟦ next-numeral-Proper xs proper ⟧ ∸ ⟦ xs ⟧) * suc b
%
% Gapped : ∀ {b d o}
%     → (xs : Numeral (suc b) (suc d) o)
%     → (proper : 2 ≤ suc (d + o))
%     → Set
% Gapped {b} {d} {o} (x ∙)    proper = Gapped#0 b d o
% Gapped {b} {d} {o} (x ∷ xs) proper = Gapped#N b d o xs proper
% \end{lstlisting}
%
% \lstinline|Gapped#0| only describes the first gap of a system, whereas the rest
% of the gaps are covered by \lstinline|Gapped#N|.
% Compared to \lstinline|Gapped#N|, the definition of \lstinline|Gapped#0| is much
% less demanding because it only depends on the three indices, making it really
% easy to be determined.

\end{document}


% Created 2021-09-09 Thu 13:21
% Intended LaTeX compiler: pdflatex
\documentclass[presentation]{beamer}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{grffile}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\usepackage{awesomebox}
\usepackage{booktabs}
\usepackage{placeins}
\usepackage{siunitx}
\usepackage{minted}
\usetheme[progressbar=frametitle,block=fill]{metropolis}
\usetheme{default}
\author{\emph{Tejaswin Parthasarathy}, Mattia Gazzola}
\date{\today}
\title{Scientific computing in Python}
\subtitle{ME447: Comp. Design \& Dyn. of Soft Syst}
\hypersetup{
 pdfauthor={\emph{Tejaswin Parthasarathy}, Mattia Gazzola},
 pdftitle={Scientific computing in Python},
 pdfkeywords={},
 pdfsubject={},
 pdfcreator={Emacs 28.0.50 (Org mode 9.3.6)},
 pdflang={English}}
\begin{document}

\maketitle

\section{\texttt{numpy}}
\label{sec:orga56d279}
\begin{frame}[label={sec:org30f73da},fragile]{\texttt{numpy} package \footnote{\href{https://www.numpy.org/}{numpy}}}
 \begin{itemize}
\item High-performance vector, matrix and higher-dimensional data structures for
\texttt{Python}
\item Shares a lot of similarity and differences (syntactically and semantically)
with \texttt{MATLAB} \footnote{\href{https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html}{numpy for Matlab users}}
\item Vectors, matrices and higher-dimensional data sets are \emph{(nd) arrays} in \texttt{numpy}
(there is also the \texttt{matrix} class, but it is being phased out)
\item Standard import---\texttt{import numpy as np}
\end{itemize}
\end{frame}
\begin{frame}[label={sec:org02caaad},fragile]{Simple array creation in \texttt{numpy}}
 \note{:B\_note:
\begin{itemize}
\item Show the documentaion and how to browse it
\item Show as a demonstration\ldots{}
\end{itemize}}
\begin{itemize}
\item \texttt{v = np.array([1,2,3,4])} creates a vector (argument : list)
\item \texttt{M = np.array([[1, 2], [3, 4]])} creates a matrix (argument : nested list)
\item \texttt{type(v), type(M)} both return \texttt{numpy.ndarray}
\item The difference lies in the \alert{shape} seen using \texttt{v.shape/M.shape}\ldots{}
\item Alternatively use function \texttt{np.shape(v)}
\item Arrays can also have different data types, seen using \texttt{v.dtype}
\begin{itemize}
\item \texttt{npint32}, \texttt{np.float32}, \texttt{np.float64} (default)\ldots{}
\end{itemize}
\item \texttt{M = np.array([[1, 2], [3, 4]], dtype=int)}
\end{itemize}
\end{frame}
\begin{frame}[label={sec:org06896aa},fragile]{Array generating functions}
 \note{:B\_note:
\begin{itemize}
\item Show as a demonstration\ldots{}
\end{itemize}}
\begin{itemize}
\item \texttt{v = np.arange(0,11,2)} gives ranges similar to \texttt{Python's range}
\item \texttt{v = np.arange(0, 11, 0.1)} is also valid! (gives step of 0.1)
\item \texttt{v = np.linspace(0, 1, 3)} creates a linearly spaced vector [0, 0.5, 1.]
\item Also have \texttt{logspace, geomspace} for other progressions
\item Multidimensional array creation using \texttt{meshgrid, ndgrid} and others
\item Other useful ones are \texttt{ones} (which generates matrix with all 1), \texttt{zeros}
(similar) and \texttt{eye} (identity matrix)
\end{itemize}
\end{frame}

\begin{frame}[label={sec:orgc25f801},fragile]{Random numbers}
 \note{:B\_note:
\begin{itemize}
\item Show as a demonstration
\item np.random.rand(5,5)\ldots{}same syntax for randn too..
\item np.random.randint(1,5,size=(2,4))
\end{itemize}}
\begin{itemize}
\item We'll work extensively with random numbers, so let's see what \texttt{numpy} has
to offer
\item \texttt{np.random.rand(<shape>)} gives random floats from uniform dist. in [0, 1)
\item \texttt{np.random.randn(<shape>)} gives random floats from univariate normal
dist. with \(\mu = 0\) and \(\sigma = 1\)
\item \texttt{np.random.randint(low, high, size)} gives random ints from discrete uniform dist.
in \texttt{[low, high)}
\end{itemize}
\end{frame}
\begin{frame}[label={sec:org5da2caf},fragile]{Indexing}
 \note{:B\_note:
\begin{itemize}
\item Show as a demonstration of all
\item A = np.random.randn(5,5); A[2:3,:] is slicing
\item Fancy indexing: idx\_rows = [1,5]; idx\_cols = [1,2,4]; A[idx\_rows, idx\_cols]
\item mask\_row = [True, False, False, False, True]; A[mask\_row]. Compare with
A[idx\_rows, :] above
\end{itemize}}
\begin{itemize}
\item Slicing works for \texttt{numpy} arrays too, across any dimension!
\item Fancy indexing
\begin{itemize}
\item Extends slicing to be more useful + practical
\end{itemize}
\item Masking
\begin{itemize}
\item Bools to \emph{mask} what is not necessary
\item Useful with conditional functions (e.g. \texttt{x < 5})
\end{itemize}
\item Reshaping using \texttt{np.reshape} changes index access
\end{itemize}
\end{frame}

\begin{frame}[label={sec:org3b90a47},fragile]{Linear Algebra}
 \note{:B\_note:
\begin{itemize}
\item In the demo construct structure A with 1:25 using \texttt{A =
      np.linspace(1.0,25.0,25)} and then do \texttt{A = A.reshape(5,5)}
\item Use \texttt{np.arange} for constructing \texttt{v=np.arange(0, 5)}
\item Show that \texttt{A*v} does element wise onlt
\end{itemize}}

\begin{itemize}
\item Scalar operations on an array \texttt{A}
\begin{itemize}
\item \texttt{A + 2}, \texttt{A * 2} , \texttt{A ** 2} \ldots{}
\end{itemize}
\item Element wise operations on an array \texttt{A}
\begin{itemize}
\item \texttt{A * A}, \texttt{A / A} \ldots{}
\item What do you get when you do \texttt{A*v}? \alert{DEMO}
\end{itemize}
\item Matrix algebra on an array \texttt{A}
\begin{itemize}
\item \texttt{np.dot(A, v)} or \texttt{A.dot(v)} or simply \texttt{A@v}
\item Shape needs to be compliant! \texttt{numpy} also has broadcasts that is useful,
but is confusing and so is not covered here \ldots{}
\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[label={sec:orgebf8dcf},fragile]{Practice}
 \begin{block}{Please attempt}
\begin{itemize}
\item \texttt{12\_numpy\_library.ipynb}
\item For a more extensive tutorial: \url{https://github.com/donnemartin/data-science-ipython-notebooks\#numpy}
\end{itemize}
\end{block}
\end{frame}
\note{:B\_note:
\begin{itemize}
\item Access to \url{https://github.com/donnemartin/data-science-ipython-notebooks}
especially the numpy section
\end{itemize}}

\section{Genetic algorithm using \texttt{numpy}}
\label{sec:org9f358bb}
\begin{frame}[label={sec:orgec5522e}]{Schematic}
\footnotesize
\begin{figure}[htbp]
\centering
\includegraphics[width=1.0\textwidth]{images/ga_schematic.png}
\caption{Schematic of an evolutionary search algorithm}
\end{figure}
\end{frame}
\begin{frame}[label={sec:org71af0f5}]{Let's use GA to solve\ldots{}}
\begin{block}{Problem statement}
Maximize the function \(f(\mathbf{x}) = \sum_{i=1}^{6} w_i x_i\) for a given
set of weights \(w_i\), with the constraints that \(x_i \; \in \; [-4,4] \;
   \forall \; i\).

\(\therefore\) Domain \(\mathbb{D}\) of the search is \(\mathbb{D}:= [-4,4]^6\).

Optimization problem: \(\left(\mathbb{D}, \mathbb{R} , \mathbf{f}, \geq \right)\).
\end{block}
\end{frame}
\begin{frame}[label={sec:org9f1ea4f},fragile]{Representation?}
 \begin{block}{Bitvector? Float vector?}
Pick a representation for \(\mathbf{x}\)
\end{block}
In any case, \texttt{np.array} seems useful. You can make a bitvector using
\texttt{np.array(..., dtype=bool)}
\end{frame}
\begin{frame}[label={sec:orgfdc435f},fragile]{GA parameters}
 \begin{block}{Decisions}
\begin{itemize}
\item How long are you going to run your campaign? (Number of generations)
\item How many solutions will you consider in one step? (Population size)
\begin{itemize}
\item If so, whats your degree of freedom? (How many numbers should you change)
\end{itemize}
\end{itemize}
\end{block}
All these are just floating point numbers

\begin{block}{Initialization}
\begin{itemize}
\item How will you initialize your population?
\end{itemize}
\end{block}

Consider the \texttt{np.random} module\ldots{}
\end{frame}

\begin{frame}[label={sec:org209e4d2}]{Fitness assignment}
\begin{block}{What's your fitness?}
\begin{itemize}
\item Feed in objective function directly?
\item Competitive fitness between members?
\end{itemize}
\end{block}
Use matrix-vector products and/or slicing to determine fitness
\end{frame}
\begin{frame}[label={sec:org4cfb15a},fragile]{Selection (for variation)}
 \begin{block}{Stochastic / Deterministic}
\begin{itemize}
\item How many parents do you want to select? Or do you want to leave it up to
the algorithm?
\item Deterministic / Stochastic?
\begin{itemize}
\item Remember that stochastic selection is usally used for variation, but
we do not need to do it necessarily\ldots{}
\end{itemize}
\item Competitive fitness between members?
\begin{itemize}
\item It's definitely a good exercise to learn \texttt{numpy}
\end{itemize}
\end{itemize}
\end{block}
\texttt{np.argsort/np.sort} is very useful to sort/rank stuff, indexing magic
needed. The brave souls doing SUS may also need \texttt{searchsorted, cumsum, sum}
and so on (familiarize yourself with the \texttt{numpy} documentation)
\end{frame}
\begin{frame}[label={sec:org53f9b5f},fragile]{Variation}
 \begin{block}{Recombination}
\begin{itemize}
\item What will be your \(p_c\), the rate of recombination?
\item Is there a limit on the number of offspring you generate?
\item How to achieve crossover for your representation?
\item Uniform crossover? N-point crossover? \ldots{}
\item In which gene do you want to effect crossover?
\end{itemize}
\end{block}
Extensively use slicing and index magic. You may use any algorithm (say
using the \texttt{\%} operator) to select parents.
\end{frame}
\begin{frame}[label={sec:org4f36e15},fragile]{Variation}
 \begin{block}{Mutation}
\begin{itemize}
\item What will be your \(p_m\), the rate of mutation?
\item How do you want to achieve mutation? Flip bits? Number exchange? Random numbers?
\item Do you want to mutate the entire vector? Or only one gene?
\end{itemize}
\end{block}
\texttt{np.random} once again. You can also use other \texttt{np} tools
\end{frame}
\begin{frame}[label={sec:orge82c7b6}]{Selection (environmental)}
\begin{block}{Constraints / Deterministic schemes}
\begin{itemize}
\item What about constraints of \(-4 \leq x_i \leq 4\)?
\item How do you select individuals (chromosomes) from the population to
propogate to the next generation? Objective function alone?
\item If so what scheme do you want to use? \(\left( \mu, \lambda \right)\),
\(\left( \mu + \lambda \right)\),\ldots{}?
\end{itemize}
\end{block}
All the tools seen above apply to this case too\ldots{}
\end{frame}
\begin{frame}[label={sec:orge229e9c}]{Putting it all together}
\begin{block}{Convergence, performance, diagnostics}
\begin{itemize}
\item Now that we have all the \emph{modules}, how do they perform when you put
them together?
\item How do we track performance as generations progress?
\item Can you think of some diagnostics that may well-characterize the scheme
that you have just developed?
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[label={sec:org1bf18c1}]{Practice}
\begin{block}{Exploration}
\begin{itemize}
\item Explore representations, parameters and all other design choices that you
made
\item You will essentially be doing a scaled up version of this exercise for
your project 1
\end{itemize}
\end{block}
\end{frame}
\end{document}


\subsection{Signatures}

\subsubsection{Structures}

A logical structure consists of:

\begin{itemize}
\item Domain
\item Interpretation
\item Signature
\end{itemize}

\subsubsection{Domain}

The domain is the set of variables in the structure.

We include an infinite number of variables.

\subsubsection{Interpretation}

The interpretation assigns values to propositional and predicate variables.

\subsubsection{Signature}

A logical signature describes the language of the logic which is used to construct statements. This includes:

\begin{itemize}
\item Functions
\item Relations
\item Operators
\end{itemize}

The language of a signature is all possible sentences, or formulae which can be constructed from this signature.

We include an infinite number of functions, relations and all operators.