\chapter{VRPTW via AI}\label{vrptw-ai}
In this chapter, we will describe our end-to-end deep learning method for solving \gls{vrptw}.

Machine learning and artificial intelligence have been replacing many hand-engineered algorithms and providing state-of-the-art results. In recent years, reinforcement learning \ref{rl} and advances in attention models \ref{attention} has shown great promise to disrupt the field of heuristics algorithms \cite{rl-constraint-opt, attention-route, dpdp}. Heuristics algorithms \cite{heuristics-algo} are incomplete methods that can compute solutions efficiently, but are not able to prove the optimality of a solution. Most of the business challenges do not require the most optimal exact solution \cite{excat-algo} but focus on approximation of the optimal solution in a reasonable time.

\section{Related Work}
Regarding the research of solving the \gls{vrp}, researchers have been mainly concentrating on designing hand-crafted metaheurictis via optimization. However, the great adoption of deep learning is starting to catch up with the field of operations research.

The first relatively successful deep learning model for solving general \gls{vrp} was proposed by Vinyals et al. \cite{vinyals} in the year of 2015 by introducing Pointer Networks. The model uses attention to output
a permutation of the input and the model was trained in the supervised manner by example solutions. In the next year, Bello et al. \cite{actor-critic-pointer} extended the model of Pointer Networks by adopting the Actor-Critic algorithm that introduced \gls{rl} and the model was trained on the training samples and did not require labelled data anymore. The reward function was a simple Euclidean length of the routes. The network showed improved performance on larger instances of 50 nodes over the predecessor model using supervised learning. In 2018, Nazari et al. \cite{nazari} simplified the model of RL-based Pointer Network by omitting the recurrent neural network encoder and replaced it with embedding to D-dimensional vector space. The recurrent neural network is not necessary because the inputs of delivery nodes are not dependent on order \cite{nazari}. There was no deterioration in performance and the model also supported the constraint for solving split delivery \ref{split-delivery}.

In 2018, Kool et al. \cite{attention-route} proposed a new approach and replaced the Pointer Network with Transformers \ref{transformer} using Graph Attention Network \ref{graph-attention-network} instead of positional encoding, and the Actor-Critic algorithm was changed to REINFORCE algorithm. The model showed superior performance. In this thesis, we will extend this model to support the soft time window constraint.

In 2019, Hottung et al. \cite{hottung} introduced a novel approach that was inspired by \gls{lns} \ref{lns} called Neural Large Neighborhood Search. This model learns the destroy and repair operators by using graph attention network and attention mechanism, and it is outperforming the standard metahesuristics on capacitated vehicle routing problem. However, it is still iterative algorithm based on the local search which results in much larger runtime then end-to-end deep learning methods for \gls{vrp}.

In 2021, another paper by Kool et al.\cite{dpdp} was released with a completely new approach. It combines  dynamic programming and deep learning to solve \gls{vrp} and promises much better performance than previous solutions. The method uses deep learning to restrict the dynamic programming search space using a policy derived from graph neural network. In the future, we will explore this method in depth and extend the support of constraints for time windows and pick and deliver problem \ref{pick-and-delivery}

\section{Solution}
The end-to-end deep learning method pro solving \gls{vrptw} is extension of the work done by Kool et al. \cite{attention-route}.

