\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}


\chapter{Natural Deduction For Propositional Logic}
\label{chapter:propositional-deduction}
\marginurl{%
  Natural Deduction:\\\noindent
  Introduction to Mathematical Logic \#3
}{youtu.be/PfVafyptFtM}

There are two issues with thr method discussed in
\Cref{chapter:propositional-truth}: first to check a semantic implication
we need to consider \textbf{all} possible values of the variables, secondly this
method does not look like the proofs we use in mathematics.

In this chapter we introduce the way to check semantic implications that looks
more similar to real-life proofs.
Let us illustrate this using the following example. Imagine that we know that
$\lnot q$, $p \limplies q$. Using the contraposition argument and modus ponens
we may derive $\lnot p$. Indeed, by contraposition we may conclude that
$\lnot q \limplies \lnot p$ and modus ponens implies that $\lnot p$ is true
since $\lnot q$ is true.

In other words, we can combine several tautologies to prove another tautology.
Apparently it is enough to fix some small number of tautologies to derive all
other tautologies, we call these tautologies ``rules''. There are several ways
to write such proofs, we are going to use Fitch notation for natural deduction.
In this notation any proof is written in several rows, each row in a Fitch-style
proof is either:
\begin{itemize}
  \item an assumption or subproof assumption.
  \item a sentence justified by the citation of
    \begin{enumerate*}[label=(\roman*)]
      \item a rule of inference and
      \item the prior line or lines of the proof that license that rule.
    \end{enumerate*}
\end{itemize}
We say that there is a natural deduction derivation of $\phi$ from $\psi_1$,
\dots, $\psi_k$. If there is a Fitch-style proof starting with the assumptions
$\psi_1$, \dots, $\psi_k$, and finishes with the formula $\phi$.
Using this scheme we may write the argument we just mentioned as follows.

\noindent $
  \begin{nd}
    \hypo {1} {\lnot q}
    \hypo {2} {p \limplies q}
    \have {3} {\lnot q \limplies \lnot p} \by{contraposition}{2}
    \have {4} {\lnot p} \by{modus ponens}{1, 3}
  \end{nd}
$

\noindent In the rest of the section we are going to list all the rules we use.

\paragraph{Conjunctions.}
In order to introduce a conjunction we can use the following rule.
\[
  \begin{nd}
    \have [m] {1} {A}
    \have [n] {3} {B}
    \have [~] {5} {A \land B} \ai{1, 3}
  \end{nd}
\]
This rule corresponds to the tautology $(A \land B) \limplies (A \land B)$.

In order to eliminate conjunctions we can use the following two rules.
\begin{center}
  \begin{tabular}{c c}
    $\begin{nd}
      \have [m] {1} {A \land B}
      \have [~] {3} {A} \ae{1}
    \end{nd}$
    &
    $\begin{nd}
      \have [m] {1} {A \land B}
      \have [~] {3} {B} \ae{1}
    \end{nd}$
  \end{tabular}
\end{center}
These rules correspond to the tautologies $(A \land B) \limplies A$ and
$(A \land B) \limplies B$.

\paragraph{Disjuctions.}
In order to introduce a disjunction we can use the following two rules.
\begin{center}
  \begin{tabular}{c c}
    $\begin{nd}
      \have [m] {1} {A}
      \have [~] {3} {A \lor B} \oi{1}
    \end{nd}$
    &
    $\begin{nd}
      \have [m] {1} {A}
      \have [~] {3} {B \lor A} \oi{1}
    \end{nd}$
  \end{tabular}
\end{center}
These rules correspond to the tautologies $A \limplies (A \lor B)$ and
$A \limplies (B \lor A)$.

In order to eliminate a disjunction we can use the following rule.
\[
  \begin{nd}
    \have [m] {1} {A \lor B}
    \open
      \hypo [i] {3} {A}
      \have[j] {5} {C}
    \close
    \open
      \hypo [k] {6} {B}
      \have[l] {8} {C}
    \close
    \have[~] {9} {C} \oe{1, 3-5, 6-8}
  \end{nd}
\]
This rule corresponds to the tautology
$\bigl( (A \lor B) \land (A \limplies C) \land (B \limplies C) \bigr)
\limplies C$.

