\documentclass[12pt, a4paper]
{article}

\usepackage[margin=2cm]{geometry}
\usepackage{svg}
\setsvg{inkscape=inkscape -z -D,svgpath=images/}
\usepackage{float}
\usepackage{amsmath}
\usepackage{todonotes}
\usepackage{xspace}
\usepackage{booktabs}
\usepackage[]{algorithm2e}

\title{Pybricks motor control algorithms}
\author{The Pybricks authors}

% Generic macros
\providecommand{\lr}[1]{\left(#1\right)}
\providecommand{\sub}[1]{_{\text{#1}}}
\renewcommand{\sup}[1]{^{\text{#1}}}

% omega symbols
\providecommand{\w}{\omega}
\providecommand{\wt}{\w^*}
\providecommand{\wref}{\w\sub{ref}}
\providecommand{\wmax}{\w\sub{max}}

% theta symbols
\renewcommand{\th}{\theta}
\providecommand{\thref}{\th\sub{ref}}

% alpha symbols
\renewcommand{\a}{\alpha}

% math
\providecommand{\minab}[2]{\min\,\lr{{#1},\,\,{#2}}}
\providecommand{\abs}[1]{\left|#1\right|}
\providecommand{\inlineadd}{\,\,+\!\!=\,\,}
\providecommand{\inlinesubtract}{\,\,-\!\!=\,\,}

%
%
% Begin Document
%
%
\begin{document}
\maketitle

\tableofcontents
\pagebreak

\section{Control system overview}

\begin{figure}[H]
    \centering
    \fontsize{8}{10}\selectfont
    \includesvg[inkscapelatex=false,width=1\textwidth]{control}
    \caption{
        Control system overview.
        \label{fig:controloverview}}
\end{figure}

\section{Reference trajectories}

When the user gives a motor command, we compute the reference trajectories for
the motor angle ($\thref$) and angular velocity ($\wref$) as a function of
time ($t$). These trajectories describe the ideal motion that would be followed
if the motor is not subject to external loads or disturbances.

\subsection{Trajectory definition}

For a typical maneuver, the reference trajectories for $\thref$ and $\wref$
are shown in Figure \ref{fig:plots}. Initially, when the user executes the
command at time $t_0$, the motor has a given initial angle $\th_0$ and a given
initial angular velocity $\w_0$. The motor accelerates with a magnitude
$\abs{\a_0}$ until it reaches the user-specified target angular velocity $\wt$
at time $t_1$. The target speed is maintained until it begins decelerating at
time $t_2$, in order to stop precisely at $t_3$. During this maneuver, at the
corresponding times, the motor angle reference traverses from $\th_0$ through
$\th_3$.

The reference trajectories $\thref(t)$ and $\wref(t)$ are uniquely specified by
the time instants $t_0$, $t_1$, $t_2$, $t_3$, the angles $\th_0$, $\th_1$,
$\th_2$, $\th_3$, the initial velocity $\w_0$, the target velocity $\wt$, the
final velocity $\w_3$, the acceleration $\a_0$ and deceleration $\a_2$.

Depending on which command is executed, we are given a subset of these
parameters and we have to compute the dependent variables.

\begin{figure}[H]
    \centering
    \includesvg[width=0.9\textwidth]{trajectory}
    \caption{
        Reference velocity (top) and reference angle (bottom).
        \label{fig:plots}}
\end{figure}

If these parameters are known, the trajectories $\wref(t)$ and $\thref(t)$ are
given by
%
\begin{align}
    \label{eq:wref}
    \wref(t)&=
    \begin{cases}
    \w_0 & \text{if} \quad t = t_0\\
    \w_0 + \a_0(t-t_0) & \text{if} \quad t < t_1\\
    \w_1=\w_2=\wt  & \text{if} \quad t_1 \leq t \leq t_2\\
    \w_2 + \a_2(t-t_2) & \text{if}\quad t_2 < t < t_3\\
    \w_3 & \text{if} \quad t = t_3
    \end{cases}\\[1em]
    \label{eq:thref}
    \thref(t)&=
    \begin{cases}
        \th_0 & \text{if} \quad t = t_0\\
        \th_0 + \w_0(t-t_0) + \dfrac{1}{2}\a_0(t-t_0)^2 &
            \text{if} \quad t_0 < t \leq t_1\\
        \th_1 + \w_1(t-t_1)  & \text{if} \quad t_1 < t \leq t_2\\
        \th_2 +\w_2(t-t_2)+\dfrac{1}{2}\a_2(t-t_2)^2 &
            \text{if}\quad t_2 < t < t_3\\
        \th_3 & \text{if} \quad t = t_3
    \end{cases}
\end{align}

Some parameters are known because they are measured or because they are
specified by the user, while others are to be computed from the known
parameters. Which of the parameters are known depends on the user-specified
maneuver.

If the user specifies to rotate the motor for a certain duration with
\texttt{run\_time(speed, duration)}, the final time $t_3=t_0+t\sub{duration}$
is known but we must compute the corresponding angle $\th_3$. If instead the
final angle $\th_3$ is specified by the user command, we have to compute the
final time $t_3$. This applies to \texttt{run\_target(speed, target)}, where
$\th_3=\th\sub{target}$. The following two sections provide the formulas to
compute the unknown parameters for both cases.

\begin{table}[H]
    \centering
    \caption{Overview of known and computed trajectory parameters}
    \label{tab:parameters}
    \begin{tabular}{@{}lllll@{}}
    \toprule
                & Known    & Obtained from & Computed & Method \\
                &          & user command  &          &        \\ \midrule
    Time-based  &
        $t_0$, $\th_0$, $\w_0$ &
        $\abs{\a_0}$, $\abs{\a_2}$, $\wt$, $t_3$, $\w_3$ &
        $\a_0$, $\a_2$, $t_1$, $t_2$, $\th_1$, $\th_2$, $\boldsymbol{\th_3}$
        & Section \ref{sec:timebasedref}\\
    Angle-based &
        $t_0$, $\th_0$, $\w_0$ &
        $\abs{\a_0}$, $\abs{\a_2}$, $\wt$, $\th_3$, $\w_3$ &
        $\a_0$, $\a_2$, $t_1$, $t_2$, $\boldsymbol{t_3}$, $\th_1$, $\th_2$ &
        Section \ref{sec:anglebasedref}  \\
        \bottomrule
    \end{tabular}
\end{table}

For a typical single command, the final speed is always zero ($\w_3 = 0$), in
which case $\th(t) \equiv \th_3$ for $t > t_3$. We will also allow the user to
specify $\w_3 = \wt$. This can be used to blend subsequent commands together
without stopping.

\subsection{Calculating trajectory parameters given time target}
\label{sec:timebasedref}
This section derives the parameters in Table \ref{tab:parameters} for a
time-based maneuver. Without loss of generality, we will assume that the
target angular velocity is nonnegative:
%
\begin{align}
    \label{eq:t:forwardmaneuver}
    \wt \geq 0, \quad \w_3 \in \{0, \wt\}
\end{align}
%
If it is not, we can mirror the inputs along the $\w=0$ line, perform the
following computations, and mirror back the final result. This is discussed
in Section \ref{sec:t:reversing}.

In a time-based maneuver, we are only concerned with angular velocity control,
while the final angle is arbitrary. In principle, this means we are only
concerned with tracking $\wref(t)$ as shown in the top graph of
Figure \ref{fig:plots}. However, that graph depicts only one possible angular
velocity trajectory, for a particular set of parameters.
Figure \ref{fig:time} captures four possible types of angular velocity
reference trajectories, which differ in initial speed compared to the
target speed and final speed.

\begin{figure}[H]
    \centering
    \includesvg[width=0.8\textwidth]{timebased}
    \caption{
        Time-based motions with a duration of $t_3-t_0$ for various initial
        conditions, with a stationary endpoint (left), or a nonzero final speed
        (right). The trajectory is determined by the initial speed $\w_0$,
        which may be equal to or greater than the target $\wt$ (blue),
        or lower than the target (green). It could also be so low or high that
        it will not be able to reach the target speed before completion
        (orange and red).\label{fig:time}}
\end{figure}

Because we allow only positive duration arguments, we have $t_3-t_0 > 0$ by
definition. In order to ensure that the motor is able to reach $\w_3$ at time
$t_3$, the initial angular velocity must be bound by the gray area in Figure
\ref{fig:time}. The slope magnitude of the upper boundary equals the magnitude
of the acceleration $\abs{\a_0}$ or deceleration $\abs{\a_2}$, whichever is
larger. The lower boundary slope corresponds to the acceleration magnitude
$\abs{\a_0}$. We also limit the target speed such that it is able to
decelerate to the final speed with the given deceleration $\a_2$. This gives
the constraints
%
\begin{align}
    -\abs{\a_0} \lr{t_3-t_0} &\leq \w_0 \leq \max \{\abs{\a_0}, \abs{\a_2}\} \lr{t_3-t_0} + \w_3\label{eq:t:timeboundary1}\\[1em]
    0 &\leq \wt \leq \abs{\a_2} \lr{t_3-t_0} + \w_3\nonumber
\end{align}
%
In all cases, the trajectory decelerates between $t_2$ and $t_3$, so that
$\a_2  = - \abs{\a_2} < 0$. The initial acceleration between $t_0$ and $t_1$
depends on the initial speed $\w_0$ with respect to the \mbox{target $\wt$},
which gives
%
\begin{align}
    \label{eq:t:accel0}
    \a_0 &=
        \begin{cases}
        \phantom{-}\abs{\a_0} & \text{if} \quad \w_0 < \wt\\
        -\abs{\a_0} &  \text{otherwise}
        \end{cases}
\end{align}
%
The case of equality is handled intrinsically within the
second case by ensuring that $\a_0$ is never used if $\w_0 = \wt$.

\subsubsection{Standard case}
\label{sec:t:standard}
The first step is to accelerate or decelerate to reach the target speed $\wt$.
Solving for the intersection time $t_1$ gives:
%
\begin{align}
    \label{eq:t:t1mt0:standard}
    \lr{t_1 - t_0}\sub{standard} &= \dfrac{\wt-\w_0}{\a_0}
\end{align}
%
Similarly, the time $t_2$ at which we start decelerating becomes defined by:
%
\begin{align}
    \label{eq:t:t3mt2:standard}
    \lr{t_3 - t_2}\sub{standard} &= \dfrac{\w_3-\wt}{\a_2}\\[1em]
    \label{eq:t:t2mt1:standard}
    \lr{t_2 - t_1}\sub{standard} &=
        (t_3-t_0) - \lr{t_1 - t_0}\sub{standard} - \lr{t_3 - t_2}\sub{standard}
\end{align}
%
Since the target speed is reached the constant speed value is simply
\begin{align}
    \lr{\w_1}\sub{standard} &= \wt
\end{align}
%
The result is valid if and only if $\lr{t_2 - t_1}\sub{standard}\geq 0$.
Otherwise, we resort to the cut-short case covered below.

\subsubsection{Cut short case}
\label{sec:t:cutshort}
If the initial velocity is too low or if the maneuver is too short to be able
to reach the target velocity, it accelerates until it must begin to
decelerate, as shown by the first segment of the red line in Figure
\ref{fig:time}. Solving for the intersection time $t_1$
gives:
%
\begin{align}
    \label{eq:t:t1mt0:cutshort}
    \lr{t_1 - t_0}\sub{cut short} &=
        \dfrac{\w_3-\w_0 - \a_2(t_3-t_0)}{\a_0-\a_2}
\end{align}
%
This result also applies if the initial acceleration is negative (orange line).
Zero division would occur if $\a_2 = \a_0$. Since $\a_2 < 0$, this is a concern
only when $\a_0 < 0$. However, this never happens since $\a_2 = \a_0 < 0$
implies that the standard case in Section \ref{sec:t:standard} has a valid
solution.

Similarly, the time when we start decelerating ($t_2$) becomes defined by:
%
\begin{align}
    \label{eq:t:t3mt2:cutshort}
    \lr{t_3 - t_2}\sub{cut short} &= (t_3 - t_0) - (t_1 - t_0)\sub{cut short}
    \\[1em]
    \label{eq:t:t2mt1:cutshort}
    \lr{t_2 - t_1}\sub{cut short} &= 0
\end{align}
%
When cut short, the target speed $\wt$ is not reached but it peaks out at
%
\begin{align}
    \lr{\w_1}\sub{cut short} &= \w_0 + \a_0(t_1 - t_0)\sub{cut short}
\end{align}

\subsubsection{Cut short case with $\w_3 = \w_1$ and $\a_0 > 0$}
\label{sec:t:cutshortw3}

If $\w_3 = \wt$ and $\a_0 > 0$, there is only the increasing
ramp for the whole duration of the maneuver, indicated by the
red line in the right graph of Figure \ref{fig:time}, giving:
%
\begin{align}
    \w_1 = \w_3 := \w_0 + \a_0(t_3 - t_0)
\end{align}
%
and accordingly $t_3=t_2=t_1$.

\subsubsection{Reversing and unreversing the final and target speed}

\label{sec:t:reversing}
The aforementioned derivation assumes $\wt \geq \w_3 \geq 0$
\eqref{eq:t:forwardmaneuver} to reduce the number of (similar) cases that must
be accounted for. This section shows how to transform a given time based
maneuver to match this assumption, calculate the trajectory, and map the final
result back to obtain the originally requested command.

\begin{itemize}
    \item Cap $\w_0$ and $\wt$ using \eqref{eq:t:timeboundary1}.
    \item Let the boolean $a := \wt < 0$.
    \item If $a$, then invert all speeds: $\w_0 := -\w_0$, $\wt := -\wt$,
        $\w_3 := -\w_3$.
    \item Calculate time and speed intersections using Sections \ref{sec:t:standard}--
    \ref{sec:t:cutshortw3}.
    \item If $a$, then invert the results as shown in Section \ref{sec:invert}.
\end{itemize}

\subsubsection{Intermediate angles (all cases)}

Having derived expressions to evaluate $t_1$, $t_2$, and $\w_1$, the remaining
parameters of Table \ref{tab:parameters} to compute are the angles
$\th_1$, $\th_2$, and $\th_3$, which can be derived by integrating the
angular velocity reference signal \eqref{eq:thref}:
% %
\begin{align}
    \label{eq:t:anglepar1}
    \th_1  &= \th_0  + \w_0(t_1-t_0)+\dfrac{1}{2}\a_0(t_1-t_0)^2\\
    \label{eq:t:anglepar2}
    \th_2&=\th_1+ \w_1(t_2-t_1)\\
    \label{eq:t:anglepar3}
    \th_3  &=\th_2+ \w_2(t_3-t_2)+\dfrac{1}{2}\a_2(t_3-t_2)^2
\end{align}
%

\subsection{Calculating trajectory parameters given angle target}
\label{sec:anglebasedref}
This section derives the parameters in Table \ref{tab:parameters} for an
angle-based maneuver. For simplicity of the derivation will assume that
the target angle  is greater than the initial angle. This
means that the motor must move forward to reach its goal:
%
\begin{align}
    \label{eq:a:forwardmaneuver}
    \th_3 &> \th_0\\
    \wt &> 0
\end{align}
%
If it is not, we can mirror the inputs along the $\th_3$ line, perform the
following computations, and mirror back the final result. This is discussed
in Section \ref{sec:a:reversing}.

In an angle-based maneuver, the end time $t_3$ is arbitrary, so the trajectory
is best analyzed in a ($\th$, $\w$) phase plot. This is shown in Figure
\ref{fig:positions} for various initial conditions indicated with blue dots.
To reduce the complexity of quadratic solutions on the microcontroller, we
restrict the final velocity to be either $\w_3=0$ or $\w_3=\w_2=\w_1$, implying
either deceleration to zero or no deceleration at all. Possible end states are
indicated with orange dots. In all cases $\a_2 < 0$.

\begin{figure}[H]
    \centering
    \includesvg[width=1\textwidth]{angbased}
    \caption{
        Phase portrait of trajectory from different types of initial conditions
        indicated with blue dots:
        (a) nonnegative initial speed with a
        sufficient distance from target to have a constant speed phase.
        (b) Same as (a), except with negative initial speed.
        (c) nonnegative initial speed without a constant speed phase because
        the target is too close.
        (d) Same as (c), except with negative initial speed.
        \label{fig:positions}}
\end{figure}

The typical trajectory is similar to case (a) and (c): The motor starts
with a nonnegative velocity, accelerates, optionally runs through a constant
speed phase, and then decelerates to standstill at the target.
If the initial speed is negative ($\w_0 < 0$) as in initial conditions (b)
and (d), the motor slows down and goes backwards in the process. Once the
velocity passes through zero, the remaining trajectory is just like case (a)
and (c). For all trajectory types, it is convenient to define the common
zero-speed angle $\th_f$ as indicated
with green dots in Figure~\ref{fig:positions}:
%
\begin{align}
    \th_f = \th_0 - \dfrac{1}{2 \a_0}\w_0^2
\end{align}

Because we allow only positive speeds we have $\th_3-\th_0 > 0$ by
definition. In order to ensure that the motor is able to reach $\w_3$ at time
$t_3$, the initial angular velocity must be bound by the gray area in Figure
\ref{fig:positions}. The upper boundary corresponds to the maximum speed
we can be at initially and still decelerate to the target angle on time.

In particular, we restrict the initial speed to the value from which we can
decelerate with either $\abs{\a_0}$ or $\abs{\a_2}$, whichever is larger.
There is no need for a negative lower bound. To see this, consider cases (b)
and (d) in Figure~\ref{fig:positions}: a negative initial speed makes it move
farther from the target angle, eliminating the risk of overshooting it. This
gives the constraint:
%
\begin{align}
    \w_0 \leq \sqrt{\w_3^2 + 2 \max\{ \abs{\a_0}, \abs{\a_2}\}\lr{\th_3-\th_0}}
\end{align}
%
Likewise, we bind the strictly positive target speed to a value from which we
can still decelerate to the final speed with the given deceleration
$\abs{\a_2}$:
%
\begin{align}
    0 < \wt \leq \sqrt{\w_3^2 + 2\abs{\a_2}\lr{\th_3-\th_0}}
\end{align}
%

In all cases, the trajectory decelerates between $t_2$ and $t_3$, so that
$\a_2  = - \abs{\a_2} < 0$. The initial acceleration between $t_0$ and $t_1$
depends on the initial speed $\w_0$ with respect to the \mbox{target $\wt$},
which gives
%
\begin{align}
    \label{eq:a:accel0}
    \a_0 &=
        \begin{cases}
        \phantom{-}\abs{\a_0} & \text{if} \quad \w_0 < \wt\\
        -\abs{\a_0} &  \text{otherwise}
        \end{cases}
\end{align}
%
The case of equality is handled intrinsically within the
second case by ensuring that $\a_0$ is never used if $\w_0 = \wt$.

\subsubsection{Standard case with $\w_3 \in \{0, \wt\}$}
\label{sec:a:standard}
In the standard maneuver, it accelerates or decelerates
until it reaches the target speed $\w_1$, as shown for cases (a), (b), (c),
(d), and (e) in Figure \ref{fig:positions}.
Solving for the intersection with $\wt$ gives:
%
\begin{align}
    \label{eq:a:t1mt0:standard}
    \lr{\th_1}\sub{standard} &= \th_f  + \dfrac{1}{2\a_0}(\wt)^2\\[1em]
    \lr{\th_2}\sub{standard} &= \th_3  + \dfrac{1}{2\a_2}\lr{(\wt)^2 - \w_3^2}
\end{align}
%
%
Since the target speed is reached the constant speed value is simply
\begin{align}
    \lr{\w_1}\sub{standard} &= \wt
\end{align}
%
The standard case is valid if and only if:
\begin{align}
    \label{eq:a:t1mt0:standardvalidity}
    \lr{\th_1}\sub{standard} &< \lr{\th_2}\sub{standard}
\end{align}
%
Otherwise, we have to evaluate the cut-short case.
%

\subsubsection{Cut short case with $\w_3 = 0$}
\label{sec:a:cutshortw3is0}
If initial velocity is too low or if the
maneuver is too short to be able to reach the target velocity, it accelerates
until it must begin to decelerate, as in cases (c) and (d) in
Figure \ref{fig:positions}.
Solving for the intersection angle $\th_1=\th_2$ for $\w_1=\w_2$ gives:
%
\begin{align}
    \label{eq:a:cutshort}
    \lr{\th_1}\sub{cut short} &= \lr{\th_2}\sub{cut short}\\[1em]
    \dfrac{1}{2\a_0}\w_1^2 + \th_f  &= \th_3 + \dfrac{1}{2\a_2} \w_1^2
\end{align}
%
which can be solved for $\w_1$ as:
%
\begin{align}
    \label{eq:a:cutshortsolve}
    \w_1^2 = 2 \dfrac{\a_0\a_2}{\a_2-\a_0}\lr{\th_3 - \th_f}
\end{align}
%
from which $\th_1=\th_2$ follow via \eqref{eq:a:cutshort}.
%
When cut short, the target speed $\wt$ is not reached but the
peak $\w_1 \geq 0$ can be obtained as the square root
of \eqref{eq:a:cutshortsolve}.
%
\subsubsection{Cut short case with $\w_3 = \w_1$ and $\a_0 > 0$}
\label{sec:a:cutshortw3isw1}

If $\a_0 > 0$ and there is no deceleration phase but we still can't reach the
target speed, we have $\w_3=\w_1 < \wt$ with $\th_1=\th_2=\th_3$:
%
\begin{align}
    \label{eq:a:cutshortw1}
    \w_1^2  &= 2\a_0\lr{\th_3 - \th_f}
\end{align}

\subsubsection{Reversing and unreversing the final and target speed}
\label{sec:a:reversing}
The aforementioned derivation assumes $\th_3 > \th_0$ and so $\wt > 0$ to
reduce the number of (similar) cases that must be accounted for. This section
shows how to transform a given angle based maneuver to match this assumption,
calculate the trajectory, and map the final result back to obtain the
originally requested command.

\begin{itemize}
    \item Let the boolean $a := \th_3 < \th_0$.
    \item If $a$, then invert targets as:
          $\th_3 := 2 \th_0 - \th_3$, $\wt := -\wt$, $\w_0 := -\w_0$,
          $\w_3 := -\w_3$.
    \item Calculate angle and speed intersections using
          Sections \ref{sec:a:standard}--\ref{sec:a:cutshortw3isw1}.
    \item If $a$, then reverse results using Section \ref{sec:invert}.
\end{itemize}

\subsubsection{Intermediate times (all cases)}

Having derived expressions to evaluate $\th_1$, $\th_2$, and $\w_1$, the
remaining parameters of Table \ref{tab:parameters} to compute are the times
$t_1$, $t_2$, and $t_3$:
%
\begin{align}
    t_1 - t_0 &= \dfrac{\w_1-\w_0}{\a_0}\\[1em]
    t_2 - t_1 &= \dfrac{\th_2-\th_1}{\w_1}\\[1em]
    t_3 - t_2 &= \dfrac{\w_3-\w_1}{\a_2}
\end{align}

\subsection{Making a stationary trajectory}
\label{sec:stationary}
For a stationary hold trajectory, we have:
%
\begin{align}
    t_3 = t_2 = t_1 = t_0 \\[1em]
    \th_3 = \th_2 = \th_1 = \th_0 \\[1em]
    \w_1 = \w_0 = 0 \\[1em]
    \a_0 = \a_2 = 0
\end{align}

\subsection{Reversing a trajectory}
\label{sec:invert}
In Sections \ref{sec:timebasedref} and \ref{sec:anglebasedref} several
assumptions were made to ensure that the calculated trajectory is always
forwards with $\wt > 0$. If the original target speed was negative, the
newly computed maneuver can be reversed as follows:
%
\begin{align}
    \th_1 &:= 2 \th_0 - \th_1\\[1em]
    \th_2 &:= 2 \th_0 - \th_2\\[1em]
    \th_3 &:= 2 \th_0 - \th_3\\[1em]
    \w_0 &:= -\w_0\\[1em]
    \w_1 &:= -\w_1\\[1em]
    \a_0 &:= -\a_0\\[1em]
    \a_2 &:= -\a_2
\end{align}

\subsection{Stretching trajectories for synchronization}

In some applications, two or more separate trajectories are executed in
parallel to synchronize their movements. Typically, each trajectory has its own
target angle $\th_3$. To make them run in parallel, we slow down the shorter
maneuvers such that they take as long as the longest maneuver. For this
analysis, let the trajectory with superscript $0$ take the longest, so that
%
\begin{align}
    t^0_3 - t^0_0 \geq t^i_3 - t^i_0  \quad \forall \quad i
\end{align}

For synchronization we require that for all other trajectories $i$ we have:
%
\begin{align}
    t^i_1 &= t^0_1=t_1\\[1em]
    t^i_2 &= t^0_2=t_2\\[1em]
    t^i_3 &= t^0_3=t_3
\end{align}
%
Each trajectory still has to reach its own target $\th^i_3$.
Using (\ref{eq:t:anglepar1}--\ref{eq:t:anglepar3}) this gives the constraint:
%
\begin{align}
    \label{eq:stretchconstraint1}
    \th^i_3 - \th^i_0  &=  \w^i_0(t_1-t_0)+\dfrac{1}{2}\a^i_0(t_1-t_0)^2+
        \w^i_1(t_2-t_1)+ \w^i_1(t_3-t_2)+\dfrac{1}{2}\a^i_2(t_3-t_2)^2
\end{align}
%
Likewise, each trajectory has to reach its top speed $\w^i_1$ and its final
speed $\w^i_3$ in the same time spans as the longest maneuver, which gives the
two additional constraints:
%
\begin{align}
    \label{eq:stretchconstraint2}
    \a^i_0 &= \dfrac{\w^i_1-\w_0^i}{t_1 - t_0}\\[1em]
    \label{eq:stretchconstraint3}
    \a_2^i &= \dfrac{\w_3^i-\w_1^i}{t_3 - t_2}
\end{align}
%
With three constraints we can solve for the three unknowns $\a^i_0$, $\a^i_1$.
and $\w^i_1$. To do so, solve for $\w^i_1$ by substituting
\eqref{eq:stretchconstraint2}, \eqref{eq:stretchconstraint3} into
\eqref{eq:stretchconstraint1}:
%
\begin{align}
    \label{eq:stretchconstraintsolved}
    \w^i_1 = \dfrac{2\lr{\th_3^i-\th_0^i}-\w_0^i\lr{t_1-t_0} -
    \w_3^i\lr{t_3-t_2}}{t_3-t_0 + t_2 - t_1}
\end{align}
%
Since $t_2 - t_1 \geq 0$, zero division is avoided if $t_3 - t_0 > 0$. If $t_3
- t_0 = 0$, then we have a stationary trajectory as per Section
\ref{sec:stationary}. If $\w_3^i$ was nonzero, it needs to be lowered
too as $\w_3^i := \w_1^i$.

Once $\w^i_1$ is known, $\a^i_0$, $\a^i_1$ follow directly from
\eqref{eq:stretchconstraint2}, \eqref{eq:stretchconstraint3}. Zero division is
avoided because $\a^i_0$ is undefined (not used) when $t_1 = t_0$ and $\a^i_2$
is undefined (not used) when $t_3 = t_2$. The intermediate angles $\th_1^i$
and $\th_2^i$ can be obtained from
(\ref{eq:t:anglepar1}--\ref{eq:t:anglepar2}).

\end{document}


%\documentclass[12pt,onecolumn]{report}
%\usepackage{amssymb, amsmath, amsthm,graphicx,
%paralist,algpseudocode,algorithm,cancel,url,color}
%\usepackage[margin=1in]{geometry}

\documentclass[11pt]{article}
%\usepackage{amsmath, amssymb, amsthm, fullpage, algorithm,
%  algorithmic, hyperref}

\newcommand\numberthis{\addtocounter{equation}{1}\tag{\theequation}}

\input{arxiv_style}
\input{macros}
\input{ayush}

\bibliographystyle{alpha}

%\usepackage{sectsty}
%\usepackage{fancyvrb}
%\usepackage{mathrsfs}
%\usepackage{multirow}
%\usepackage{hhline}
%\usepackage{booktabs}
%\usepackage[table]{xcolor}
%\usepackage{tikz}
%\usepackage{amssymb}
%\usepackage{amsmath}
%\usepackage{dsfont}
%\usepackage{enumitem}
%\usepackage{amsmath}
%\usepackage{amsfonts}
%\usepackage{mathtools}
%\theoremstyle{definition}
%
%\newtheorem{definition}{Definition}[section]
%\newtheorem{theorem}{Theorem}[section]
%\newtheorem{lemma}[theorem]{Lemma}
%\newtheorem{corollary}{Corollary}[theorem]

\title{Concentration Inequalities II: Bernstein, Freedman, Martingale Methods  and Applications}
\author{Presenter: Seth Strimas-Mackey \\ Scribe: Leo Huang}
\date{1st March 2019}

\begin{document}

\maketitle

\subsubsection*{Topics Covered}
\begin{itemize}
  \item Sub-Gaussian/Sub-Exponential Random Variables
  \item Bernstein's Inequality (3 types)
  \item Johnson-Lindenstrauss (JL) Lemma
\end{itemize}

\section{Sub-Gaussian Random Variables}
\begin{definition}[Sub-Gaussian Random Variable]
A random variable $X$, with $\mathbb{E}[X]=0$, is Sub-Gaussian with variance proxy $\sigma^2$, i.e., $X \sim \text{subG}(\sigma^2)$ if $$\mathbb{E}e^{sX}\le e^{s^2\sigma^2/2}~~\forall s\in \mathbb{R}$$.
\end{definition}

\begin{theorem}[Sub-Gaussian Hoeffding]
Let $X_1, ...X_n\sim \text{subG}(\sigma^2)$ be independent, with $\mathbb{E}[X]=0$. Then
\[P(\frac{1}{n}\sum_{i=1}^nX_i\ge t)\le e^{-nt^2/2\sigma^2}\]
In the bounded Case: $|X_i|\le k, \sigma^2 \leq k^2$
\end{theorem}
\begin{proof}
Let $\overline(X) = \frac{1}{n}\sum_{i=1}^n X_i$. Then,
\begin{align*}
    P(\overline{X}>t) &\le e^{-st}\mathbb{E}[e^{s}\overline{X}]
    \\ & = e^{-st}(\mathbb{E}[e^{sX_i}/n])^n
    \\&\le e^{-st}(e^{s^2\sigma^2/2n^2})^n \\& = e^{-st+s^2\sigma^2/2n}
\end{align*}
Setting $s = \frac{nt}{\sigma^2}$ minimizes the exponent, so that we have
\[P(\overline{X}>t)\le e^{-\frac{nt^2}{2\sigma^2}}\]
\end{proof}

As an example, one can observe that for $n=1$, $P(X\ge t)\le e^{-t^2/2\sigma^2}$. Sub-Gaussian random variables have Gaussian like tails.

\section{Sub-exponential Random Variables}
This class of random variables is similar to sub-Gaussian random variables, but have heavier exponential tails.

\paragraph{Example}
Consider Laplace(1), with $f_X(x)=\frac{1}{2}e^{-|x|}$ for $x \in \mathbb{R}$. Then, $P(|x|\ge t)=e^{-t}$, and clearly, $X$ is not subG($\sigma^2$) for any $\sigma$.

But for small s, i.e., $|s| < \frac{1}{2}$, $\mathbb{E}[e^{sX}]=\frac{1}{1-s^2} \leq e^{2s^2}$, which is bounded by a sub-Gaussian moment generating function. Thus, the random variable behaves like sub-gaussian for small $s$, but not as $s$ gets larger. It turns out that this is more general.

\begin{lemma} $\mathbb{E}[X]=0, \mathbb{P}(|x|>t)\le 2e^{-t/\lambda}, \lambda>0\implies \mathbb{E}[|x|^k]\le 2 \lambda^k k!$ and $ \mathbb{E}[e^{sX}]\le e^{2s^2\lambda^2}$.
\end{lemma}

This lemma is used to prove bound on all moments of $X$. The
first step is to write $\mathbb{E}[|X|^k]=\int_{0}^\infty P(|x|^k>t)\,dt$. The second step is to Taylor expand and use the bound on $\mathbb{E}[|X|^k]$.

This motivates an equivalent definition using moment generating functions.

\begin{definition}(Sub-Exponential Random Variables)
A random variable $X$, with $\mathbb{E}[X]=0$, is Sub-Exponential with parameter $\lambda$, i.e., $X \in \text{subE}(\lambda)$,  if $\mathbb{E}[e^{sX}]\le e^{s^2\lambda^2/2},~~\forall ~|s|\le \frac{1}{\lambda}$.
\end{definition}

\section{Bernstein's Inequality}
\subsection{Bernstein's Inequality I}
\begin{theorem}
Let $X_1, ...X_n\sim \text{subE}(\lambda)$ be independent random variables with $\mathbb{E}[X]=0$. Then,
\[P(\frac{1}{n}\sum_{i=1}^n X_i>t)\le \exp\left(-\frac{n}{2}\left(\frac{t^2}{\lambda^2}\wedge \frac{t}{\lambda}\right)\right)\]
\end{theorem}

\begin{proof}
\begin{align*}
P\left(\frac{1}{n}\sum_{i=1}^n X_i>t\right)\le e^{-snt}\prod_{i=1}^n \mathbb{E}[e^{sX_i}]\le e^{-snt}e^{ns^2\lambda^2/2}=\exp(-snt+ns^2\lambda^2/2)=\exp\prn*{-\frac{n}{2} \prn*{\frac{t^2}{\lambda^2}\wedge \frac{t}{\lambda}}}
\end{align*}
If, $\abs*{t} \leq \lambda^2$, optimizer $s$, otherwise set $S = \frac{1}{\lambda}$.

%Optimize, $s=\frac{t}{}$ if $|t|\le 1, s=1$, else $s=t\wedge 1$.
\end{proof}

%Normalize by $\frac{1}{\sqrt{n}}$. Then
%\[P(\frac{1}{\sqrt{n}}\sum_{i=1}^n X_i > t ) \le \begin{cases}e^{-t^2/2\lambda^2} & |t|<\lambda \sqrt{n}\\ e^{-t\sqrt{n}/2\lambda} & |t|\ge \lambda \sqrt{n}\end{cases}
%\]

\begin{lemma} \label{lem: subgaussian_to_subexponential}
 Let $X\sim \text{subG}(\sigma^2)$. Consider $Z=X^2-\mathbb{E}[X^2]$. Then $Z\sim \text{subE}[16\sigma^2]$.
\end{lemma}
 \begin{proof}{(informal)}
 \begin{align*}
P(|x|>t) &\le 2e^{-ct^2}\\
\intertext{implies,} P(X^2>t) &\le 2e^{-ct^2} \\
\intertext{implies,}
P(X^2>t) &\le 2e^{-ct}.
\end{align*}
\end{proof}

For bounded RV, we can get stronger version of Bernstein's Inequality, with smooth transition from regime to regime.

\subsection{Bernstein's Inequality II}
\textbf{Theorem}
Consider $X_1, ..., X_n$ with $\mathbb{E}[X_i]=0, \mathbb{E}[X_i^2]=\sigma^2$ and $|X_i|\le K$. Then
\[P\left(\frac{1}{n}\sum_{i=1}^n X_i>t\right)\le \exp\left(\frac{-nt^2/2}{\sigma^2+Kt/3}\right)\]

\begin{proof}
Using the standard Chernoff method,
\begin{align}
P\left(\frac{1}{n}\sum_{i=1}^n X_i>t\right) &\le \frac{\mathbb{E} \left[ e^{ s \frac{\sum_{i=1}^n X_i}{n}} \right]}{e^{st}} \notag \\
&= e^{-st} \prod_{i=1}^n \mathbb{E} \left[e^{s \frac{X_i}{n} } \right] \label{eq:bernstein_at_chernoff}
\end{align}
Note that if $|s|<\frac{3n}{k}$, then $|s \frac{X_i}{n}|\le 3$, and thus using lemma \ref{lem:bernstein_algebraic}
\begin{align*}
\mathbb{E}[e^{s\frac{X_i}{n}}]&\le 1+ \frac{s}{n}\mathbb{E}[X_i]+\mathbb{E}\left[ \frac{\frac{s^2X^2_i}{2n^2}}{1-\frac{|s||X_i|}{3n}}\right] \\
					   &\le 1 + \mathbb{E}\left[\frac{\frac{s^2X^2_i}{2n^2}}{1-\frac{|s|K}{3n}}\right]  \\
					   &\leq 1 + \frac{\frac{s^2\sigma^2}{2n^2}}{1-\frac{|s|K}{3n}} \\
					   &\leq \exp\left(\frac{\frac{s^2\sigma^2}{2n^2}}{1-\frac{|s|K}{3n}}\right)  \numberthis \label{eq:mgf_bound}
					   %&\le \exp\left(\frac{s^2\sigma^2/2}{1-|s|K/3}\right)
\end{align*}

Using this back in Equation \ref{eq:bernstein_at_chernoff}, we get:
\begin{align*}
P\left(\frac{1}{n}\sum_{i=1}^n X_i>t\right) &\le \exp\left(  \frac{\frac{s^2\sigma^2}{2n}}{1-\frac{|s|K}{3n}} - st \right)
\intertext{Choosing $s=\frac{nt}{\sigma^2+tK/3}$}
&\leq \exp\left(\frac{-nt^2}{2(\sigma^2 + \frac{tK}{3})}\right)
\end{align*}
\end{proof}

\paragraph{Comparison to Hoeffding's inequality for Bounded Random variables}
For the same failure probability $\delta$, Bernstein's inequality allows with probability at-least $1 - \delta$,
\begin{align*}
	\frac{\sum_{i=1}^n X_i}{n} \leq \mathbb{E} [X] + O \left( \frac{\sigma}{\sqrt{n}} + \frac{K}{n} \right)
\end{align*}

whereas, Hoeffding's inequality gives us
\begin{align*}
	\frac{\sum_{i=1}^n X_i}{n} \leq \mathbb{E} [X] + O \left( \frac{K}{\sqrt{n}} \right).
\end{align*}

Thus, for random variables for which $\sigma << K$, Bernstein gives a tigher rate.
\begin{lemma} \label{lem:bernstein_algebraic} For all $z \in [-3, 3] $,
\[e^z\le 1+z+\frac{z^2/2}{1-|z|/3}\] \end{lemma}
\begin{proof} Proof by picture. Compare the two graphs.
\end{proof}

\subsubsection{An Application: Johnson Lindenstrauss Lemma}
For any two vectors $a, a' \in \bbR^p$, define the distance to be $\nrm*{a - a'}_2^2$. The Johnson Lindenstrauss (JL) lemma deals with the following question.

\paragraph{Question}  Given a finite set of $n$ points, $A=\{a_1, ...a_n\}\subset \mathbb{R}^D$, with $D$ large. Can one find a $d < D$ such that there exists a linear mapping $f: \bbR^D \mapsto \bbR^d$ that preserves distance upto an error $\epsilon$, i.e., $f$ is an $\epsilon-$isometry on $A\subset \mathbb{R}^D$, or,
$$(1-\epsilon)\|a-a'\|^2\le \|f(a)-f(a')\|^2 \le (1+\epsilon)\|a-a'\|^2 ~~ \forall a, a'\in A$$

We first show that such a mapping exists using the probabilistic method. Consider a random matrix $X \in \bbR^{d \times D}$ such that for all $i\in\{1, ...d\}, j\in \{1, ...D\}$,  $X_{ij}$ is an independent random variable with $\En \brk*{X_{ij}}=0$ and $var(X_{ij})=1$ (for example normal gaussians).  Define the function $f: \bbR^D \mapsto \bbR^d$ as $f(a) \ldef{} \frac{1}{\sqrt{d}}Xa$, or for any $k \in [d]$,  $f_k(a) = \sum_{j=1}^d X_{ij} a_j$. Thus, we have:

\begin{align*}\mathbb{E}[f_k^2(a)] &= \frac{1}{d}\sum_{j=1}^D a_j^2 \mathbb{E}[X_{ij}^2] = \|a\|^2 \\
\mathbb{E}[\|f(a)\|^2] &= \frac{1}{d} \mathbb{E}\sum_{k=1}^d f_k^2(a) = \|a\|^2
\end{align*}

This shows that $\|\alpha\|^2$ is preserved by $f$ in expectation. The following theorem gives a condition on $d$ such that this also holds in high probability.

\begin{theorem}[JL lemma]
Let $A\subset \mathbb{R}^D$ such that  $|A|=n$. Consider a matrix $X: \bbR^D \mapsto \bbR^d$ such that for all $i \in [d], j \in [D], ~~ X_{ij} \in  \text{subG}(\sigma^2)$ and is sampled independently. Then for any $\epsilon, \delta\in(0, 1)$, if $d\ge 100 \frac{\sigma^4}{\epsilon^{2}}\log(n/\sqrt{\delta})$, then with probability at-least $1 - \delta$, the linear map defined by $f(a) \ldef{} \frac{1}{\sqrt{d}} Xa$ is an $\epsilon-$isometry on $A$, or more specifically,
$$(1-\epsilon)\|a-a'\|^2\le \|f(a)-f(a')\|^2 \le (1+\epsilon)\|a-a'\|^2 ~~ \forall a, a'\in A$$
\end{theorem}

Before we provide a proof for the JL lemma, observe that the projection dimension $d$ is independent of the dimension $D$ of our feature vectors.
\begin{proof}
Define $T=\{\frac{a-a'}{\|a-a'\|}: a, a'\in A, a\ne a' \}$. We first state the following fact, which is quite easy to prove,

\begin{fact}
$f$ is a linear $\epsilon-$isometry of A iff \[\left|\|f(\alpha)\|^2-1\right|\le \epsilon \ \ \forall \alpha\in T\]
\end{fact}

We will thus show that with probabilty at-least $1 - \delta $, $\left|\|f(\alpha)\|^2-1\right|\le \epsilon \ \ \forall \alpha\in T$. Note that $|T|\le {{n}\choose{2}}\le \frac{n^2}{2}$, and $\En \brk*{f(\alpha)} = 1$ $\forall \alpha \in T$. First observe that $f_{i}(\alpha)$ is $\sigma^2$ sub-gaussian.

\begin{align*}
\mathbb{E}[e^{sf_i(\alpha)}] &= \mathbb{E}\exp\left(s\sum_{j=1}^D \alpha_j X_{ij}\right) \\& = \prod_{j=1}^D \exp(s\alpha_jX_{ij})\\&\le \exp(\frac{s^2\sigma^2}{2}  \sum_{j=1}^D \alpha_j^2 /\|\alpha\|^2) \\ & = e^{s^2\sigma^2/2}
\end{align*}

Using \pref{lem: subgaussian_to_subexponential}, this implies that $f^2_i(\alpha)\sim \text{subE}(16\sigma^2)$. Thus, applying Bernstein's inequality, with $\En \brk*{f_i(\alpha)} = 1 $  and taking a union bound over all $\alpha \in T$,

 Using the Bernstein's inequality in the regime $|t|\le 16\sigma^2$,

 \begin{align*}
 P(\sup_{\alpha\in T}\left|\sum_{i=1}^d  \frac{f_i^2(\alpha)}{d} -1\right|\ge \epsilon)\le 2 \times \frac{n^2}{2} \exp(\frac{-dt^2}{2 \times16^2\sigma^4}),
\intertext{Setting $t = \sqrt{\frac{512\sigma^4\log(n^2/\delta)}{d}} ~~(\leq 16 \sigma^2)$, we get, }
P\left(\sup_{\alpha\in T}\left|\|f(\alpha)\|^2-1\right|\ge \sqrt{\frac{512\sigma^4\log(n^2/d)}{d}} \right )\ge \delta.
 \end{align*}
Thus, our choice of $d$ suffices for  $\epsilon$-isometry.
\end{proof}

\subsection{Berstein's Inequality III: Martingales}

\begin{theorem}[Freedman's Inequality]
Let $X_1, ..., X_n$ be a bounded martingale difference sequence, i.e.,  $\mathbb{E}[X_i|X_{i-1}]=0$ and  $|X_i|\le K$. Define the martingale $S_i = \sum_{j=1}^i X_i$. Additionally, define $\En_{i-1}[S_1]$ to be the expectation w.r.t. $X_i$ while the random variables $X_1, \ldots, X_i$ are fixed. Similarly, define $V_n = \sum_{i=1}^n \En_{i-1} \brk*{X_i^2} $.Then,
$$ P\prn*{S_n>t \text{ and } V_n\le \sigma^2} \le \exp\left(\frac{-t^2/2}{\sigma^2+Kt/3}\right) $$
\end{theorem}

$E_{i-1}[S_i] = E_{i-1}[X_i]+S_{i-1}=S_{i-1}$. Let $V_n = \sum_{i=1}^n \mathbb{E}[X_i^2]$. Then

\begin{proof}(informal)
Previously, we saw $\mathbb{E}[e^{\lambda X_i}]\le \exp(\mathbb{E}[X_i^2\psi(\lambda)])$, $\psi(s) = \frac{\lambda^2/2}{1-|\lambda|K/3}$ (see \pref{eq:mgf_bound}). Repeat argument using $\mathbb{E}_{i-1}$ instead of $\mathbb{E}$ to show that $\mathbb{E}_{i-1}e^{\lambda X_i}\le \exp(\mathbb{E}_{i-1}X_i^2\psi(\lambda))$. Then

\begin{align*}
    P(S_n\ge t, V_n\le \sigma^2) &= \mathbb{E}1(e^{\lambda S_n}\ge e^{\lambda t})1(V_n\le \sigma^2) \\& \le e^{-\lambda t}\mathbb{E}[e^{\lambda S_n}1(V_n\le \sigma^2)] \\&= e^{-\lambda t}\mathbb{E}[e^{\lambda S_n-V_n\psi(\lambda)}e^{V_n\psi(\lambda)}1(V_n\le \sigma^2)] \\ &\le e^{-\lambda t+\sigma^2 \psi(\lambda)}\mathbb{E}[e^{\lambda S_n-V_n\psi(\lambda)}1(V_n\le \sigma^2)]
    \\&\le e^{-\lambda t+\sigma^2 \psi(\lambda)}\mathbb{E}[e^{\lambda S_n -V_n\psi(\lambda)}]
    \\&= e^{-\lambda t +\sigma^2\psi(\lambda)}\mathbb{E}[e^{\lambda S_{n-1}-V_{n-1}\psi(\lambda)-\mathbb{E}_{n-1}[X_n]^2\psi(\lambda)}\times e^{\lambda X_n}]\\&= e^{-\lambda t +\sigma^2\psi(\lambda)}\mathbb{E}[e^{\lambda S_{n-1}-V_{n-1}\psi(\lambda)-\mathbb{E}_{n-1}[X_n]^2\psi(\lambda)}\times \mathbb{E}_{n-1}[e^{\lambda X_n}]]  \\& =
    [e^{-\lambda t +\sigma^2 \psi(\lambda)}\mathbb{E}[e^{\lambda S_{n-1}-V_{n-1}\psi(\lambda)-\mathbb{E}_{n-1}[X_n^2]\psi(\lambda)}\times e^{\mathbb{E}_{n-1}[X_n^2]\psi(\lambda)}]
    \\& = e^{-\lambda t+\sigma^2 \psi(\lambda)}\mathbb{E}[e^{\lambda S_{n-1}-V_{n-1}\psi(\lambda)}]\le ...\le e^{-\lambda t +\sigma^2\psi(\lambda)}
\end{align*}
Optimizing over $\lambda$ gives the required tail bound.
\end{proof}

\nocite{*}
{\small
\bibliography{refs}
}

\end{document}


\documentclass[../searching.tex]{subfiles}
\begin{document}
% \paragraph{refers}
% \url{https://tp-iiita.quora.com/The-Two-Pointer-Algorithm}

There are actually 50/900 problems on LeetCode are tagged as two pointers. Two pointer search algorithm are normally used to refer to searching that use two pointer in one for/while loop over the given data structure. Therefore, this part of algorithm gives linear performance as of $O(n)$. While, it does not refer to situation such as searching a pair of items in an array that sums up to a given target value, then two nested for loops are needed to search all the possible pairs. There are different ways to put these two pointers:
\begin{enumerate}
    \item Equi-directional:  Both start from the beginning: we have \textbf{slow-faster pointer}, \textbf{sliding window algorithm}.
    \item Opposite-directional: One at the start and the other at the end, they move close to each other and meet in the middle, (-> <-).
\end{enumerate}
In order to use two pointers, most times the data structure needs to be ordered in some way, and decrease the time complexity from $O(n^2)$ or $O(n^3)$ of two/three nested for/while loops to $O(n)$ of just one loop with two pointers and search each item just one time. In some cases, the time complexity is highly dependable on the data and the criteria we set.

As shown in Fig.~\ref{fig:two pointer}, the pointer $i$ and $j$ can decide: a pair or a subarray (with all elements starts from i and end at j). We can either do search related with a pair or a subarray. For the case of subarray, the algorithm is called sliding window algorithm. As we can see, two pointers and sliding window algorithm can be used to solve K sum (Section~\ref{}), most of the subarray (Section~\ref{}), and string pattern match problems (Section~\ref{}).
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.9\columnwidth]{fig/two_pointers.png}
    \caption{Two pointer Example}
    \label{fig:two pointer}
\end{figure}

Two pointer algorithm is less of a talk and more of problem attached. We will explain this type of algorithm in virtue of both the leetcode problems and definition of algorihtms.
% \subsection{Two Pointers Techniques}
To understand two pointers techniques, better to use examples, here we use two examples: use slow-faster pointer to find the median and Floyd's fast-slow pointer algorithm for loop detection in an array/linked list and two pointers to get two sum.

\subsection{Slow-fast Pointer}
\paragraph{Find middle node of linked list} The simpest example of slow-fast pointer application is to get the middle node of a given linked list. (LeetCode problem: 876. Middle of the Linked List)
\begin{lstlisting}[numbers=none]
Example 1 (odd length):

Input: [1,2,3,4,5]
Output: Node 3 from this list (Serialization: [3,4,5])

Example 2 (even length):

Input: [1,2,3,4,5,6]
Output: Node 4 from this list (Serialization: [4,5,6])
\end{lstlisting}
\begin{figure}[h]
    \centering
    \includegraphics[width = 0.8\columnwidth]{fig/middle node of a given linked list.png}
    \caption{Slow-fast pointer to find middle}
    \label{fig:slow-faster}
\end{figure}
We place two pointers simultaneously at the head node, each one moves at different paces, the slow pointer moves one step and the fast moves two steps instead. When the fast pointer reached the end, the slow pointer will stop at the middle. For the loop, we only need to check on the faster pointer, make sure fast pointer and fast.next is not None, so that we can successfuly visit the fast.next.next. When the length is odd, fast pointer will point at the end node, because fast.next is None, when its even, fast pointer will point at None node, it terimates because fast is None.
\begin{lstlisting}[language=Python]
def middleNode(self, head):
    slow, fast = head, head
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
    return slow
\end{lstlisting}

\paragraph{Floyd's Cycle Detection (Floyd's Tortoise and Hare)} Given a linked list which has a cycle, as shown in Fig.~\ref{fig:floyd_cycle}. To check the existence of the cycle is quite simple. We do exactly the same as traveling by the slow and fast pointer above, each at one and two steps. (LeetCode Problem: 141. Linked List Cycle). The  code is pretty much the same with the only difference been that after we change the fast and slow pointer, we check if they are the same node. If true, a cycle is detected, else not.
\begin{lstlisting}[language=Python]
def hasCycle(self, head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False
\end{lstlisting}

In order to know the starting node of the cycle. Here, we set the distance of the starting node of the cycle from the head is $x$, and $y$ is the distance from the start node to the slow and fast pointer's node, and $z$ is the remaining distance from the meeting point to the start node.
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.7\columnwidth]{fig/TQoyH.png}
    \caption{Floyd's Cycle finding Algorithm}
    \label{fig:floyd_cycle}
\end{figure}

Now, let's try to device the algorithm. Both slow and fast pointer starts at position 0, the node index they travel each step is: [0,1,2,3,...,k] and [0,2,4,6,...,2k] for slow and fast pointer respectively. Therefore, the total distance traveled by the slow pointer is half of the distance travelled by the fat pointer. From the above figure, we have the distance travelled by slow pointer to be $d_s = x+y$, and for the fast pointer $d_f = x+y+z+y = x+2y+z$. With the relation $2*d_s = d_f$. We will eventually get $x = z$. Therefore, by moving slow pointer to the start of the linked list after the meeting point, and making both slow and fast pointer to move one node at a time, they will meet at the starting node of the cycle. (LeetCode problem: 142. Linked List Cycle II (medium)).
\begin{lstlisting}[language=Python]
def detectCycle(self, head):
    slow = fast = head
    bCycle = False
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast: # a cycle is found
            bCycle = True
            break

    if not bCycle:
        return None
    # reset the slow pointer to find the starting node
    slow = head
    while fast and slow != fast:
        slow = slow.next
        fast = fast.next
    return slow
\end{lstlisting}
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.6\columnwidth]{fig/circularlinkedlist.png}
    \caption{One example to remove cycle}
    \label{fig:cycle_remove}
\end{figure}
In order to remove the cycle as shown in Fig.~\ref{fig:cycle_remove}, the starting node is when slow and fast intersect, the last fast node before they meet. For the example, we need to set -4 node's next node to None. Therefore, we modify the above code to stop at the last fast node instead:
\begin{lstlisting}[language=Python]
    # reset the slow pointer to find the starting node
    slow = head
    while fast and slow.next != fast.next:
        slow = slow.next
        fast = fast.next
    fast.next = None
\end{lstlisting}

\subsection{Opposite-directional Two pointer}
Two pointer is usually used for searching a pair in the array. There are cases the data is organized in a way that we can search all the result space by placing two pointers each at the start and rear of the array and move them to each other and eventually meet and terminate the search process. The search target should help us decide which pointer to move at that step.  This way, each item in the array is guaranteed to be visited at most one time by one of the two pointers, thus making the time complexity to be $O(n)$. Binary search used the technique of two pointers too, the left and right pointer together decides the current searching space, but it erase of half searching space at each step instead.

\paragraph{Two Sum - Input array is sorted} Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.  (LeetCode problem: 167. Two Sum II - Input array is sorted (easy).)
\begin{lstlisting}[numbers=none]
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
\end{lstlisting}

Due to the fact that the array is sorted which means in the array [s,s1 ..., e1, e], the sum of any two integer is in range of [s+s1, e1+e]. By placing two pointers each start from s and e, we started the search space from the middle of the possible range. [s+s1, s+e, e1+e].  Compare the target $t$ with the sum of the two pointers $v_1$ and $v_2$:
\begin{enumerate}
    \item  $t == v_1 + v_2$: found
    \item  $v_1+v_2 < t$: we need to move to the right side of the space, then we increase $v_1$ to get larger value.
    \item $v_1+v_2 > t$: we need to move to the left side of the space, then we decrease $v_2$ to get smaller value.
\end{enumerate}
\begin{lstlisting}[language=Python]
def twoSum(self, numbers, target):
    #use two pointers
    n = len(numbers)
    i, j  = 0, n-1
    while i < j:
        temp = numbers[i] + numbers[j]
        if temp == target:
            return [i+1, j+1]
        elif temp < target:
            i += 1
        else:
            j -= 1
    return []
\end{lstlisting}
% T1: If you see in the problem that you can do comparison and it is always one type of satisfactory element is in ahead of the other, this could be resolved by two pointers (slower and faster). Note: when the while loop stops, is there operations you need?

% Two pointers or three pointers are the most possible. \textit{Two pointers or three pointers is a superset of the sliding window algorithm, prefix sum too.} It can lower the complexity by one power level of n.

%%%%%%%%%%%%%%%%%%%%%%Sliding Window Algorithm%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Sliding Window Algorithm}
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.7\columnwidth]{fig/sliding1.png}
    \caption{Sliding Window Algorithm}
    \label{fig:slide_window}
\end{figure}
Given an array, imagine that we have a fixed size window as shown in Fig.~\ref{fig:slide_window}, and we can slide it forward each time. If we are asked to compute the sum of each window, the bruteforce solution would be $O(kn)$ where k is the window size and n is the array size by using two nested for loops, one to set the starting point, and the other to compute the sum. A sliding window algorithm applied here used the property that the sum of the current window ($S_c$) can be computed from the last winodow ($S_l$) knowling the items that just slided out and moved in as $a_o$ and $a_i$. Then $S_c = S_l-a_o+a_i$. Not necessarily using sum, we generalize it as state, if we can compute $S_c$ from $S_l$, $a_o$ and $a_i$ in O(1), a function $S_c = f(S_l, a_o, a_i)$ then we name this \textbf{sliding window property}. Therefore the time complexity will be decreased to $O(n)$.
\begin{lstlisting}[language=Python]
def fixedSlideWindow(A, k):
    n = len(A)
    if k >= n:
        return sum(A)
    # compute the first window
    acc = sum(A[:k])
    ans = acc
    # slide the window
    for i in range(n-k): # i is the start point of the window
        j = i + k # j is the end point of the window
        acc = acc - A[i] + A[j]
        ans = max(ans, acc)
    return ans
\end{lstlisting}

\paragraph{When to use sliding window} It is important to know when we can use sliding window algorithm, we summarize three important standards:
\begin{enumerate}
    \item It is a subarray/substring problem.
    \item \textbf{sliding window property:}T he requirement of the sliding window satisfy the sliding window property.
    \item \textbf{Completeness:} by moving the left and right pointer of the sliding window in a way that we can cover all the search space. Sliding window algorithm is about optimization problem, and by moving the left and right pointer we can search the whole searching space. \textbf{Therefore, to testify that if applying the sliding window can cover the whole search space and guarentee the completeness decide if the method works.}
\end{enumerate}

For example, 644. Maximum Average Subarray II (hard) does not satisfy the completeness. Because the average of subarray does not follow a certain order that we can decided how to move the window.

\paragraph{Flexible Sliding Window Algorithm} Another form of sliding window where the window size is flexble, and it can be used to solve a lot of real problems related to subarray or substring that is conditioned on some pattern. Compared with the fixed size window, we can first fix the left pointer, and push the right pointer to enlarge the window in order to find a subarray satisfy a condition. Once the condition is met, we save the optimal result and shrink the window by moving the left pointer in a way that we can set up a new starting pointer to the window (shrink the window). At any point in time only one of these pointers move and the other one remains fixed.

\paragraph{Sliding Window Algorithm with Sum} In this part, we list two examples that we use flexible sliding window algorithms to solve subarray problem with sum condition.

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum >= s. If there isn't one, return 0 instead. (LeetCode Problem: 209. Minimum Size Subarray Sum (medium)).
\begin{lstlisting}[numbers=none]
Example:

Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.
\end{lstlisting}
\begin{figure}[h!]
    \centering
    \includegraphics[width=0.5\columnwidth]{fig/prefixsum.png}
    \caption{The array and the prefix sum}
    \label{fig:prefix_sum_array}
\end{figure}
As we have shown in Fig.~\ref{fig:prefix_sum_array}, the prefix sum is the subarray starts with the first item in the array, we know that the sum of the subarray is monotonically increasing as the size of the subarray increase. Therefore, we place a 'window' with left and right as i and j at the first item first. The steps are as follows:
\begin{enumerate}
    \item Get the optimal subarray starts from current i, 0: Then we first move the j pointer to include enough items that sum[0:j+1]>=s, this is the process of getting the optimial subarray that starts with 0. And assume j stops at $e_0$
    \item Get the optimal subarray ends with current j, $e_0$: we shrink the window size by moving the i pointer forward so that we can get the optimal subarray that ends with current j and the optimal subarray starts from $s_0$.
    \item Now, we find the optimal solution for subproblem [0:i,0:j](the start point in range [0, i] and end point in range [0,j]. Starts from next i and j, and repeat step 1 and 2.
\end{enumerate}

The above process is a standard flexible window size algorithm, and it is a complete search which searched all the possible result space. Both j and i pointer moves at most n, it makes the total operations to be at most 2n, which we get time complexity as $O(n)$.
\begin{lstlisting}[language=Python]
def minSubArrayLen(self, s, nums):
    ans = float('inf')
    n = len(nums)
    i = j = 0
    acc = 0 # acc is the state
    while j < n:
        acc += nums[j]# increase the window size
        while acc >= s:# shrink the window to get the optimal result
            ans = min(ans, j-i+1)
            acc -= nums[i]
            i += 1
        j +=1
    return ans if ans != float('inf') else 0
\end{lstlisting}
\begin{bclogo}[couleur = blue!30, arrondi=0.1,logo=\bccrayon,ombre=true]{What happens if there exists negative number in the array? } Sliding window algorithm will not work any more, because the sum of the subarray is no longer monotonically increase as the size increase. Instead (1) we can use prefix sum and organize them in order, and use binary search to find all posible start index.  (2) use monotone stack (see  LeetCode probelm: 325. Maximum Size Subarray Sum Equals k, 325. Maximum Size Subarray Sum Equals k (hard)))
\end{bclogo}

More similar problems:
\begin{enumerate}
    \item 674. Longest Continuous Increasing Subsequence (easy)
\end{enumerate}

\paragraph{Sliding Window Algorithm with Substring} For substring problems, to be able to use sldiing window, s[i,j] should be gained from s[i,j-1] and s[i-1,j-1] should be gained from s[i,j-1]. Given a string, find the length of the longest substring without repeating characters. (LeetCode Problem: 3. Longest Substring Without Repeating Characters (medium))
\begin{lstlisting}[numbers=none]
Example 1:

Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
\end{lstlisting}

First, we know it is a substring problem. Second, it askes to find substring that only has unique chars, we can use hashmap to record the chars in current window, and this satisfy the sliding window property. When the current window violates the condition ( a repeating char), we shrink the window in a way to get rid of this char in the current window by moving the i pointer one step after this char.
\begin{lstlisting}[language=Python]
def lengthOfLongestSubstring(self, s):
    if not s:
        return 0
    n = len(s)
    state = set()
    i = j = 0
    ans = -float('inf')
    while j < n:
        if s[j] not in state:
            state.add(s[j])
            ans = max(ans, j-i)
        else:
            # shrink the window: get this char out of the window
            while s[i] != s[j]: # find the char
                state.remove(s[i])
                i += 1
            # skip this char
            i += 1
        j += 1
    return ans if ans != -float('inf') else 0
\end{lstlisting}

Now, let us see another example with string ang given a pattern to match. Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). (LeetCode Problem: 76. Minimum Window Substring (hard))
\begin{lstlisting}[numbers=none]
Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
\end{lstlisting}

In this problem, the desirable window is one that has all characters from T. The solution is pretty intuitive. We keep expanding the window by moving the right pointer. When the window has all the desired characters, we contract (if possible) and save the smallest window till now. The only difference compared with the above problem is the definition of desirable: we need to compare the state of current window with the required state in T. They can be handled as a hashmap with character as key and frequency of characters as value.
\begin{lstlisting}[language=Python]
def minWindow(self, s, t):
    dict_t = Counter(t)
    state = Counter()
    required = len(dict_t)

    # left and right pointer
    i, j = 0, 0

    formed = 0
    ans = float("inf"), None # min len, and start pos

    while j < len(s):
        char = s[j]
        # record current state
        if char in dict_t:
            state[char] += 1
            if state[char] == dict_t[char]:
                formed += 1

        # Try and contract the window till the point where it ceases to be 'desirable'.
        # bPrint = False
        while i<=j and formed == required:
            # if not bPrint:
            #     print('found:', s[i:j+1], i, j)
            #     bPrint = True
            char = s[i]
            if j-i+1 < ans[0]:
                ans = j - i + 1, i
            # change the state
            if char in dict_t:
                state[char] -= 1
                if state[char] == dict_t[char]-1:
                    formed -= 1

            # Move the left pointer ahead,
            i += 1

        # Keep expanding the window
        j += 1
        # if bPrint:
        #     print('move to:', s[i:j+1], i, j)
    return "" if ans[0] == float("inf") else s[ans[1] : ans[1] + ans[0]]
\end{lstlisting}

The process would be:
\begin{lstlisting}[numbers=none]
found: ADOBEC 0 5
move to: DOBECO 1 6
found: DOBECODEBA 1 10
move to: ODEBAN 6 11
found: ODEBANC 6 12
move to: ANC 10 13
\end{lstlisting}
\paragraph{Three Pointers and Sliding  Window Algorithm}
Sometimes, by manipulating two pointers are not enough for us to get the final solution.
\begin{examples}
\item \textbf{930. Binary Subarrays With Sum.} In an array A of 0s and 1s, how many non-empty subarrays have sum S?
\begin{lstlisting}[numbers=none]
Example 1:

Input: A = [1,0,1,0,1], S = 2
Output: 4
Explanation:
The 4 subarrays are bolded below:
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
\end{lstlisting}
\textit{Note: A.length <= 30000, 0 <= S <= A.length, A[i] is either 0 or 1.}

For example in the following problem, if we want to use two pointers to solve the problem, we would find we miss the case; like in the example $1, 0, 1, 0, 1$, when $j = 5$, $i = 1$, the sum is $2$, but the algorithm would miss the case of $i = 2$, which has the same sum value.

To solve this problem, we keep another index $i_hi$, in addition to the moving rule of $i$, it also moves if the sum is satisfied and that value is $0$. This is actually a Three pointer algorithm, it is also a mutant sliding window algorithm.
\begin{lstlisting}[language=Python]
class Solution:
    def numSubarraysWithSum(self, A, S):
        i_lo, i_hi, j = 0, 0, 0 #i_lo <= j
        sum_window = 0
        ans = 0
        while j < len(A):

            sum_window += A[j]

            while i_lo < j and sum_window > S:
                sum_window -= A[i_lo]
                i_lo += 1
            # up till here, it is standard sliding window

            # now set the extra pointer at the same location of the i_lo
            i_hi = i_lo
            while i_hi < j and sum_window == S and not A[i_hi]:
                i_hi += 1
            if sum_window == S:
                ans += i_hi - i_lo + 1

            j += 1 #increase the pointer at last so that we do not need to check if j<len again

        return ans
\end{lstlisting}
\end{examples}

\paragraph{Summary} Sliding Window is a powerful tool for solving certain subarray/substring related problems. The normal situations where we use sliding window is summarized:
\begin{itemize}
    \item Subarray: for an array with numerical value, it requires all positive/negative values so that the prefix sum/product has monotonicity.
    \item Substring: for an array with char as value, it requires the state of each subarray does not related to the order of the characters (anagram-like state) so that we can have the sliding window property.
\end{itemize}

The steps of using sliding windows:
\begin{enumerate}
    \item Initialize the left and right pointer;
    \item Handle the right pointer and record the state of the current window;
    \item While the window is in the state of desirable: record the optimal solution, move the left pointer and record the state (change or stay unchanged).
    \item Up till here, the state is not desirable.  Move the right pointer in order to find a desirable window;
\end{enumerate}
\subsection{LeetCode Problems}
\paragraph{Sliding Window}
\begin{examples}
\item 76. Minimum Window Substring
\item 438. Find All Anagrams in a String
\item 30. Substring with Concatenation of All Words
\item 159. Longest Substring with At Most Two Distinct Characters
\item 567. Permutation in String
\item 340. Longest Substring with At Most K Distinct Characters
\item 424. Longest Repeating Character Replacement
\end{examples}
\end{document}


\subsection{Robustness}
\label{subsec:experiments-robustness}

Similar to Neubert and Protzel \cite{NeubertProtzel:2012}, we investigate the influence
of noise, blur and affine transformations.
We evaluated all algorithms for $\K \approx 400$ on the \BSDS dataset.
In the following we exemplarily discuss salt and pepper noise and average blurring.

\begin{figure}[t]
	\centering
	\input{plots/implementations}
	\caption{\Rec, \UE and runtime in seconds $t$ on the \BSDS dataset for different implementations of \SLIC, \SEEDS and \FH.
	In particular, \reSEEDS and \reFH show slightly better performance which may be explained by
	improved connectivity. \vlSLIC, in contrast, shows similar performance to \SLIC and, indeed,
	the implementations are very similar. Finally, \preSLIC reduces runtime by reducing the number
	of iterations spend on individual superpixels.
    \textbf{Best viewed in color.}}
	\label{fig:experiments-implementations-bsds500}
    \vskip 12px
    \input{legends/implementations-half}
\end{figure}

Most algorithms are robust to salt and pepper noise; blurring, in contrast, tends
to reduce performance. We consider Figure \ref{subfig:experiments-robustness-noise} showing \Rec, \UE and \K
for $p \in \{0, 0.04,$ $0.08, 0.12, 0.16\}$ being the probability of a pixel being salt or pepper.
Note that Figure \ref{subfig:experiments-robustness-noise} shows the number of
superpixels $K$ before enforcing connectivity as described in Section \ref{subsec:parameter-optimization-connectivity}.
As we can deduce, salt and pepper noise only slightly reduces \Rec and \UE for most algorithms.
Some algorithms compensate the noise by generating more superpixels such as \VCr or \SEAWr
while only slightly reducing performance. In contrast, for \QSr the performance even increases
-- a result of the strongly increasing number of superpixels.
Similar results can be obtained for Gaussian additive noise.
Turning to Figure \ref{subfig:experiments-robustness-blur}
showing \Rec, \UE and \K for $k \in \{0, 5, 9, 13, 17\}$ being the size of a box
filter used for average blurring. As expected, blurring leads to reduced performance with
respect to both \Rec and \UE. Furthermore, it leads to a reduced number of generated
superpixels for algorithms such as \QSr or \VCr. Similar observations can be made for motion blur as well as Gaussian blur.

\begin{figure}[t]
    \centering
    \input{plots/robustness-salt-pepper}
    \caption{The influence of salt and pepper noise for $p \in \{0, 0.04, 0.08, 0.12, 0.16\}$ being the
    probability of salt or pepper. Regarding \Rec and \UE, most algorithms are not
    significantly influence by salt and pepper noise. Algorithms such as
    \QS and \VC compensate the noise by generating additional superpixels.
    \textbf{Best viewed in color.}}
    \label{subfig:experiments-robustness-noise}
\end{figure}
\begin{figure}[t]
	\centering
    \input{plots/robustness-blur}
    \caption{The influence of average blur for $k \in \{0, 5, 9, 13, 17\}$ being
    the filter size. As can be seen, blurring gradually reduces performance
    -- which may be explained by vanishing image boundaries. In addition, for
    algorithms such as \VC and \QS, blurring also leads to fewer superpixels being generated.
    \textbf{Best viewed in color.}}
    \label{subfig:experiments-robustness-blur}
    \vskip 12px
	\input{legends/full-half}
\end{figure}

Overall, most superpixel algorithms are robust to the considered noise models,
while blurring tends to reduce performance. Although the corresponding experiments are omitted for brevity,
we found that affine transformations do not influence performance.


\section{Modelling and plotting parametric responses}

In addition to analysing the data in the above "categorical" design, we now illustrate an alternative "parametric" design in which repetition is viewed as a continuum. In this case, the response to each presentation of famous and non-famous faces is modulated by the time interval (lag) since the previous presentation of that face (for first presentations, this lag is infinite).

\subsection{Specification and estimation}

Finally, consider the effects of the interval between first and second presentations of famous and non-famous faces. For this purpose, an alternative statistical model needs to be estimated, with four trial types. (1) First and second presentation of a non-famous face (N1 and N2 collapsed). (2) First and second presentation of a famous face (F1 and F2 collapsed). (3) Errors in judging non-famous faces. (4) Errors in judging famous faces. These are modelled with the canonical hrf alone, with two parametric (exponential) modulations added for second presentations of non-famous and famous faces. See the README.txt for details of design specification.

\subsection{Inference and plotting}

After completion of model estimation, press `Results' and select the SPM.mat file. When the Contrast Manager appears, define an F-contrast `Effect of Lag (on canonical N+F)' (name) and `0 1 0 1', and a t-contrast `Canonical: Faces $>$ Baseline' (name) and `1 0 1 0'. Select the F-contrast, specify `mask with other contrasts' (yes), select `Canonical: Faces $>$ Baseline', specify `uncorrected mask p-value' (accept default), `nature of mask (inclusive), `title for comparison' (accept default), `corrected height threshold' (no), and `corrected p-value' (accept default). When the MIP appears, press `Volume'.

The table displays all clusters where the exponential change in activation between first and second presentations for famous OR non-famous faces for the canonical hrf is significantly different from zero AND the canonical hrf for the first two conditions is significantly larger than zero (baseline). We can now plot these parametric effects at particular voxels.

To plot these parametric effects, select the R fusiform region (45 -60 -18, similar to the region identified in the previous categorical analysis for repetition effects), and press 'plot'. Select 'Plots of parametric responses' and select 'F' (or 'N').  Note that the 'attrib' option does not allow adjustment of the scale of the Z-axis; therefore, to change the scale for all axes, type e.g. 'figure (1), axis ([0 30 0 100 0 1])' in the Matlab window.

Note that these repetition effects are transient (decrease with increasing intervals between first and second presentations), especially for famous faces.


\documentclass{beamer}
\usepackage{appendixnumberbeamer}

\mode<presentation>{\usetheme[subsectionpage=progressbar,block=fill,numbering=none]{metropolis}}

\usepackage[sfdefault]{FiraSans} %% option 'sfdefault' activates Fira Sans as the default text font
\usepackage[english]{babel}
% \usepackage[utf8]{inputenc}

\usepackage{graphicx} % Allows including images
\usepackage{caption}
\usepackage{booktabs} % Allows the use of \toprule, \midrule and \bottomrule in tables
\usepackage{multicol}

% Math packages
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{mathpartir}

% Lean
\usepackage[outputdir=build]{minted}
\setminted{encoding=utf-8}
\usepackage{fontspec}
\setmainfont{FreeSerif}
\setmonofont{FreeMono}
\setminted[Lean]{
mathescape=true,
linenos=true,
breaklines=true,
numbersep=5pt,
fontsize=\small,
frame=lines,
framesep=2mm
}

% Coloured boxes
\usepackage{tcolorbox}
\colorlet{alert}{mLightBrown}
\newtcolorbox{alertbox}
{standard jigsaw, opacityback=0,colframe=alert}
\newtcolorbox{tbox}
{standard jigsaw, opacityback=0,opacityframe=0}

\title{Continued Fractions in Lean} % the title on the title page
\subtitle{A Newbie's Adventure}

\author{Kevin Kappelmann} % Your name
\institute[VU Amsterdam]{Vrije Universiteit Amsterdam}
\date{June 14, 2019} % Date, can be changed to a custom date

\begin{document}

\maketitle

%------------------------------------------------
\section{Let's Go on an Adventure}
\begin{frame}{Choose a Weapon}
\pause
\only<2>{\begin{figure}\includegraphics[height=0.6\textheight]{img/choose_prover.png}\end{figure}}
\only<3->{\begin{figure}\includegraphics[height=0.6\textheight]{img/choose_prover2.png}\end{figure}}
\visible<4>{
\centerline{\dots perhaps because I am interning at VU Amsterdam}
}
\end{frame}
%------------------------------------------------
\begin{frame}{The Adventurer's Skill Set}
\pause
\begin{itemize}[<+->]
\item Some experience using Isabelle
\item First project with a dependent type theorem prover
\item Basic maths and functional programming knowledge
\end{itemize}
\end{frame}
%------------------------------------------------
\begin{frame}
\begin{figure}
    \includegraphics[height=0.8\textheight]{img/salt_shaker.png}
\end{figure}
\end{frame}
%------------------------------------------------
\section{Definitions}
\begin{frame}{Generalized Continued Fractions}
A generalized continued fraction is\dots
\pause
\begin{equation*}
b + \cfrac{a_0}{b_0 + \cfrac{a_1}{b_1 + \cfrac{a_2}{b_2 + \cfrac{a_3}{b_3 + \ddots\,}}}}
\end{equation*}
\pause
\begin{itemize}[<+->]
\item $b$ is called the \emph{integer part}
\item each $a_i$ is a \emph{partial numerator}
\item each $b_i$ is a \emph{partial denominator}
\end{itemize}
\end{frame}
%------------------------------------------------
\begin{frame}{Generalized Continued Fractions of $\pi$}
\begin{columns}
\column{0.49\textwidth}
\visible<2->{
    \only<1-2>{\centerline{\alert{Continued fraction}}}
    \only<3->{\centerline{Continued fraction}}
}
\begin{equation*}
\resizebox{1\hsize}{!}{$
\pi=3+\cfrac{1}{7+\cfrac{1}{15+\cfrac{1}{1+\cfrac{1}{292+\cfrac{1}{1+\ddots}}}}}
$}
\end{equation*}
\column{0.49\textwidth}
\vspace{5.3mm}
\visible<3->{
\visible<4->{
    \centerline{\alert{Generalized continued fraction}}
}
\begin{equation*}
\resizebox{1\hsize}{!}{$
\pi=3+\cfrac{1^2}{6+\cfrac{3^2}{6+\cfrac{5^2}{6+\cfrac{7^2}{6+\cfrac{9^2}{6+\ddots}}}}}
$}
}
\end{equation*}
\end{columns}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Generalized Continued Fractions in Lean}
\begin{columns}
\column{0.30\textwidth}
\begin{equation*}
\resizebox{1\hsize}{!}{$
b + \cfrac{a_0}{b_0 + \cfrac{a_1}{b_1 + \cfrac{a_2}{b_2 + \cfrac{a_3}{b_3 + \ddots\,}}}}$
}
\end{equation*}
\pause
\column{0.65\textwidth}
\begin{onlyenv}<4->
    \begin{minted}[fontsize=\tiny,linenos=false]{Lean}
    /- Fix a type -/
    variable (α : Type*)

    /-- A gcf_pair consists of a partial numerator a and partial denominator b -/
    structure gcf_pair := (a : α) (b : α)
    \end{minted}
\end{onlyenv}
\end{columns}
\begin{onlyenv}<1-2>
\begin{visibleenv}<2>
\begin{minted}{Lean}
/- Fix a type -/
variable (α : Type*)
\end{minted}
\end{visibleenv}
\end{onlyenv}
\begin{onlyenv}<3>
    \begin{minted}{Lean}
    /- Fix a type -/
    variable (α : Type*)

    /-- A gcf_pair consists of a partial numerator a and partial denominator b -/
    structure gcf_pair := (a : α) (b : α)
    \end{minted}
\end{onlyenv}
\begin{onlyenv}<4>
\begin{minted}[linenos=false]{Lean}
-- Once a sequence hits none, it stays none
def seq := {f : ℕ → option α // ∀ {n}, f n = none → f (n + 1) = none}
\end{minted}
\end{onlyenv}
\begin{onlyenv}<5>
\begin{minted}[linenos=false]{Lean}
def seq := {f : ℕ → option α // ∀ {n}, f n = none → f (n + 1) = none}
/-- A generalized continued fraction consists of a leading head term (the "integer part") and a sequence of partial partial numerators $a_n$ and partial denominators $b_n$ -/
structure gcf := (head : α) (seq : seq (gcf_pair α))
\end{minted}
\end{onlyenv}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Evaluate Generalized Continued Fractions}
\begin{onlyenv}<1>
\begin{minted}[fontsize=\small]{Lean}
def convergents (g : gcf α) (n : ℕ) : α :=
g.head + if n = 0 then 0 else aux n g.seq
\end{minted}
\end{onlyenv}
\begin{onlyenv}<2>
\begin{minted}[fontsize=\small]{Lean}
def aux : ℕ → seq (gcf_pair α) → α
| 0 s := match s.head with
  | none := 0
  | some ⟨a, b⟩ := a / b
  end
| (n + 1) s := match s.head with
  | none := 0
  | some ⟨a, b⟩ := a / (b + aux n s.tail)
  end

def convergents (g : gcf α) (n : ℕ) : α :=
g.head + if n = 0 then 0 else aux n g.seq
\end{minted}
\end{onlyenv}

\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Continued Fractions}
\begin{equation*}
\resizebox{0.4\hsize}{!}{$
b + \cfrac{1}{b_0 + \cfrac{1}{b_1 + \cfrac{1}{b_2 + \cfrac{1}{b_3 + \ddots\,}}}}$
}
\end{equation*}
\pause
\vspace{-5mm}
\begin{visibleenv}<2->
\begin{minted}{Lean}
/-- A continued fraction is a gcf whose partial numerators are equal to 1. -/
def cf := {g : gcf α // ∀ (n : ℕ) (a : α), (partial_numerators g).nth n = some a → a = 1}
\end{minted}
\end{visibleenv}
\visible<3-4>{\centerline{First impression: \visible<4>{\alert{Pretty Sweet!}}}}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Fun with Subtypes}
So, since \emph{cf} is a subtype of \emph{gcf}, we can do
\begin{onlyenv}<1-4>
\begin{minted}{Lean}
def convergents (g : gcf α) (n : ℕ) : α := ...

variable (c : cf α)
#check convergents c 0
\end{minted}
\visible<2->{
    \only<1-2>{\textcolor{red}{\centerline{\Large{NOPE!}}}}
    \only<3-4>{\begin{center}{\includegraphics[height=0.4\textheight]{img/subtype_error.png}}\end{center}}
    \visible<4>{\centerline{\alert{Oh, I see -- I need to cast!}}}
}
\end{onlyenv}
\begin{onlyenv}<5->
\begin{minted}{Lean}
def convergents (g : gcf α) (n : ℕ) : α := ...

variable (c : cf α)
#check convergents (c : gcf α) 0
\end{minted}
\visible<6->{
    \only<5-6>{\textcolor{red}{\centerline{\Large{NOPE!}}}}
    \only<7->{\begin{center}{\includegraphics[height=0.3\textheight]{img/subtype_error2.png}}\end{center}}
    \visible<8->{\centerline{\alert{\dots alright, let's go on Zulip \includegraphics[height=0.04\textheight]{img/zulip.png}}}}
}
\end{onlyenv}
\end{frame}
%------------------------------------------------
\begin{frame}{Please Help Me}
    \center A few minutes and messages from \href{http://wwwf.imperial.ac.uk/~buzzard/}{\emph{Kevin Buzzard}} later\dots
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{The ``Solution''}
We first need to define the casting
\pause
\begin{minted}{Lean}
instance cf_to_gcf : has_coe (cf β) (gcf β)
:= by {unfold cf, apply_instance}

/- Best practice: create a lemma for your cast -/
@[simp, elim_cast]
lemma coe_cf (c : cf β) : (↑c : gcf β) = c.val
:= by refl
\end{minted}
\begin{visibleenv}<3->
\begin{onlyenv}<1-3>
\alert{Now this works:}
\begin{minted}{Lean}
variable (c : cf α)
#check convergents (c : gcf α) 0
\end{minted}
\end{onlyenv}
\begin{onlyenv}<4->
\textcolor{red}{This, however, still does not work:}
\begin{minted}{Lean}
variable (c : cf α)
#check convergents c 0
\end{minted}
\end{onlyenv}
\end{visibleenv}
\end{frame}
%------------------------------------------------
\section{Proofs}
%------------------------------------------------
\begin{frame}[fragile]{The Proof Is Trivial}
\begin{minted}{Lean}
lemma floor_rat_eq_num_div_denom (n d : ℤ) :
  ⌊rat.mk n d⌋ = n / d
\end{minted}

\vspace{10mm}
\only<2>{\centerline{Wait, let's do some examples first\dots}}
\only<3>{\centerline{\alert{Alright, I am sold!}}}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Proving\dots\ Please Wait}
\only<1>{\begin{figure}{\includegraphics[height=0.5\textheight]{img/clock.png}}\end{figure}}
\only<2>{
\begin{figure}{\includegraphics[height=0.5\textheight]{img/melting_clock.png}}\end{figure}

\vspace{5mm}
\centerline{\alert{Something seems wrong}}
}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{Now It Is Trivial}
\begin{minted}{Lean}
lemma floor_rat_eq_num_div_denom (n : ℤ) (d : ℕ) :
  ⌊rat.mk n d⌋ = n / d
\end{minted}
\vspace{5mm}
\centerline{That's better!}
\end{frame}
%------------------------------------------------
\begin{frame}[fragile]{A Short Note About Tactics}
\centerline{\emph{<Show two short examples in VS Code>}}
\end{frame}
%------------------------------------------------
\section{Results}
\begin{frame}[fragile]{Collected Treasures}
\only<1>{\begin{figure}\includegraphics[height=0.6\textheight]{img/chest.png}\end{figure}}
\begin{onlyenv}<2>
Definition of (generalized) continued fractions and their evaluation
\begin{minted}{Lean}
structure gcf := (head : α) (seq : seq (gcf_pair α))
def cf := {g : gcf α // ∀ (n : ℕ) (a : α), (partial_numerators g).nth n = some a → a = 1}
def convergents (g : gcf α) (n : ℕ) : α := ...
\end{minted}
\end{onlyenv}
\begin{onlyenv}<3-4>
Computable continued fractions for discrete linear ordered floor fields
\begin{minted}{Lean}
def get_cf [discrete_linear_ordered_field α] [floor_ring α] (v : α) : cf α := ...
\end{minted}
\visible<4>{\centerline{Also works for $\mathbb{R}$ -- just not computable\dots}}
\end{onlyenv}
\begin{onlyenv}<5-7>
Termination proof for archimedian fields
\begin{minted}{Lean}
theorem termination_iff_rat [archimedean α] (v : α) :
  Terminates (get_gcf v) ↔ ∃ (q : ℚ), v = (q : α)
\end{minted}
\visible<6-7>{Including a theorem a mathematician would never prove:}
\begin{visibleenv}<7>
\begin{minted}{Lean}
theorem translate_rat_get_cf {q : ℚ}
(v_eq_q : v = q) :
  ((get_gcf q : gcf ℚ) : gcf α) = get_gcf v :=
\end{minted}
\end{visibleenv}
\end{onlyenv}
\begin{onlyenv}<8>
Finite correctness of the computation
\begin{minted}{Lean}
theorem get_gcf_finite_correctness
(terminates: Terminates (get_gcf v)) :
  ∃ (n : ℕ), v = convergents (get_gcf v) n
\end{minted}
\end{onlyenv}
\begin{onlyenv}<9-10>
Some interesting inequalities, and finally:
\begin{minted}{Lean}
theorem epsilon_convergence : ∀ (ε > (0 : α)),
  ∃ (N : ℕ), ∀ (n ≥ N),
  |v - convergents (get_gcf v) n| < ε :=
\end{minted}

\vspace{5mm}
\visible<10>{\centerline{But sadly no library for sequence limits in Lean :(}}
\end{onlyenv}
\end{frame}
%------------------------------------------------
\section{End of the Story}
%------------------------------------------------
\begin{frame}{Lessons Learnt}
\pause
\begin{itemize}[<+->]
\item Lean's type system is very expressive and great for definitions\dots
\begin{itemize}
\item \dots if one knows the gotchas.
\end{itemize}
\item Support on Zulip is fantastic.
\item Existing tactics help a LOT\dots
\begin{itemize}
\item \dots but no integration of automated theorem provers yet.
\end{itemize}
\end{itemize}
\end{frame}
%------------------------------------------------
\begin{frame}{We Need You!}
\Large
\centerline{\alert{Help us making interactive theorem proving}}

\centerline{\alert{an even better place!}}

\end{frame}
%------------------------------------------------
\begin{frame}[standout]
\normalsize{Formalisation can be found at \url{github.com/kappelmann/lean-continued-fractions}}
\pause
\center
% \Large{Thanks for your attention! Any questions?}
\begin{equation*}
Thanks + \cfrac{1}{for + \cfrac{1}{your + \cfrac{1}{attention!}}}
\end{equation*}

\vspace{10mm}

\pause
\Large{\alert{Any questions?}}
\end{frame}
%----------------------------------------------------------------------------------------
%\begin{frame}[allowframebreaks]{References}
  %\bibliography{../paper/sources.bib}
  %\bibliographystyle{abbrv}
%\end{frame}

\begin{frame}[allowframebreaks]{Image Sources}
\begin{itemize}
\item Salt shaker: Modified from \url{bit.ly/2K8Jw8s}
\item Link 1: \url{bit.ly/2wMGOwE}
\item Link 2: \url{bit.ly/2RaypfX}
\item Link 3: \url{bit.ly/2MNGUPt}
\item Clock: \url{bit.ly/2HOc9GC}
\item Melting clock: \url{bit.ly/2MKWknv}
\end{itemize}
\end{frame}

\end{document}


\begin{document}

\chapter*{Notation}

\begin{table}[h!]

    \centering

    \begin{tabular}{l|l}
    \hline
    Notation                                              & Description                                                                          \\ \hline
    $a$                                                 & A dynamic obstacle                                                                   \\
    $A$                                                 & Set of dynamic obstacles                                                             \\
    $P_a(\cdot)$                              & Cost distribution for a single dynamic obstacle, $a$                               \\
    $P(\cdot)$                                 & Cost distribution for a set of dynamic obstacles                                     \\
    $\mathcal{N}(\cdot)$            & Three dimensional normal distribution                                                \\
    $\dot{\zeta}(\cdot)$   & Velocity function for a dynamic obstacle                                             \\
    $\zeta(\cdot)$                    & Predicted trajectory of a dynamic obstacle                                           \\
    $\tilde{\zeta}(\cdot)$ & Observed trajectory for a dynamic obstacle                                           \\
    $C(\cdot)$                                 & Dynamic edge cost for the probabilistic roadmap excluding revisiting penalty         \\
    $TC(\cdot)$                                & Dynamic edge cost for the probabilistic roadmap including revisiting penalty         \\
    $I$                                                 & Initial configuration of a dynamic obstacle                                          \\
    $\epsilon$                                 & Amount of noise injected into a dynamic obstacle's trajectory                        \\
    $\xi$                                      & Last configuration used for trajectory prediction                                    \\
    $T$                                                 & Last time used for trajectory prediction                                             \\
    $\alpha$                                   & Multiplicative weight for the variance in $\mathcal{N}(\cdot)$ \\
    $\beta$                                    & Additive weight for the variance in $\mathcal{N}(\cdot)$       \\
    $\gamma$                                   & Exponential constant used for weighting basis functions in $P$                     \\
    $\psi$                                     & Multiplicative weight for the cost distribution in $TC$                            \\
    $\omega$                                   & Multiplicative weight for revisiting a node in $TC$                                \\
    \end{tabular}
\end{table}

\end{document}