% This is a XeLaTeX document. To process and view it use the following command:
% xelatex Torch_for_Matlab_users.tex && open Torch_for_Matlab_users.pdf

% Also, I avoided using equations to make the document compatible to automatic conversion to markdown. Here is the command for that:
% pandoc -r latex -w markdown_github -o Torch_for_Matlab_users.md Torch_for_Matlab_users.tex
% To view the Github markdown locally, you can use grip package:
% grip Torch_for_Matlab_users.md

\documentclass[letter]{article}
\usepackage[margin=.7in]{geometry}

\usepackage{hyperref}

\usepackage{fontspec}
\setmainfont{Palatino Linotype}
\newfontfamily{\maintext}{Palatino Linotype}
\newfontfamily{\stressed}{Helvetica}
\newfontfamily{\exotic}{Code2000}
\newfontfamily{\math}{Asana Math}
\pagenumbering{gobble}

\newcommand{\frstClmnWidth}{.43in}
\newcommand{\scndClmnWidth}{6.37in}

\title{Torch for Matlab\textsuperscript{\textregistered}{\let\thefootnote\relax\footnote{Matlab\textsuperscript{\textregistered} is a registered trademark of The MathWorks, Inc.}} Users}
\author{Ata Mahjoubfar\\
\href{mailto:ata.m@ucla.edu}{ata.m@ucla.edu}}

\begin{document}
\maketitle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{General Commands}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Get help for a specific function:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!help sqrt! \\ \hline
\textbf{Torch} & \verb!help(torch.sqrt)! \\ \hline
\end{tabular}
\\

\noindent Documentation of \verb!sqrt! function is shown.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Scalar operations:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!testVar1 = (4*5-1+10.1)/3^2;! \\ \hline
\textbf{Torch} & \verb!testVar1 = (4*5-1+10.1)/3^2;! \\ \hline
\end{tabular}
\\

\noindent The resultant value (3.2333) is assigned to variable \verb!testVar1!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Scalar assignment:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!testVar2 = testVar1;! or \verb!testVar2 = testVar1! \\ \hline
\textbf{Torch} & \verb!testVar2 = testVar1;! or \verb!testVar2 = testVar1! \\ \hline
\end{tabular}
\\

\noindent The value of variable \verb!testVar1! (3.2333) is assigned to variable \verb!testVar2!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Display strings and numbers:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!disp(['The distance is ', num2str(100), ' meters.'])! \\ \hline
\textbf{Torch} & \verb!print('The distance is ' .. 100 .. ' meters.')! \\ \hline
\end{tabular}
\\

\noindent This prints \verb!The distance is 100 meters.! in the output.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Determine type:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!class('Hi')! \\ \hline
\textbf{Torch} & \verb!torch.type('Hi')! \\ \hline
\end{tabular}
\\

\noindent For this example, Matlab returns \verb!char!, and Torch returns \verb!string!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Matrices and Tensors}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a two-dimensional tensor or matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!m = [9, 6, 3, 4; 7, 2, 8, 1]! \\ \hline
\textbf{Torch} & \verb!m = torch.Tensor({{9, 6, 3, 4}, {7, 2, 8, 1}})! \\ \hline
\end{tabular}
\\

\noindent A 2×4 two-dimensional tensor (matrix) with specified elements is formed and assigned to \verb!m!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Number of dimensions of a tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!ndims(m)! \\ \hline
\textbf{Torch} & \verb!m:dim()! \\ \hline
\end{tabular}
\\

\noindent For example here, for the previously defined two-dimensional tensor (matrix) \verb!m!, the returned number is 2.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Size of a tensor in all dimensions:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!size(m)! \\ \hline
\textbf{Torch} & \verb!m:size()! or \verb!#m! \\ \hline
\end{tabular}
\\

\noindent For example here, for the previously defined two-dimensional tensor (matrix) \verb!m!, the returned numbers are 2 and 4, which are the numbers of rows and columns, respectively.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Size of a tensor in a specific dimension:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!size(m,2)! \\ \hline
\textbf{Torch} & \verb!m:size(2)! or \verb!(#m)[2]! \\ \hline
\end{tabular}
\\

\noindent For example here, for the previously defined two-dimensional tensor (matrix) \verb!m!, the returned number is 4, which is the size of the second dimension (number of columns).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Number of elements in a tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!numel(m)! \\ \hline
\textbf{Torch} & \verb!m:numel()! \\ \hline
\end{tabular}
\\

\noindent For example here, for the previously defined two-dimensional tensor (matrix) \verb!m!, the returned number is 8.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a row vector:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!v = [9, 7, 6, 8]! or \verb!v = [9 7 6 8]! \\ \hline
\textbf{Torch} & \verb!v = torch.Tensor({{9, 7, 6, 8}})! \\ \hline
\end{tabular}
\\

\noindent Unlike Matlab, this is not used as a vector in Torch because it is a two-dimensional Tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a column vector:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!v = [9; 7; 6; 8]! \\ \hline
\textbf{Torch} & \verb!v = torch.Tensor({{9}, {7}, {6}, {8}})! \\ \hline
\end{tabular}
\\

\noindent Again unlike Matlab, this is not used as a vector in Torch because it is still a two-dimensional Tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \textit{Not available} \\ \hline
\textbf{Torch} & \verb!t = torch.Tensor({9, 7, 6, 8})! \\ \hline
\end{tabular}
\\

\noindent Matlab does not have \textit{one-dimensional tensors}; this can be verified by running \verb!ndims([9, 7, 6, 8])!. On the other hand, for many operations that Matlab uses row or column vectors, Torch uses one-dimensional tensors.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access an element in a vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!v(2)! \\ \hline
\textbf{Torch} & \verb!t[2]! \\ \hline
\end{tabular}
\\

\noindent Second element of the vector is accessed.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access an element from the end of a vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!v(end-1)! \\ \hline
\textbf{Torch} & \verb!t[-2]! \\ \hline
\end{tabular}
\\

\noindent Second element from the end of the vector is accessed.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a range of elements in a vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!v(2:4)! \\ \hline
\textbf{Torch} & \verb!t[{{2,4}}]! \\ \hline
\end{tabular}
\\

\noindent Second to fourth elements of the vector are accessed.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access an element in a matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!m(2, 3)! \\ \hline
\textbf{Torch} & \verb!m[{2, 3}]! or \verb!m[2][3]! \\ \hline
\end{tabular}
\\

\noindent Second row, third column element is accessed. Accessing in the form of \verb!m[2][3]! is not recommended, because it causes an \verb!out of memory! error for large tensors.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a row in a matrix as a two-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!m(2, :)! \\ \hline
\textbf{Torch} & \verb!m[{{2}, {}}]! \\ \hline
\end{tabular}
\\

\noindent The returned row is a two-dimensional tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a row in a matrix as a one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \textit{Not available} \\ \hline
\textbf{Torch} & \verb!m[{2, {}}]! or \verb!m[2]! \\ \hline
\end{tabular}
\\

\noindent The returned row is a one-dimensional tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a column in a matrix as a two-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!m(:, 2)! \\ \hline
\textbf{Torch} & \verb!m[{{}, {2}}]! \\ \hline
\end{tabular}
\\

\noindent The returned column is a two-dimensional tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a column in a matrix as a one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \textit{Not available} \\ \hline
\textbf{Torch} & \verb!m[{{}, 2}]! \\ \hline
\end{tabular}
\\

\noindent The returned column is a one-dimensional tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Access a range of elements in a matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!m(2, 2:4)! \\ \hline
\textbf{Torch} & \verb!m[{{2}, {2,4}}] or m[{2, {2,4}}]! \\ \hline
\end{tabular}
\\

\noindent The second to fourth columns of the second row are returned. In Torch, there is a slight difference between using \verb!index! (e.g. \verb!2!) or \verb!{index}! (e.g. \verb!{2}!) for pointing to a singleton dimension. For \verb!{index}!, the dimension of the returned tensor is same as the original tensor (e.g. tensor~\verb!m!). For \verb!index!, the singleton dimension is removed, and the dimension of the returned tensor is one less than the original tensor (e.g. tensor~\verb!m!). Also, \verb!{}! refers to all elements in that dimension. Finally, \verb!-index! (e.g. \verb!-4!) means \verb!index!-th (e.g. fourth) element from the end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Forming Basic Tensors}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a vector over a range of values with unit step:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!3:8! \\ \hline
\textbf{Torch} & \verb!torch.range(3, 8)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with elements spaced \verb!1! strating at \verb!3!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a vector over a range of values with an arbitrary step:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!3:-1.9:-4.2! \\ \hline
\textbf{Torch} & \verb!torch.range(3, -4.2, -1.9)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with elements spaced \verb!-1.9! strating at \verb!3!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a vector with linearly-located elements:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!linspace(3, 8, 50)! \\ \hline
\textbf{Torch} & \verb!torch.linspace(3, 8, 50)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!50! equally-spaced elements strating at \verb!3! and ending at \verb!8!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a vector with logarithmically-located elements:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!logspace(3, 8, 50)! \\ \hline
\textbf{Torch} & \verb!torch.logspace(3, 8, 50)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!50! exponentially-spaced elements strating at 10\textsuperscript{3} and ending at 10\textsuperscript{8}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create an all zeros vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!zeros(1,4)! or \verb!zeros(4,1)! \\ \hline
\textbf{Torch} & \verb!torch.zeros(4)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!4! zero elements.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create an all zeros matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!zeros(5,3)! \\ \hline
\textbf{Torch} & \verb!torch.zeros(5,3)! \\ \hline
\end{tabular}
\\

\noindent 5×3 matrix of zeros is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create an all ones vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!ones(1,4)! or \verb!ones(4,1)! \\ \hline
\textbf{Torch} & \verb!torch.ones(4)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!4! one elements.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create an all ones matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!ones(5,3)! \\ \hline
\textbf{Torch} & \verb!torch.ones(5,3)! \\ \hline
\end{tabular}
\\

\noindent 5×3 matrix of ones is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create an identity matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!eye(5,3)! \\ \hline
\textbf{Torch} & \verb!torch.eye(5,3)! \\ \hline
\end{tabular}
\\

\noindent 5×3 identity matrix is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a square identity matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!eye(4)! \\ \hline
\textbf{Torch} & \verb!torch.eye(4)! \\ \hline
\end{tabular}
\\

\noindent 4×4 identity matrix is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a uniformly-distributed random vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!rand(1,4)! or \verb!rand(4,1)! \\ \hline
\textbf{Torch} & \verb!torch.rand(4)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!4! random elements from uniform probability distribution.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a uniformly-distributed random matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!rand(5,3)! \\ \hline
\textbf{Torch} & \verb!torch.rand(5,3)! \\ \hline
\end{tabular}
\\

\noindent 5×3 matrix of random elements from uniform probability distribution is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a normally-distributed random vector or one-dimensional tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!randn(1,4)! or \verb!randn(4,1)! \\ \hline
\textbf{Torch} & \verb!torch.randn(4)! \\ \hline
\end{tabular}
\\

\noindent Torch's result is a one-dimensional tensor with \verb!4! random elements from normal probability distribution.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Create a normally-distributed random matrix:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!randn(5,3)! \\ \hline
\textbf{Torch} & \verb!torch.randn(5,3)! \\ \hline
\end{tabular}
\\

\noindent 5×3 matrix of random elements from normal probability distribution is generated.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Operations}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Tensor assignment without memory copy:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \textit{Not directly available} \\ \hline
\textbf{Torch} & \verb!matOut = matIn! or \verb!matOut = matIn;! \\ \hline
\end{tabular}
\\