Let us describe the high-level concept behind the method. Consider we have a model as blackbox which takes \gls{vrptw} instance as an input and outputs probabilities for all the \gls{vrptw} nodes. The probability represents which node should be visited next and by following to the most probable node we get a partial solution which will be considered by the blackbox. We iterate this process until all nodes have been visited and we acquire a feasible plan as shown on Figure \ref{fig:attention-route-diagram}.

    \begin{figure}[ht]
        \centering
        \includegraphics[width=1.0\textwidth]{resources/vrptw-ai/attention-route-diagram.pdf}
        \caption{High-level concept behind the used method.}
        \label{fig:attention-route-diagram}
    \end{figure}

    \subsection{Model Architecture}\label{vrptw-model}
    The model architecture \cite{attention-route} leveraging recent advancements in attention mechanism is here extended by the time window constraint. The model is built upon transformers \ref{transformer}, graph attention network \ref{graph-attention-network}, and reinforcement learning \ref{rl}. The network structure is encoder-decoder that fits well for solving sequential decision problems. The structural input instance is extracted by the encoder \ref{vrptw-encoder} and then the solution is incrementally constructed by the decoder \ref{vrptw-decoder}.

    The \gls{vrptw} input instance is consisted from:
    \begin{itemize}\label{input-data}
        \item $X = \{x_1, \cdots, x_n\}$ where $x_i$ is two-dimensional coordinates in the euclidean space.
        \item $x_0$ is the location of depot.
        \item $D = \{d_1, \cdots, d_n\})$ is the demand capacity for each of the locations.
        \item $T = \{(e_1, l_1), \cdots, (e_n, l_n)\})$ is time windows for each of the location where $e_i$ is the beginning and $l_i$ is the end of the considered time window.
    \end{itemize}

    The output is the solution of VRPTW instance and is represented as a permutation $\pi$ of locations $X \cup x_0$.
    \begin{itemize}
        \item $\pi = \{\pi_1, \cdots, \pi_T\} \in \{x_0, \cdots, x_n\})$
    \end{itemize}

    \subsubsection{Encoder}\label{vrptw-encoder}
    The encoder uses graph attention network \ref{graph-attention-network} to embed the node features to graph embedding. Then the decoder architecture is the same as the decoder of transformer \ref{transformer}. Typicaly, the decoder of transformer uses positional encoding \cite{positional-encoding} to embed the input, but in this case it has been replace with \gls{gat} \ref{graph-attention-network} since we deal with graph-based structure and the input order does not matter.

    The first step is to perform the initial embedding of input data \ref{input-data} via learned linear projections as in \gls{gat}. The $h_{i}^{l}$ represents the node embedding of layer $l \in \{0, \cdots, N\}$ (N=3).
    \begin{equation}
        \widetilde{x} = \text{concat}(X, D, T)
    \end{equation}
    \begin{equation}
        h_{i}^{0} = \begin{cases} W \widetilde{x}_i + b_i &\mbox{if } i > 0 \\ W \widetilde{x}_0 + b_0 & \mbox{if } n = 0 \end{cases}
    \end{equation}

    The node embeddings are updated via $N$ attention layers, each containing multi-head attention \ref{multi-head-attention} (M=8) and a fully connected feed-forward network with normalization. The structure is identical to transformer's encoder \ref{transformer} with additional support of graph structure \ref{graph-attention-network} as shown on Figure \ref{fig:encoder-diagram}.

    \begin{figure}[ht]
        \centering
        \includegraphics[width=1.0\textwidth]{resources/vrptw-ai/encoder-diagram.png}
        \caption{Encoder layers \cite{attention-route}}
        \label{fig:encoder-diagram}
    \end{figure}

    The equation \ref{encoder-qkv} calculates the query $Q$, key $K$ and value $V$ of multi-head attention layer using the node embeddings and weights $W_m^Q$, $W_m^Q$, and $W_m^Q$, respectively. The number of heads is represented by $m \in \{1, \cdots, M\}$ (M=8).

    \begin{equation}\label{encoder-qkv}
        \textbf{q}_{im}^l = W_m^Q h_i^(l-1), \textbf{k}_{im}^l = W_m^K h_i^(l-1), \textbf{v}_{im}^l = W_m^V h_i^(l-1)
    \end{equation}

    The query and key values are used in calculating the compatibility $u_{ijm}^l$ of node $i$ with a node $j$ \ref{mha-compatibility}. If node $i$ is not adjecnt to node $j$ then they are not compatible and the value is set to a large negative number.

    \begin{equation}\label{mha-compatibility}
        u_{ijm}^l = \begin{cases} q_{im}^l k_{jm}^l &\mbox{if $i$ adjacent to $j$} \\ -\infty &\mbox{otherwise} \end{cases}
    \end{equation}

    The attention score $a_{ijm}^l \in [0,1]$ is calculated using softmax from the compatibility values of nodes \ref{encoder-attention-score}

    \begin{equation}\label{encoder-attention-score}
        a_{ijm}^l = \dfrac{e^{u_{ijm}^l}}{\sum_{j'=0}^n e^{u_{ij'm}^l}}
    \end{equation}

    The transformed $h'_{im}^l$ \ref{h-prime} aggregates all attention scores across neighbour nodes, which is based on GAT \ref{graph-attention-network}.

    \begin{equation}\label{h-prime}
        h'_{im}^l = \sum_{j=0}^n a_{ijm}^l v_{jm}^l
    \end{equation}

    Finally, we may calculate the multi-head attention \ref{transformer} for layer $l$ as a function of $\{h_1^{l-1}, \cdots, h_n^{l-1}\}$ through $h'_{im}^l$.

    \begin{equation}
        \text{MHA}_i^l(h_1^{l-1}, \cdots, h_n^{l-1}) = \sum_{m=1}^M W_{m}^O h'_{im}^l
    \end{equation}

    \begin{equation}
        \widetilde{h}_i = \text{BN}^l(h_i^{l-1} + \text{MHA}_i^l(h_1^{l-1}, \cdots, h_n^{l-1})))
    \end{equation}
    \begin{equation}
        h_i^l = \text{BN}^l(\widetilde{h}_i + \text{FF}^l(\widetilde{h}_i))
    \end{equation}

    In the final layer, the encoder computes the aggregated embedding of the input graph as the mean of the final node embeddings.
    \begin{equation}
        h^N = \dfrac{1}{n} \sum_{i=1}^m h_i^N
    \end{equation}

    The output of the encoder's final layer is passed to the decoder, which is detailed in the next sections \ref{vrptw-decoder}.

    \subsubsection{Decoder}\label{vrptw-decoder}
    Decoder works sequentially through timestamps $t \in \{0, \cdots, n\}$, at each timestamp one node is selected to be visited based on partial route $\pi_{1:t-1}$. It is predicting the probability distribution over nodes according to the node embedding and context vector of the encoder \ref{vrptw-encoder}.

    \begin{figure}[ht]
        \centering
        \includegraphics[width=1.0\textwidth]{resources/vrptw-ai/decoder-diagram.png}
        \caption{Describes the decoder iteration in the construction of a solution. This diagram very nicely visualizes the process and it was used in the paper by Kool et al. \cite{attention-route}}
        \label{fig:encoder-diagram}
    \end{figure}

    The decoder uses a new context vector $h_{c}^{'}$ which represents the state \ref{rl} and it goes as follows:
    \begin{equation}\label{decode-state-vec}
        h_{c}^{'} = \begin{cases} \text{concat}(h_N; h_0^N; D_t) & \mbox{if } t = 0 \\ \text{concat}(h_N; h_{\pi_{1:t-1}}^N; D_t) & \mbox{if } t > 0 \end{cases}
    \end{equation}
    The state of $h_{c}^{'}$ is concatenation of $h_N$, the output of the encoder, $h_{\pi_{1:t-1}}^N$, the embedding of previous partial solution, and $D_t$, the remaining demand capacity of the vehicle.

    Due to the fact that the decoder architecture is transformer \ref{transformer}, the next layers are multi-head attentions which are responsible for choosing the next node to visit. This defines the system action \ref{rl}.

    The multi-head attention in the decoder is computed in a similar manner as in the decoder \ref{vrptw-encoder} with a little alternation.
    \begin{equation}
        q_{(c)m} = W_m^Q h_{c}^{'}, k_{jm} = W_m^K h_{j}^{N}, v_{jm} = W_m^V h_{j}^{N}
    \end{equation}

    \begin{equation}\label{compatibility-decoder}
        u_{(c)j} = \begin{cases} q_c^T k_j &\mbox{if }  d_j <= D_t \text{ and } x_j \notin \pi_{1:t-1} \\ -\infty &\mbox{otherwise} \end{cases}
    \end{equation}

    The equation \ref{compatibility-decoder} computes the compatibility score and performs a masking mechanism to mask the nodes which have already been visited during the partial route (besides depot $x_0$) and eliminates nodes where the vehicle capacity would overflow. If we would consider a time window as a hard constraint, the calculation of compatibility would have extended masking mechanism to show only nodes which correspond to the time $t$.

    \begin{equation}
        h'_{(c)m} = \sum_{j=0}^n softmax(u_{(c)j}) v_jm
    \end{equation}

    \begin{equation}
        h_{c} = \text{MHA}(h_{c}^{'}) = \sum_{m=1}^M W_{m}^O h'_{(c)m}
    \end{equation}

    In order to calculate the desired probability $p_{\theta}(\pi_t|X, \pi_{1:t-1})$, a logit layer. The final layer is a single-head attention.

    \begin{equation}
        q = W^Q h_c, k_j = W^K h_j^N
    \end{equation}

    \begin{equation}
        u_j = \begin{cases} C . \text{tanh}(q^T k_{c}) &\mbox{if }  d_j <= D_t \text{ and } x_j \notin \pi_{1:t-1} \\ -\infty &\mbox{otherwise} \end{cases}
    \end{equation}

    \begin{equation}\label{encoder-attention-score}
        p_i = p_{\theta}(\pi_t|X, \pi_{1:t-1}) = \dfrac{e^{u_j}}{\sum_{j'=0}^n e^{u_{j'}}}
    \end{equation}

    \subsection{Reinforcement Learning}\label{vrptw-rl}
    The model \ref{vrptw-model} takes \gls{vrptw} instance and outputs probability distribution over nodes $p_{\theta}(\pi|X)$ which is used to sample a full feasible route as a solution $\pi$. The instance of \gls{vrptw} $S$ is defined as concatenation of locations, demand capacity and time windows for each node, $S = [X, D, T]$.

    To train the model, we have to define a reward, respectively, a cost function. The model is trained using REINFORCE algorithm \ref{reinforce} as proposed by Kool et al. \cite{attention-route}. The algorithm is based on the computation of the policy gradient, which is defined as
    \begin{equation}\label{encoder-attention-score}
        \nabla_{\theta} \mathcal{L}(\theta|X) = \mathop{\mathbb{E}}[ \mathcal{L}(\pi|X) - b(X)) \nabla \ln \pi (\pi|X))]
    \end{equation}

        \subsubsection{VRPTW Cost}\label{vrptw-rl}
        For effectively solving \gls{vrptw}, the cost function is an integral part of a successfully trained model. In this thesis, we propose a new cost function to solve the vehicle routing problem with soft constrained time windows and demand capacity for each node.

        The cost function is ranking the given solution of \gls{vrptw} instance. It penalizes the solution based on the length of the routes, early and late visits, and unequal distribution of nodes across vehicles.

        For a given \gls{vrptw} instance $S$ and its solution $\pi$, we propose the cost function as follows:
        \newcommand{\norm}[1]{\left\lVert#1\right\rVert}
        \begin{equation}\label{vrptw-cost}
            \mathcal{L}(\pi|S) = dis_p(\pi, S) + t_p(\pi, S) + bal_p(\pi, S)
        \end{equation}
        \begin{equation}\label{distance-cost}
            dis_p(\pi, S) = \sum_{i=0}^N \norm{x_{\pi(i)} - x_{\pi(i+1)}}_2
        \end{equation}
        The equation \ref{distance-cost} calculates the length of all routes in Euclidean space.

        \begin{equation}\label{time-cost}
            t_p(\pi, S) = \sum_{i=0}^N (I_{e_i > \widetilde{t}_i} (e_i - \widetilde{t}_i) p_e + I_{l_i < \widetilde{t}_i} (\widetilde{t}_i - l_i) p_l)
        \end{equation}
        The equation \ref{time-cost} calculates the penalty for early or late arrival. The time of the visit for a given node $i$ is defined by vector $\widetilde{t}_i$. We assume that the travel speed is always identical and we approximate that one unit of distance equals to one unit of time. The vector $I$ behaves as a mask $I \in (0, 1)^n$ which represents if either early or late arrival occurred. The penalty for late arrival $p_l$ should be greater than for early arrival $p_e$ and finding the proper penalties will be empirically determined as a part of experiment chapter \ref{penalty-experiment}.

        \begin{equation}\label{balance-cost}
            bal_p(\pi, S) = \sigma([|R_0|, \cdots, |R_k|])
        \end{equation}
        The last subpart of the cost function is calculating balance cost \ref{balance-cost} that aims to evenly distribute the number of nodes in a route $R_i$ by minimizing its standard deviation. In logistics, we expect to utilize couriers evenly.

        \subsubsection{Training loop}\label{vrptw-loop}

        Pseudocode of the \gls{rl} system training loop is as follows

        \SetKwInput{KwInput}{Input}
        \begin{algorithm}[H]
            \KwInput{Number of epoch $E$, steps per epoch $T$, batch size $B$} %significance $\alpha$
            \KwResult{Updated $\theta$ that maximises reward}

            Initialize $\theta$ at random\;
            \For{$epoche = 1, 2, \cdots, E$}{
                \For{$steps = 1, 2, \cdots, T$}{
                    Compute context embedding $h^N$ via decoder (\ref{vrptw-encoder});

                    \For{$t = 1, 2, \cdots, N$}{
                        Calculate $p_{\theta}(\pi_t|X, \pi_{1:t-1})$ via encoder for $t$ (\ref{vrptw-decoder});

                        Pick an action based on probability distribution;

                        Update the state by visiting a new node;
                    }

                    Compute reward $\mathcal{L}(\pi|S)$ (\ref{vrptw-cost});

                    %Compute reward baseline;

                    % $\nabla_{\theta} \mathcal{L} \gets \mathop{\mathbb{E}}[ \mathcal{L}(\pi|X) - b(X)) \nabla \ln \pi (\pi|X))]$;

                    $\nabla_{\theta} \mathcal{L} \gets \mathop{\mathbb{E}}[ \mathcal{L}(\pi|X) \nabla \ln \pi (\pi|X))]$;

                    $\theta \gets \text{Adam}(\theta, \nabla_{\theta} \mathcal{L})$;
                }
         }
         \caption{REINFORCE algorithm}
        \end{algorithm}

    \subsection{Integrating Duration Matrix}
    Real-world application of \gls{vrp} require to obtain the distance and duration matrix which represents the weighted transition between graph nodes. The duration between two locations is typically defined by the infrastructure and speed limits on a given route. Such a duration matrix is calculated using map data such as OpenStreetMap \cite{osm}.

    The neural network solving \gls{vrptw} learns to approximate the Euclidean distance between two given points. However, if we would integrate the duration matrix into the cost function of the model, the network would have to derive the duration between two points, which is an impossible task with the given model architecture. Moreover, the planning would be fixed to the location (city) on which the model was trained on.

    We propose an indirect integration of the duration matrix for the input instance. We may project the duration matrix into the node locations using multidimensional scaling \cite{mds} which would embed the duration information in a given 2D space.


\par
\section{Driver programs found in the {\tt Misc} directory}
\label{section:Misc:drivers}
\par
This section contains brief descriptions of the driver programs.
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
testNDperm msglvl msgFile n1 n2 n3 outPermFile
\end{verbatim}
This driver program generates a {\tt Perm} object that contains a
nested dissection ordering for a {\tt n1 x n2 x n3} regular grid.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
{\tt n1} is the number of points in the first direction.
\item
{\tt n2} is the number of points in the second direction.
\item
{\tt n3} is the number of points in the third direction.
\item
The {\tt outPermFile} parameter is the output file for the {\tt Perm}
object.
If {\tt outPermFile} is {\tt none} then the {\tt Perm} object is not
written to a file.
Otherwise, the {\tt Perm\_writeToFile()} method is called to write
the object to
a formatted file (if {\tt outPermFile} is of the form {\tt *.permf}),
or
a binary file (if {\tt outPermFile} is of the form {\tt *.permb}).
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
testOrderViaMMD msglvl msgFile GraphFile seed ETreeFile
\end{verbatim}
This program reads in a {\tt Graph} object from a file and computes
a multiple minimum degree ordering of the graph.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt inGraphFile} parameter is the input file for the {\tt Graph}
object. It must be of the form {\tt *.graphf} or {\tt *.graphb}.
The {\tt Graph} object is read from the file via the
{\tt Graph\_readFromFile()} method.
\item
The {\tt seed} parameter is a random number seed.
\item
The {\tt ETreeFile} parameter is the output file for the {\tt ETree}
object.
If {\tt ETreeFile} is {\tt none} then the {\tt ETree} object is not
written to a file.
Otherwise, the {\tt ETree\_writeToFile()} method is called to write
the object to
a formatted file (if {\tt ETreeFile} is of the form {\tt *.etreef}),
or
a binary file (if {\tt ETreeFile} is of the form {\tt *.etreeb}).
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
testOrderViaND msglvl msgFile GraphFile maxdomainsize seed ETreeFile
\end{verbatim}
This program reads in a {\tt Graph} object from a file and computes
a generalized nested dissection ordering of the graph.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt inGraphFile} parameter is the input file for the {\tt Graph}
object. It must be of the form {\tt *.graphf} or {\tt *.graphb}.
The {\tt Graph} object is read from the file via the
{\tt Graph\_readFromFile()} method.
\item
The {\tt maxdomainsize} parameter governs the partition of a graph.
If a subgraph has more than {\tt maxdomainsize} vertices, it is
split.
\item
The {\tt seed} parameter is a random number seed.
\item
The {\tt ETreeFile} parameter is the output file for the {\tt ETree}
object.
If {\tt ETreeFile} is {\tt none} then the {\tt ETree} object is not
written to a file.
Otherwise, the {\tt ETree\_writeToFile()} method is called to write
the object to
a formatted file (if {\tt ETreeFile} is of the form {\tt *.etreef}),
or
a binary file (if {\tt ETreeFile} is of the form {\tt *.etreeb}).
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
testOrderViaMS msglvl msgFile GraphFile maxdomainsize seed ETreeFile
\end{verbatim}
This program reads in a {\tt Graph} object from a file and computes
a multisection ordering of the graph.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt inGraphFile} parameter is the input file for the {\tt Graph}
object. It must be of the form {\tt *.graphf} or {\tt *.graphb}.
The {\tt Graph} object is read from the file via the
{\tt Graph\_readFromFile()} method.
\item
The {\tt maxdomainsize} parameter governs the partition of a graph.
If a subgraph has more than {\tt maxdomainsize} vertices, it is
split.
\item
The {\tt seed} parameter is a random number seed.
\item
The {\tt ETreeFile} parameter is the output file for the {\tt ETree}
object.
If {\tt ETreeFile} is {\tt none} then the {\tt ETree} object is not
written to a file.
Otherwise, the {\tt ETree\_writeToFile()} method is called to write
the object to
a formatted file (if {\tt ETreeFile} is of the form {\tt *.etreef}),
or
a binary file (if {\tt ETreeFile} is of the form {\tt *.etreeb}).
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
drawGraph msglvl msgFile inGraphFile inCoordsFile inTagsIVfile
          outEPSfile linewidth1 linewidth2 bbox[4] rect[4] radius