\paragraph{Implications.}
In order to introduce an implication we can use the following two rules.
\[
  \begin{nd}
    \open
      \hypo [i] {3} {A}
      \have[j] {5} {B}
    \close
    \have[~] {9} {A \limplies B} \ii{3-5}
  \end{nd}
\]
This rule corresponds to the tautology
$(A \limplies B) \limplies (A \limplies B)$.

In order to eliminate an implication we can use the following rule.
\[
  \begin{nd}
    \have [m] {1} {A \limplies B}
    \have [n] {2} {A}
    \have[~] {9} {B} \ie{1, 2}
  \end{nd}
\]
This rule corresponds to the tautology
$\bigl( (A \limplies B) \land A \bigr)
\limplies B$.

\paragraph{Negations.}
In order to introduce a negation we can use the following two rules ($\perp$ is
a special symbol representing a false statement).
\[
  \begin{nd}
    \open
      \hypo [i] {3} {A}
      \have[j] {5} {\perp}
    \close
    \have[~] {9} {\lnot A} \ni{3-5}
  \end{nd}
\]
This rule corresponds to the tautology
$\bigl( A \limplies \perp \bigr)
\limplies \lnot A$.

In order to eliminate a negation we can use the following rule.
\[
  \begin{nd}
    \have [m] {1} {A}
    \have [n] {2} {\lnot A}
    \have[~] {9} {\perp} \ne{1, 2}
  \end{nd}
\]
This rule corresponds to the tautology
$\bigl( A \land \lnot A \bigr)
\limplies \perp$.

\paragraph{Truths and falsities.}
Additionally, we have the following two rules.
\begin{center}
  \begin{tabular}{c c}
    $\begin{nd}
      \have [m] {1} {\perp}
      \have [~] {3} {A} \be{1}
    \end{nd}$
    &
    $\begin{nd}
      \open
        \hypo [i] {3} {\lnot A}
        \have[j] {5} {\perp}
      \close
      \have[~] {9} {A} \by{IP}{3, 5}
    \end{nd}$
  \end{tabular}
\end{center}

\marginurl{%
  An online tool to check natural deduction proofs
}{proofs.openlogicproject.org/}

\begin{exercise}
  Check that all the tautologies we mentioned are indeed tautologies.
\end{exercise}

\section{Examples of Derivations}
In this section we give several derivations using the rules we just introduced.

First, we prove that if we know that $A \limplies \lnot A$ we can derive that
$\lnot A$.

\noindent $
  \begin{nd}
    \hypo {1} {A \limplies \lnot A}
    \open
      \hypo {2} {A}
      \have {3} {\lnot A} \ie{1, 2}
      \have {4} {\perp} \ne{2, 3}
    \close
    \have {5} {\lnot A} \ni{2-4}
  \end{nd}
$

Another statement we are going to prove is that if
$A \limplies (A \land \lnot A)$ is true, then $\lnot A$ is also true.

\noindent $
  \begin{nd}
    \hypo {1} {A \limplies (A \land \lnot A)}
    \open
      \hypo {2} {A}
      \have {3} {A \land \lnot A} \ie{1, 2}
      \have {4} {\lnot A} \ae{3}
      \have {5} {\perp} \ne{2, 4}
    \close
    \have {6} {\lnot A} \ni{2-5}
  \end{nd}
$

A bit more complicated is the proof of the law of excluded middle:
$A \lor \lnot A$.

\noindent $
  \begin{nd}
    \hypo {1} {}
    \open
      \hypo {2} {\lnot (A \lor \lnot A)}
      \open
        \hypo {3} {A}
        \have {4} {A \lor \lnot A} \oi{3}
        \have {5} {\perp} \ne{2, 4}
      \close
      \have {6} {\lnot A} \ni{3-5}
      \have {7} {A \lor \lnot A} \oi{6}
      \have {8} {\perp} \ne{2, 8}
    \close
    \have {9} {A \lor \lnot A} \by{IP}{2-8}
  \end{nd}