\noindent Matlab internally handles memory assignment for a copied array. As soon, as the copied array is modified in Matlab, a copy of the initial array is generated. Whereas, Torch gives this option to have a copied tensor that points to the same location in the memory as the initial tensor. For example, if elements of the \verb!matOut! tensor are modified here, the same changes happen to the elements of the \verb!matIn! tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Tensor assignment with memory copy:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matOut = matIn! or \verb!matOut = matIn;! \\ \hline
\textbf{Torch} & \verb!matOut = matIn:clone()! or \verb!matOut = matIn:clone();! \\ \hline
\end{tabular}
\\

\noindent Matlab's internal memory handling for array assignment is somewhat closer to this. Here, Torch generates a copy of the tensor content in memory. Any changes in \verb!matOut! elements are independent of the changes in the elements of the \verb!matIn! tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Change type of a tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!uint8(matIn)!, \verb!int8(matIn)!, \verb!int16(matIn)!, \verb!int32(matIn)!, \verb!int64(matIn)!, \verb!single(matIn)!, or \verb!double(matIn)! \\ \hline
\textbf{Torch} & \verb!matIn:byte()!, \verb!matIn:char()!, \verb!matIn:short()!, \verb!matIn:int()!, \verb!matIn:long()!, \verb!matIn:float()!, or \verb!matIn:double()! \\ \hline
\end{tabular}
\\

\noindent By default, double precision is used.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Multiplication of a tensor by a scalar:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matIn * 17! or \verb!17 * matIn! \\ \hline
\textbf{Torch} & \verb!matIn * 17! \\ \hline
\end{tabular}
\\

\noindent Pay attention that in Torch, the scalar cannot be the first argument of the multiplication.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Matrix multiplication of a tensor by another tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matA * matB! \\ \hline
\textbf{Torch} & \verb!matA * matB! \\ \hline
\end{tabular}
\\

\noindent Tensor sizes must be appropriate for the multiplication.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Element-wise multiplication of a tensor by another tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matA .* matB! \\ \hline
\textbf{Torch} & \verb!torch.cmul(matA, matB)! \\ \hline
\end{tabular}
\\

\noindent Tensor sizes must be identical.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Transpose of a two-dimensional tensor (matrix):}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matIn.'! \\ \hline
\textbf{Torch} & \verb!matIn:t()! \\ \hline
\end{tabular}
\\

\noindent A new tensor, which is the transpose of the input matrix (two-dimensional tensor) is returned.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Vertical tensor concatenation:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb![matTop; matBottom]! \\ \hline
\textbf{Torch} & \verb!torch.cat(matTop, matBottom, 1)! \\ \hline
\end{tabular}
\\

\noindent The number of columns in input tensors must be equal.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Horizontal tensor concatenation:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb![matLeft, matRight]! \\ \hline
\textbf{Torch} & \verb!torch.cat(matLeft, matRight, 2)! \\ \hline
\end{tabular}
\\

\noindent The number of rows in input tensors must be equal.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Square root of elements returned in a new tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matOut = sqrt(matIn)! \\ \hline
\textbf{Torch} & \verb!matOut = torch.sqrt(matIn)! \\ \hline
\end{tabular}
\\

\noindent Square root of each element is saved in an output tensor with the same size as the input tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Square root of elements returned in the same tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matIn = sqrt(matIn)! \\ \hline
\textbf{Torch} & \verb!matIn = torch.sqrt(matIn)! or \verb!matIn.sqrt(matIn)! or \verb!matIn:sqrt()! \\ \hline
\end{tabular}
\\

\noindent \verb!matIn:sqrt()! is same as \verb!matIn.sqrt(matIn)!. Generally in Torch, \verb!object:function(p1, p2, ...)! is same as\\ \verb!object.function(object, p1, p2, ...)!, where the function's object (also known as \verb!self!) is passed as the first input to the function.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Element-wise power to a scalar:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matIn.^5! \\ \hline
\textbf{Torch} & \verb!torch.pow(matIn, 5)! \\ \hline
\end{tabular}
\\

\noindent Each element to the power of 5 is saved in an output tensor with the same size as the input tensor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Element-wise power to a tensor:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!matIn.^matPow! \\ \hline
\textbf{Torch} & \verb!torch.cpow(matIn, matPow)! \\ \hline
\end{tabular}
\\