\end{verbatim}
This driver program generates a Encapsulated Postscript file
{\tt outEPSfile} of a 2-D graph using a {\tt Graph} object,
a {\tt Coords} object and a tags {\tt IV} object that contains the
component ids of the vertices.
\par
See the {\tt doDraw} script file in this directory for an example
calling sequence.
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means that all objects are written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt inGraphFile} parameter is the input file for the {\tt Graph}
object. It must be of the form {\tt *.graphf} or {\tt *.graphb}.
The {\tt Graph} object is read from the file via the
{\tt Graph\_readFromFile()} method.
\item
The {\tt inCoordsFile} parameter is the input file for the {\tt Coords}
object. It must be of the form {\tt *.coordsf} or {\tt *.coordsb}.
The {\tt Coords} object is read from the file via the
{\tt Coords\_readFromFile()} method.
\item
The {\tt inTagsIVfile} parameter is the input file for the tags
{\tt IV} object.
It must be of the form {\tt 'none'}, {\tt *.ivf} or {\tt *.ivb}.
The {\tt IV} object is read from the file via the
{\tt IV\_readFromFile()} method.
\item
The {\tt outEPSfile} parameter is the output file for the Encapsulated
Postscript file.
\item
The {\tt linewidth1} parameter governs the linewidth of edges
between vertices in the same component.
\item
The {\tt linewidth2} parameter governs the linewidth of edges
between vertices in different components.
\item
The {\tt bbox[4]} array is the bounding box for the plot.
In Postscript the coordinates are in {\it points}, where there are
72 points per inch.
For example, a bounding box of {\tt 0 0 200 300} will create a plot
whose size is 2.78 inches by 4.17 inches.
\item
The {\tt rect[4]} array is the enclosing rectangle for the plot.
To put a 20 point margin around the plot, set
{\tt rect[0] = bbox[0] + 20},
{\tt rect[1] = bbox[1] + 20},
{\tt rect[2] = bbox[2] - 20} and
{\tt rect[3] = bbox[3] - 20}.
\item
The {\tt radius} parameter governs the size of the filled circle
that is centered on each vertex.
The dimension is in points.
\end{itemize}
See Figure~\ref{fig-R2D100} for a plot of the graph of {\tt R2D100},
a randomly triangulated grid with 100 vertices with {\tt linewidth1
= 3}.
Figure~\ref{fig-R2D100-fishnet} illustrates a domain decomposition
obtained from the fishnet algorithm
of Chapter~\ref{chapter:GPart:intro}
with {\tt linewidth1 = 3} and {\tt linewidth2 = 0.1}.
\par
\begin{figure}[htbp]
\caption{{\sc R2D100}}
\label{fig-R2D100}
\begin{center}
\mbox{
% \psfig{file=R2D100notags.eps,height=4.00in,width=4.00in}
\psfig{file=../../misc/doc/R2D100notags.eps,height=4.00in,width=4.00in}
}
\end{center}
\end{figure}
\par
\begin{figure}[htbp]
\caption{{\sc R2D100: fishnet domain decomposition}}
\label{fig-R2D100-fishnet}
\begin{center}
\mbox{
% \psfig{file=R2D100fishnet.eps,height=4.00in,width=4.00in}
\psfig{file=../../misc/doc/R2D100fishnet.eps,height=4.00in,width=4.00in}
}
\end{center}
\end{figure}

%-----------------------------------------------------------------------
\item
\begin{verbatim}
testSemi msglvl msgFile GraphFile ETreeFile mapFile
\end{verbatim}
This program is used to compute the effect of using a semi-implicit
factorization to solve
$$
AX =
\left \lbrack \begin{array}{cc}
A_{0,0} & A_{0,1} \cr
A_{1,0} & A_{1,1}
\end{array} \right \rbrack
\left \lbrack \begin{array}{c}
X_0 \cr
X_1
\end{array} \right \rbrack
=
\left \lbrack \begin{array}{c}
B_0 \cr
B_1
\end{array} \right \rbrack
= B.
$$
$A$ is factored as
$$
\left \lbrack \begin{array}{cc}
A_{0,0} & A_{0,1} \cr
A_{1,0} & A_{1,1}
\end{array} \right \rbrack
=
\left \lbrack \begin{array}{cc}
L_{0,0} & 0 \cr
L_{1,0} & L_{1,1}
\end{array} \right \rbrack
\left \lbrack \begin{array}{cc}
U_{0,0} & U_{0,1} \cr
 0 & U_{1,1}
\end{array} \right \rbrack,
$$
and to solve $AX = B$, we do the following steps.
\begin{itemize}
\item solve $L_{0,0} Y_0 = B_0$
\item solve $L_{1,1} U_{1,1} X_1 = B_1 - L_{1,0} Y_0$
\item solve $U_{0,0} X_0 = Y_0 - U_{0,1} X_1$
\end{itemize}
An alternative factorization is
$$
A =
\left \lbrack \begin{array}{cc}
L_{0,0} & 0 \cr
A_{1,0}U_{0,0}^{-1} & L_{1,1}
\end{array} \right \rbrack
\left \lbrack \begin{array}{cc}
U_{0,0} & L_{0,0}^{-1}U_{0,1} \cr
 0 & U_{1,1}
\end{array} \right \rbrack.
$$
To solve $AX = B$, we do the following {\it semi-implicit solve}.
\begin{itemize}
\item solve $L_{0,0} U_{0,0} Z_0 = B_0$
\item solve $L_{1,1} U_{1,1} X_1 = B_1 - A_{1,0} Z_0$
\item solve $L_{0,0} U_{0,0} X_0 = B_0 - A_{0,1} X_1$
\end{itemize}
When we compare the semi-implicit solve against the explicit solve,
we see that the former needs
$A_{0,1}$ and $A_{1,0}$ but not $L_{1,0}$ or $A_{0,1}$.
and executes two solves with $L_{0,0}$ and $U_{0,0}$ (instead of one)
and performs a matrix-matrix multiply with $A_{0,1}$ and $A_{1,0}$
instead of $L_{1,0}$ and $U_{0,1}$.
In situations where the numbers of entries in $L_{1,0}$ and
$U_{0,1}$ are much larger than those in $A_{1,0}$ and $A_{0,1}$,
and the numbers of entries in $L_{0,0}$ and $U_{0,0}$ are not too
large, the semi-implicit factorization can be more efficient.
\par
This program reads in three objects:
a {\tt Graph} object,
an {\tt ETree} object to specify the ordering,
and an {\tt IV} map object that tells which vertices are in the
which blocks of the matrix.
The map from vertices to blocks follows the same convention as the
{\it component map} from the {\tt GPart} object.
If {\tt map[v] = 0}, then vertex {\tt v} belongs to the Schur
complement $(1,1)$ block.
Otherwise, {\tt v} belongs to a domain (the domain number is {\tt
map[v]}) and so belongs to the $(0,0)$ block.
The output of the program gives statistics for storage and
operation count for the two types of solves.
For example,
\begin{verbatim}
 storage: explicit = 1404, semi-implicit = 1063, ratio = 1.321
 opcount: explicit = 2808, semi-implicit = 2742, ratio = 1.024
\end{verbatim}
is the output using the {\tt do\_testSemi} driver program for
the {\tt R2D100} matrix.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt GraphFile} parameter is the input file for the {\tt Graph}
object. It must be of the form {\tt *.graphf} or {\tt *.graphb}.
The {\tt Graph} object is read from the file via the
{\tt Graph\_readFromFile()} method.
\item
The {\tt ETreeFile} parameter is the input file for the {\tt ETree}
object. It must be of the form {\tt *.etreef} or {\tt *.etreeb}.
The {\tt ETree} object is read from the file via the
{\tt ETree\_readFromFile()} method.
\item
The {\tt mapFile} parameter is the input file for the map {\tt IV}
object. It must be of the form {\tt *.ivf} or {\tt *.ivb}.
The {\tt IV} object is read from the file via the
{\tt IV\_readFromFile()} method.
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
allInOne msglvl msgFile type symmetryflag pivotingflag
         matrixFileName rhsFileName seed
\end{verbatim}
This {\it all-in-one} driver program is an example that tests the
serial $U^TDU$, $U^HDU$ or $LU$ factorization and solve.
Matrix entries are read in from a file, and then the matrix
is assembled and factored.
The right hand side entries are read in from a file, and the system
is solved.
Three input parameters specify the type of system (real or
complex),
the type of factorization (symmetric, Hermitian or nonsymmetric)
and whether pivoting is to be used for numerical stability.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
{\tt type} is the type of entries
\begin{itemize}
\item {\tt 1} --- ({\tt SPOOLES\_REAL}) for real entries
\item {\tt 2} --- ({\tt SPOOLES\_COMPLEX}) for complex entries
\end{itemize}
\item
{\tt symmetryflag} defines the factorization
\begin{itemize}
\item {\tt 0} --- ({\tt SPOOLES\_SYMMETRIC})
for a real or complex $U^TDU$ factorization
\item {\tt 1} --- ({\tt SPOOLES\_SYMMETRIC})
for a complex $U^HDU$ factorization
\item {\tt 2} --- ({\tt SPOOLES\_SYMMETRIC})
for a real or complex $LU$ factorization
\end{itemize}
\item
{\tt pivotingflag} defines pivoting or not for numerical stability
\begin{itemize}
\item {\tt 0} --- ({\tt SPOOLES\_NO\_PIVOTING}) for no pivoting
\item {\tt 1} --- ({\tt SPOOLES\_PIVOTING}) for pivoting
\end{itemize}
Note, the code has a pivoting threshold {\tt tau = 100} hardwired
into the code.
\item
The {\tt matrixFileName} parameter is the name of the input file
for the matrix entries.
For a real matrix, this file must have the following form.
\begin{verbatim}
nrow ncol nent
...
irow jcol value
...
\end{verbatim}
where the first line has the number of rows, columns and entries.
(Note, for this driver program {\tt nrow} must be equal to {\tt ncol}
since we are factoring a square matrix.)
Each of the {\tt nent} following lines contain one nonzero entry.
For a complex matrix, the file has this structure.
\begin{verbatim}
nrow ncol nent
...
irow jcol real_value imag_value
...
\end{verbatim}
For both real and complex entries, the entries need not be
disjoint,
i.e., entries with the same {\tt irow} and {\tt jcol} values are
{\it summed}.
\item
The {\tt rhsFileName} parameter is the name of the input file for
the right hand side matrix.
It has the following structure
\begin{verbatim}
nrow nrhs
...
irow value_0 value_1 ... value_\{nrhs-1\}
...
\end{verbatim}
Note, {\tt nrow} need not be the number of equations, here it is
the number of nonzero right hand side entries.
This allows us to input sparse right hand sides without specifying
the zeroes.
In contrast to the input for the matrix entries, the nonzero rows
{\it must} be unique.
The right hand side entries are not assembled into a dense matrix
object, but placed into the object.
\item
{\tt seed} is a random number seed used for the ordering process.
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
patchAndGo msglvl msgFile type symmetryflag patchAndGoFlag fudge toosmall

           storeids storevalues matrixFileName rhsFileName seed