$

\section{Soundness and Completeness}
\marginurl{%
  Soundness and Completeness:\\\noindent
  Introduction to Mathematical Logic \#4
}{youtu.be/9Utsppn-M_I}
The most important properties of the natural deduction are the following two
theorems.

\begin{theorem}[completeness of natural deductions]
  Let $\phi$ be a propositional formula. If $\phi$ is a tautology, then
  there is a proof of $\phi$. Moreover if $\Sigma$ is a finite set of
  propositional formulas and $\Sigma \models \phi$, then there is a
  derivation of $\phi$ from $\Sigma$.
\end{theorem}

\begin{theorem}[soundness of natural deductions]
  Let $\phi$ be a propositional formula. If there is a proof of $\phi$, then
  $\phi$ is a tautology. Moreover if $\Sigma$ is a finite set of
  propositional formulas and there is a derivation of $\phi$ from $\Sigma$,
  then $\Sigma \models \phi$.
\end{theorem}

Proofs of these two theorems are not that difficult but very technical. So
we will leave these theorems without proofs and just give some ideas behid
their proofs.

\paragraph{Completeness of natural deductions.}
The proof of this statement exploits the following idea: if a propositional formula
is a tautology, then we can verify this statement using the truth table. So
the proof may simply brute-force all the values of the variables of a formula
and check that the formula is indeed true.

For example, consider a tautology $(\lnot A \land \lnot B) \limplies \lnot (A \lor B)$.
The proof of this tautology is as follows.
First we derive $A \lor \lnot A$ and $B \lor \lnot B$, and we use these two
formulas to consider cases using the elimination of disjunction.

\noindent$
\begin{nd}
  \hypo {1} {}
  \have {2} {A \lor \lnot A} \by{the law of excluded middle}{}
  \have {3} {B \lor \lnot B} \by{the law of excluded middle}{}
\end{nd}
$

\noindent After that, we consider the case when $A$ and $B$ are both true. Note
that the assumption of the implication is false in this case. Thus, we just need
to assume $\lnot A \land \lnot B$, derive the contradiction, and derive
$\lnot (A \lor B)$.

\noindent$
\begin{ndresume}
  \open
    \hypo {4} {A}
    \open
      \hypo {5} {B}
      \open
        \hypo {6} {\lnot A \land \lnot B}
        \have {7} {\lnot A} \ae{6}
        \have {8} {\perp} \ne{4, 7}
        \have {9} {\lnot (A \lor B)} \be{8}
      \close
      \have {10} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \ii{6-9}
    \close
\end{ndresume}
$

\noindent After that, we consider the case when $A$ is true but and $B$ is
false. In this case, the assumption of the implication is also false; thus, the
proof is the same as in the previous case.

\noindent$
\begin{ndresume}
    \open
      \hypo {11} {\lnot B}
      \open
        \hypo {12} {\lnot A \land \lnot B}
        \have {13} {\lnot A} \ae{12}
        \have {14} {\perp} \ne{4, 13}
        \have {15} {\lnot (A \lor B)} \be{14}
      \close
      \have {16} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \ii{6-9}
    \close
    \have {17} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \oe{2, 5-10, 11-16}
  \close
\end{ndresume}
$

\noindent The third case is when $A$ is false and $B$ is
true. In this case the assumption of the implication is false again, thus the
proof is the same as in the previous two cases.

\noindent$
\begin{ndresume}
  \open
    \hypo {18} {\lnot A}
    \open
      \hypo {19} {B}
      \open
        \hypo {20} {\lnot A \land \lnot B}
        \have {21} {\lnot B} \ae{20}
        \have {22} {\perp} \ne{19, 22}
        \have {23} {\lnot (A \lor B)} \be{22}
      \close
      \have {24} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \ii{20-23}
    \close
\end{ndresume}
$