\noindent Each element of the \verb!matIn! tensor to the power of the corresponding element of the \verb!matPow! tensor is saved in an output tensor with the same size as the input tensor.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%
\end{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection*{Short description here:}

\begin{tabular}{|p{\frstClmnWidth{}}|p{\scndClmnWidth{}}|}
\hline
\textbf{Matlab} & \verb!Matlab code here! \\ \hline
\textbf{Torch} & \verb!Torch code here! \\ \hline
\end{tabular}
\\

\noindent Description of the details here.


%!TEX root = forallxsol.tex
%\part{Interpretations}
%\label{ch.semantics}
%\addtocontents{toc}{\protect\mbox{}\protect\hrulefill\par}

\setcounter{chapter}{27}
\chapter{Truth in FOL}\setcounter{ProbPart}{0}
\problempart
\label{pr.TorF1}
Consider the following interpretation:
	\begin{ebullet}
		\item The domain comprises only Corwin and Benedict
		\item `$Ax$' is to be true of both Corwin and Benedict
		\item `$Bx$' is to be true of Benedict only
		\item `$Nx$' is to be true of no one
		\item `$c$' is to refer to Corwin
	\end{ebullet}
Determine whether each of the following sentences is true or false in that interpretation:
\begin{earg}
\item $Bc$ \hfill \myanswer{False}
\item $Ac \eiff \enot Nc$ \hfill \myanswer{True}
\item $Nc \eif (Ac \eor Bc)$ \hfill \myanswer{True}
\item $\forall x Ax$ \hfill \myanswer{True}
\item $\forall x \enot Bx$ \hfill \myanswer{False}
\item $\exists x(Ax \eand Bx)$ \hfill \myanswer{True}
\item $\exists x(Ax \eif Nx)$ \hfill \myanswer{False}
\item $\forall x(Nx \eor \enot Nx)$ \hfill \myanswer{True}
\item $\exists x Bx \eif \forall x Ax$ \hfill \myanswer{True}
\end{earg}

\problempart
\label{pr.TorF2}
Consider the following interpretation:
	\begin{ebullet}
		\item The domain comprises only Lemmy, Courtney and Eddy
		\item `$Gx$' is to be true of Lemmy, Courtney and Eddy.
		\item `$Hx$' is to be true of and only of Courtney
		\item `$Mx$' is to be true of and only of Lemmy and Eddy
		\item `$c$' is to refer to Courtney
		\item `$e$' is to refer to Eddy
	\end{ebullet}
Determine whether each of the following sentences is true or false in that interpretation:
\begin{earg}
\item $Hc$ \hfill \myanswer{True}
\item $He$\hfill \myanswer{False}
\item $Mc \eor Me$ \hfill \myanswer{True}
\item $Gc \eor \enot Gc$ \hfill \myanswer{True}
\item $Mc \eif Gc$ \hfill \myanswer{True}
\item $\exists x Hx$ \hfill \myanswer{True}
\item $\forall x Hx$ \hfill \myanswer{False}
\item $\exists x \enot Mx$ \hfill \myanswer{True}
\item $\exists x(Hx \eand Gx)$ \hfill \myanswer{True}
\item $\exists x(Mx \eand Gx)$ \hfill \myanswer{True}
\item $\forall x(Hx \eor Mx)$ \hfill \myanswer{True}
\item $\exists x Hx \eand \exists x Mx$ \hfill \myanswer{True}
\item $\forall x(Hx \eiff \enot Mx)$ \hfill \myanswer{True}
\item $\exists x Gx \eand \exists x \enot Gx$ \hfill \myanswer{False}
\item $\forall x\exists y(Gx \eand Hy)$ \hfill \myanswer{True}
\end{earg}

\problempart
\label{pr.TorF3}
Following the diagram conventions introduced at the end of \S23, consider the following interpretation:
\begin{center}
\begin{tikzpicture}
\node (atom1) at (0,2) {1};
\node (atom2) at (2,2) {2};
\node (atom4) at (0,0) {3};
\node (atom5) at (2,0) {4};
\node (atom6) at (4,0) {5};
\draw[->, thick] (atom1)+(-0.15,0.15) arc (-330:-30:.3);
\draw[->, thick] (atom6)+(0.15,-0.15) arc (-150:150:.3);
\draw[->, thick] (atom1) -- (atom2);
\draw[->, thick] (atom1) -- (atom4);
\draw[<->, thick] (atom1) -- (atom5);
\draw[->, thick] (atom1) -- (atom6);
\draw[->, thick] (atom2) -- (atom6);
\end{tikzpicture}
\end{center}
Determine whether each of the following sentences is true or false in that interpretation:
\begin{earg}
\item $\exists x Rxx$ \hfill \myanswer{True}
\item $\forall x Rxx$ \hfill \myanswer{False}
\item $\exists x \forall y Rxy$ \hfill \myanswer{True}
\item $\exists x \forall y Ryx$ \hfill \myanswer{False}
\item $\forall x \forall y \forall z ((Rxy \eand Ryz) \eif Rxz)$ \hfill \myanswer{False}
\item $\forall x \forall y \forall z ((Rxy \eand Rxz) \eif Ryz)$ \hfill \myanswer{False}
\item $\exists x \forall y \enot Rxy$ \hfill \myanswer{True}
\item $\forall x(\exists y Rxy \eif \exists y Ryx)$ \hfill \myanswer{True}
\item $\exists x \exists y (\enot x = y \eand Rxy \eand Ryx)$ \hfill \myanswer{True}
\item $\exists x \forall y(Rxy \eiff x = y)$ \hfill \myanswer{True}
\item $\exists x \forall y(Ryx \eiff x = y)$ \hfill \myanswer{False}
\item $\exists x \exists y(\enot x = y \eand Rxy \eand \forall z(Rzx \eiff y = z))$ \hfill \myanswer{True}
\end{earg}

\setcounter{chapter}{29}
\chapter{Using Interpretations}\setcounter{ProbPart}{0}

\solutions
\problempart
\label{pr.Contingent}
Show that each of the following is neither a logical truth nor a contradiction:
\begin{earg}
\item \leftsolutions\ $Da \eand Db$
\item \leftsolutions\ $\exists x Txh$
\item \leftsolutions\ $Pm \eand \enot\forall x Px$
\item $\forall z Jz \eiff \exists y Jy$
\item $\forall x (Wxmn \eor \exists yLxy)$
\item $\exists x (Gx \eif \forall y My)$
\item $\exists x (x = h \eand x = i)$
\end{earg}

\solutions
\problempart
\label{pr.NotEquiv}
Show that the following pairs of sentences are not logically equivalent.
\begin{earg}
\item $Ja$, $Ka$
\item $\exists x Jx$, $Jm$
\item $\forall x Rxx$, $\exists x Rxx$
\item $\exists x Px \eif Qc$, $\exists x (Px \eif Qc)$
\item $\forall x(Px \eif \enot Qx)$, $\exists x(Px \eand \enot Qx)$
\item $\exists x(Px \eand Qx)$, $\exists x(Px \eif Qx)$
\item $\forall x(Px\eif Qx)$, $\forall x(Px \eand Qx)$
\item $\forall x\exists y Rxy$, $\exists x\forall y Rxy$
\item $\forall x\exists y Rxy$, $\forall x\exists y Ryx$
\end{earg}

\problempart
Show that the following sentences are jointly consistent:
\begin{earg}
\item $Ma, \enot Na, Pa, \enot Qa$
\item $Lee, Leg, \enot Lge, \enot Lgg$
\item $\enot (Ma \eand \exists x Ax), Ma \eor Fa, \forall x(Fx \eif Ax)$
\item $Ma \eor Mb, Ma \eif \forall x \enot Mx$
\item $\forall y Gy, \forall x (Gx \eif Hx), \exists y \enot Iy$
\item $\exists x(Bx \eor Ax), \forall x \enot Cx, \forall x\bigl[(Ax \eand Bx) \eif Cx\bigr]$
\item $\exists x Xx, \exists x Yx, \forall x(Xx \eiff \enot Yx)$
\item $\forall x(Px \eor Qx), \exists x\enot(Qx \eand Px)$
\item $\exists z(Nz \eand Ozz), \forall x\forall y(Oxy \eif Oyx)$
\item $\enot \exists x \forall y Rxy, \forall x \exists y Rxy$
\item $\enot Raa$, $\forall x (x=a \eor Rxa)$
\item $\forall x\forall y\forall z[(x=y \eor y=z )\eor x=z]$, $\exists x\exists y\ \enot x= y$
\item $\exists x\exists y((Zx \eand Zy )\eand x=y)$, $\enot Zd$, $d=e$
\end{earg}

\problempart
Show that the following arguments are invalid:
\begin{earg}
\item $\forall x(Ax \eif Bx) \therefore \exists x Bx$
\item $\forall x(Rx \eif Dx), \forall x(Rx \eif Fx) \therefore \exists x(Dx \eand Fx)$
\item $\exists x(Px\eif Qx) \therefore \exists x Px$
\item $Na \eand Nb \eand Nc \therefore \forall x Nx$
\item $Rde, \exists x Rxd \therefore Red$
\item $\exists x(Ex \eand Fx), \exists x Fx \eif \exists x Gx \therefore \exists x(Ex \eand Gx)$
\item $\forall x Oxc, \forall x Ocx \therefore \forall x Oxx$
\item $\exists x(Jx \eand Kx), \exists x \enot Kx, \exists x \enot Jx \therefore \exists x(\enot Jx \eand \enot Kx)$
\item $Lab \eif \forall x Lxb, \exists x Lxb \therefore Lbb$
\item $\forall x(Dx \eif \exists y Tyx) \therefore \exists y \exists z\ \enot y= z$
\end{earg}


\section{Introduction}

The \textit{Online Encyclopedia of Integer Sequences} \citep{OEIS} is an online
database of sequences of numbers that collects any kind of data regarding them,
available at \url{https://oeis.org/}.  It was founded by N.~J.~A.~Sloane in
$1964$ and since then has been, and continue to be, updated constantly by
contributions of many users. Despite of its powerful searching mechanisms,
shown in Figure \ref{fig:oeis:page} which reports results about the well known
sequence of Fibonacci numbers (see e.g.  \citep{ConcreteMath}), we design a
parallel \textit{suite of software tools} that satisfies the necessities (i)~to
search the OEIS offline by downloading repeated searches, (ii)~to work in the
console to use programming facilities to manipulate contents more effectively
and (iii)~to interface with third-party libraries to visualize networks
encoding connections among sequences.

\begin{figure}
\centering
\includegraphics{OEIS/oeis-page}
\caption{The OEIS search page: the present snapshot shows search
results about the sequence of Fibonacci numbers }
\label{fig:oeis:page}
\end{figure}

Looking for similar approaches in the recent literature,
\citep{Nguyen_miningthe} mines the OEIS for new mathematical identities,
discussing how to store, compare and match integer sequences toward the
formalization of some conjectures; on the other hand, searching the word
"\textit{oeis}" in GitHub returns one hundred repositories, the majority of
them host simple implementations of scripts that download data about a
given sequence, targeting all major programming languages. Moreover,
\citep{weidmann:sequencer} is a project that identifies number sequences given
a list of numbers and gives a formula that generates them.

Our approach complements the former ones because it provides a
\textit{recursive} and \textit{asynchronous} fetching process, vanilla data
storage in JSON files and visualization of sequences' relations; the
description of each tool is addressed in the following sections, respectively.

The present suite of tools had been shown at an open school on
Combinatorial Method in the analysis of Algorithms and Data Structures
in Korea \citep{Nocentini:korea}; moreover, all the sources that
implements the applications can be found online in the repository
\url{https://github.com/massimo-nocentini/oeis-tools}.

\section{The Crawler}

The script \verb|crawling.py| implements a bot that given a sequence identifier
in the form $Axxxxxx$, where $x$s are digits, issues an HTTP request to the
main OEIS server and waits for a response; once it is received, the bot stores
it locally and, looking into the response's \verb|xref| section that contains a
set of other sequences identifiers, repeats its behaviour on each one of them,
recursively.  Such a bot is commonly known as \emph{crawler}.

Our implementation features neither threads nor race conditions nor data sync;
on the contrary, it targets \textit{pure asynchronous computation} by using
\textit{async/await} Python primitives only. The approach is educational and we
strive to create a simple but elegant codebase which boils down to $300$ lines
of Python code; eventually, it allows us to cache portions of the OEIS to speed
up repeated lookups and to restart the fetching process from the cache already
downloaded.

The script presents a help message to explain itself:
\VerbatimInput[fontsize=\small]{OEIS/crawler-help.txt}

\begin{example}
We illustrate a typical session where we start from scratch. First of all, we
want to download the OEIS content about two important and nice sequences,
namely those corresponding to the Fibonacci and Catalan numbers (see e.g.
\citep{ConcreteMath,stanley:2015}), known in the OEIS by identifiers $A000045$ and
$A000108$, respectively:
\VerbatimInput[fontsize=\small]{OEIS/crawler-fetching-command.txt}
After stopping the crawler, we check the content of cache with the commands
\VerbatimInput[fontsize=\small]{OEIS/crawler-status.txt} which tell us that
$30$ sequences had been fetched and stored in the default directory
\verb|./fetched/|.  Moreover, we can restart the crawler from where it was
interrupted with the command
\VerbatimInput[fontsize=\small]{OEIS/crawler-restarting.txt}
and we check that new sequences are actually collected,
\begin{Verbatim}[fontsize=\small]
$ python3.6 crawling.py
50 sequences in cache ./fetched/
354 sequences in fringe for restarting
\end{Verbatim}
as desired.
\end{example}

Having contents stored in JSON files allows us to inspect and manipulate them
using every tool available in our working environment, as the next example
shows.

\begin{example}
Combining the \verb|cat| command with the Python module \verb|json.tool|, that prints JSON files
with respect to indentation, we can visualize data about the sequence of Fibonacci
numbers as follows
\VerbatimInput[fontsize=\small]{OEIS/crawler-A000045-chunk.txt}
\end{example}

Our implementation takes strong inspiration from
\citep{VANROSSUM:DAVIS:async:await} and provides the following main abstractions:

\begin{description}
\item[reader] objects, that have the responsibility to be \textit{asynchronous
iterators}, having to respond to the message \verb|__anext__| where the
computation waits asynchronously for incoming data from the \verb|self.read|
coroutine. The code
\inputminted[fontsize=\small,stripnl=false,firstline=28,lastline=39]
{python}{../src/crawling.py} implements the description precisely.

\item[fetcher] objects have the responsibilities to (i)~create a socket with
OEIS server, (ii)~establish a working connection, (iii)~send an HTTP \verb|GET|
request for the desired sequence, (iv)~wait for the fetching process completes
and (v)~close the socket and signal that the work ends successfully.
\inputminted[fontsize=\small,stripnl=false,firstline=41,lastline=86]
    {python}{../src/crawling.py}

\item[crawler] objects have the responsibilities (i)~to keep a queue of task,
one for each candidate sequence, (ii)~to put each ready task into the
scheduling process and (iii)~to reclaim memory for completed task and,
eventually, (iv)~to deque them.
\inputminted[fontsize=\small,stripnl=false,firstline=89,lastline=117]
    {python}{../src/crawling.py}

\end{description}

\iffalse
Finally, the function \verb|oeis| puts all together and it is the main
interface exported by the \verb|crawling| module:
\inputminted[fontsize=\small,stripnl=false,firstline=195,lastline=221]
    {python}{../src/crawling.py}
\fi

\section{The (Pretty) Printer}

The script \verb|pprinting.py| provides a proxy for searching into the OEIS,
therefore it shows exactly the same contents you see from usual web interface
on \url{http://oeis.org}; additionally, it provides (i)~tabular representations
of \verb|data| sections in \textit{one and two dimensions} using list and
matrix notations, respectively, (ii)~filtering capabilities on most response's
sections and (iii)~interoperability with the crawler tool by taking advantage of
cached sequences.

The script presents a help message to explain itself:
\VerbatimInput[fontsize=\small]{OEIS/pprinting-help.txt} In the next examples
we show how \verb|pprinting|'s facilities can be used to apply filters, to
print data-only visualization and to search by an open query, respectively.

\begin{example} Typing the following command into a shell, it outputs
on the \verb|stdout| the pretty-printed contents about the sequence of
Fibonacci numbers, with two filters applied that show comments made by
prof. Barry and the first $5$ formulae only,
\VerbatimInput[fontsize=\small]{OEIS/pprinting-A000045.txt}
other sections, such as \verb|reference| and \verb|link|, are hidden by
default to provide a cleaner output.
\end{example}

\begin{example}
The following command pretty prints (i)~the first 3 sequences from our current
cache --the result may vary if you try on your own machine--, (ii)~ranking them
according to the most recent access time, (iii)~reporting data only and
(iv)~limiting up to $10$ coefficients for linear sequences:
\VerbatimInput[fontsize=\small]{OEIS/pprinting-data-only.txt}
\end{example}

\begin{example}
The following command pretty prints (i)~response about the open query
"\verb|pascal triangle|", (ii)~using $2$-dimension representation for matrices
in \verb|data| sections and (iii)~reports the first $2$ sequences in the
returned list only,
\VerbatimInput[fontsize=\small]{OEIS/pprinting-pascal-matrix.txt}
\end{example}

In parallel of the textual interface, we develop pretty printing functions that
integrates in Jupyter notebooks. The aim remains the same, namely to present
contents taken from the OEIS targeting a different environment that accepts
their representation; this is the time of a dynamic web interface that allows
us to evaluate Python code on the fly. Using Jupyter's Markdown language to
write textual content, we propose another view of the same data, as shown in
Figures \ref{fig:oeis:notebook:fibonacci}, \ref{fig:oeis:notebook:catalan} and
\ref{fig:oeis:notebook:pascal}; in particular, we take advantage of
(i)~hyper-references to make sequences labels clickable to quickly visit them
in a new tab, (ii)~font styles to emphasize words in italics and
(iii)~bold-face and to render math notations properly such as $2$-dimensional
array representation for matrices.
\vfill

\begin{figure}
\includegraphics{OEIS/notebook-fibonacci}
\caption{This screenshot shows search results about the Fibonacci numbers where
(i)~the section about comments is filtered such that the word "\emph{binomial}"
has to appear in their text and (ii)~the section about formulae is hidden.}
\label{fig:oeis:notebook:fibonacci}
\end{figure}

\begin{figure}
\includegraphics{OEIS/notebook-catalan}
\caption{This screenshot shows search results of a query using a subsequence,
showing \emph{data} sections only.}
\label{fig:oeis:notebook:catalan}
\end{figure}

\begin{figure}
\includegraphics{OEIS/notebook-pascal}
\caption{This screenshot shows search results of an open query using the
"\emph{pascal}" keyword, representing the \emph{data} section as a
$2$-dimensional array.  }
\label{fig:oeis:notebook:pascal}
\end{figure}

\section{The Grapher}

The script \verb|graphing.py| allows us to represent networks where vertices
are sequences and edges are connections among them, according to \verb|xref|
sections in their JSON encodings. It integrates with the crawler tool by
parsing the fetched files and creates \verb|Graph| objects, defined in the
Python module \verb|networkx|, having different layouts according to a set of
drawing algorithms.

It presents a help message to explain itself:
\VerbatimInput[fontsize=\small]{OEIS/graphing-help.txt}

\begin{example}
The following command draws the graph shown in Figure
\ref{fig:oeis:sequences:network}, where the width of each vertex grows
according to the number of its \textit{incoming} connections,
\begin{Verbatim}[fontsize=\small]
$ python3.6 graphing.py --layout FRUCHTERMAN-REINGOLD graph.png
\end{Verbatim}
in order to emphasize most referenced sequences.
\end{example}

\begin{figure}
\includegraphics{OEIS/graph1}
\caption{Sequences network where vertices are emphasized according to the
number of incoming connections.}
\label{fig:oeis:sequences:network}
\end{figure}

Moreover, it can extract essential data from the whole set of JSON files, such
as the list of vertices and edges, to interface with third-party software tools
that provide different visualizations; in particular, libraries using the
\textit{Javascript} programming language are very powerful and the output they
produce are very expressive. For our purposes, we use the \verb|arborjs|
library (freely available at \url{http://arborjs.org/}) to display two
additional graphs described in the next two examples, respectively.

\begin{example}
Figure \ref{fig:oeis:sequences:network:fibonacci:catalan} reports a new
unlabeled graph that shows the underlying structure of sequences connections.
Here, the layout spreads vertices such that the ones having many
\textit{outgoing} connections are centered, while those having poor
connectivity are left on borders.

Under the hood, the Fibonacci and Catalan numbers are the two central sequences
and both of them have an orbit which contains a set of highly connected
sequences.
\end{example}

\begin{figure}
%\begin{sideways}
\includegraphics[width=15cm, height=15cm]{OEIS/points}
\caption{Sequences network abstracting over identifier to spot the underlying
structure.}
%\end{sideways}
\label{fig:oeis:sequences:network:fibonacci:catalan}
\end{figure}

\begin{example}
On the other hand, Figure
\ref{fig:oeis:sequences:network:fibonacci:catalan:labeled} adds labels and
colors to vertices in order to spot their identity and their relevance
according to a combination of their properties. In particular, each color is
represented by an RGB tuple that gets weigths (i)~the number of comments and
formulae for \textit{red}, (ii)~the number of references and links for
\textit{green} and (iii)~the number of incoming and outgoing connections for
\textit{blue}, respectively. Moreover, we get the complement to $255$ of each
component because many sequences have not so many details and this manipulation
allows us to obtain cleaner and more expressive graphs.

For the sake of clarity, the two sequences in evidence are the Fibonacci and
Catalan numbers, the former has the color $(006100)_{16}$ and its complement
$(FFFFFF)_{16}-(006100)_{16}=(FF9EFF)_{16}$ means that it has many comments,
formulae and connections; the latter has the color $(7C00E5)_{16}$ and its
complement $(FFFFFF)_{16}-(7C00E5)_{16}=(83FF1A)_{16}$ means that it has lots
of comments, links and references.
\end{example}

\begin{remark}
Recall that the interpretations given in the previous examples concern a
\textit{subset} of the OEIS only, in particular the one fetched in our session;
finally, the more we crawl, the more graphs are effective and accurate.
\end{remark}

\begin{figure}
\centering
\begin{sideways}
%\includegraphics[width=20cm, height=20cm]{OEIS/labels}
\includegraphics[width=20cm, height=35cm]{OEIS/coloured}
\end{sideways}
\caption{Sequences network with labelel vertices, here we see that the sequence
of \textit{Fibonacci numbers} (\url{https://oeis.org/A000045}) and of
\textit{Catalan numbers} (\url{https://oeis.org/A000108}) are the two central
sequences, respectively.}
\label{fig:oeis:sequences:network:fibonacci:catalan:labeled}
\end{figure}

\begin{example}
Finally, crawling for a while to get more sequences, we represent their
connections in Figure
\ref{fig:oeis:sequences:network:fibonacci:catalan:circular}, arranging them
using a circular layout and we emphasize vertices in the \textit{dominating
set} using the \textit{red} color.
\end{example}

\begin{figure}
\hspace{-2cm}
\includegraphics[width=20cm, height=20cm]{OEIS/circular}
\caption{A bigger sequences network composed of $419$ sequences; here the
sequence of \textit{Fibonacci numbers} is denoted by $\alpha$ and the sequence
of \textit{Catalan numbers} is denoted by $\beta$, respectively.}
\label{fig:oeis:sequences:network:fibonacci:catalan:circular}
\end{figure}

\section*{Conclusions}

This paper presents a suite of tools that interacts with the \textit{Online
Encyclopedia of Integer Sequences}, whose primary goal is to automate simple
and repetitive operations such as (i)~crawling sequences to hold a local copy
stored in JSON files, (ii)~pretty printing data with filtering capabilities,
both in the terminal and in Jupyter (\url{http://jupyter.org/}) notebooks and
(iii)~to visualize connections among sequences using graphs.

In parallel, this suite has been devised to be open to extension
and to interface with the hosting environment, UNIX in particular. For
instance, the printer can be used in pipe with the \verb|less| command to gain
scroll and search features for free or the grapher can be augmented to generate
more detailed graph descriptions to be processed by visualization tools.

An additional work direction is to make graphs interactive, namely to tie
together the crawler and the grapher in a web-browser interface such that a
click on a vertex triggers the execution of the fetching process (unless it has
been downloaded already) and the new connections are added to the network
dynamically.

We wish to point out that the suite of tools presented in this work, the
\textit{grapher} in particular, could be used to mine the graph structures
for study regularities and patterns among sequences which looks an interesting
research activity.

\iffalse

\begin{figure}
\includegraphics{OEIS/fibonacci-catalan}
\caption{Sequences network fetched by commands issued in the discussed session.}
\label{fig:oeis:sequences:network}
\end{figure}

\notbreakable{
    \inputminted[fontsize=\small,stripnl=false,firstline=31,lastline=44]
        {python}{../src/graphing.py}
}

\notbreakable{
    \inputminted[fontsize=\small,stripnl=false,firstline=46,lastline=76]
        {python}{../src/graphing.py}
}

\fi


\chapter{The Role of Algorithms in Computing}

\section{Algorithms}

\begin{enumerate}

\item[1.1{-}1] Give a real-world example that requires sorting or
  a real-world example that requires computing a convex hull.

\begin{framed}
Sorting. In a dictionary, it is essential to use sorting so that one
can easily find the desired word.

Convex hull. After conducting a voting intention survey, it may be
interesting to know its coverage area. One can calculate the aproximate area by
projecting the covered cities to a two dimensional plane, obtain the convex hull
of the projected cities, and then compute the approximate area of the convex
hull.
\end{framed}

\item[1.1{-}2] Other than speed, what other measures of efficiency might
  one use in a real-world setting?

\begin{framed}
For algorithms in general, we can also optimize for low memory usage or low
power consumption. In machine learning algorithms, accuracy (hit rate) is also
considered a measure of efficiency.
\end{framed}

\item[1.1{-}3] Select a data structure that you have seen previously,
  and discuss its strengths and limitations.

\begin{framed}
Linked List is a basic data structure. Some of its strengths are:

\begin{itemize}
\item Given a pointer to an element in the list, we can insert an element after
  or before it in constant time.
\item Given a pointer to an element in the list, we can delete it in constant
  time.
\end{itemize}

Some of its limitations are:

\begin{itemize}
\item The pointers requires extra memory.
\item Since it only has pointers to the next element, it takes linear time to
  retrieve the i-th element.
\end{itemize}
\end{framed}

\item[1.1{-}4] How are the shortest-path and traveling-salesman problems
  given above similar? How are they different?

\begin{framed}
They are similar because both of them aims at minimizing the distance between
A and B, given a set of possible valid paths. However, the traveling-salesman
problem has an additional constraint: for a path to be valid, besides starting
in A and ending in B, it also needs to pass through a set of other points C, D,
\ldots, E before reaching B.
\end{framed}

\item[1.1{-}5] Come up with a real-world problem in which only the best
  solution will do. Then come up with one in which a solution that is
  ``approximately'' the best is good enough.

\begin{framed}
In a competition, each candidate received a score for her/his performance. To
obtain the ranking list of the candidates, only the best sorting solution is
accepted. Approximated sorting algorithms are not feasible in this situation.

Recently, Facebook computed the approximate degree of separation between every
two people in the world. Since Facebook has billion of users, it would take too
long to compute the solution that takes into account all the connections between
all the users. Also, an approximate result is very feasible in this case. They
then used an approximate to get the result of 3.57.
\end{framed}

\end{enumerate}

\pagebreak

\section{Algorithms as a technology}

\begin{enumerate}

\item[1.2{-}1] Give an example of an application that requires
  algorithmic content at the application level, and discuss the function of the
  algorithms involved.

\begin{framed}
The search engines we have today involves a lot of complex algorithms to work.
It needs a ranking algorithm to sort the search results appropriately. It is
also important to use a crawler that systematically browses and indexes the web
content. During searching, this indexed content is gathered and filtered from
the database using sophisticated algorithms.
\end{framed}

\item[1.2{-}2] Suppose we are comparing implementations of insertion
  sort and merge sort on the same machine. For inputs of size $n$, insertion sort
  runs in $8 n^2$ steps, while merge sort runs in $64 n \lg n$ steps. For which
  values of $n$ does insertion sort beat merge sort?

\begin{framed}
For input values less than or equal to 43, insertion sort beats merge sort. We
can ignore the case where $n = 1$, since a single element is already sorted by
definition.
\end{framed}

\item[1.2{-}3] What is the smallest value of $n$ such that an algorithm
  whose running time is $100 n^2$ runs faster than an algorithm whose running
  time is $2^n$ on the same machine?

\begin{framed}
The smallest value of $n$ is 15.
\end{framed}

\end{enumerate}

\pagebreak

\section*{Problems}
\addcontentsline{toc}{section}{\protect\numberline{}Problems}%

\begin{enumerate}

\item[1{-}1] Comparison of running times. For each function $f(n)$ and
  time $t$ in the following table, determine the largest size $n$ of a problem
  that can be solved in time $t$, assuming that the algorithm to solve the problem
  takes $f(n)$ microseconds.

\begin{framed}
\centering
\footnotesize
\begin{tabular}{cccccccc}
  \toprule
  \multirow{2}{*}{$f(n)$} & \textbf{1} & \textbf{1} & \textbf{1} & \textbf{1} &
  \textbf{1} & \textbf{1} & \textbf{1}\\
  & \textbf{second} & \textbf{minute} & \textbf{hour} & \textbf{day} &
    \textbf{month} & \textbf{year} & \textbf{century}\\

  \midrule

  $\lg n$ & $2^{10^6}$ & $2^{10^7 \times 6}$ & $2^{10^8 \times 36}$ &
  $2^{10^8 \times 864}$ & $2^{10^9 \times 2592}$ &
  $2^{10^9 \times 31536}$ & $2^{10^{11} \times 31536}$ \\

  $\sqrt{n}$ & $10^{12}$ & $10^{14} \times 36$ & $10^{16} \times 1296$ &
  $10^{16} \times 746496$ & $10^{18} \times 6718264$ &
  $10^{18} \times 994519296$ & $10^{22} \times 994519296$ \\

  $n$ & $10^6$ & $10^7 \times 6$ & $10^8 \times 36$ &
  $10^8 \times 864$ & $10^9 \times 2592$ &
  $10^9 \times 31536$ & $10^{11} \times 31536$ \\

  $n \lg n$ & 62746 & 2801418 & 133378059 & 2755147513 & 71870856404 &
  797633893349 & 68610956750570 \\

  $n^2$ & $10^3$ & $7745$ & $10^4 \times 6$ & 293938 & 1609968 & 5615692 &
  561569229 \\

  $n^3$ & $10^2$ & 391 & 1532 & 4420 & 13736 & 31593 & 146645\\

  $2^n$ & 9 & 25 & 31 & 36 & 41 & 44 & 51\\

  $n!$ & 9 & 11 & 12 & 13 & 15 & 16 & 17\\

  \bottomrule
\end{tabular}
\end{framed}

\end{enumerate}


         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         % Information sheet for the Matlab lab - Maths 6111 %
         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[10pt]{article}
\input ma_no_html_header

\usepackage{color}
\usepackage{hyperref}
\hypersetup{breaklinks=true,colorlinks=true}
%\input ma_header
\setlength{\parindent}{0pt}
\pagestyle{myheadings}
% \markright{
% \protect {\protect \epsfxsize=0.2 true cm \protect \epsffile {dolph.line.eps}}
% \it Maths 3018/6111 - Numerical methods \hfill}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\thispagestyle{empty}
\begin{center}
\textbf{\Large Maths 3018/6111 - Numerical Methods \\*[8mm]
Worksheet 2 - Solutions}\\*[.8cm]
\end{center}

\section*{Theory}

\begin{enumerate}
\item Perform the $LU$ decomposition of
  \begin{equation*}
    A =
    \begin{pmatrix}
      1 & 3 \\ 4 & 16
    \end{pmatrix}.
  \end{equation*}
  Use both standard factorisation methods.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  Remember the general algorithm from Table 2.1 in the notes.

  We first assume the Doolittle factorization ($\ell_{kk} = 1$). We
  immediately get that
  \begin{align*}
    u_{11} & = \left( a_{11} - \sum_{s=1}^{0} \ell_{1s} u_{s1} \right) /
    \ell_{11} \qquad \text{(using $k=1$)} \\
    & = 1.
  \end{align*}
  We then build the first row of $U$ to get
  \begin{align*}
    u_{12} & = \left( a_{12} - \sum_{s=1}^{0} \ell_{1s} u_{s2} \right) /
    \ell_{11} \qquad \text{(using $k=1$)} \\
    & = 3.
  \end{align*}
  We then build the first column of $L$ to get
  \begin{align*}
    \ell_{21} & = \left( a_{21} - \sum_{s=1}^{0} \ell_{2s} u_{s1} \right) /
    \ell_{11} \qquad \text{(using $k=1$)} \\
    & = 4.
  \end{align*}
  Given the factorization we have that $\ell_{22} = 1$ and hence that
  \begin{align*}
    u_{22} & = \left( a_{22} - \sum_{s=1}^{1} \ell_{2s} u_{s2} \right) /
    \ell_{22} \qquad \text{(using $k=2$)} \\
    & = (16 - 4 \times 3) \\
    & = 4.
  \end{align*}
  Hence we have
  \begin{equation*}
    L =
    \begin{pmatrix}
      1 & 0 \\ 4 & 1
    \end{pmatrix}, \qquad U =
    \begin{pmatrix}
      1 & 3 \\ 0 & 4
    \end{pmatrix}.
  \end{equation*}
  Quickly check that
  \begin{align*}
    L U & = \begin{pmatrix}
      1 & 0 \\ 4 & 1
    \end{pmatrix}
    \begin{pmatrix}
      1 & 3 \\ 0 & 4
    \end{pmatrix} \\
    & = \begin{pmatrix}
      1 & 3 \\ 4 & 16
    \end{pmatrix} \\
    & = A.
  \end{align*}

  With the Crout factorization ($u_{kk} = 1$), we immediately get
  that
  \begin{align*}
    \ell_{11} & = \left( a_{11} - \sum_{s=1}^{0} \ell_{1s} u_{s1} \right) /
    u_{11} \qquad \text{(using $k=1$)} \\
    & = 1.
  \end{align*}
  We then build the first row of $U$ to get
  \begin{align*}
    u_{12} & = \left( a_{12} - \sum_{s=1}^{0} \ell_{1s} u_{s2} \right) /
    \ell_{11} \qquad \text{(using $k=1$)} \\
    & = 3.
  \end{align*}
  We then build the first column of $L$ to get
  \begin{align*}
    \ell_{21} & = \left( a_{21} - \sum_{s=1}^{0} \ell_{2s} u_{s1} \right) /
    \ell_{11} \qquad \text{(using $k=1$)} \\
    & = 4.
  \end{align*}
  Given the factorization we have that $u_{22} = 1$ and hence that
  \begin{align*}
    \ell_{22} & = \left( a_{22} - \sum_{s=1}^{1} \ell_{2s} u_{s2} \right) /
    u_{22} \qquad \text{(using $k=2$)} \\
    & = (16 - 4 \times 3) \\
    & = 4.
  \end{align*}
  Hence we have
  \begin{equation*}
    L =
    \begin{pmatrix}
      1 & 0 \\ 4 & 4
    \end{pmatrix}, \qquad U =
    \begin{pmatrix}
      1 & 3 \\ 0 & 1
    \end{pmatrix}.
  \end{equation*}
  Quickly check that
  \begin{align*}
    L U & = \begin{pmatrix}
      1 & 0 \\ 4 & 4
    \end{pmatrix}
    \begin{pmatrix}
      1 & 3 \\ 0 & 1
    \end{pmatrix} \\
    & = \begin{pmatrix}
      1 & 3 \\ 4 & 16
    \end{pmatrix} \\
    & = A.
  \end{align*}

  Note that in this case only one entry has changed; in general the
  different factorizations will give totally different answers.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item{} [Additional] Write out the Thomas algorithm for a tridiagonal
  system.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  We assume that the tridiagonal matrix $A$ has diagonal entries $b_i,
  i = 1, \dots, N$, sub-diagonal entries $a_j, j = 1, \dots, N-1$, and
  super-diagonal entries $c_j, j = 1, \dots, N-1$. We assume that we
  are trying to solve the problem
  \begin{equation*}
    A {\bf x} = {\bf f},
  \end{equation*}
  which has size $N$.

  The Thomas algorithm is essentially Gaussian elimination; forward
  elimination is used to get an upper triangular problem, and then
  back substitution used to find the answer. The tridiagonal nature of
  the problem means that it is sufficiently simple to write it out
  explicitly.

  The first step is the forward elimination process. This yields the
  system
  \begin{equation*}
    B {\bf x} = {\bf y},
  \end{equation*}
  where $B$ has entries only on the diagonal, and these entries are
  all 1, and on the super-diagonal, which are written as $c_j / d_j, j
  = 1, \dots, N-1$. The vectors ${\bf d}, {\bf y}$ are given by the
  procedure
  \begin{enumerate}
    %
  \item At the first step $d_1=b_1$ and $y_1=f_1/d_1$;
    %
  \item At the $k$-th step $d_k=b_k-a_{k-1}c_{k-1}/d_{k-1}$ and
    $y_k=(f_k-y_{k-1} a_{k-1})/d_k$.
  \end{enumerate}
  We can then solve this simplified system using back substitution to find
  \begin{enumerate}
  \item At the first step $x_N = y_N$;
  \item In reverse order, $k = N-1, \dots, 1$ we have
    $x_{k}=y_{k}-x_{k+1} c_{k}/d_{k}$.
  \end{enumerate}
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Write down the general framework for iterative methods for
  linear systems. Give the convergence matrix. If the linear system
  uses the matrix $A$ above, will an iterative method converge? [Hint:
  remember what to do with the diagonal entries]
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  The system to be solved is
  \begin{equation*}
    A {\bf x} = {\bf b},
  \end{equation*}
  with $\det(A) \ne 0$. \emph{We first scale the problem such that all
    diagonal entries of $A$ are 1}. We split the coefficient matrix
  $A$ into the matrices $N, P$, such that
  \begin{equation*}
    A = N - P
  \end{equation*}
  where $\det(N) \ne 0$. We therefore have that
  \begin{equation*}
    N {\bf x} = P {\bf x} + {\bf b}
  \end{equation*}
  and we use this to write an iteration scheme as
  \begin{equation*}
    N {\bf x}^{(n)} = P {\bf x}^{(n-1)} + {\bf b}, \qquad n = 1, 2, 3,
    \dots
  \end{equation*}
  where we start from some arbitrary initial guess ${\bf x}^{(0)}$.

  The convergence matrix $M$ is given by $M = N^{-1} P$. Convergence
  is guaranteed if the spectral radius of $M$ is less than one. For
  the matrix given in the first part we have the \emph{rescaled} $A$
  is
  \begin{equation*}
    A =
    \begin{pmatrix}
      1 & 3 \\ 1/4 & 1
    \end{pmatrix}.
  \end{equation*}
  Clearly to talk about convergence we need to first decide how to
  split $A$ into $N, P$ matrices. For simplicity we consider Jacobi's
  method for which $N = I$ and hence we have
  \begin{align*}
    N & =
    \begin{pmatrix}
      1 & 0 \\ 0 & 1
    \end{pmatrix}, \\
    P & =
    \begin{pmatrix}
      0 & -3 \\ -1/4 & 0
    \end{pmatrix}, \\
    M & = N^{-1} P \\
      & = P \\
      & =
    \begin{pmatrix}
      0 & -3 \\ -1/4 & 0
    \end{pmatrix}, \\
    \Rightarrow \qquad \rho(M) & = \max_i | \lambda_i | \\
    & = \max \left\{ \pm \sqrt{-3/4} \right\} \\
    & = \sqrt{3/4} \\
    & < 1.
  \end{align*}
  Therefore Jacobi will converge for this matrix.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Check which of the matrices on this sheet are diagonally
  dominant.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  For (strict) diagonal dominance we need the absolute value of the
  diagonal coefficient to be (strictly) greater than the sum of the
  absolute values of all other coefficients in the row.

  For $A$ this is not true; for the first row we have $1 \ngtr 3$,
  although dominance holds for the second row.

  For $B$ it is not true; for the second row we have $28 \ngtr 24 +
  53$, although dominance holds for the other rows.

  For $C$ it is not true; for the first row it fails, although
  dominance holds for the other rows.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item Briefly explain what is meant by quadrature methods based on
  polynomial interpolation.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  {\it Standard exam question; see, e.g., 07/08}.

  The function $f(x)$ to be integrated is replaced by an interpolating
  function, in this case a polynomial of degree $n$, that interpolates
  it at $n+1$ \emph{nodes} $x_j$, $j=0,1,\ldots,n$. In general, when
  constructing a compound quadrature formula, we may split the
  interval into subintervals, each subinterval containing $n+1$ nodes,
  and use a polynomial interpolating function on each subinterval. The
  integral of the function is approximated by the integral of the
  (piecewise polynomial) interpolating function.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\item{} [3018 only] Write down the contraction mapping theorem. Check
  that $g(x) = \cos(x)$ is contracting on the unit interval.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
  The contraction mapping theorem is
  \begin{quote}
    If $g(x)$ is a contraction mapping in an interval $I=[a,b]$ then
    there exists one and only one fixed point of the map in $[a,b]$.
  \end{quote}
  In order to state we need the definition of a contraction mapping,
  which is
  \begin{quotation}
    \textbf{Definition} - A continuous map $g(x)$ from an interval
    $I=[a,b] \subseteq \bR$ into $\bR$ is \textit{contracting} (or a
    \emph{contraction mapping}) if
    %
    \begin{enumerate}
      %
    \item the image of $I$ is contained in $I$:
      %
      \begin{align*}
        g(I) & \subseteq I \\
        \Leftrightarrow \quad g(x) & \in I \, \forall x \in I .
      \end{align*}
      %
    \item the function $g(x)$ is Lipschitz continuous in $I$ with
      Lipschitz constant $L < 1$:
      %
      \begin{equation*}
        | g(x) - g(y) | \le L | x - y | \quad \forall x,y \in I .
      \end{equation*}
    \end{enumerate}
  \end{quotation}

  Given this we want to check $g(x) = \cos(x)$ on $I = [0, 1]$. We
  have that $g$ is continuous and differentiable, so it must be
  Lipschitz continuous. We know that $L < \max_{x \in I} |g'(x)|$ so
  we look at $g' = -\sin(x)$. We note that the extrema of $g'$ occur
  when $g'' = - \cos(x) = 0$ which is at $x = (n+1/2)\pi$, of which
  none occur in the interval $[0, 1]$. We also note that $g'$ is
  monotonic on the interval. Therefore the extreme values of $g'$ are
  taken at the ends of the interval and are $[0, -\sin(1)]$, which are
  both less than 1 in absolute value. So $L<1$.

  We also need to check that $g(I) \subseteq I$. Again we note that
  $g$ is monotonic on the interval. Hence we only need to check that
  $g(0) = 1 \in I$ and $g(1) = \cos(1) \in I$, both of which
  hold. Therefore the map is contracting.
  %
  \begin{center}
    \rule{0.9\textwidth}{.1pt}
  \end{center}
  %
\end{enumerate}

\end{document}


 \documentclass [12pt]{article}

\usepackage {amsmath}
\usepackage {amsthm}
\usepackage {amssymb}
\usepackage {graphicx}
\usepackage {float}
\usepackage {multirow}
\usepackage {xcolor}
\usepackage [ruled,vlined,commentsnumbered,titlenotnumbered]{algorithm2e} \usepackage {array}
\usepackage {booktabs}
\usepackage {url}
\usepackage {parskip}
\usepackage [margin=1in]{geometry}
\usepackage [T1]{fontenc}
\usepackage {cmbright}
\usepackage [many]{tcolorbox}
\usepackage [colorlinks = true,
            linkcolor = blue,
            urlcolor  = blue,
            citecolor = blue,
            anchorcolor = blue]{hyperref}
\usepackage {enumitem}
\usepackage {xparse}
\usepackage {verbatim}
\usepackage{algpseudocode}
\usepackage{listings}
\usepackage{xcolor}
\lstset { %
    language=C++,
    backgroundcolor=\color{black!5}, % set backgroundcolor
    basicstyle=\footnotesize,% basic font setting
}
\newtheorem{theorem}{Theorem}
\newtheorem{remark}{Remark}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\theoremstyle{definition}
\newtheorem{definition}{Definition}[section]
\newtheorem{claim}{Claim}
\newtheorem{proposition}{Proposition}

\DeclareTColorBox {Solution}{}{breakable, title={Solution}} \DeclareTColorBox {Solution*}{}{breakable, title={Solution (provided)}} \DeclareTColorBox {Instruction}{}{boxrule=0pt, boxsep=0pt, left=0.5em, right=0.5em, top=0.5em, bottom=0.5em, arc=0pt, toprule=1pt, bottomrule=1pt} \DeclareDocumentCommand {\Expecting }{+m}{\textbf {[We are expecting:} #1\textbf {]}} \DeclareDocumentCommand {\Points }{m}{\textbf {(#1 pt.)}}

\begin {document}

\vspace {1em}
\begin {Instruction}
Adapted From Virginia Williams'lecture notes.
\end {Instruction}

{\LARGE \textbf {COMP 285 (NC A\&T, Spr `22)}\hfill \textbf {Lecture 33} }