\end{verbatim}
This driver program is used to test the ``patch-and-go''
functionality for a factorization without pivoting.
When small diagonal pivot elements are found,
one of three actions are taken.
See the {\tt PatchAndGoInfo} object for more information.
\par
The program reads in a matrix $A$ and right hand side $B$,
generates the graph for $A$ and orders the matrix,
factors $A$ and solves the linear system $AX = B$ for $X$
using multithreaded factors and solves.
Use the script file {\tt do\_patchAndGo} for testing.
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output.
Use {\tt msglvl = 1} for just timing output.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
The {\tt type} parameter specifies a real or complex linear system.
\begin{itemize}
\item
{\tt type = 1 (SPOOLES\_REAL)} for real,
\item
{\tt type = 2 (SPOOLES\_COMPLEX)} for complex.
\end{itemize}
\item
The {\tt symmetryflag} parameter specifies the symmetry of the matrix.
\begin{itemize}
\item
{\tt type = 0 (SPOOLES\_SYMMETRIC)} for $A$ real or complex symmetric,
\item
{\tt type = 1 (SPOOLES\_HERMITIAN)} for $A$ complex Hermitian,
\item
{\tt type = 2 (SPOOLES\_NONSYMMETRIC)}
\end{itemize}
for $A$ real or complex nonsymmetric.
\item
The {\tt patchAndGoFlag} specifies the ``patch-and-go'' strategy.
\begin{itemize}
\item
{\tt patchAndGoFlag = 0} --- if a zero pivot is detected, stop
computing the factorization, set the error flag and return.
\item
{\tt patchAndGoFlag = 1} --- if a small or zero pivot is detected,
set the diagonal entry to 1 and the offdiagonal entries to zero.
\item
{\tt patchAndGoFlag = 2} --- if a small or zero pivot is detected,
perturb the diagonal entry.
\end{itemize}
\item
The {\tt fudge} parameter is used to perturb a diagonal entry.
\item
The {\tt toosmall} parameter is judge when a diagonal entry is small.
\item
If {\tt storeids = 1}, then the locations where action was taken is
stored in an {\tt IV} object.
\item
If {\tt storevalues = 1}, then the perturbations are
stored in an {\tt DV} object.
\item
The {\tt matrixFileName} parameter is the name of the files where
the matrix entries are read from.
The file has the following structure.
\begin{verbatim}
neqns neqns nent
irow jcol entry
...  ...  ...
\end{verbatim}
where {\tt neqns} is the global number of equations and {\tt nent}
is the number of entries in this file.
There follows {\tt nent} lines, each containing a row index, a
column index and one or two floating point numbers, one if real,
two if complex.
\item
The {\tt rhsFileName} parameter is the name of the files where
the right hand side entries are read from.
The file has the following structure.
\begin{verbatim}
nrow nrhs
irow entry ... entry
...  ...   ... ...
\end{verbatim}
where {\tt nrow} is the number of rows in this file
and {\tt nrhs} is the number of rigght and sides.
There follows {\tt nrow} lines, each containing a row index
and either {\tt nrhs} or {\tt 2*nrhs} floating point numbers,
the first if real, the second if complex.
\item
The {\tt seed} parameter is a random number seed.
\end{itemize}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
QRallInOne msglvl msgFile type matrixFileName rhsFileName seed
\end{verbatim}
This {\it all-in-one} driver program is an example that tests the
serial $QR$ factorization and solve.
Matrix entries are read in from a file, and then the matrix
is assembled and factored.
The right hand side entries are read in from a file, and the system
is solved.
One input parameter specifies the type of system (real or
complex).
\par
\begin{itemize}
\item
The {\tt msglvl} parameter determines the amount of output ---
taking {\tt msglvl >= 3} means the {\tt Perm} object is written
to the output file.
\item
The {\tt msgFile} parameter determines the message file --- if {\tt
msgFile} is {\tt stdout}, then the message file is {\it stdout},
otherwise a file is opened with {\it append} status to receive any
output data.
\item
{\tt type} is the type of entries
\begin{itemize}
\item {\tt 1} --- ({\tt SPOOLES\_REAL}) for real entries
\item {\tt 2} --- ({\tt SPOOLES\_COMPLEX}) for complex entries
\end{itemize}
\item
The {\tt matrixFileName} parameter is the name of the input file
for the matrix entries.
For a real matrix, this file must have the following form.
\begin{verbatim}
nrow ncol nent
...
irow jcol value
...
\end{verbatim}
where the first line has the number of rows, columns and entries.
Each of the {\tt nent} following lines contain one nonzero entry.
For a complex matrix, the file has this structure.
\begin{verbatim}
nrow nrhs nent
...
irow jcol real_value imag_value
...
\end{verbatim}
For both real and complex entries, the entries need not be
disjoint,
i.e., entries with the same {\tt irow} and {\tt jcol} values are
{\it summed}.
\item
The {\tt rhsFileName} parameter is the name of the input file for
the right hand side matrix.
It has the following structure
\begin{verbatim}
nrow nrhs
...
irow value_0 value_1 ... value_\{nrhs-1\}
...
\end{verbatim}
Note, {\tt nrow} need not be the number of equations, here it is
the number of nonzero right hand side entries.
This allows us to input sparse right hand sides without specifying
the zeroes.
In contrast to the input for the matrix entries, the nonzero rows
{\it must} be unique.
The right hand side entries are not assembled into a dense matrix
object, but placed into the object.
\item
{\tt seed} is a random number seed used for the ordering process.
\end{itemize}
%-----------------------------------------------------------------------
\end{enumerate}


\documentclass{article} % This command is used to set the type of document you are working on such as an article, book, or presenation
\usepackage{amsmath}  % This package allows the use of a large range of mathematical formula, commands, and symbols=]
\usepackage[linguistics]{forest}
\usepackage{tikz}

\begin{document}

\title{multiFaAcceleration: A program for the measurement of mutation velocity and acceleration from a four-species multiple alignment}
\author{Riley J. Mangan}
\maketitle

\section{Usage}
multiFaAcceleration - Performs velocity and acceleration on a four way multiple alignment in multiFa format.\par
A four way multiple alignment must contain four species (index 0 to 3) in the topology that species 1 to 3 are successive outgroups of species 0.\par
While this program accepts an alignment of any four species in this configuration, this program was initially written for a multiple alignment of Human, Chimpanzee, Gorilla, and Orangutan. Variable names in this documentation and in the code itself are named according to these species names.\par
Three bed files are returned. The first produces the normalized velocity score, the second returns the normalized acceleration score, and the third returns the normalized initial velocity score for each window of the genome for aln[0] (Human). This program can also produce the raw Velocity and Initial Velocity branch lengths as optional returns.\par
multiFaAcceleration chromName in.fa velocity.bed acceleration.bed initialVelocity.bed\par

\section{Distance-based phylogenetic inference with the Fitch-Margoliash method}

Consider a phylogenetic tree with four extant species (Human, Chimpanzee, Gorilla, Orangutan), two extinct ancestors (Human-Chimp Ancestor (HCA) and Human-Gorilla Ancestor (HGA)), and branch lengths (BhumHca, BchimpHca, HCA-HGA, BhgaGor, BhgaOrang) with the following topology.\par

\begin{center}
\begin{tikzpicture}
\node[above] at (-2,0) {$\textbf{HCA}$};
\draw (-2,0) -- node[above] {$BhcaHga$} (2,0) node[above] {$\textbf{HGA}$};
\draw (-2,0) -- node[above] {$BhumHcaA$}(-3.5,1.5) node[above] {$\textbf{Hum}$};
\draw (-2,0) -- node[above] {$BchimpHca$}(-3.5,-1.5) node[below] {$\textbf{Chimp}$};
\draw (2,0) -- node[above] {$BhgaGor$}(3.5,1.5) node[above] {$\textbf{Gor}$};
\draw (2,0) -- node[above] {$BhgaOrang$}(3.5,-1.5) node[below] {$\textbf{Orang}$};\
\end{tikzpicture}
\end{center}

Consider that we can measure the pairwise mutation distance between any two extant species on this tree, represented by $D_{ij}$. The distance defined by the sum of branch lengths, also known as the patristic distance, is represented as $d_{ij}$. It follows that the pairwise distance between two extant species is equal to the sum of branch lengths separating those species on the phylogenetic tree shown above. Thus, we are able to produce the following system of linear equations.

\begin{equation}
\begin{split}
&D_{hum-chimp} \approx d_{hum-chimp} =  BhumHca + BchimpHca\\
&D_{hum-gor} \approx d_{hum-gor} = BhumHca + BhcaHga + BhgaGor\\
&D_{chimp-gor} \approx d_{chimp-gor} = BchimpHca + BhcaHga + BhgaGor\\
&D_{hum-orang} \approx d_{hum-orang} = BhumHca + BhcaHga + BhgaOrang\\
&D_{chimp-orang} \approx d_{chimp-orang} = BchimpHca + BhcaHga + BhgaOrang\\
&D_{gor-orang} \approx d_{gor-orang} = BhgaGor + BhgaOrang
\end{split}
\end{equation}

If our interest is to study Human genome evolution, we can define the mutation distance as $BhumHca$, the distance between the human sequence and the sequence of its most recent ancestor with chimpanzees. We can then define the initial mutation distance as $BhcaHga$, the distance along the previous branch the inferred Human-Chimp ancestor and the common ancestor between humans and gorillas (HGA).\par
We can compute branch lengths using the method of Fitch and Margoliash \cite{pmid5334057} with an alternating least squares optimization algorithm developed by Felsenstein \cite{pmid11975348}. While the full details and derivations for these methods can be found in these two papers, I will briefly explain the method below.\par
Due to such phenomenon as back mutation and discrepancies in INDEL-sensitive distance metrics, it is not always possible to find a set of branch lengths for the above system of equations such that $D_{ij} = d_{ij} \: \forall \: i,j \in S$, where $S$ is the set of all extant species. Thus, in the Fitch-Margoliash method, we aim to find a set of branch lengths $B$ that minimizes the squared difference between the pairwise and patristic distances. In symbolic terms:
\begin{equation*}
	Q = \sum_{i \in S}\sum_{j \in S}w_{ij}(D_{ij} - d_{ij})^2
\end{equation*}
In the above expression, $w_{ij}$ represents a weight for error terms, and serves to place more of the overall error in the estimated branch lengths on longer branches. This expression is of the form:
\begin{equation*}
\begin{split}
	w_{ij} = \frac{1}{D_{ij}^2} \mid D_{ij} \ne 0\\
\end{split}
\end{equation*}

When $D_{ij} = 0$, the weight term $w_{ij}$ approaches positive infinity. In this program, we approximate this limit by assigning an arbitrarily large number to $w_{ij}$. This value is $1000$ by default, but can be controlled by the user with the option $zeroDistanceWeightConstant$.

\section{Tree reduction and subtree optimization}
In the alternating least squares approach top optimize Q described by Felsenstein, we must first reduce the above tree, which contains two internal nodes $HCA$ and $HGA$, to subtrees containing only one internal node. These subtrees, which we refer to as the left and right subtrees, are shown below.