\noindent Finally, we consider the case when $A$ and $B$ are false. In this
case the assumption of the implication is true, and since the formula is a
tautology and $\lnot A \land \lnot B$ is true, we know that $\lnot (A \lor B)$
is also true. Assume that $A \lor B$ is true and note that this is impossible.
Thus using introduction of the negation we can prove the statement.

\noindent$
\begin{ndresume}
    \open
      \hypo {25} {\lnot B}
      \open
        \hypo {26} {\lnot A \land \lnot B}
        \open
          \hypo {27} {A \lor B}
          \open
            \hypo {28} {A}
            \have {29} {\perp} \ne{18, 28}
          \close
          \open
            \hypo {30} {B}
            \have {31} {\perp} \ne{25, 30}
          \close
          \have {32} {\perp} \oe{27, 28-29, 30-31}
        \close
        \have {33} {\lnot (A \lor B)} \ne{26-32}
      \close
      \have {39} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \ii{26-33}
    \close
    \have {40} {(\lnot A \land \lnot B) \limplies \lnot (A \lor B)} \oe{1, 3-17, 18-39}
  \close
\end{ndresume}
$

\paragraph{Soundness of natural deductions.}
The idea behind the proof of the soundness is also simple. We just explain that
every line of the proof represent a tautology, including the last one. We
illustrate this on the exaple of the proof of $A \lor \lnot A$. Recall that the
proof of this tautology is the following.

\noindent $
  \begin{nd}
    \hypo {1} {}
    \open
      \hypo {2} {\lnot (A \lor \lnot A)}
      \open
        \hypo {3} {A}
        \have {4} {A \lor \lnot A}
        \have {5} {\perp}
      \close
      \have {6} {\lnot A}
      \have {7} {A \lor \lnot A}
      \have {8} {\perp}
    \close
    \have {9} {A \lor \lnot A}
  \end{nd}
$

\begin{enumerate}
  \item The second line is just an assumption, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies \lnot (A \lor \lnot A)$.
  \item Line~3 is also an assumption so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies (A \limplies A)$.
  \item Line~4 is a formula $A \lor \lnot A$ which we derived under assumptions
    $\lnot (A \lor \lnot A)$ and $A$, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies (A \limplies (A \lor \lnot A))$ (it is a
    tautology since we replaced $A$ by $A \lor \lnot A$ in the conclusion of
    the formula corresponding to Line~3).
  \item Line~5 is the formula $\perp$ which we derived under assumptions
    $\lnot (A \lor \lnot A)$ and $A$, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies (A \limplies \perp)$ (it is a
    tautology since on Line~4 we explained that $\lnot (A \lor \lnot A)
    \limplies (A \limplies (A \lor \lnot A))$).
  \item Line~6 is a formula $\lnot A$ which we derived under assumptions
    $\lnot (A \lor \lnot A)$, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies \lnot A$ (it is a
    tautology since on Line~5 we explained that $A \limplies \perp$ under the
    assumption $\lnot (A \lor \lnot A)$).
  \item Line~7 is a formula $A \lor \lnot A$ which we derived under assumptions
    $\lnot (A \lor \lnot A)$, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies (A \lor \lnot A)$ (it is a
    tautology since on Line~6 we explained that $A$ under the
    assumption $\lnot (A \lor \lnot A)$).
  \item Line~8 is a formula $\perp$ which we derived under assumptions
    $\lnot (A \lor \lnot A)$, so the corresponding tautology is
    $\lnot (A \lor \lnot A) \limplies \perp$ (it is a
    tautology since on Line~6 we explained that $A \lor \lnot A$ under the
    assumption $\lnot (A \lor \lnot A)$).
  \item Finally, Line~9 is a formula $A \lor \lnot A$ (it is a tautology since
    we proved that $\lnot (A \lor \lnot A) \limplies \perp$ is a tautology)
\end{enumerate}