\begin{centering}
\section*{Max Flows and Mininum Cuts}
\end{centering}

\section{Formulation of the Maximum Flow Problem}

You are given an input graph $G = (V, E)$, where the edges are directed. There is a function $c : E \to R\geq 0$ that defines the capacity of each edge. We also label two nodes in $G$, $s$ and $t$, as the source and destination, respectively. The task is to output a flow of maximum value. We will shortly define what a flow is and what a flow of maximum value means.

A flow $f$ is a function $f : E \to R\geq 0$ such that
\begin{enumerate}
    \item Capacity constraints are satisfied:
    $$
        \forall (u, v ) \in E : 0 \leq f (u, v ) \leq c(u, v )
    $$.
    \item Flow conservation constraints are satisfied:
    $$
    \forall v \in V \setminus \{s, t\} : \sum_{x \in N_{\text{in}}(v)} f (x, v ) = \sum_{y\ in N_{\text{out}}(v)} f (v, y )
    $$
    Here $N_{\text{in}}(v )$ denotes the set of nodes with an edge that points to $v$ and $N_{\text{out}}(v )$ denotes the set of nodes that $v$ points to.
\end{enumerate}

\begin{figure}[h!]
    \centering
    \includegraphics[scale=0.6]{max_flow_ex.png}
    \caption{(Left) Graph $G$ with edge capacities (Right) Graph $G$ with a sample flow.}
    \label{fig:max_flow_ex}