Left subtree:
\begin{center}
\begin{tikzpicture}
\node[above] at (-2,0) {$\textbf{HCA}$};
\draw (-2,0) -- node[above] {$BhcaHga$} (2,0) node[above] {$\textbf{HGA}$};
\draw (-2,0) -- node[above] {$BhumHca$}(-3.5,1.5) node[above] {$\textbf{Hum}$};
\draw (-2,0) -- node[above] {$BchimpHca$}(-3.5,-1.5) node[below] {$\textbf{Chimp}$};
\end{tikzpicture}
\end{center}

Right subtree:
\begin{center}
\begin{tikzpicture}
\node[above] at (-2,0) {$\textbf{HCA}$};
\draw (-2,0) -- node[above] {$BhcaHga$} (2,0) node[above] {$\textbf{HGA}$};
\draw (2,0) -- node[above] {$BhgaGor$}(3.5,1.5) node[above] {$\textbf{Gor}$};
\draw (2,0) -- node[above] {$BhgaOrang$}(3.5,-1.5) node[below] {$\textbf{Orang}$};\
\end{tikzpicture}
\end{center}

In the $multiFaAcceleration$ program, these subtrees are produced with the $pruneLeft$ and $pruneRight$ helper functions, respectively. To find the optimal branch lengths for these subtrees, we must find the pairwise distances between the extant species nodes and the ancestral node which is now a leaf in the subtree. For the left subtree, Felsenstein demonstrates that we can calculate these distances as:
\begin{equation*}
	D_{HumHga} = \frac{w_{HumGor}(D_{HumGor} - BhgaGor) + w_{Humorang}(D_{HumOrang} - BhgaOrang)}{w_{HumGor} + w_{HumOrang}}
\end{equation*}
\begin{equation*}
	D_{ChimpHga} = \frac{w_{ChimpGor}(D_{ChimpGor} - BhgaGor) + w_{ChimpOrang}(D_{ChimpOrang} - BhgaOrang)}{w_{ChimpGor} + w_{ChimpOrang}}
\end{equation*}
Similarly, for the right subtree:
\begin{equation*}
	D_{HcaGor} = \frac{w_{HumGor}(D_{HumGor} - BhgaGor) + w_{ChimpGor}(D_{ChimpGor} - BhgaOrang)}{w_{HumGor} + w_{ChimpGor}}
\end{equation*}
\begin{equation*}
	D_{HcaOrang} = \frac{w_{HumOrang}(D_{HumOrang} - BhgaGor) + w_{ChimpOrang}(D_{ChimpOrang} - BhgaOrang)}{w_{HumOrang} + w_{ChimpOrang}}
\end{equation*}
As distance is necessarily a non-negative quantity, and the weight constant is set to an arbitrarily large number when $D_{ij} = 0$, the denominator in the above equations can never be zero, and does not need to be otherwise constrained.\par
The three-species left subtree with branch lengths $v$ has the following optimal branch lengths:
\begin{equation*}
\begin{split}
v_a = \frac{(D_{ab} + D_{ac} - D_{bc})}{2}\\
v_b = \frac{(D_{ab} + D_{bc} - D_{ac})}{2}\\
v_c = \frac{(D_{ac} + D_{bc} - D_{ab})}{2}
\end{split}
\end{equation*}

\section{Constraint for non-negative branch lengths}
In some cases, the optimal set of branch lengths for the minimization of Q will include negative branch lengths. While this can be allowed by the user with the option $allowNegative$, this program constrains branch lengths to non-negative values by default. Briefly, when one or more branches from the 3-species subtrees are evaluated as negative values, they are set to 0. From Felsenstein 1997, if branch lengths $v_b$ or $v_c$ are set to zero in this fashion, the new optimal branch length for $v_a$, given that either of these terms are set to zero, can be approximated as:
\begin{equation*}
	\hat v_a = \frac{w_{ab}(D_{ab} - v_b) + w_{ac}(D_{ac} - v_c)}{w_{ab} + w_{ac}}
\end{equation*}

\section{Algorithm for branch length calculations}
With these equations in hand, we can now describe the algorithm for computing optimal branch lengths for the four-species tree, which is performed by the helper function $alternatingLeastSquares$ in $multiFaAcceleration$. First, the set of output branch lengths are initialized such that each branch length is equal to 1. In each iteration, the tree is first pruned to the left subtree, and the branch lengths $BhumHca, BchimpHca, BhcaHga$ are then set to the optimal branch lengths for this subtree. Next, the tree is pruned into the right subtree, and the branches $BhcaHga, BhgaGor, BhgaOrang$ are then set to the optimal values for this subtree. Once both optimizations have occurred, the value of Q is calculated for the current branch lengths and compared to the value of Q observed in the previous iteration. If the difference between the estimates of Q falls below a user-specified level of error $\epsilon$, the answer is returned. Otherwise, a new iteration is initiated. This heuristic will converge on a local minimum for Q and achieve stationarity in finite iterations. Due to the approximation used for non-negative branch lengths, it is possible stationarity will be achieved as the oscillation between two sets of branch lengths. In this case, we take the set of branch lengths associated with the lowest value of Q.
\section{Genome-wide acceleration calculation}
For a given four-way alignment in multiFa format, $gonomics:multiFaAcceleration$ calculates $BhumHca$ and $BhcaHga$ using pairwise mutation distance (defined as the number of SNPs and INDELs, where each INDEL counts as one mutation regardless of length) for each window of a user-specified window size. Windows may be every possible window of the genome, or may be restricted to a particular subset of the genome using the option $-searchSpaceBed$, which enables the input of a bed file which specifies the regions that should be considered. The option $-searchSpaceProportion$ enables the user to consider all windows in which at least a user-specified proportion of bases are within the searchSpace.

We define $\textbf{v}$ as the normalized mutation velocity, or the normalized rate of mutation over the branch $BhumHca$. To calculate $\textbf{v}$, we calculate the average $BhumHca$ length $E(BhumHca)$ across all windows. For each window:
\begin{equation*}
	\textbf{v} = \frac{BhumHca}{E(BhumHca)}
\end{equation*}

Similarly, the normalized initial rate of mutation, or the normalized rate of mutation over the branch $BhcaHga$, can be calculated as:
\begin{equation*}
	\textbf{v}_0 = \frac{BhcaHga}{E(BhcaHga)}
\end{equation*}
Where $e(BhcaHga)$ is the average value of $BhcaHga$ over all windows.\par
$\textbf{v}$ and $\textbf{v}_0$ have intuitive numerical interpretations. If $\textbf{v} = 1$ for a particular window, the mutation rate in the branch $BhumHca$ is equal to the chromosome-wide average mutation rate. $\textbf{v} = 2$ would be found in a region evolving twice as quickly, and $\textbf{v} = 0.5$ in a region evolving at half the average rate. The same interpretations apply for $\textbf{v}_0$, the rate of evolution along the branch $BhcaHga$.\par
Finally, we define the quantity $\textbf{a}$, for acceleration, as the normalized change in mutation rate between branches branches $BhumHca$ and $BhcaHga$:
\begin{equation*}
\textbf{a} = \textbf{v} - \textbf{v}_0
\end{equation*}

The quantity $\textbf{a}$ is equal to zero when the mutation rate along $BhumHca$ is equal to the mutation rate along $BhcaHga$. As both $\textbf{v}$ and $\textbf{v}_0$ are normalized, this holds true even if $BhumHca$ and $BhcaHga$ are not equal in absolute length, which will be the case when the extant species are not separated by equal amounts of evolutionary time (in the example here, the distance between humans and chimpanzees, about six million years, is nearly triple the 2.5 million years separating the Human-Chimp Ancestor from the Human-Gorilla Ancestor). Positive values for $\textbf{a}$ indicate accelerated regions, and negative values suggest regions under negative acceleration, in which a region evolved at a slower rate along $BhumHca$ than $BhcaHga$.

\bibliographystyle{genres}
\bibliography{multiFaRefs}

\end{document}


\chapter{Interactive Assumptions}

This chapter covers the implementation of our approach for
analyzing interactive assumptions.
%
We get an input of the following form:
\begin{verbatim}
emaps G1 * G2 -> GT.
isom G1 -> G2.

input [ X, Y ] in G1.

oracle O(m : Fq) = sample A:G1, (A, A*Y, A*X + m*A*X*Y).

win(U:G1, V:G1, W:G1, mm) = U <> 0 /\ mm <> m_i /\ V = UX /\ W = U*X + m*U*X*Y.
\end{verbatim}
%
For now, we make the following assumptions:
\begin{enumerate}
\item Either the group setting is a generic group or the input, oracle
  arguments and return values, and winning condition input
  are all in one group. In the last case, we exploit that the
  problem is computational.
\item All oracle inputs are of type \verb!Fq!. Allowing for group
  elements complicates the definition.
\end{enumerate}
%
We first compute a formal sum for each \verb!win! input of type $\group$
  as follows:
\begin{enumerate}
\item Assume that the adversary is given inputs
  $\vec{f}$ where $f_j$ defines an element in
  $\group$ over random variables~$\vec{X}$.
\item That there is one oracle taking field elements
  $\vec{m}$ and returning $\vec{g}$
  where $g_j$ defines an element in $\group$
  over the variables $\vec{X}$ and the variables
  $\vec{A}$ sampled in the oracle call.
\item We assume there are $q$ oracle queries.
\item As a first step, we introduce indexed parameters
  $m_{1,j},\ldots,m_{l,j}$ ($j \in [q]$) and
  indexed random variables
  $A_{1,j},\ldots,A_{r,j}$ ($j \in [q]$).
\item Then all computable elements can
  be expressed as linear combinations as follows:
  \[
    \alpha_1 f_1 + \ldots + \alpha_k f_k
    + \Sigma_{i=1}^q \beta_{1,i}\, g_1(\vec{m_i},\vec{A_i},\vec{X})
    \ldots
    + \Sigma_{i=1}^q \beta_{n,i}\, g_n(\vec{m_i},\vec{A_i},\vec{X})
  \]
\item We assume the winning condition takes
  elements $\vec{U}$ in $\group$.
  Then we use $\alpha_i^{(j)}$ and $\beta_i^{(j)}$ (this is a vector) for
  the coefficients of $U_j$.
\end{enumerate}

We represent such linear combinations as formal sums.


\documentclass{memoir}
\usepackage{notestemplate}

%\logo{~/School-Work/Auxiliary-Files/resources/png/logo.png}
%\institute{Rice University}
%\faculty{Faculty of Whatever Sciences}
%\department{Department of Mathematics}
%\title{Class Notes}
%\subtitle{Based on MATH xxx}
%\author{\textit{Author}\\Gabriel \textsc{Gress}}
%\supervisor{Linus \textsc{Torvalds}}
%\context{Well, I was bored...}
%\date{\today}

\begin{document}

% \maketitle

% Notes taken on 05/18/21

Now let us consider the Euler-Lagrange equations of a graph:
\begin{align*}
	&\inf_{u} \left\{ \int_\Omega f(\nabla u) \mid \int_\Omega g(u) = M \right\} \quad &(P_1)\\
	&\inf_{u} \left\{ \int_\Omega f(\nabla u) \mid \int_{\Omega }g(u) = M; \; u = u_0 \; \partial \Omega  \right\}  \quad &(P_2)
\end{align*}