\begin{chapterendexercises}
  \exercise  Write a natural deduction derivation of $A \lor C$ from
    hypothesis $(A \land B) \lor C$.
  \exercise Write a natural deduction derivation of $B \lor C$ from
    hypothesis $A \limplies B$ and $\lnot A \limplies C$.
  \exercise Write a natural deduction derivation of
    $(W \lor Y) \limplies (X \lor Z)$ from
    hypotheses $W \limplies X$ and $Y \limplies Z$.
  \exercise Let us formulate the pigeonhole principle using propositional
    formulas. Let
    $V = \set{x_{1, 1}, \dots, x_{n + 1, 1}, x_{1, 2} \dots, x_{n + 1, n}}$
    (informally $x_{i, j}$ is true iff the $i$th pigeon is in the $j$th hole).
    Consider the following propositional formulas on the variables from
    $V$.
    \begin{itemize}
      \item $L_i$ ($i \in [n + 1]$) is equal to $\bigvee_{j = 1}^n x_{i, j}$.
        (Informally this formula says that the $i$th pigeon is in a hole.)
      \item $R_j$ ($j \in [n]$) is equal to
        $\biglor_{i_1 = 1}^{n + 1} \biglor_{i_2 = i_1 + 1}^{n + 1}
        (x_{i_1, j} \land x_{i_2, j})$.
        (Informally this formula says that there are two pigeons in the $j$th
        hole.)
      \end{itemize}

      Show that there is a natural deduction derivation of
      $\left(
          \bigland_{i = 1}^{n + 1} L_i
        \right)
        \limplies
        \left(
          \biglor_{i = 1}^{n} R_i
        \right)$.
    \exercise In this exercise we think about clauses as sets of literals so
      the order of disjunctions and repetitions of literals are not important.
      We say that a clause $C$ can be obtained from clauses $A$ and $B$
      using the \emph{resolution} rule if $C = A^\prime \lor B^\prime$,
      $A = x \lor A^\prime$, and $B = \lnot x \lor B^\prime$, for some variable
      $x$.

      We say that a clause $C$ can be derived from clauses $A_1$, \dots, $A_m$
      using resolutions
      if there is a sequence of clauses $D_1$, \dots, $D_\ell = C$ such that
      each $D_i$
      \begin{itemize}
        \item is either obtained from clauses $D_j$ and $D_k$ for $j, k < i$ using the
          \emph{resolution} rule, or
        \item is equal to $A_j$ for some $j \in [m]$, or
        \item is equal to $D_j \lor E$ for some $j < i$ and a clause $E$.
      \end{itemize}

      Show that if an empty clause $\perp$ can be derived from clauses $A_1$,
      \dots, $A_m$ using the resolution rule, then $A_1$, \dots, $A_m$
      semantically imply $\perp$.
\end{chapterendexercises}


\subsection{Baire spaces}\label{subsec:baire_spaces}

\begin{remark}\label{rem:baire_categories}
  René-Louis Baire introduced the concept of \term{Baire categories} in 1899, almost 50 years before Samuel Eilenberg and Saunders MacLane introduced \term{categories} in \cite{EilenbergMacLane1945} (see \fullref{sec:category_theory} for the latter).

  Unfortunately, topology utilizes both concepts, so the word \enquote{category} should be used with caution. To circumvent this, we use alternative terminology for Baire categories.
\end{remark}

\begin{definition}\label{def:meager_set}\mcite[def. 2.1]{Rudin1991Functional}
  Any countable union of \hyperref[def:topologically_dense_set/nowhere_dense]{nowhere dense sets} is called \term{meager} or a \term{first category set} (see \fullref{rem:baire_categories} for terminology). If a set is not meager, we call it \term{nonmeager} or a \term{second category set}.
\end{definition}

\begin{proposition}\label{thm:def:meager_set}\mcite[43]{Rudin1991Functional}
  \hyperref[def:meager_set]{Meager sets} have the following basic properties (compare to \fullref{thm:def:nowhere_dense}):
  \begin{thmenum}
    \thmitem{thm:def:meager_set/union} A countable union of meager sets is meager.
    \thmitem{thm:def:meager_set/subset} A subset of a meager set is meager.
    \thmitem{thm:def:meager_set/homeomorphism} The \hyperref[def:homeomorphism]{homeomorphic} image of a set \( A \) is meager if and only if \( A \) itself is meager.
  \end{thmenum}