\end{figure}

Suppose that there are no edges going into $s$ and no edges coming out of $t$. From the above, you can verify yourself that $\sum_{x \in N_{\text{out}}(s)} f (s, x) = \sum_{y \in N_{\text{in}}(t)} f (y, t)$. We define the value $x \in N_{\text{out}}(s) f (s, x)$ to be the value of the flow $f$ . We usually denote the value of a flow $f$ as $|f |$. If there are edges going into $s$ and out of $t$, then the value of $f$ is $$
|f | = \sum_{x \in N_{\text{out}}(s)} f (s, x) - \sum_{ y \in N_{\text{in}}(s)} f (y, s)
$$.

The max flow problem is to find some flow f such that $|f |$ is maximized. Remark 1. In the analysis below we consider graphs with a single source s and a single sink t. However, if we need to work with a graph with multiple sources, we can do so by adding a new source node, and then adding edges with capacity infinity from it to each of the multiple sources. Similarly, if we want to have multiple sinks, we add a new sink node and add edges from the multiple sinks to that sink with capacity infinity.

\section{Example}

In Fig. \ref{fig:max_flow_ex}, we have a graph $G$ and a sample flow $f$ . Observe that the two constraints for a flow are satisfied. There can be multiple other flows possible that can satisfy the constraints. For our given flow, $|f | = 16$. The max flow for this graph is actually $18$, as we will see shortly.