\begin{exmp}
	Consider \(f(z) = \sqrt{1+\left| z \right|^2} \) and \(g(s) = \left| s \right| \), \(u_0 = 0\). We are looking for minimizers that satisfy \(\int_\Omega \left| u \right| = M\). If \(u\geq 0\), then this integral is exactly the area below the graph of \(u\).\\

	Problems of this sort are referred to as being of \textbf{isoperimetric type}. We have a fixed perimeter, and we want to minimize a function which is constrained along it. It does not always admit a solution, however.\\

	To see this, consider \(\Omega = B_R(0)\). The minimizer will be a spherical cap described by \(u(x) = \sqrt{S^2-\left| x \right|^2} - \sqrt{S^2 - R^2} \) for some \(S\geq R\). If \(M > \dfrac{\left| B_R \right| }{2}\) then there is no graph which can attain \(M\) within the constraints!
\end{exmp}
\begin{figure}[ht]
    \centering
     \def\svgwidth{1\linewidth}
     \input{./figures/example-space-for-p_1-and-p_2.pdf_tex}
     \caption{Area graph with \(f(z) = \sqrt{1+\left| z \right|^2} \) and \(g(s) = \left| s \right| \)}
    \label{fig:example-space}
\end{figure}

\begin{exmp}
	Consider \(f(\nabla u) = \dfrac{\left| \nabla u \right|^2}{2}\), \(g(u) = \dfrac{u^2}{2}\) and \(u_0 = 0\).\\

	In this case, minimizers \textit{always} exist, and are eigenfunctions of \(-\Delta \) that satisfy the zero Dirichlet condition.
\end{exmp}

\section{Linear Transformations by Smooth Functions}
\label{sec:linear_transformations_by_smooth_functions}

We can learn more about minimizers on the graph family of Euler-Lagrange equations by combining them with nicely behaved functions. Consider
\begin{align*}
	\int_\Omega g(u+t\varphi ) = M
\end{align*}
for all non-negative real \(t\). What constraints must \(\varphi \) have to satisfy this? We can see that
\begin{align*}
	g(u+t\varphi ) = g(u) + tg'(u)\varphi + \dfrac{t^2}{2}g''(u)\varphi^2 + o(t^3)\implies\\
	M = M+t \int_\Omega g'(u) \varphi  + \dfrac{t^2}{2}\int_\Omega g''(u)\varphi^2 + o(t^3)