\end{proposition}
\begin{proof}
  \SubProofOf{thm:def:meager_set/union} Follows from \fullref{thm:countably_infinite_union_of_countably_infinite_sets}.
  \SubProofOf{thm:def:meager_set/subset} Fix a meager set \( A \) and let \( B \subseteq A \). Then \( A = \bigcup_{k=1}^\infty A_k \) for some nowhere dense sets \( A_1, A_2, \ldots \). By \fullref{thm:def:nowhere_dense/subset}, the sets \( A_1 \cap B, A_2 \cap B, \ldots \) are also nowhere dense. But
  \begin{equation*}
    B
    =
    A \cap B
    =
    \left(\bigcup_{k=1}^\infty A_k \right) \cap B
    \reloset {\ref{thm:boolean_algebra_of_subsets}} =
    \bigcup_{k=1}^\infty (A_k \cap B).
  \end{equation*}

  Therefore, \( B \) is also nowhere dense.

  \SubProofOf{thm:def:meager_set/homeomorphism}
  \hfill
  \NecessitySubProof If \( A \) is meager, any homeomorphic image of \( A \) is meager by \fullref{thm:def:function_image/union} and \fullref{thm:def:nowhere_dense/homeomorphism}.
  \SufficiencySubProof If \( f: X \to Y \) is a homeomorphism and \( f(A) \) is meager for some \( A \subseteq X \), then \( A \) is the homeomorphic image of the meager set \( f(A) \) under \( f^{-1} \) and is thus meager.
\end{proof}

\begin{definition}\label{def:baire_space}
  A topological space is called a \term{Baire space} if any of the following equivalent conditions hold:
  \begin{thmenum}
    \thmitem{def:baire_space/meager} Every nonempty open set is nonmeager.
    \thmitem{def:baire_space/dense} A countable intersection of dense sets is dense.
  \end{thmenum}
\end{definition}
\begin{proof}
  \EquivalenceSubProof{def:baire_space/meager}{def:baire_space/dense} Follows from \fullref{thm:def:nowhere_dense/complement_dense} and \fullref{thm:de_morgans_laws}.
\end{proof}

\begin{proposition}\label{thm:open_subspace_of_baire_space_is_baire}
  Every open subspace of a \hyperref[def:baire_space]{Baire space} is a Baire space.
\end{proposition}
\begin{proof}
  Let \( (X, \mscrT) \) be a Baire space and let \( (X', \mscrT_{X'}) \) be an open \hyperref[def:topological_subspace]{subspace} with the canonical embedding \( \iota: X' \to X \). The proposition holds vacuously if \( X' = \varnothing \), so we assume that \( X' \neq \varnothing \).

  Note that \( \iota \) is continuous by definition, however it is also an open map because if \( U \in T_{X'} \), then \( \iota(U) = U \cap X' \) is open in \( X \) as the intersection of two open sets. Therefore, it is a homeomorphic embedding and by \fullref{thm:def:meager_set/homeomorphism}, \( U \) is meager if and only if \( \iota(U) \) is meager. Since \( X \) is a Baire space, \( \iota(U) \) is not meager and hence \( U \) is also not meager.

  We showed that every nonempty open set \( U \in T_{X'} \) is nonmeager, therefore \( X' \) is a Baire space.
\end{proof}

\begin{theorem}[Baire category theorem]\label{thm:baire_category_theorem}\mcite{Rudin1991Functional}
  \begin{thmenum}
    \thmitem{thm:baire_category_theorem/metric} \hyperref[def:complete_metric_space]{Complete metric spaces} are \hyperref[def:baire_space]{Baire spaces}.
    \thmitem{thm:baire_category_theorem/compact} \hyperref[def:locally_compact_space]{Locally compact} \hyperref[def:separation_axioms/T2]{Hausdorff} spaces are Baire spaces.
  \end{thmenum}
\end{theorem}