\section{Formulation of the Minimum Cut Problem}

Now, we give a formulation of the min cut problem defined for directed graphs with source and destination nodes $s$ and $t$. Note that there is also a version of the min cut problem without a source and sink node, though we won't discuss that now. An s-t cut is a partition $V = S \cup T$ where $S$ and $T$ are disjoint and $s \in S, t \in T$, and the size/cost of an s-t cut is $c(S, T) := \sum_{x\in S, y\in T} c(x, y )$.

For our graph $G$ shown above, if we set$ S = \{s, a, c\}$ and $T = \{b, t\}$, then the cost of the cut is $c(a, b) + c(c, b) + c(c, t) = 5 + 3 + 10 = 18$. If we take another cut $S
' = \{s, c\}, T' = \{a, b, t\}$, then $c(S', T') = c(s, a) + c(c, b) + c(c, t) = 10 + 3 + 10 = 23$. Note that we do
not consider the edge $\{a, c\}$ as it is in the wrong direction (we only consider edges from $S'$ to $ T'$).

\section{The Max-Flow Min-Cut Theorem}

\begin{lemma}
For any flow $f$ and any s-t cut $(S, T)$ of $G$, we have $|f | \leq c(S, T)$. In particular,the value of the max flow is at most the value of the min cut.
\end{lemma}

\begin{proof}

\begin{align*}
|f| &= \sum_{x \in N_{\text{out}}(s)} f(s,x) - \sum_{y \in N_{\text{in}}(s)} f(y,s) \\
&=\sum_{v \in S} \left(\sum_{x \in N_{\text{out}}(v)} f(v,x) - \sum_{y \in N_{in}(v)} f(y,v) \right) \tag{by flow conservation constraing for $v \neq s$} \\
&=\sum_{v \in S} \left(\sum_{x \in N_{\text{out}}(v) \cap S} f(v,x) - \sum_{y \in N_{in}(v) \cap S} f(y,v) \right) + \sum_{v \in S} \left(\sum_{x \in N_{\text{out} \cap T}(v)} f(v,x) - \sum_{y \in N_{in}(v) \cap T} f(y,v) \right) \\
&=\sum_{v \in S} \left(\sum_{x \in N_{\text{out} \cap T}(v)} f(v,x) - \sum_{y \in N_{in}(v) \cap T} f(y,v) \right) \tag{first term sums to $0$} \\
&\leq \sum_{v \in S, x \in T, x \in N_{\text{out}}(v)} f(v,x) \\
&=\leq \sum_{v \in S, x \in T, x \in N_{\text{out}}(v)} c(v,x) \\
&= c(S,T)
\end{align*}

In the proof, $\sum_{v \in S} \left(\sum_{x\in N_{\text{out}}(v)} f(v,x) - \sum_{y\in N_{\text{int}}(v)} f(y,v)\right) = 0$ since we add and subtract the flow $f (u, v )$ for every $u, v \in S$ such that $(u, v ) \in E$.
\end{proof}

We get the following consequence.

\begin{corollary}
If we can find $f$ and $(S,T)$ such that $|f| = c(S,T)$ then $f$ is a max-flow and $(S,T)$ is a min s-t cut.
\end{corollary}

It turns out we can always find such an $f$ and $(S,T)$ for any graph.

\begin{theorem}{Max-Flow Min-cut Theorem}
For any graph $G$, source $s$ and destination $t$, the value of the max flow is equal to the cost of the min cut
\end{theorem}

We will show this by coming up with an algorithm. The algorithm will take the graph $G$ and some flow $f$ that has already been constructed, and create a new graph that is called the residual graph. In this new graph, the algorithm will try to find a path from s to t. If no such path exists, we will show that the value of the flow we started with is the value of the maximum flow. If not, we show how to increase the value of our flow by pushing some flow
on that path.

\begin{figure}[h!]
\centering
\includegraphics[scale=0.6]{max_flow_res.png}
\caption{The Residue network given the flow presented in Figure \ref{fig:max_flow_ex}}
\label{fig:max_flow_res}
\end{figure}

\section{The Ford-Fulkerson Max-Flow Algorithm}

We will make an assumption on our graph. The assumption can be removed, but it will make our lives easier. We will assume that for all $u, v \in V$ , $G$ does not have both edges $(u, v )$ and $(v, u)$ in $E$. We can make this condition hold by modifying the original graph in the following way. If $(u, v ), (v, u) \in E$, we split the edge $(u, v )$ to two edges $(u, x)$ and $(x, v )$, where $x$ is a new node we introduce into the graph. This makes the number of nodes at most $m + n$.

Now, let $f$ be a flow given to us. We will try to see if we can improve this flow. We will define the residual capacity $c_f : V \times V \to R_{\geq 0}$ as follows.

$$
c_f (u, v ) = \begin{cases}
    c(u, v ) - f (u, v ) & \text{if }(u, v ) \in E \\
    f (v, u) & \text{if }(v, u) \in E \\
    0 & \text{ otherwise. }
\end{cases}
$$

Basically, what this does is that, if there is any flow through the edge, you remove the flow from the capacity and add an edge in the opposite direction with the value of the flow. The reason we do this is because the flow we picked thus far might not be the correct flow, and this formulation allows us to undo changes that we have done through ``adding flow'' in the revere direction. The residual capacity $c_f (u, v )$ represents how much flow we can send from $u$ to $v$ in addition to the flow $f$.

We define $G_f$ to be a residual network defined with respect to $f$ , where $V (G_f ) = V (G)$ and $(u, v ) \in E(G_f )$ if $c_f (u, v ) > 0$. Figure \ref{fig:max_flow_res} shows $G$ with the residual edges. We will show that, if there is a path from $s$ to $t$ in $G_f$ , then $f$ is not a max flow. If no such path exists, that $f$ is a max flow.