\end{align*}
for all \(t\). We can actually infer from this that \(\int_\Omega g'(u) \varphi  = 0\) by the first-order conservation of \(\int g(u)\)!\footnote{To check this, apply integration by parts and see what you get.} Then the sum \(u+t\varphi \) only differs from \(u\) by \(o(t^2)\), and so for small \(t\) is relatively close.\\

% Diagram

In the context of differential geometry, we can interpret this new family as the functions in
\begin{align*}
	T_u\mathcal{M} = \left\{\varphi  \mid \int g'(u)\varphi  = 0 \right\} .
\end{align*}
This is because if \(\varphi :\int_{\Omega }g'(u)\varphi  = 0\), then there should be an \(O(t^2)\) correction such that
\begin{align*}
	u+t\varphi +O(t^2) \in \mathcal{M}.
\end{align*}

Let us discuss these families more formally. Let \(\varphi, \xi  \in C^{\infty}(\overline{\Omega })\) such that
\begin{align*}
	\int_\Omega g'(u)\varphi =0 \quad \int_\Omega  g'(u) \xi   = 1
\end{align*}
Consider \(u+t\varphi +s \xi  \in C^{\infty}(\Omega )\) with two parameters \((t,s)\). The implicit function theorem tells us that there exists \(\varepsilon>0\) and \(s(t):(-\varepsilon,\varepsilon)\to \R\) such that, if \(u(t) = u + t\varphi  + s(t) \xi  \), then
\begin{align*}
	\int_\Omega g(u(t)) = M \quad \forall \left| t \right| <\varepsilon\\
	s(0) = 0
\end{align*}
This \(s(t)\) is in essence our \(O(t^2)\) correction that allows the families \(\varphi \) to still satisfy our condition. Let us look in more detail how \(s(t)\) interacts with our current formulations:

\begin{align*}
	\int_\Omega g(u) &= \int_\Omega g(u+t\varphi +s(t) \xi ) \\
	&= \int_\Omega g(u) + t \int _\Omega g'(u) \left[ \varphi +s'(0) \xi  \right] + \dfrac{t^2}{2}\int_\Omega  g''(u)\left[ \varphi +s'(0)\xi  \right]^2 + g'(u) \xi  s''(0) + o(t^2) \\
	&\implies 0 = \int _\Omega g'(u) \left[ \varphi +s'(0) \xi  \right] = s'(0) \int_\Omega g'(u) \xi  = s'(0)\\
	&\implies 0 = \int_\Omega g''(u)\varphi^2 + s''(0) \int_\Omega g'(u) \xi
\end{align*}
But notice that \(\int_\Omega g'(u) \xi  = 1\), so that
\begin{align*}
	s''(0) = - \int_\Omega g''(u) \varphi^2
\end{align*}
This classifies our correction factor up to low orders, so we have that
\begin{align*}
	s \approx - \left[ \int_\Omega g''(u) \varphi^2 \right] \cdot \dfrac{t^2}{2}
\end{align*}

Now we can plug this back into the Euler-Lagrange equations of the problem
\begin{align*}
	\inf_{u} \left\{ \int_\Omega f(\nabla u) \mid \int_\Omega g(u) = M \right\} .
\end{align*}
to get
\begin{align*}
	\mathcal{F}(u+t\varphi +s(t) \xi ) \geq \mathcal{F}(u) \quad \forall \left| t \right| < \varepsilon\\
\end{align*}
and our variations on
\begin{align*}
	f(\nabla u + t \nabla \varphi + s(t) \nabla \xi )
\end{align*}
are given by
\begin{align*}
	&\frac{d}{dt} f(\nabla u + t\nabla \varphi + s(t) \nabla \xi ) = \nabla f(\nabla u+\ldots) \cdot (\nabla \varphi +s'(t) \nabla \xi )\\
	&= \nabla f(\nabla u)\cdot \nabla \varphi \\
	&\frac{d^2}{dt^2}f(\nabla u+t \nabla \varphi + s(t) \nabla \xi) = (\nabla \varphi +s'(t) \nabla \xi ) \cdot \nabla^2 f(\nabla u + \ldots)(\nabla \varphi + s'(t) \nabla \xi ) + \nabla f(\nabla u + \ldots)\cdot \nabla \xi s''(t) \\
	&= \nabla \varphi \cdot (\nabla^2f(\nabla u)\nabla \varphi ) + \nabla f(\nabla u)\cdot \nabla \xi s''(0)
\end{align*}

\hrulefill

Now let \(\psi \in C^{\infty}(\overline{\Omega })\) and choose
\begin{align*}
	\varphi = \psi - \left[ \frac{\int g '(u) \psi }{\int  g '(u)^2} \right] g'(u) = \int_\Omega g'(u)\varphi =0
\end{align*}
Or in other words, we are choosing \(\varphi \) to be \(\psi \) subtracted by its projection along \(g'(u)\). We are choosing \(\varphi \) this way so that \(\langle g'(u), \varphi  \rangle = 0\). Note that there is an implicit assumption here that \(g\) satisfies \(\int g '(u)^2 > 0\). Lastly, choose \(\xi = \dfrac{g'(u)}{\int_\Omega g'(u)^2}\) so that \(\langle g'(u),\xi  \rangle= 1\).

Now let's reconsider the Euler-Lagrange equations, but with the choices of \(\varphi \) and \(\xi \) as above. That is, for all \(\varphi \) and \(\xi \) of the form above:
\begin{align*}
	\int_\Omega \nabla f(\nabla u)\cdot \nabla \varphi = 0\\
	\int_\Omega \nabla \varphi \cdot (\nabla^2f(\nabla u)\nabla \varphi ) + s''(0) \nabla f(\nabla u)\cdot \nabla \xi \geq 0
\end{align*}
Now we substitute in the projection form for \(\varphi \) :
\begin{align*}
	\int_\Omega \nabla f ( \nabla u) \cdot \left[ \nabla \psi - \left[ \frac{\int g'(u) \psi }{\int g'(u)^2} \right] g''(u) \nabla u \right]= 0 \\
\implies \int_\Omega \nabla f(\nabla u)\cdot \nabla \psi - \lambda (u) \int_\Omega g'(u) \psi = 0
\end{align*}
and so
\begin{align*}
	\lambda (u) = \frac{\int_\Omega g''(u) \left[ \nabla u \cdot \nabla f(\nabla u) \right] }{\int_\Omega g'(u)^2}
\end{align*}
This \(\lambda(u)\) is what we refer to by a \textbf{Lagrange multiplier}.\\

Now denote \(X \cong \nabla f(\nabla u)\) and observe:
\begin{align*}
	\int_\Omega X \cdot \nabla \psi = \int_\Omega dw(\psi X) - \int_\Omega \psi \textrm{div}X\\
	= \int_{\partial\Omega }\psi (X\cdot \nu_\Omega ) - \int_\Omega \psi \textrm{div}X.
\end{align*}

\begin{align*}
	0 = \int_{\partial\Omega }\psi \nu_\Omega \cdot \nabla f(\nabla u) + \int_\Omega \psi \left[ -dw(\nabla f(\nabla u)) - \lambda g'(u) \psi  \right] \quad \forall \psi \in C^{\infty}(\overline{\Omega })
\end{align*}
Testing on \(\psi =0\) on \(\partial\Omega \), but arbitrary otherwise, we get on \(\Omega \) :
\begin{align*}
	-dw(\nabla f(\nabla u)) = \lambda g'(u)
\end{align*}
Once we know this we get

\begin{align*}
	\begin{cases}
	-dw(\nabla f(\nabla u)) = \lambda g'(u) & \Omega \\
	\nu_\Omega \cdot \nabla f(\nabla u) = 0 & \partial\Omega
	\end{cases}
\end{align*}

\begin{exmp}
	Choosing \(f(z) = \dfrac{\left| z \right|^2 }{2}\) and \(g(u) = \dfrac{u^2}{2}\), the above becomes
	\begin{align*}
		- \Delta u = \lambda u \quad \Omega \\
		\frac{\partial u}{\partial \nu_\Omega } = \nabla u\cdot \nu_\Omega  = 0 \quad \partial\Omega
	\end{align*}
	This is the Neumann eigenfunctions of the Laplacian \(\Omega \).
\end{exmp}

\begin{exmp}
	Consider the space \(\Omega  = (0,\pi )\), and let \(u_k(x) = \cos(kx)\) for \(k \in \N\). These are all solutions to
	\begin{align*}
		-u_k'' = \lambda u_k \quad (0,\pi )\\
		u'_k\mid_{0,\pi }=0
	\end{align*}
	\(\lambda =k^2\) and \((u_k) \cong k^2\). This is an example of a variational problem with many critical points.
\end{exmp}

Notice that if \(f(z) = \sqrt{1+\left| z \right|^2} \) then \(\nabla f(\nabla u) \cdot \nu_\Omega = \frac{\nabla u \cdot \nu_{\Omega }}{\sqrt{1+ \left| \nabla u \right|^2} }=0\).

\end{document}

Topics in Partial Differential Equations/Calculus of Variations/Notes/source/Lecture2.tex


\documentclass{tufte-handout}
\input{vc.tex}  % For version control
\usepackage{graphicx}
\title{HashJoins}
\author{}
\date{\GITAuthorDate, rev. \GITAbrHash}

\begin{document}
\maketitle
%\section{}
%\subsection

\begin{abstract}
  Implement a symbol table using a \emph{Hash Pipe} data structure.
  This exercise introduces yet another implementation of symbol tables (besides those presented in chapter 3 of [SW]) with logarithmic insertion and search.
  The main difficulty are low-level implementation choices and careful programming  similar to what is needed for implemeting a binary search tree of hash table.
\end{abstract}

\section{Description}

Write the class HashPipe that implements many of the methods for an ordered symbol table with String keys and Integer values.
In particular, implement the following API:

\begin{quotation}
\begin{fullwidth}\small
\begin{verbatim}
public class HashPipe

public HashPipe() // create an empty symbol table
public int size() // return the number of elements
public void put(String key, Integer val) // put key-value pair into the table
public Integer get(String key) // value associated with key
public String floor(String key) // largest key less than or equal to key
 \end{verbatim}
\end{fullwidth}
\end{quotation}

\subsection{Data structure}

The \emph{Hash Pipe} data structure is a pointer-based structure that represents every key--value pair using a so-called \emph{pipe}.
The Pipes are arranged from left to right, in sorted key order.
The entries of each pipe point to the pipes to its right, as shown here:

\begin{figure}
  \includegraphics[width=\textwidth]{img/full.png}
  \caption{The data structure after running the basic symbol table client in [SW, 3.1] on input {\tt S E A R C H E X A M P L E}.}
\end{figure}

To be quite precise, consider key $k$.
The pipe's reference at height $h$ points to the smallest key $k'$ larger than $k$ of height at least $h$.
There is a special \emph{root} pipe to the left, which you can think of as `negative infinity.'
The root pipe does not represent any key--value pair, no other pipe points to it, and it is at least as high as any other pipe.
References with `nothing to the right' contain \emph{null}, shown as empty boxes in the figure.

The number of entries (the `height' of a pipe) is given by the Java hash code of the key,\footnote{Note that we provide a python version of this hash-function that you can import with \texttt{from algs4.fundamentals.java\_helper import java\_string\_hash}}
more specifically it is the \emph{number of trailing zeros of {\tt key.hashCode()} $+1$}.
For instance, the {\tt "A".hashCode()} is 65, which is 1000001 in binary and has no trailing zeros; thus, the height of the pipe of key ``A'' is $0+1=1$.
Similarly, the {\tt "P".hashCode()} is 80, which is 1010000 in binary and has four trailing zeros; thus, the height of the pipe of key ``P'' is $4+1=5$.

Navigation in a Hash Pipe works very much like navigation in a search tree.
To look for a key $k$, start at the root pipe on the highest level containing a reference.
Depending on the comparison with the pointed-to key $k'$, proceed either down the pipe of $k$, stay at the same level but move to the pipe of $k'$.
To insert a new key $k$, find its immediate predecessor (or `floor'), create a new pipe of the height defined by $k$, and (and this is the tricky part) update all the references.

\subsection{Deliverables}

\begin{enumerate}
\item {\tt HashPipe.java} or {\tt HashPipe.py}
\item a report
\end{enumerate}

\subsection{Requirements}

Under the uniform hashing assumption, your update times have to be logarithmic in the number of keys.

If you use more than 100 lines of code, you are probably making a mistake.

Apart from the symbol table methods, you are required to implement a control method {\tt public String control(String key, int h)} that returns the contents of the pipe of the given {\tt key} at the given height $h$, counting from below and starting with $0$.
The control method returns the key that is referenced at that position, or \emph{null}.
For instance, in Figure 1, {\tt control("H", 3)} is ``{\tt P}'', {\tt control("H", 2)} is ``{\tt L}'', and {\tt control("P", 4)} is \emph{null}.
\footnote{This method exists partly for testing your hand-in, but it is also meant as help to you for debugging while you write your code.}
The codeJudge instance relies upon this method.
Your code has to at least pass the tests in \texttt{testsSmall}.
If it does not pass the large tests in \texttt{TestsBest}, most probably your insertion algorithm does not have the required logarithmic performance.
\subsection{Remarks}

\begin{enumerate}
  \item The intuition why the Hash Pipe is very fast is because the pipes have random heights.
Of course, the hash code is not random at all, and you can easily attack the performance of this data structure using maliciously chosen keys.
A better way of deciding the height of a pipe would be to use \emph{randomness}.
(For instance, the number of consecutive `tails' in a sequence of coin flip.)
However, this is a programming exercise, and we have to be able to verify your implementation, which is why we prefer a deterministic policy for determining pipe heights.

  \item You have to write very little code, but it is \emph{very hard} to get that code right.
    You are strongly advised to use your own {\tt control} method to continuously test your constructions.
    Use pen and paper to make precise drawings for very small examples (with only 0, 1, or 2 keys in the symbol table) and use {\tt control} to make sure that all references point to where you think they do.
    Figure 2 is your friend.

  \item The most important design decision is how you define the inner class that represents a key--value pair (you will probably call this {\tt Node} or maybe {\tt Pipe}, depending on how you do it).
      There are at least two different ways of doing this.

    \item We avoid generics in this exercise---our keys are always of type {\tt String} and our values are always of type {\tt Integer}.
      There is a reason for that\footnote{One of the ways of implementing {\tt Node} very quickly gets you bogged down into annoying details of Java's type system for generic arrays. So this restriction makes the exercise a lot easier.}, but if you are ambitious, you are welcome to write a generic symbol table with signature
    \begin{quote}
    \tt HashPipe<Key extends Comparable<Key>, Value>
    \end{quote}

    \item If you want, you can fix the height of the root pipe (all the way to the left) to 32 (and fill the top levels with {\emph null}).
      Otherwise, you have to rebuild the root pipe every time a new, higher, pipe enters the data structure, which involves some simple (but annoying) extra code.

  \item Hint: You will probably make your life easier by having  a private method like \begin{quote}
    \tt private Node floorNode(Key key)
    \end{quote}
    that returns the pipe of the floor of the given key.
      (The details depend a bit on how you chose to implement the pipes.)

    \item The hash pipe really shines for range queries.
      If you're ambitious (and everything else really works), implement
      \begin{quote}
	\tt public Iterable<String> keys(String lo, String hi)
      \end{quote}
      and enjoy how easy (and fast!) that was.

    \item If you like binary arithmitic, you can count trailing zeros by repeated modulo and halving operations.
      For everybody else, there is
    \begin{quote}
    \tt Integer.numberOfTrailingZero(int i)
  \end{quote}
  in the Java standard library and \texttt{trailing zeros} in \texttt{algs4.fundamentals.java\_helper}.

    \item As always, follow the coding style and naming conventions in the book.

\end{enumerate}
\begin{figure}
  \includegraphics{img/fig2.png}
  \caption{Trace of Hash Pipe implementation for standard symbol table indexing client.}
\end{figure}
\end{document}


\documentclass[12pt]{article} \input{physics1}
\begin{document}

\noindent
Name: \rule[-1ex]{0.55\textwidth}{0.1pt}
NetID: \rule[-1ex]{0.2\textwidth}{0.1pt}

\section*{NYU Physics I---Term Exam 6}

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
What is the speed of a package orbiting on a circular orbit right near
the surface of the Earth? Give your answer in $\mps$.
(from Problem Set 11)

\vfill

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
Sketch an orbit of roughly eccentricity 0.9. Most importantly: Show the
point about which the object is orbiting, and make sure your pericenter
and apocenter distances make sense. Don't worry about getting it all right,
just roughly!
(from Problem Set 12)

\vfill

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
Draw a space-time diagram that shows a stationary base E (in the rest
frame of E) and a ship S moving at speed $0.5\,c$ in the $x$
direction with respect to E. At some time (your choice!) when the base and ship are far
apart, base E sends a light signal to the ship S. Draw that light
signal on your diagram too.
(from Problem Set 13)

\vfill
~
\clearpage

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
Earth orbits on a nearly circular orbit at 1\,AU; Jupiter orbits
on a nearly circular orbit at 5.2\,AU. What is the semi-major axis
of the transfer orbit that just kisses both of these orbits?
(from lecture on 2018-11-27)

\vfill

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
If you want to observe a time-dilated celebration (or, say, lifetime
of some unstable particles), time dilated by a factor of 10, how fast
does the party (or do the particles) have to move with respect to you?
Give your answer in terms of the speed of light $c$.
(from lecture on 2018-12-04)

\vfill

\paragraph{\problemname~\theproblem:}\refstepcounter{problem}%
What is the spacetime interval $(\Delta s)^2$ between the two events $A$ and $B$?
$$A = (c\,t_A, x_A) = (2\,\m, 6\,\m) $$
$$B = (c\,t_B, x_B) = (7\,\m, 3\,\m) $$
Don't forget your units. (from the recitation on the interval)

\vfill
~
\end{document}


\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{enumitem}
\usepackage{amsmath}
\usepackage{listings}
\usepackage{color}
\usepackage{booktabs}
\usepackage[font=small, labelfont=bf]{caption}
\usepackage[T1]{fontenc}

% macro to select a scaled-down version of Bera Mono (for instance)
\makeatletter
\newcommand\BeraMonottfamily{%
  \def\fvm@Scale{0.85}% scales the font down
  \fontfamily{fvm}\selectfont% selects the Bera Mono font
}
\makeatother

\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}

\lstdefinestyle{mystyle}{
    backgroundcolor=\color{backcolour},
    commentstyle=\color{codegreen},
    keywordstyle=\color{magenta},
    numberstyle=\tiny\color{codegray},
    stringstyle=\color{codepurple},
    basicstyle=\BeraMonottfamily\footnotesize,
    breakatwhitespace=false,
    breaklines=true,
    captionpos=b,
    keepspaces=true,
    numbers=left,
    numbersep=5pt,
    showspaces=false,
    showstringspaces=false,
    showtabs=false,
    tabsize=2
}
\lstset{style=mystyle,
        otherkeywords={True,False}
}

\title{CS249 Fall 2020\\
       Problem Set 2: Statistical Inference II}
\author{Christopher Munoz Cortes}
\date{\today}

\usepackage{natbib}
\usepackage{graphicx}

\begin{document}

\maketitle

\section{Hypothesis Testing}
Assume a friend of yours currently has a salary of \$70k per year. She is
considering a switch in her career, and has narrowed down her choices to
three different options. She has been able to find the following data points
for entry-level salaries (in thousand dollars) for these three choices:
\begin{enumerate}
\item 143 102 119 157 146 61 119 85 87 102
\item 77 143 108 76 92 87 145 60 86 27
\item 19 83 87 55 115 41 71 66 101 99
\end{enumerate}
Assume that these data points are IID observations, and the difference between
them can only be attributed to noise. Additionally, assume that after
a career change your friend’s salary will be a sample from the same distribution
as the one behind your observed data points.
\begin{enumerate}[label={(\alph*)}]
    \item Can your friend expect an increase in her salary on average if she
    chooses \#1?

    An appropriate null hypothesis to answer this question would be the following
    one-tail test: $H_0: \mu_0 \leq 70$. If we can reject $H_0$, then we can assert
    that the population mean is higher than \$70k, and conclude that our friend
    should expect, on average, an increase in her salary.
    Since $\frac{p}{2} = 0.0009 < \alpha = 0.05$
    and $t>0$ we reject $H_0$. As a consequence, our friend should expect an
    increase in her salary on average if she chooses \#1.

    \item Is there any difference between the average salary of the three
    choices?

    Here we define $H_0: \mu_1 = \mu_2 = \mu_3$ as our null hypothesis and use an
    ANOVA test to verify it. The result of the test shows that we have enough evidence
    to reject the null hypothesis, since $p = 0.04 < \alpha = 0.05$. As a
    consequence, we assert that there is a difference between the average salary of
    the three choices.

    \item Is there any difference between the average salary of \#1 and \#3?

    We can answer this question testing the following null hypothesis: $H_0: \mu_1
    = \mu_3$ and verifying its validity. Since $p = 0.01 < \alpha = 0.05$ we reject
    $H_0$ and assert that the mean salary for choice 1 and choice 2 are different.
\end{enumerate}

\begin{lstlisting}[language=Python, caption=Code for Question 1 \emph{Hypothesis
Testing}]
import numpy as np
from scipy import stats

y_1 = np.array([143, 102, 119, 157, 146, 61, 119, 85, 87, 102])
y_2 = np.array([77, 143, 108, 76, 92, 87, 145, 60, 86, 27])
y_3 = np.array([19, 83, 87, 55, 115, 41, 71, 66, 101, 99])

# Part (a): H_0: mean >= 70k
mu_0 = 70
t_stat, p_val = stats.ttest_1samp(y_1, mu_0)
print(f"t-stat: {t_stat}")
print(f"p-value: {p_val/2}")

# Part (b): H_0: mu_1 = mu_2 = mu_3
f_stat, p_val = stats.f_oneway(y_1, y_2, y_3)
print(f"f-stat: {f_stat}")
print(f"p-value: {p_val}")

# Part (c): H_0: mu_1 = mu_3
t_stat, p_val = stats.ttest_ind(y_1, y_3, equal_var=True)
print(f"t-stat: {t_stat}")
print(f"p-value: {p_val}")
\end{lstlisting}

\pagebreak

\section{Regression to the Mean}
\begin{enumerate}[label={(\alph*)}]
    \item Assume $x$ represents the height of the father and $y$
    represents the height of the son. Standardize the two
    covariates. You can use the following code:

    \lstinline{x = (x - np.mean(x)) / np.std(x)}

    \lstinline{y = (y - np.mean(y)) / np.std(y)}

    Plot \lstinline{y} vs. \lstinline{x} in a scatter plot in Python.
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.7]{scatter_father_son_height.png}
        \caption{\lstinline{y} vs. \lstinline{x}}
        \label{fig:father_son}
    \end{figure}

    \item Based on your intuition and without fitting a model, draw the line corresponding to the linear regression for this data.

    See Figure \ref{fig:father_son}.

    \item Fit a linear regression in Python where the response variable is
    \lstinline{y}. Draw the line corresponding to the fitted linear regression in the
    scatter plot. Does this line match your intuition from the previous part?

    The line corresponding to the fitter linear regression does not match the line I
    plotted based on my intuition. See Figure \ref{fig:father_son} above.
    %TODO: add equation for the line of best fit

    \item Based on the fitted regression line, if a father is 10 inches taller than
    the average, how much greater is the expected height of the son compared to the
    average? And if a father is 10 inches shorter than the average, how much smaller
    is the expected height of the son compared to the average?

    If a father is 10 inches taller than the average, the expected height of the son
    is 5.14 inches taller than the average. Conversely, if a father is 10 inches
    shorter than average, the expected height of the son is 5.14 inches shorter
    than average.

    \item Based on the answer to the previous part, do you think it is fair to say
    that heights become more and more ``average'' over time? Read about ``regression
    to the mean'' and revisit your answer.

    If we didn't take the regression error into consideration, the results from the
    previous part would lead us to believe that the heights do become more ``average''
    over generations. However, this is a naive interpretation that ignores the fact
    that the actual $y_i$ values will not be exactly where the model predicts them to
    be. Some of them will be closer to the mean, while other will be further from it.
    In other words, we when take the error in the regression predicting $y$ from $x$,
    this interpretation is incorrect.

    \begin{lstlisting}[language=Python, caption=Standard Error and Confidence
    Interval for $T$]
import pandas as pd
from google.colab import drive
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Mount drive
drive.mount('/content/drive')
df = pd.read_csv('/content/drive/My Drive/father_son.txt', delim_whitespace=True)

# Standardize the two covariates
def standardize_feature(feature):
  return (feature - np.mean(feature)) / np.std(feature)

x = standardize_feature(df['Father'])
y = standardize_feature(df['Son'])

# Part (a): plot y vs. x
fig, ax = plt.subplots()
ax.scatter(x, y)

# Part (b): plot intuition line of best fit (y=x)
x_int = np.linspace(-3,3)
y_int = x_int
ax.plot(x_int, y_int, linestyle='dashed', color='C1')

# Part (c): fit a linear regression
x = x.values.reshape(-1, 1)
y = y.values.reshape(-1,1)
model = LinearRegression()
model.fit(x,y)
y_hat = model.predict(x)
ax.plot(x, y_hat, linestyle='dashed', color='C2')
ax.legend(['Intuition line of best fit', 'Line of best fit'])

# Part (d)
# Father 10 in taller than the average
x_father = df['Father'].mean() + 10

# Transform the value to match the scale of the model fit
x_father = (x_father - df['Father'].mean()) / df['Father'].std()
x_father = np.array([x_father])

# Son height for x_father
y_hat_son = model.predict(x_father.reshape(-1,1))
y_hat_son = y_hat_son[0][0] * df['Son'].std() + df['Son'].mean()
print(f"The son is {y_hat_son - df['Son'].mean()} inches taller than the average")

# Part (e)
# What if the father is 10 in shorter than the average?
x_father_2 = df['Father'].mean() - 10
x_father_2 = (x_father_2 - df['Father'].mean()) / df['Father'].std()
x_father_2 = np.array([x_father_2]).reshape(-1,1)

y_hat_son_2 = model.predict(x_father_2)
y_hat_son_2 = y_hat_son_2[0][0] * df['Son'].std() + df['Son'].mean()
print(f"The son is {np.abs(y_hat_son_2 - df['Son'].mean())} inches shorter than the average")
\end{lstlisting}
\end{enumerate}
\pagebreak

\section{Linear Regression}
In this problem, we are going to see what happens if we use a linear regression to
model the relationship between two independent random variables.
\begin{enumerate}[label={(\alph*)}]
    \item Simulate 1000 data points from a normal distribution with mean 0 and standard
    deviation 1. Assign it to a variable named $x$. Simulate another 1000 data points
    from a similar normal distribution and assign them to variable $y$. Run a linear
    regression of $y$ vs. $x$. Use \texttt{statsmodels} to view the statistical
    properties of the model. What is the slope of the model? Report your observations.

    I generated $y$ drawing samples from a normal distribution $N(0,1)$. The linear regression results from fitting $y$ vs. $x$ with \texttt{statsmodels} are shown below:
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.5]{ols_res.png}
        \caption{OLS Regression Results with \texttt{statsmodels}.}
        \label{fig:ols_res}
    \end{figure}

    As shown in Figure \ref{fig:ols_res}, the slope of the fitted line is -0.0309.

    \item Repeat the simulation in the previous part 100 times and gather the
    slopes in a list. Draw the distribution, and report your conclusions based
    on the result.
    \begin{figure}[h]
        \centering
        \includegraphics[scale=0.5]{slopes_dist.png}
        \caption{Distribution of slope values}
        \label{fig:slopes}
    \end{figure}

    The distribution for the slope values is centered around ~0 and has a standard
    deviation of 0.03. The slope reported by the linear regression model is roughly
    within one standard deviation of the distribution of the slope values found by
    running several simulations.
\begin{lstlisting}[language=Python, caption=Standard Error and Confidence]
import numpy as np
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

# Simulate 1000 data points from a normal distribution with a mean 0 and std 1
x = np.random.normal(0,1,1000)
y = np.random.normal(0,1,1000)

# Fit the model
x_with_intercept = sm.add_constant(x)
model = sm.OLS(y, x_with_intercept).fit()
y_hat = model.predict(x_with_intercept)

# Print the results
print(model.summary())

# Repeat the simulation 100 times
slopes = []
for i in range(100):
  x = np.random.normal(0,1,1000)
  y = np.random.normal(0,1,1000)
  x_with_intercept = sm.add_constant(x)
  model = sm.OLS(y, x_with_intercept).fit()
  slopes.append(model.params[1])

# Get the mean and std dev of the distribution
slope_std = np.std(slopes)
slope_mean = np.mean(slopes)
print(f"Slope std: {slope_std}")
print(f"Slope mean: {slope_mean}")

# Plot the distribution
plt.hist(slopes, ec='azure')
plt.title('Distribution of slope values')
plt.xlabel('OLS regression slope')
plt.ylabel('Count')
plt.savefig('/content/drive/My Drive/slopes_dist.png', dpi=300)
\end{lstlisting}

\end{enumerate}
\pagebreak

\section{Linear Regression Properties}
\begin{enumerate}[label={(\alph*)}]
    \item Assume we have fitted a linear regression model with an intercept to our
    data. Prove that the sum of residuals in the fitted model is equal to zero:
    \[
        \sum_{i=0}^n \hat{\varepsilon_i} = 0
    \]
    Proof:
    \begin{align*}
        \sum_{i=0}^n \hat{\varepsilon_i} &=
        \sum_{i=0}^n (Y_i - \widehat{Y_i}) \\
        &= Y - X(X^TX)^{-1}X^TY \\
        &= Y - X X^{-1} (X^T)^{-1}  X^T Y \\
        &= Y - I I Y \\
        &= Y - Y = 0
    \end{align*}

    \item We can write the equation for a linear regression model fitted to a dataset
    with $p$ features and $n$ data points as
    \[
        Y_i = \hat{\beta}_0 + \sum_{j=1}^p \hat{\beta}_j X_{i,j} + \hat{\varepsilon_i}
    \]
    where $X_{i,j}$ is the value of $j$-th feature for $i$-th data point and $Y_i$ is
    the response variable for the $i$-th data point. Assume we have
    \emph{centered features} in our data, meaning
    \[
        \dfrac{1}{n} \sum_{i=1}^n X_{i,j} = 0
    \]
    prove that the value of the intercept in the fitted model is equal to the
    average of the response variable in our data:
    \[
        \hat{\beta_0} = \dfrac{1}{n} \sum_{i=1}^n Y_i
    \]
    Proof:
    \begin{align*}
        \hat{\beta_0} &= \dfrac{1}{n} \sum_{i=1}^n Y_i \\
        &= \dfrac{1}{n} \sum_{i=1}^n (\hat{\beta_0} + \sum_{j=1}^p \hat{\beta_j}
        X_{i,j} + \hat{\varepsilon_i}) \\
        &= \dfrac{1}{n} \left(n\hat{\beta_0} + \sum_{i=1}^n \sum_{j=1}^p \hat{\beta_j}
        X_{i,j} + \sum_{i=1}^n\hat{\varepsilon_i} \right) \\
        &= \hat{\beta_0} + \sum_{j=1}^p \hat{\beta_j} \left(\dfrac{1}{n}
        \sum_{i=1}^n X_{i,j}\right) \\
        &= \hat{\beta_0}
    \end{align*}
\end{enumerate}

%\bibliographystyle{plain}
%\bibliography{references}
\end{document}