\begin{lemma}
If $t$ is not reachable from $s$ is $G_f$ , then $f$ is a maximum flow.
\end{lemma}
\begin{proof}
Let $S$ be the set of nodes reachable from $s$ in $G_f$ and $T = V \setminus S$. There are no edges in $G_f$ from $S$ to $T$ since the nodes in $T$ are not reachable from $s$. Note that $(S, T)$ defines an $s-t$ cut. Now consider any $v \in S, w \in T$. We have $c_f (v, w) = 0$ since $(v, w)$ is not an edge in $G_f$ . There are three cases:
\begin{enumerate}
    \item If $(v, w) \in E$, then by definition $c_f (v, w) = c(v, w) - f (v, w) = 0 \implies c(v, w) = f (v, w)$\item If $(w, v ) \in E$, then $c_f (v, w) = f (w, v ) = 0$.
    \item If $(v, w) \notin E and (w, v ) \notin E$, we can disregard $(v, w)$ and $(w, v )$ since they do not appear in any flow or cut.
\end{enumerate}

 Using this, and the proof in Lemma 2, we have
 \begin{align*}
 |f | &= \sum_{v\in S} \left( \sum_{x\in N_{\text{out}(v)} \cap T} f (v, x) - \sum_{y\in N_{\text{in}}(v) \cap T} f (y, v ) \right) \\
 &= \sum_{v\in S} \sum_{x\in N_{\text{out}(v)} \cap T} f (v, x) \tag{from case 2 the second term is 0} \\
 &= \sum_{v\in S} \sum_{x\in N_{\text{out}(v)} \cap T} c(v, x) \tag{from case 1}\\
 &= c(S, T)
 \end{align*}

 Thus, we show that the flow is equal to the cut. From Corollary 3 we know that $f$ is a maximum flow, and $(S, T)$ is a min cut.
\end{proof}

\begin{lemma}
If $G_f$ has a path from $s$ to $t$, we can modify $f$ to $f'$ such that $|f | < |f'|$.
\end{lemma}
\begin{proof}

Pick a path $P$ from $s$ to $t$ in $G_f$ , and consider the edge of minimum capacity on the path. Let that capacity be $F$ . Then we can increase our flow by $F$ . For each edge in $P$, if $c_f (v, w)$ is the right direction (i.e., there is an edge $(v, w) \in E(G)$), then we can increase our flow on this edge by $F$ . If $c_f (v, w)$ is in the opposite direction (i.e., $(w, v ) \in E(G)$), then we can decrease the flow on this edge by $F$ . In effect, we are ``undoing'' the flow on this edge. By doing so, we have increased our flow by $F$.

As an example, consider Fig. \ref{fig:max_flow_res} again. The path $s \to a \to c \to b \to t$ is a path with minimum capacity $2$. Therefore, we can update our flow and push additional $2$ units of flow, resulting in a flow of $18$.

Formally, Let $s = x_0 \to x_1 \to ... \to x_k = t$ be a simple path $P$ in $G_f$ , and let $F = \min_i c_f (x_i , x_{i+1})$. Define a new flow $f'$ where
$$
f' (u, v ) = \begin{cases}
    f (u, v ) + F & \text{ if }(u, v ) \in P\\
    f (u, v ) - F & \text{ if }(v, u) \in P \\
    f (u, v ) & \text{ otherwise }.
    \end{cases}
$$

We now need to show that $f'$ is a flow. The capacity constraints are satisfied because for every $(u, v ) \in E$,
\begin{enumerate}
    \item If $(u, v ) \in P$, then $0 \leq f (u, v ) + F \leq f (u, v ) +c_f (u, v ) = f (u, v ) +c(u, v )-f (u, v ) = c(u, v )$.
    \item If $(v, u) \in P$, then $f (u, v ) - F \leq f (u, v ) \leq c(u, v )$ and $f (u, v ) - F \geq f (u, v ) - c_f (v, u) = 0$.
    \item Otherwise, $f (u, v )$ is from the original flow $f$ .
\end{enumerate}

The conservation constraints are also satisfied: Recall that $P$ is a simple path. Thus, for every $v \in V \setminus \{s, t\}$, $P$ uses $0$ or two edges incident on $v$ . If $P$ uses $0$ edges on $v$, then flow values of the edges incident on $v$ have not changed when going from $f$ to $f'$ . Thus, suppose that $P$ uses two edges $(x, v )$ and $(v, y )$ incident on $v$. Because in $G_f$ some edges appear in the opposite direction compared to $G$, we need to consider a few cases.

\begin{enumerate}
    \item $(x, v )$ and $(v, y )$ are both in the same direction (an edge into $v$ and an edge out of $v$ ); the flow into $v$ increases by $F$ and the flow out of it also increases by $F$ .
    \item $(x, v )$ and $(v, y )$ are both in the opposite direction $((v, x), (y, v ) \in E$); the flow into $v$ decreases by $F$ and the flow out of it also decreases by $F$ .
    \item $(x, v )$ is in the correct direction and $(v, y )$ is in the opposite direction. Then the flow into $v$ changes by $F - F = 0$.
    \item $(x, v )$ is in the opposite direction and $(v, y )$ is in the correct direction. Then the flow out of $v$ changes by $F - F = 0$.
\end{enumerate}

Finally, note that we increase our flow by $F$ . Consider the edge $(s, x_1)$ in $P$. If $(s, x_1) \in E$, the flow out of $s$ increases by $F$ . If $(x_1, s) \in E$, the flow into s decreases by $F$ . By our definition of $G_f$ , it must be that $F > 0$, and we get that $|f'| > |f |$.
\end{proof}

From this, we can construct an algorithm to find the maximum flow. Starting with some arbitrary flow of the graph, construct the residual network, and check if there is a path from $s$ to $t$. If there is a path, update the flow, construct the new residual graph and repeat. Otherwise, we have found the max flow.

A path from $s$ to $t$ in the residual graph is called an augmenting path, and pushing flow through it to modify the current flow is referred to as augmenting along the path.

The run time of this algorithm is bounded by the number of times we update our flow. If the edge capacities are all integers, we can increase the flow by at least 1 each time we update our flow. Therefore, the runtime is $O(|f |m)$ where $|f |$ is the value of the max flow. If we have rational edge capacities, then we can multiply all edge capacities by a factor to make them all integers. However, the runtime blows up by that factor as well. If we have irrational edge capacities, then the algorithm is no longer guaranteed to terminate. So we have a problem.

\begin{algorithm}
\caption{maxflow($G,s, t$)}
\label{alg:maxflow_algorithm}
\begin{algorithmic}
\State $f \gets$ all zeros flow
\State $G_f \gets G$
\State \While{$t$ is reachable from $s$ in $G_f$ (check using DFS/BFS)}{
    \State $P \gets$ path in $G_f$ from $s$ to $t$
    \State $F \gets$ min capacity on $P$
    \State $f \gets f'$ as defined in Lemma 5 above.
    \State Update $G_f$ to the corresponding new flow.
}
\State \Return $f$
\end{algorithmic}
\end{algorithm}

We will save the day in the next sections. Algorithm \ref{alg:maxflow_algorithm} is called the Ford-Fulkerson method.

It is actually part of a family of algorithms that depend on how the path $P$ between $s$ and $t$ in $G_f$ is selected. One can obtain $P$ via DFS, BFS, or any other method for selecting paths. It turns out that two methods work particularly well: the shortest path method and the fattest path method. The shortest path method is known as the Edmonds-Karp algorithm or Dinic's algorithm.

\textbf{The fattest path method.} This method finds a path between $s$ and $t$ that maximizes $\min_{e \in P} c_f (e)$ among all $s-t$ paths $P$. Finding such a path can be done in $O(m + n)$ time by a clever mix of linear time median-finding and $DFS$.

\textbf{The shortest path method (the Edmonds-Karp algorithm/Dinic's algorithm)}. This method picks the path between $s$ and $t$ using BFS, thus picking a path that minimizes the number of edges. Finding such a path also runs in $O(m)$ time: BFS takes $O(m + n)$ to explore the whole graph, but since we only care about the vertices reachable from $s$ this is $O(m)$ time.

Since both methods of selecting a path run in linear time, the main question becomes, how many iterations does Ford-Fulkerson perform? We will answer these questions below in the next section.

\end{document}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% ICML 2013 EXAMPLE LATEX SUBMISSION FILE %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Use the following line _only_ if you're still using LaTeX 2.09.
%\documentstyle[icml2013,epsf,natbib]{article}
% If you rely on Latex2e packages, like most moden people use this:
\documentclass{article}

% For figures
\usepackage{graphicx} % more modern
%\usepackage{epsfig} % less modern
\usepackage{subfigure}

% For citations
\usepackage{natbib}

% For algorithms
\usepackage{algorithm}
\usepackage{algorithmic}

% As of 2011, we use the hyperref package to produce hyperlinks in the
% resulting PDF.  If this breaks your system, please commend out the
% following usepackage line and replace \usepackage{icml2013} with
% \usepackage[nohyperref]{icml2013} above.
\usepackage{hyperref}

% Packages hyperref and algorithmic misbehave sometimes.  We can fix
% this with the following command.
\newcommand{\theHalgorithm}{\arabic{algorithm}}

% Employ the following version of the ``usepackage'' statement for
% submitting the draft version of the paper for review.  This will set
% the note in the first column to ``Under review.  Do not distribute.''
\usepackage{icml2013}
% Employ this version of the ``usepackage'' statement after the paper has
% been accepted, when creating the final version.  This will set the
% note in the first column to ``Proceedings of the...''
% \usepackage[accepted]{icml2013}

% The \icmltitle you define below is probably too long as a header.
% Therefore, a short form for the running title is supplied here:
\icmltitlerunning{Building Multi-Class Models with the Iris Dataset}

\begin{document}

\twocolumn[
\icmltitle{Building Multi-Class Models with the Iris Dataset}

% It is OKAY to include author information, even for blind
% submissions: the style file will automatically remove it for you
% unless you've provided the [accepted] option to the icml2013
% package.
\icmlauthor{Carl Cortright}{carl.cortright@colorado.edu}
\icmladdress{University of Colorado Boudler}
\icmlauthor{Your CoAuthor's Name}{email@coauthordomain.edu}

% You may provide any keywords that you
% find helpful for describing your paper; these are used to populate
% the "keywords" metadata in the PDF but will not be shown in the document
\icmlkeywords{boring formatting information, machine learning, ICML}

\vskip 0.3in
]

\section{Introduction}

One of the classic example data sets in machine learning is the Iris dataset. This dataset contains three different species of iris, each entry with a measurement of sepal length and width and pedal length and width. For this project, I split the Iris dataset in to two, one for testing and one for training. Then, I trained two different models, one using a custom naive bayes algorithm and the other using vowpal wabbit. Later we compare the two models for accuracy and explain some flaws in our experiment.

\section{Naive Bayes Analysis}

\subsection{Experimental Setup}

For this experiment, I used a python script to train a model on various sized datasets. Then, using the rest of the iris model, I tested for accuracy. I also used basic "Add 1" smoothing to account for features that weren't seen in training.  The naive bayes algorithm used, uses log space multiplication to simplify the expression\\

$P(C) \prod_{i=0}^n P(X_i | C) = log(P(C)) + log(P(X_0|C)) + ... + log(P(X_n|C)$

\subsection{Results}

Shuffling the dataset between runs, I computed the accuracy based on different ratios of training:test data. With ratios ranging from 1:1 to 15:1 , I ran 5000 tests on each ratio to calculate the average accuracy, producing figure 1.

\begin{figure}[!ht]

\caption{The blue line represents best fit, and the ratio is the number on the x-axis:1 (training:test)}
\includegraphics[width=\columnwidth]{figure_1.png}

\end{figure}

As expected, the larger the training set, the more accurate the model. As we approach the full size of the dataset, the accuracy appears to approach somewhere around 91 percent, a decent result for naive bayes. With a larger dataset, the accuracy could likely be increased.

\section{Vowpal Wabbit Analysis}

\subsection{Experimental Setup}

To set up VW, I shuffled the iris dataset and put it in two separate files, one for training and one for testing. Then, I used the scripts given to us to train and test the dataset using vowpal wabbit. Afterwards, I used a custom python script to calculate the accuracy of the model.

\subsection{Results}

After training my model with VW, I was able to get an accuracy of 100 percent using a similar ratio to that used in the naive bayes model. This makes sense, a model like vowpal wabbit that uses logistic regression rather than naive bayes normally performs better.

\section{Conclusion}

For this project, I used the iris dataset to create two different multi-class models to predict flower type. Based on the experiments I ran, I determined that vowpal wabbit is a superior method to naive bayes for predicting class using this dataset. Overall, our predictions weren't very accurate. We did show that the more training examples, the better the model that resulted. In order to create a more robust system with either method, we would likely need a larger dataset to train on.

\section{Software and Data}

Vowpal Wabbit\\ https://github.com/JohnLangford/vowpal_wabbit\\
Iris Dataset\\ https://archive.ics.uci.edu/ml/datasets/Iris\\

% In the unusual situation where you want a paper to appear in the
% references without citing it in the main text, use \nocite
\nocite{langley00}

\end{document}

% This document was modified from the file originally made available by
% Pat Langley and Andrea Danyluk for ICML-2K. This version was
% created by Lise Getoor and Tobias Scheffer, it was slightly modified
% from the 2010 version by Thorsten Joachims & Johannes Fuernkranz,
% slightly modified from the 2009 version by Kiri Wagstaff and
% Sam Roweis's 2008 version, which is slightly modified from
% Prasad Tadepalli's 2007 version which is a lightly
% changed version of the previous year's version by Andrew Moore,
% which was in turn edited from those of Kristian Kersting and
% Codrina Lauth. Alex Smola contributed to the algorithmic style files.


\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{enumerate}
\usepackage{amssymb}
\usepackage{graphicx}

\title{Proiect SDA}
\author{Dragos-Gabriel Danciulescu}
\date{May 2022}

\begin{document}

\maketitle

\section*{Example Exercise}

Use the baby-step giant-step method to find x such that   $$ 5^{x} \equiv 107 \bmod{179} $$. Pick m = $\lfloor\sqrt{89}\rfloor$.Copy, extend and fill the
appropriate tables.\\
\begin{enumerate}[a.]
    \item
We will create the Baby steps table in which $g=5$ for $i$ up to $9$:\\
\begin{tabular}{ |c|c|c|c|c|c|c|c|c|c|c| }
 \hline
 i & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 \\
 \hline
 $5^i \bmod 179$ & 1 & 5 & 25 & 125 & 88 & 82 & 52 & 81 & 47 &  56\\
 \hline

\end{tabular}
\\
Next, we note that:\\
$g^{-\sqrt{89}}=5^{-9}=56^{-1}=16 \bmod 179$\\
So, $h \cdot g^{-mj} = 107 \cdot 16^j$\\
Now,we will create the Giant steps table. Note that in the algorithm, these values are not stored in memory like the ones in the first table.\\
\begin{tabular}{ |c|c|c|c| }
 \hline
 j & 0 & 1 & 2\\
 \hline
 $107 \cdot 16^j \bmod 179$ & 107 & 101 & 5\\
 \hline

\end{tabular}
We can now observe that we've found a match, for $i=1$ and $j=2$.\\
So,following the theory:\\
$g^{i+m \cdot j}=h$\\
$5^{1+9 \cdot 2}=107$\\
$5^{19} \bmod 179 = 107$\\
We've also checked the value with Wolfram Alpha, it is correct, so:\\
$x=19$\\

\end{enumerate}

\section*{Notebook Examples and Theory}
\begin{figure}
  \includegraphics[width=\textwidth]{GCD.png}
  \caption{Extended Euclidean algorithm notebook example}
  \label{fig:D_P}
 \end{figure}

\begin{figure}
  \includegraphics[width=\textwidth]{BSGS.png}
  \caption{Baby-Step Giant-Step notebook example}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{theory_gcd.png}
  \caption{Greatest Common divisor}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{euclidean.png}
  \caption{Euclidean algorithm}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{EEA.png}
  \caption{Extended euclidean algorithm}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{Invertibility.png}
  \caption{Computing inverse using Euclid's algorithm}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{DiscreteLog.png}
  \caption{The discrete log problem in cryptography}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{TheoryBSGS.png}
  \caption{Explanation of Baby-Step Giant-Step algorithm}
  \label{fig:D_P}
\end{figure}

\begin{figure}
  \includegraphics[width=\linewidth]{Discussion.png}
  \caption{A discussion about BSGS}
  \label{fig:D_P}
\end{figure}

\end{document}


\(\today\)

\section{In the morning}\label{in-the-morning}

\begin{itemize}
\tightlist
\item
  Eat eggs
\item
  Drink coffee
\item
  inf:
\item
  \(\infty\)
\item
  today:
\item
  \(\today\)
\end{itemize}

\(\today\)

\section{In the evening}\label{in-the-evening}

\begin{itemize}
\tightlist
\item
  Eat spaghetti
\item
  Drink wine
\end{itemize}

\section{Conclusion}\label{conclusion}

\begin{itemize}
\tightlist
\item
  And the answer is\ldots{}
\item
  \(f(x)=\sum_{n=0}^\infty\frac{f^{(n)}(a)}{n!}(x-a)^n\)
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Part of EBESS and MESS Presentation: Learn to LaTeX 2019
% Prepared by JT
% March 2019
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[]{article}
\usepackage{amsmath}
\begin{document}

\section{Introduction}
\label{sec:intro}

% this is how we use equation referencing
In Section \ref{sec:method}, we \ldots

\section{Test section}

\section{Method}
\label{sec:method}

\begin{equation}
    \label{eq:euler}
    e^{i\pi} + 1 = 0
\end{equation}

By \eqref{eq:euler}, we have \ldots
\end{document}


\documentclass{article}
\usepackage{graphicx}
\usepackage{marvosym}
\usepackage{dingbat}

\title{Prefix Scan}
\date{}

\begin{document}
\maketitle

\section{Sequential and parallel Prefix Scan}

Prefix Scan is an operation that computes all the partial sums of a
vector of values. Given an array, the result of this operation is an
array where each element is the sum of the preceding elements in the
original vector up to the corresponding position. There are two
versions of prefix scan: inclusive and exclusive. For an inclusive
scan, the result is the sum of all preceding values, as well as the
value of the element in the position under consideration. Therefore,
the value of coefficient $i$ in the result vector is equal to the sum
of all the values $1,2,...,i$ in the original vector. The exclusive
version does not include the value of the vector element at the
position of interest. Therefore, the value of coefficient $i$ in the
result vector is equal to the sum of all the values $1,2,...,i-1$ in
the original vector. Here is an example of these two variants:

\vspace{0.3cm}

\noindent\includegraphics[width=\textwidth]{prefscan_seq}

\vspace{0.3cm}

Both variants are commonly implemented {\it in-place} which mean that
the result is stored in the input array. {\bf The objective of this
exercise is to implement a parallel version of the inclusive prefix
scan using OpenMP}.

The sequential version of the inclusive prefix scan is extremely
simple and consists of the following lines of code
\begin{verbatim}
  for(i=1; i<l; i++)
    pref[i] = pref[i]+pref[i-1];
\end{verbatim}

As you can see, the above loop cannot be parallelized with a simple
\texttt{\#pragma omp parallel for} directive because of a loop-carried
dependency (iteration \texttt{i} uses the result of iteration
\texttt{i-1}). For this reason a more complicated algorithm has to be
used; this methods consists of the following 5 steps:
\begin{enumerate}
\item the initial vector is split into four chunks (parts) of roughly
  the same size and each chunk is assigned to one thread;
\item each thread computes the inclusive prefix scan of the chunk it
  was assigned;
\item each thread copies the last element of its local result into the
  corresponding location of a temporary array \texttt{loc\_last}
  (i.e., thread number 0 will copy the value in \texttt{loc\_last[0]},
  thread number 1 in \texttt{loc\_last[1]} etc.);
\item {\bf one} thread (it can be the master as well as any other
  thread, but only one) computes the {\bf exclusive} prefix scan of
  the \texttt{loc\_last} array;
\item each thread sums the corresponding element of the resulting
  \texttt{loc\_last} array into its own chunk.
\end{enumerate}

Here is an example of how this algorithm is applied to the vector in
the previous figure when the number of threads is equal to 4:

\vspace{0.3cm}

\noindent\includegraphics[width=\textwidth]{prefscan_par}

\section{Package content}

The \texttt{PrefixScan} directory contains a single file named
\texttt{prefixscan.c}.
This file contains:
\begin{itemize}
\item a sequential inclusive prefix scan routine
  \texttt{prefix\_inc\_seq} that takes two arguments:
  \begin{enumerate}
  \item an integer \texttt{l} containing the length of the array whose
    prefix scan has to be computed;
  \item a reference \texttt{*pref} of the array whose
    prefix scan has to be computed;
  \end{enumerate}
\item a sequential exclusive prefix scan routine
  \texttt{prefix\_exc\_seq} with the same
  interface as the inclusive routine;
\item the declaration of the parallel inclusive prefix scan routine
  \texttt{prefix\_inc\_par} (at the beginning the routine is empty and
  the objective of the exercise is to write it);
\item a main program that creates a vector, fills it with random
  numbers, computes the inclusive prefix scan with both the sequential
  and the parallel version and finally checks that the result of the
  parallel version is the same as that of the sequential one.
\end{itemize}

The code can be compiled with the \texttt{make} command: simply type
\texttt{make} int the \texttt{PrefixScan} directory. This will
generate an executable \texttt{main} file that can be run like this
\begin{verbatim}
$ ./main l
\end{verbatim}
where l is the length of the array whose prefix scan has to be
computed. Obviously, at the beginning the execution of the main
program will report an error because the parallel version is not
implemented.

\section{Assignment}
\begin{itemize}
\item {\huge \Keyboard} Implement the parallel inclusive prefix scan
  algorithm described above using OpenMP inside. Compile and run the code
  with 1, 2 and 4 threads to check the correctness of your parallel
  implementation.
\item \smallpencil Did you observe any speedup (reduction of the
  execution time) when using 2 or 4 threads instead of 1? If not, how can
  you explain this? report your comments in the \texttt{responses.txt}
  file.
\end{itemize}

\paragraph{Advice.}
\begin{itemize}
\item Note that inside the empty initial version of the parallel
  routine, the \texttt{loc\_last} array is already declared of size
  \texttt{MAXTHREADS} (equal to 16). Clearly you only have to use the
  first \texttt{nth} elements where \texttt{nth} is the number of
  threads in your parallel region.
\item Pay attention to the synchronization between threads.
\item Note that the original vector is only logically partitioned into
  chunks: this means threads don't have to allocate memory for storing
  the local chunks but that each thread simply has to identify the
  first element and the length of its own local chunk.
\item Use the \texttt{prefix\_inc\_seq} sequential routine to compute
  the inclusive prefix scan on the local chunks as described in step 2
  of the parallel algorithm. Use the \texttt{prefix\_exc\_seq} routine
  to compute the exclusive prefix scan of the \texttt{loc\_last} array
  as described in step 4 of the parallel algorithm.
\item Compile with \texttt{make main\_dbg} to get some messages useful
  for debugging.
\end{itemize}

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End: