% Standard Article Definition
\documentclass[]{article}

% Page Formatting
\usepackage[margin=1in]{geometry}
\setlength\parindent{0pt}

% Graphics
\usepackage{graphicx}

% Math Packages
\usepackage{physics}
\usepackage{amsmath, amsfonts, amssymb, amsthm}
\usepackage{mathtools}

% Code Def
\usepackage{listings}

% Section Heading Settings
\usepackage{enumitem}
\renewcommand{\theenumi}{\alph{enumi}}
\renewcommand*{\thesection}{Problem \arabic{section}}
\renewcommand*{\thesubsection}{\alph{subsection})}
\renewcommand*{\thesubsubsection}{\quad \quad \roman{subsubsection})}

%Custom Commands
\newcommand{\Rel}{\mathcal{R}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\C}{\mathbb{C}}
\newcommand{\N}{\mathbb{N}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\Q}{\mathbb{Q}}

\newcommand{\toI}{\xrightarrow{\textsf{\tiny I}}}
\newcommand{\toS}{\xrightarrow{\textsf{\tiny S}}}
\newcommand{\toB}{\xrightarrow{\textsf{\tiny B}}}

\newcommand{\divisible}{ \ \vdots \ }
\newcommand{\st}{\ : \ }

% Theorem Definition
\newtheorem{definition}{Definition}
\newtheorem{assumption}{Assumption}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}{Lemma}
\newtheorem{proposition}{Proposition}

%opening

\title{MATH 5301 Elementary Analysis - Homework 8}

\author{Jonas Wagner}

\date{2021, October 29\textsuperscript{th}}

\begin{document}

\maketitle

% Problem 1 ----------------------------------------------
\section{}
Show that the norms $\norm{\cdot}_1$, $\norm{\cdot}_p$ for $p > 1$, and $\norm{\cdot}_\infty$ are equivalent.

\begin{definition}
    For $\norm{\cdot}_a, \norm{\cdot}_b$ on $S$,
    $\norm{\cdot}_a$ is said to be \emph{stronger} then $\norm{\cdot}_b$ if
    \[
        \forall \{x_n\} \subset S \st x_n \xrightarrow[d_a]{} x \implies x_n \xrightarrow[d_b]{} x
    \]
\end{definition}
\begin{definition}
    $\norm{\cdot}_a$ and $\norm{\cdot}_b$ are said to be \emph{equivalent},  $\norm{\cdot}_a \sim \norm{\cdot}_b$,
    if $\norm{\cdot}_a$ is stronger then $\norm{\cdot}_b$
    and $\norm{\cdot}_b$ is stronger then $\norm{\cdot}_a$.
    This means that
    \[
        \norm{\cdot}_a \sim \norm{\cdot}_b
            \iff \exists{\alpha,\beta \in \R_{>0}} :
            \forall_{x\in S} \alpha \norm{\cdot}_b \leq \norm{\cdot}_a \leq \beta \norm{x}_b
    \]
\end{definition}
\begin{definition} The following norms are defined as
    \begin{enumerate}
        \item $\norm{\cdot}_1 := \norm{x}_1 = \sum_{i=1}^n \abs{x_i} = \abs{x_1} + \abs{x_2} + \dots + \abs{x_n}$
        \item $\norm{\cdot}_2 := \norm{x}_2 = \qty(\sum_{i=1}^n \abs{x_i}^2)^{1/2} = \qty(\abs{x_1}^2 + \abs{x_2}^2 + \dots + \abs{x_n}^2)^{1/2}$
        \item $\norm{\cdot}_p := \norm{x}_p = \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p} =\qty(\abs{x_1}^p + \abs{x_2}^p + \dots + \abs{x_n}^p)^{1/p}, \ p > 1$
        \item $\norm{\cdot}_\infty := \norm{x}_\infty = \max_{i=1}^n \abs{x_i} = \max(\abs{x_1}, \abs{x_2}, \dots, \abs{x_n})$
    \end{enumerate}
\end{definition}

\newpage
\begin{theorem}
    The norms $\norm{\cdot}_1, \norm{\cdot}_p,$ and $\norm{\cdot}_\infty$ are equivalent.
    \begin{proof}
        % 1-norm ~ p-norm
        \begin{lemma}\label{lem:1-1toP}
            $\norm{\cdot}_1 \sim \norm{\cdot}_p$
            \begin{proof}
                $\norm{\cdot}_1 \sim \norm{\cdot}_p$ is true iff
                \begin{multline*}
                    \forall_{x} \exists_{\alpha,\beta \in \R_+} :\\
                    \alpha \norm{x}_p
                        \leq \norm{x}_1
                        \leq \norm{x}_p\\
                    \alpha \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                        \leq \sum_{i=1}^n \abs{x_i}
                        \leq \beta \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}\\
                \end{multline*}
                From the Holder's inequality we have
                \begin{align*}
                    \norm{x}_1 = \sum_{i=1}^n \abs{x_i}
                        &= \sum_{i=1}^n \abs{x_i} (1)\\
                        &\leq \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                            \qty(\sum_{i=1}^n \abs{1}^{(1-p)})^{1/(1-p)}\\
                        &\leq n^{1/(1-p)} \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                \end{align*}
                So for $0 < \alpha \leq n^{1/(1-p)}$ and $\beta \geq n^{1/(1-p)}$,
                \begin{align*}
                    &\alpha \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                        &&\leq \sum_{i=1}^n \abs{x_i}
                        &&\leq \beta \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}\\
                    &\qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                        &&\leq n^{1/(1-p)} \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                        &&\leq n^{1/(1-p)} \qty(\sum_{i=1}^n \abs{x_i}^p)^{1/p}
                \end{align*}
                Therefore,
                \[\norm{x}_p \leq \norm{x}_1 \leq n^{\frac{1}{1-p}} \norm{x}_p\]
                which proves $\norm{\cdot}_1 \sim \norm{\cdot}_p$.
            \end{proof}
        \end{lemma}
        % \newpage
        %1-norm ~ \infty-norm
        \begin{lemma}\label{lem:1-1toInfty}
            $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$
            \begin{proof}
                $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$ is true iff
                \begin{multline*}
                    \forall_{x} \exists_{\alpha,\beta \in \R_+} :\\
                    \alpha \norm{x}_\infty \leq \norm{x}_1 \leq \beta \norm{x}_\infty\\
                    \alpha \max_{i=1}^n \abs{x_i} \leq \sum_{i=1}^n \abs{x_i} \leq \beta \max_{i=1}^n \abs{x_i}\\
                \end{multline*}
                Clearly, this is true for when $\alpha \in (0,1]$. Similarly, when $\beta \geq n$ then $\sum_{i=1}^n \max_{i=1}^n \abs{x_i}$ and then clearly greater then the $\norm{x}_1$; therefore $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$.
            \end{proof}
        \end{lemma}
        From, Lemma \ref{lem:1-1toP} and Lemma \ref{lem:1-1toInfty}, it is clear that $\forall_{p > 1}$:
        \[
            \norm{x}_\infty
            \leq \norm{x}_p
            \leq \norm{x}_1
            \leq n^{1/{1-p}} \norm{x}_p
            \leq n \norm{x}_\infty
        \]
        Therefore, $\norm{\cdot}_1 \sim \norm{\cdot}_p \sim \norm{\cdot}_\infty$ ($\forall_{p > 1}$).
    \end{proof}
\end{theorem}

% Problem 2
\newpage
\section{}
Let $(S, \norm{\cdot})$ and $(S', \norm{\cdot}')$ to be two normed spaces.
Show that the following norms on $S \cross S'$ are equivalent.
\begin{enumerate}
    \item $\norm{(x,y)}_1 = \norm{x} + \norm{y}'$
    \item $\norm{(x,y)}_2 = \sqrt{\norm{x}^2 + (\norm{y}')^2}$
    \item $\norm{(x,y)}_p = \qty(\norm{x}^p + (\norm{y}')^p)^{1/p}$
    \item $\norm{(x,y)}_\infty = \max\qty{\norm{x} + \norm{y}'}$
\end{enumerate}

\begin{theorem}
    The norms $\norm{\cdot}_1,\norm{\cdot}_2,\norm{\cdot}_p,$ and $\norm{\cdot}_\infty$ are all equivalent on $S \cross S'$.
    \begin{proof}
        % 1-norm ~ 2-norm
        \begin{lemma}\label{lem:2-1to2}
            $\norm{\cdot}_1 \sim \norm{\cdot}_2$
            \begin{proof}
                $\norm{\cdot}_1 \sim \norm{\cdot}_2$ is true iff
                \begin{multline*}
                    \forall_{(x,y) \in S \cross S'} \exists_{\alpha,\beta \in \R_+} :\\
                    \alpha \norm{(x,y)}_2
                        \leq \norm{(x,y)}_1
                        \leq \beta \norm{(x,y)}_2\\
                    \alpha (\norm{x}^2 + (\norm{y}')^2)^{1/2}
                        \leq \norm{x} + \norm{y}'
                        \leq \beta (\norm{x}^2 + (\norm{y}')^2)^{1/2}\\
                \end{multline*}
                First, the following demonstrates that $\norm{(x,y)}_2 \leq \norm{(x,y)}_1$
                \begin{align*}
                    \norm{(x,y)}_1^2
                        &= (\norm{x} + \norm{y}')^2\\
                        &= \norm{x}^2 + (\norm{y}')^2 + \norm{x}\norm{y}'\\
                        &\leq \norm{x}^2 + (\norm{y}')^2 + (\norm{x})^2 + (\norm{y}')^2\\
                        &= 2 \norm{x}^2 + 2(\norm{y}')^2\\
                        &= 2 \norm{(x,y)}_2^2\\
                    \frac{1}{2} \norm{(x,y)}_1^2
                        &\leq \norm{(x,y)}_2^2
                \end{align*}
                Therefore,
                \[
                    \frac{1}{\sqrt{2}} \norm{(x,y)}_2 \leq \norm{(x,y)}_1
                \]
                and this is also true for any $p>2$ as well using an arbitrary number of power expansions.

                Next, from the Cauchy Schwartz's inequality we have
                \begin{align*}
                    \norm{(x,y)}_1
                        &= \norm{x} + \norm{y}'\\
                    &= \qty(\norm{x} (1) + \norm{y}' (1))\\
                    &\leq \qty(\norm{x}^2 + (\norm{y}')^2)^{\frac{1}{2}} \qty(1^2 + 1^2)^{1 - \frac{1}{2}}\\
                    &= \qty(2)^\frac{1}{2} \qty(\norm{x}^2 + (\norm{y}')^2)^{\frac{1}{2}}\\
                    &= \sqrt{2} \sqrt{\norm{x}^2 + (\norm{y}')^2}\\
                    \norm{(x,y)}_1
                        &\leq \sqrt{2} \norm{(x,y)}_2
                \end{align*}
                Therefore,
                \[\frac{1}{\sqrt{2}} \norm{x}_2 \leq \norm{x}_1 \leq \sqrt{2} \norm{x}_2\]
                which proves $\norm{\cdot}_1 \sim \norm{\cdot}_2$.
            \end{proof}
        \end{lemma}
        \newpage
        % 1-norm ~ p-norm
        \begin{lemma}\label{lem:2-1toP}
            $\norm{\cdot}_1 \sim \norm{\cdot}_p$
            \begin{proof}
                $\norm{\cdot}_1 \sim \norm{\cdot}_p$ is true iff
                \begin{multline*}
                    \forall_{(x,y) \in S \cross S'} \exists_{\alpha,\beta \in \R_+} :\\
                    \alpha \norm{(x,y)}_p
                        \leq \norm{(x,y)}_1
                        \leq \beta \norm{(x,y)}_p\\
                    \alpha \qty(\norm{x}^p + (\norm{y}')^p)^{1/p}
                        \leq \norm{x} + \norm{y}'
                        \leq \beta \qty(\norm{x}^p + (\norm{y}')^p)^{1/p}\\
                \end{multline*}
                From the Holder's inequality we have
                \begin{align*}
                    \norm{x}_1 = \norm{x} + \norm{y}'\\
                        &= \norm{x}(1) + \norm{y}'(1)\\
                        &\leq \qty(\norm{x}^p + (\norm{y}')^p)^{1/p} \qty(\sum_{i=1}^2 \abs{1}^{(1-p)})^{\frac{1}{1-p}}\\
                        &= n^{\frac{1}{1-p}} \qty(\norm{x}^p + (\norm{y}')^p)^{1/p}\\
                        &= n^{\frac{1}{1-p}} \norm{(x,y)}_p
                \end{align*}
                Therefore,
                \[
                    \norm{(x,y)}_1 \leq n^{\frac{1}{1-p}} \norm{(x,y)}_p
                \]
                and, since $p > 1$, then the remainder of the arguments from Lemma \ref{lem:2-1to2} can be applied here to any arbitrary $p > 1$ to prove the norm equivalence with 1, 2, and any $p$ norms.
            \end{proof}
        \end{lemma}
        %1-norm ~ \infty-norm
        \begin{lemma}\label{lem:2-1toInfty}
            $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$
            \begin{proof}
                $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$ is true iff
                \begin{multline*}
                    \forall_{(x,y) \in S \cross S'} \exists_{\alpha,\beta \in \R_+} :\\
                    \alpha \norm{(x,y)}_\infty \leq \norm{(x,y)}_1 \leq \beta \norm{(x,y)}_\infty\\
                    \alpha \max\qty{\norm{x} + \norm{y}'} \leq \norm{x} + \norm{y}' \leq \beta \max\qty{\norm{x} + \norm{y}'}\\
                \end{multline*}
                Clearly, this is true for when $\alpha \in (0,1]$. Similarly, when $\beta \geq 2$ then $\max{\norm{x},\norm{y}'}$ and is clearly greater then the $\norm{(x,y)}_1$; therefore $\norm{\cdot}_1 \sim \norm{\cdot}_\infty$.
            \end{proof}
        \end{lemma}
    \end{proof}
\end{theorem}

% Problem 3
\newpage
\section{}
Let $X$ be a vector space and $V$ be a normed space.
The function $f : X \to V$ is called bounded if $\exists M \st \forall_{x\in X} \implies \norm{f(x)} < M$.
Consider the set $\mathcal{B}(X,V)$ of all bounded functions from $X \to V$.

%Part a
\subsection{}
Show that $\mathcal{B}(X,V)$ is a vector space.

\begin{definition}\label{def:vec_space}
    A \emph{Vector space} over a field is the set $V$ along with two operations (vector addition and vector multiplication) satisfying the basic vector properties.
    \begin{enumerate}
        \item Associativity of vector addition
        \[\vb{u} + (\vb{v} + \vb{w}) = (\vb{u} + \vb{v}) + \vb{w}\]
        \item Commutativity of vector addition
        \[\vb{u} + \vb{v} = \vb{v} + \vb{u}\]
        \item Identity element of vector addition (zero vector)
        \[\forall_{\vb{v} \in V} \exists_{\vb{0} \in V} \st \vb{v} + \vb{0} = v \]
        \item Inverse elements of vector addition (additive inverse)
        \[\forall_{\vb{v} \in V} \exists_{-v \in V} \st \vb{v} + (-\vb{v}) = \vb{0}\]
        \item Compatibility of scalar and field multiplication
        \[a (b \vb{v}) = (a b) \vb{v}\]
        \item Identity element of scalar multiplication (multiplicative identity)
        \[\exists_{1 \in F} \vb{1} \vb{v} = v\]
        \item Distributivity of scalar multiplication with vector addition
        \[a (\vb{u} + \vb{v}) = a \vb{u} + a \vb{v}\]
        \item Distributivity of scalar multiplication with field addition
        \[(a + b) \vb{v} = a \vb{v} + b \vb{v}\]
    \end{enumerate}
\end{definition}

\begin{definition}
    $\mathcal{B}(X,V)$ is the set of all functions $f : X \to V$ that are bounded under the definition:
    \[\exists_{M \in V} \st \forall_{x\in X} \implies \norm{f(x)} < M\]
\end{definition}

\begin{theorem}
    $\mathcal{B}(X,V)$ is a vector space.
    \begin{proof}
        It is known that $X$ is a vector space and $V$ is a normed vector space.
        For all functions between $X$ and $V$ the normed space result implies many of the required vector space properties directly.
        For instance, assuming standard function addition and multiplication methods, the mapped results of the new superimposed function will satisfy Associativity, Commutativity, Identity and inverse for addition, Compatibility and identity of multiplication.
        The Distributivity properties require more justification as they do not clearly result from the results of a single function.
        Fortunately, the boundedness of $\mathcal{B}(X,V)$ provides that an upper bound exists for the output and so the complicated parts of accounting for weirder functions allows for a proof of distributivity based on the output and the induced addition and multiplication operations will satisfy all of the superposition properties.
    \end{proof}
\end{theorem}

%Part b
\subsection{}
Show that the function $\norm{\cdot}_\infty : \mathcal{B}(X,V) \to \R_{+} :$
\[
    \norm{f}_\infty := \sup_{x\in X} \norm{f(x)}
\]
defines a norm on $\mathcal{B}(X,V)$.

\begin{definition}
    A \emph{norm} is a function $\norm{\cdot} : V \to \R_{+}$ satisfying
    \begin{enumerate}
        \item Non-negativity
            \[\forall_{x\in V} \norm{x} \geq 0 \implies \norm{x} = 0 \iff x = 0\]
        \item Homogeneity
            \[\norm{\lambda \cdot x} = \abs{\lambda} \norm{x}\]
        \item Triangle inequality
            \[\norm{x + y} \leq \norm{x} + \norm{y}\]
    \end{enumerate}
\end{definition}

\begin{theorem}
    $\norm{\cdot}_\infty$ is a norm on $\mathcal{B}(X,V)$.
    \begin{proof}
        Since $\mathcal{B}(X,V)$ is a vector space, the important properties of a field and simple vector operations can be assumed.

        First, by definition, the non-negativity is satisfied by the mapped results are within $\R_+$.

        Second, the original norm properties from the normed vector space $V$ can be applied to each of the $\norm{f(x)}$ within the $\sup_{x \in X}$, resulting in the homogeneity required for a norm.

        Third, The triangle inequality can also be easily seen with the following:
        \begin{align*}
            \norm{x + y}
                &\leq \norm{x} + \norm{y}\\
            \sup_{(x + y) \in X} \norm{f(x + y)}
                &\leq \sup{x \in X} \norm{f(x)} + \sup_{y \in X} \norm{f(y)}\\
            \sup_{x,y \in X \st x+y \in X} \norm{f(x + y)}
                &\leq \sup_{x,y \in X} \norm{x} + \norm{y}
        \end{align*}
        which is clearly true considering the definition of the original normed space $V$.
    \end{proof}
\end{theorem}

% Problem 4
\newpage
\section{}
Let $A$ be a dense set in metric space $(S,d)$, let $(V,d_1)$ be a complete metric space, and $f : A \to Y$ be a uniformly continuous function.

Note: assuming that there was a typo and that $Y$ is also dense within $V$.

%Part a
\subsection{Show that if $\{x_n\}$ is a Cauchy sequence in $A$ then $\{f(x_n)\}$ is a Cauchy sequence in $Y$.}

\begin{definition}
    A set $A$ is \emph{dense} within metric space $(S,d)$ if and only if $A = X$.
\end{definition}

\begin{definition}\label{def:complete}
    Metric space $(S,d)$ is called a \emph{complete metric space} if every cauchy sequence $\{a_n\}\subset S$ converges in $S$.
    \[\forall_{\{a_n\} \subset S \st \{a_n\} \ \textnormal{cauchy} \ \implies \exists_{a \in S} \st \lim_{n\to\infty} a_n = a}\]
\end{definition}

\begin{definition}
    $\{a_n\}$ is said to be a \emph{cauchy} sequence if
    \[\{a_n\} : \forall_{\epsilon>0} \exists_{N} : \forall_{n,m > N} \implies d(a_n,a_m) < \epsilon\]
\end{definition}

\begin{definition}
    A function $f : X \to Y$ is said to be \emph{uniformly continuous} if and only if
    \[\forall_{\epsilon>0} \exists_{\delta>0} \forall_{x,x' \in X} d_X(x,x') < \delta \implies d_Y(f(x), f(x')) < \epsilon\]
\end{definition}

\begin{theorem}
    If $\{x_n\}$ is a Cauchy sequence in $A$ then $\{f(x_n)\}$ is a Cauchy sequence in $Y$.
    \begin{proof}
        \begin{align*}
            \{x_n\} \ \text{cauchy} &\implies \{f(x_n)\} \ \text{cauchy}\\
            \forall_{\epsilon,\delta>0} \exists_{N(\epsilon,\delta) \in \N} : \forall_{n,m > N} \implies d(x_n,x_m) < \epsilon)
            &\implies d_1(f(x_{n_1}),f(x_{n_1})) < \epsilon_1)
        \end{align*}
        By definition of the complete metric space $Y$, every cauchy sequence within $Y$ will converge to within $Y$, therefore every cauchy sequence that gets mapped from the dense $A$ to $Y$ via the uniformly continuos function $f$ will be guaranteed to be cauchy as well.
        (this could also be written out in a more complicated way using quantifiers, but the words just explained it better)
    \end{proof}
\end{theorem}

%Part b
\subsection{Show that there is only one continuous function $g : X \to Y$ so that $g(x) = f(x)$ forall $x \in A$.}
\begin{theorem}
    There is only one continuous $g : X \to Y$ so that $g(x) = f(x)$ forall $x \in A$.
    \begin{proof}
        This means that each continuous function from $X$ or $A$ to $Y$ only has one complimentary function that produces the same image as it in $Y$.
        For $f$, the definition of uniformly continuous is
        \[\forall_{\epsilon>0} \exists_{\delta>0} \forall_{x,x' \in A} d(x,x') < \delta \implies d_1(f(x), f(x')) < \epsilon\]
        Similarly, $g$ being continuous is defined by
        \[\forall_{x \in X} \forall_{\epsilon>0} \exists_{\delta > 0} \forall_{x, x'\in X} d(x,x') < \delta \implies d_1(g(x),g(x')) < \epsilon\]
        There is only one possible mapping for each complete relation between each of the element $x \in A$ to $f(x) \in Y$, so since $A$ is dense in $X$, each element $x \in X$ can be mapped from $X$ to the image in $Y$.
        Although this is simple and the result clearly follows, the quantifiers can be used to demonstrate this as follows:
        \begin{multline*}
            \qty(\forall_{\epsilon>0} \exists_{\delta>0} \forall_{x,x' \in A} d(x,x') < \delta \implies d_1(f(x), f(x')) < \epsilon) \land \\
            \land \qty(\forall_{x \in X} \forall_{\epsilon>0} \exists_{\delta > 0} \forall_{x, x'\in X} d(x,x') <
            \delta \implies d_1(g(x),g(x')) < \epsilon)\\
            \forall_{\epsilon>0} \exists_{\delta>0} \forall_{x,x' \in A} d(x,x') < \delta \implies d_1(f(x), f(x')) < \epsilon \land \exists_{\epsilon_1(\epsilon,x,x')} d_1(g(x),g(x'))) < \epsilon_1
        \end{multline*}
        And since we want $g(x) = f(x)$, it is clear that the exact same restrictions (for each element across all of $A$ and $X$) will be in place, which implies that only one function will be able to satisfy it.
    \end{proof}
\end{theorem}

% Problem 5
\newpage
\section{}
Let $(L, \norm{\cdot})$ be a Banach space.
Let $L_0$ be a closed subspace of $L$.
Define the factor-space $L/L_0$ as $:L_1 := L/L_0 = \qty{x + y \st x \in L, y \in L_0}$.
In other works, $L_1$ consists of all subsets of $L$ obtained from $L_0$ by shifting all its elements by some element $x$.

%Part a
\subsection{Show that $L_1$ is a vector space.}
\begin{theorem}
    $L_1$ is a vector space.
    \begin{proof}
        From the definition of a vector space, Definition \ref{def:vec_space}, it is necessary for all vector spaces to have additive and multiplicative operations that satisfy the multiple properties of superposition.
        Directly by definition of the of $L_1$, being composed of a Banach space and a closed subspace within it, it may be possible to directly claim that it is also Banach. Regardless, the definition of each element within $L_1$ as a summation of two elements within a Banach (and therefore vector) space, already demonstrates the additive properties. Similarly, the composition of $L_1$ as a linear combination of elements from $L$ (and $L_0$) that individually satisfy all of the vector space properties will imply that an induced (yet technically undefined in the problem statement) set of additive and multiplicative operations that obey superposition.
    \end{proof}
\end{theorem}

%Part b
\subsection{}
Define the function $\norm{\cdot} : L_1 \to \R_{+}$ as $\norm{x}_1 = \inf_{x - y \in L_0} \norm{y}$.
Show that this function defines a norm on the space $L_1$.

\begin{theorem}
    $\norm{x}_1$ is a norm on $L_1$.
    \begin{proof}
        Since $L_1$ is a vector space, the important properties of a field and simple vector operations can be assumed.

        First, by definition, the non-negativity is satisfied by the mapped results are within $\R_+$.

        Second, the original norm properties from $L$ apply to each  $\norm{y}$ within the $\inf_{x-y \in L_0}$, resulting in the homogeneity required for a norm.

        Third, The triangle inequality can also be easily seen with the following:
        \begin{align*}
            \norm{(a,b) + (x,y)}
                &\leq \norm{(a,b)} + \norm{(x,y)}\\
            \inf_{(a+x) - (b+y) \in L_0} \norm{b+y}
                &\leq \inf_{a - b \in L_0} \norm{b} + \inf_{x-y \in L_0} \norm{y}\\
                &\leq \inf_{(a-b), (x-y) \in L_0} \norm{b + y}
        \end{align*}
        which is clearly true considering the definition of the original banach space $L$.
    \end{proof}
\end{theorem}

%Part c
\subsection{Show that $L_1$ is a Banach space.}
\begin{definition}
    A complete, normed, space is called a \emph{Banach space}.
\end{definition}

\begin{theorem}
    $L_1$ is a Banach space.
    \begin{proof}
        From the first two parts of this question, we know that $L_1$ is a vector space, and $(L_1, \norm{x}_1)$ is a normed space.
        The only remaining requirement is that of completeness, which by Definition \ref{def:complete}, means
        \begin{align*}
            \forall\{l_n\} \subset L_1 \st \{l_n\} \ \textnormal{cauchy} \ \implies \exists_{l \in L_1} \st \lim_{n\to\infty} l_n = l
        \end{align*}
        Since $L_1$ is composed of the complete collection of projections of the closed $L_0$ shifted by arbitrary values within $L$, both of which are complete (since they are Banach), so any possible cauchy sequences within $L_1$ will tend towards another element within $L_1$.
    \end{proof}
\end{theorem}

% Problem 6
\newpage
\section{}
Let $C([-1,1])$ be the space of all continuous real-valued functions $f(x)$ with $x \in [-1,1]$.
Let $\norm{f}_\infty := \sup_{x \in [-1,1]} \abs{f(x)}$.
Find the distance from point $p = x^{2021}$ to the space $P_{2020}$ of all polynomials of degree less than or equal to 2020.

\begin{definition}
    The \emph{distance} between a point and a set is defined by
    \[dist(x,A) := \inf_{a \in A} d(x,a) = \inf_{a \in A} \norm{x - a}\]
\end{definition}

The distance between point $p = x^{2021}$ and $P_{2020}$ is calculated as follows:
\begin{align*}
    \textnormal{dist}(p,P)
        &= \inf_{y \in P_{2020}} d(p,y)
            = \inf_{y \in P_{2020}} \norm{p - y}\\
        &= \inf_{y \in P_{2020}} \sup_{x \in [-1,1]} \abs{p(x) - y(x)}\\
        &= \inf_{y \in P_{2020}} \sup_{x \in [-1,1]} \abs{x^{2021} - \sum_{i=0}^{2020} a_i^{(y)} x^i}
    \intertext{Since the supremum has to bound the maximum value, it can be assumed that the suppremmum of an absolute value will only occur when $a_i^{(y)}<0$ and $x = \max{x \in [-1,1]} = 1$.}
        &= \inf_{y \in P_{2020}} (1)^{2021} - \sum_{i=0}^{2020} -\abs{a_i^{(y)}} (1)^i\\
        &= \inf_{y \in P_{2020}} 1 + \sum_{i=0}^{2020} \abs{a_i^{(y)}}
\end{align*}
We can then see that the largest lower bound would be when $a_i^{(y)} = 0, \ \forall_{i\in [0,2020]}$.

Therefore, \[\textnormal{dist}(p=x^{2021},P_{2020}) = 1\]

\end{document}


\documentclass{article}
\title{Matlab and LaTeX integration}
\author{Ben Newhouse, Super Happy Dev House 32}
\begin{document}
\maketitle
\section{Abstract}
I am lazy.  I do lots of problem sets.  I do lots of problem sets in LaTeX because I am to lazy to find real paper to write on.  I also use matlab because I am too lazy to find a calculator.  From one script I want to be able to do everything.  Screw MVC, I need what PHP is to HTML what I'm doing is to LaTeX.
As you can see here, $1 + 1=$
<?ml
1 + 1
?>
The integral of
\begin{displaymath}
<?ml
syms x;
latex(x^2 + log(x))
?>
\end{displaymath}
is
\begin{displaymath}
<?ml
latex((int(x^2 + log(x),x)))
?>
\end{displaymath}
\end{document}


\documentclass[10pt]{article}
\usepackage{nameref}
\usepackage{cleveref}
\usepackage{palatino}
\usepackage[scaled=0.9]{beramono}
\usepackage[T1]{fontenc}
\usepackage[protrusion=true,expansion=true]{microtype}
\usepackage[draft=false]{hyperref}
\usepackage[left=4cm, right=4cm, top=2cm, bottom=1.8cm]{geometry}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{ulem}
\usepackage{attrib}
\begin{document}

\title{Experiments with an Abstract Machine}
\maketitle

\noindent The aim is to build an abstract machine which follows the semantics of OCaml, but which 1) can operate step-by-step 2) keeps around enough information to be able to recompute a source-code representation of the currently-executing portion of the program 3) and its place in the rest of the source code. In Leroy ``Functional Programming Languages: Part II: Abstract Machines'', a basic arithmetic example is provided, followed by an SECD machine (with tail-call elimintion), and then OCaml's actual bytecode, the Zinc Abstract Machine.

The arithmetic example is implemented like this. Here is the type for programs:

\begin{verbatim}
type op = Add | Sub | Mul | Div

type prog =
  Int of int
| Op of prog * op * prog
\end{verbatim}

And here is the type for bytecode instructions:

\begin{verbatim}
type instr =
  IConst of int
| IOp of op
\end{verbatim}

Compilation is very simple, consisting of just conversion to  Reverse Polish:

\begin{verbatim}
let rec compile = function
  Int i -> [IConst i]
| Op (a1, op, a2) -> compile a1 @ compile a2 @ [IOp op]
\end{verbatim}

Evaluation is simple, too. The program is run instruction-by-instruction, keeping a stack on to which operands are placed. An operator takes two operands off the stack, and pushes its result. At the end, the answer is left on the stack and may be returned:

\begin{verbatim}
let calc_op a b = function
  Add -> a + b | Sub -> a - b
| Mul -> a * b | Div -> a / b

let rec run s = function
  [] -> hd s
| IConst i::r -> run (Int i::s) r
| IOp op::r ->
    match s with
      Int n2::Int n1::s' ->
        run (Int (calc_op n1 n2 op)::s') r
\end{verbatim}

Running step-by-step is then simple: just process one instruction of the bytecode as above, returning the remaining ones and the new state of the stack. Now, how can we reconstruct the program source code, given the current state of the program and the stack? Here is the uncompilation function. We take the remainder of the program and the current stack. When we find an IOp instruction, we take two things off the stack and build an Op node. This is the conversion back to infix.

\begin{verbatim}
let rec uncompile s = function
  [] -> hd s
| IConst i::r ->
    uncompile (Int i::s) r
| IOp op::r ->
    match s with
      a::b::s' -> uncompile (Op (b, op, a)::s') r
\end{verbatim}

We only print out steps where something important happens. For arithmetic, this means an op.

How do we highlight the current redex? It's easy because the first piece of work to be done is always at the top of the program, since the program is executed in linear order.

\section*{Example}

\begin{verbatim}
$ ./arith -e "1 + 2 * (3 + 4)" -show-unimportant
1 + 2 * (3 + 4)
1 + 2 * (3 + 4)
1 + 2 * (3 + 4)
1 + 2 * (3 + 4)
1 + 2 * (3 + 4)
1 + 2 * 7
1 + 14
15

$ ./arith -e "1 + 2 * (3 + 4)"
1 + 2 * (3 + 4)
1 + 2 * 7
1 + 14
15

$ ./arith -e "1 + 2 * (3 + 4)" -debug
IOp +; IOp *; IOp + || 4; 3; 2; 1
1 + 2 * (3 + 4)
IOp *; IOp + || 7; 2; 1
1 + 2 * 7
IOp + || 14; 1
1 + 14
15
\end{verbatim}

\section*{Speed}
Calculating $1 + 2 * (3 + 4)$ one million times, this bytecode interpreter is 64x faster than our syntactic interpreter when not printing anything out, and 5x faster when printing out all the steps.

\section*{Next Steps}

Note that, because each step reduces the size of the expression (and does not generate anything new), 2) and 3) in the first paragraph above are the same thing. Soon, they will not be, and we will need to find some way to keep enough information around.

\end{document}


\lab{Breadth-first Search}{Breadth-first Search}
\objective{
Shortest path problems are an important part of graph theory and network analysis.
Applications include finding the fastest way to drive between two points on a map, network routing, genealogy, automated circuit layout, and a variety of other important problems.
In this lab we represent graphs as adjacency dictionaries, implement a shortest path algorithm based on a breadth-first search, and use the NetworkX package to solve a shortest path problem on a large network of movies and actors.}

\section*{Adjacency Dictionaries} % ===========================================

Computers can represent mathematical graphs in various ways.
Graphs with very specific structures are often stored with specialized data structures, such as binary search trees.
More general graphs without structural constraints are usually represented with an \emph{adjacency matrix}, where each row and column of the matrix corresponds to a node in the graph, and the entries indicate connections between nodes.
Adjacency matrices are usually implemented in a sparse matrix format since only the entries corresponding to node connections are nonzero.

Another common graph data structure is an \emph{adjacency dictionary}, a dictionary with a key for each node in the graph.
The dictionary values are the set of nodes connected to the key node.
Adjacency dictionaries automatically gain the advantages of a sparse matrix format since they only store information on the actual node connections (the nonzero entries of the adjacency matrix).
% In Python, dictionaries are also much faster for lookup than matrices.

\begin{figure}[H] % simple graph, its adjacency matrix, and its adjacency dict.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.32\textwidth}
\centering
\begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
    % Nodes
    \node[normalcircle] (A) [] {A};
    \node[normalcircle] (B) [above of=A] {B};
    \node[normalcircle] (C) [right of=B] {C};
    \node[normalcircle] (D) [below of=C] {D};
    % Edges
    \foreach \a/\b in {A/B,A/D,B/D,C/D} \draw[thick,-,>=stealth'] (\a) edge (\b);
\end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
\centering
\begin{align*}
    \begin{blockarray}{ccccccc}
    & & \small\text{\textcolor{gray}{A}} & \small\text{\textcolor{gray}{B}} & \small\text{\textcolor{gray}{C}} & \small\text{\textcolor{gray}{D}} & \\
    \begin{block}{c[cccccc]}
    \small\text{\textcolor{gray}{A}} & & 0 & 1 & 0 & 1 & \topstrut\\
    \small\text{\textcolor{gray}{B}} & & 1 & 0 & 0 & 1 & \\
    \small\text{\textcolor{gray}{C}} & & 0 & 0 & 0 & 1 & \\
    \small\text{\textcolor{gray}{D}} & & 1 & 1 & 1 & 0 & \botstrut\\
    \end{block}\end{blockarray}
\end{align*}
\end{subfigure}
%
\begin{subfigure}{.32\textwidth}
\centering
\begin{align*}
\{\text{A}&:\ \{\text{B},\ \text{D}\},\\
  \text{B}&:\ \{\text{A},\ \text{D}\},\\
  \text{C}&:\ \{\text{D}\},\\
  \text{D}&:\ \{\text{A},\ \text{B},\ \text{D}\}\}
\end{align*}
\end{subfigure}
\caption{A simple unweighted graph (left), its adjacency matrix (middle), and its adjacency dictionary (right).
The graph is undirected, so the adjacency matrix is symmetric.
Note that the adjacency dictionary also encodes this behavior: since A and B are connected, B is in the set of values corresponding to the key A, and A is in the set of values corresponding to the key B.}
% There are eight $1$'s in the matrix, corresponding to $8$ total values in the dictionary.}
\label{fig:bfs-simple-graph}
\end{figure}

\subsection*{Hash-based Data Structures} % ------------------------------------

A Python \li{set} is an unordered data type with no repeated elements.
The set class is implemented as a \emph{hash table}, meaning it uses \emph{hash values}---integers that uniquely identify an object---to organize its elements.
Roughly speaking, in order to access, add, or remove an object \li{x} to a set, Python computes the hash value of \li{x}, and that value indicates where \li{x} is (or should be) in memory. % (usually with the built-in \li{hash()} function)
In other words, there is only one place in memory that \li{x} could be; if it isn't in that place, it isn't in the set.
This implementation results in $O(1)$ lookup, insertion, and removal operations, an enormous improvement over the $O(n)$ search time for lists and the $O(\log{n})$ search time for sorted structures like binary search trees.
It is also why set elements are unique.

\begin{table}[H]
\begin{tabular}{r|l}
    Method & Description\\
    \hline
    \li{add()} & Add an element to the set. This has no effect if the element is already present. \\
    \li{remove()} & Remove an element from the set, raising\\
    & a \li{KeyError} if it is not a member of the set.\\
    \li{discard()} & Remove an element from the set without raising \\
    & an exception if it is not a member of the set.\\
    \li{pop()} & Remove and return an arbitrary set element.\\
    \li{union()} & Return all elements that are in either set as a new set.\\
    \li{intersection()} & Return all elements that are in both sets as a new set.\\
    \li{update()} & Add all elements of another set in-place.
\end{tabular}
\caption{Basic methods of the \li{set} class.}
\end{table}

\begin{lstlisting}
# Initialize a set. Note that repeats are not added.
>>> animals = {"cow", "cat", "dog", "mouse", "cow"}
>>> print(animals)
<<{'cow', 'dog', 'mouse', 'cat'}>>

>>> animals.add("horse")     # Add an object to the set.
>>> "horse" in animals
<<True>>
>>> animals.remove("emu")    # Attempt to delete an object from the set,
<<KeyError: 'emu'>>              # resulting in an exception.
>>> animals.pop()            # Delete and return a random object from the set.
<<'mouse'>>
>>> print(animals)
<<{'cat', 'horse', 'dog', 'cow'}>>

# Add all of the elements of another set to this one.
>>> animals.update({"dog", "velociraptor"})
>>> print(animals)
<<{'velociraptor', 'cat', 'horse', 'dog', 'cow'}>>

# Intersect this set with another one.
>>> animals.intersection({"cat", "cow", "cheetah"})
<<{'cat', 'cow'}>>
\end{lstlisting}

Sets are extremely fast, but they do not support indexing because the elements are unordered.
A Python \li{dict}, on the other hand, is a hash-based data structure that stores key-value pairs: the keys of a dictionary act like a set (unique and unordered, with $O(1)$ lookup), but each key corresponds to another object, called its value.
The keys index the dictionary and allow $O(1)$ lookup of the values.

\begin{table}[H]
\begin{tabular}{r|l}
    Method & Description\\
    \hline
    \li{keys()} & Return a set-like iterator for the dictionary's keys.\\
    \li{values()} & Return a set-like iterator for the dictionary's values.\\
    \li{items()} & Return an iterator for the dictionary's key-value pairs.\\
    \li{pop()} & Remove a specified key and return the corresponding value,\\
    & raising a \li{KeyError} if the key is not a member of the dictionary.\\
    \li{update()} & Add or overwrite key-value pairs in-place with those from another dictionary.
\end{tabular}
\caption{Basic methods of the \li{dict} class.}
\end{table}

\begin{lstlisting}
# Initialize a dictionary.
>>> grades = {"business": "A", "math": "A+", "visual arts": "B"}
>>> grades["math"]
<<'A+'>>                            # The key "math" maps to the value "A+".

# Add a "science" key with corresponding value "A".
>>> grades["science"] = "A"

# Remove the "business" key.
>>> grades.pop("business")
<<'A'>>
>>> print(grades)
<<{'math': 'A+', 'visual arts': 'B', 'science': 'A'}>>

# Display the keys, values, and items.
>>> list(grades.keys()), list(grades.values())
<<(['math', 'visual arts', 'science'], ['A+', 'B', 'A'])>>
>>> for key, value in grades.items():
...   print(key, "=>", value)
...
<<math => A+
visual arts => B
science => A>>

# Add key-value pairs from another dictionary.
>>> grades.update({"cooking":"A+", "math": "C"})
>>> print(grades)
<<{'math': 'C', 'visual arts': 'B', 'science': 'A', 'cooking': 'A+'}>>
\end{lstlisting}

Dictionaries are ideal for storing values that need to be accessed often and for representing one-to-one or one-to-many relationships.
Thus, the \li{dict} class is a natural choice for implementing adjacency dictionaries.
For example, the following code defines the adjacency dictionary for the graph in Figure \ref{fig:bfs-simple-graph}.
Note that the dictionary values are sets.

\begin{lstlisting}
>>> adjacency = {'A': {'B', 'D'},
                 'B': {'A', 'D'},
                 'C': {'D'},
                 'D': {'A', 'B', 'C'}}

# The nodes of the graph are the dictionary keys.
>>> set(adjacency.keys())
<<{'B', 'D', 'A', 'C'}>>

# The values are the nodes that the key node is adjacent to.
>>> adjacency['A']
<<{'B', 'D'}>>                  # A is adjacent to B and D.
>>> 'C' in adjacency['B']
<<False>>                       # B and C are not adjacent.
>>> 'C' in adjacency['D']
<<True>>                        # C and D are adjacent.
\end{lstlisting}

\begin{warn} % hashable objects only
Elements of a \li{set} and keys of a \li{dict} must be \emph{hashable}.
Mutable objects---lists, sets and dictionaries---are not hashable, so they are not allowed as set elements or dictionary keys.
Thus, in order to represent a graph with an adjacency dictionary, each of the node labels should a string, a number, or some other hashable type.
\end{warn}

\begin{problem} % node, edge methods for Graph class (dictionary warm up).
\label{prob:bfs-graph-warmup}
Consider the following \li{Graph} class.
\begin{lstlisting}
class Graph:
    """A graph object, stored as an adjacency dictionary. Each node in the
    graph is a key in the dictionary. The value of each key is a set of
    the corresponding node's neighbors.

    Attributes:
        d (dict): the adjacency dictionary of the graph.
    """
    def __init__(self, adjacency={}):
        """Store the adjacency dictionary as a class attribute"""
        self.d = dict(adjacency)

    def __str__(self):
        """String representation: a view of the adjacency dictionary."""
        return str(self.d)
\end{lstlisting}
Add the following methods to this class.
\begin{enumerate}
\item \li{add_node()}: Add a node (with no initial edges) if it is not already present.
\\ (Hint: use \li{set()} to create an empty set.)
\item \li{add_edge()}: Add an edge between two nodes. Add the nodes to the graph if they are not already present.
\item \li{remove_node()}: Remove a node, including all edges adjacent to it.
This method should raise a \li{KeyError} if the node is not in the graph.
\item \li{remove_edge()}: Remove the edge between two nodes.
This method should raise a \li{KeyError} if either node is not in the graph, or if there is no edge between the nodes.
\end{enumerate}
\end{problem}

\section*{Breadth-first Search} % =============================================

Many common problems that arise in graph theory require finding the shortest path between two nodes in a graph.
For some highly structured graphs, such as binary search trees, this is a fairly straightforward problem (in the case of a tree, the shortest path is also the only path).
Finding a path between nodes in a graph of arbitrary structure, however, requires a careful and methodical approach.
The two most common graph search algorithms are \emph{depth-first search} (DFS) and \emph{breadth-first search} (BFS).
The breadth-first strategy is almost always better at finding shortest paths than the depth-first strategy,\footnote{See \url{https://xkcd.com/761/}.} though a DFS can be useful for path problems in certain graphs.

To traverse a graph with a BFS, choose a node to start at, called the \emph{source} node.
First, visit each of the source node's neighbors.
Next, visit each of the source node's neighbors' neighbors.
Then visit each of their neighbors, continuing the process until all nodes have been visited.
This strategy explores all of the nodes closest to the source node before incrementally moving ``deeper'' (further from the source node) into the tree.

The implementation of a BFS requires the following data structures to keep track of which nodes have already been visited and the order in which to visit nodes in future steps.
\begin{itemize}
    \item A list $V$: The nodes that have been \textbf{visited}, in visitation order.
    \item A \textbf{queue} $Q$: The nodes to be visited, in the order that they were discovered.
    Recall that a \emph{queue} is a limited-access list where data is inserted to one end, but removed from the other (first-in, first-out).
    \item A set $M$: The nodes that have been visited, or that are \textbf{marked} to be visited.
    This is the union of the nodes in $V$ and $Q$.
\end{itemize}
To begin the search, add the source node to $Q$ and $M$.
Then, until $Q$ is empty, repeat the following:
\begin{enumerate}
    \item Pop a node off of $Q$; call it the \emph{current} node.
    \item ``Visit'' the current node by appending it to $V$.
    \item Add the neighbors of the current node that are not in $M$ to $Q$ and $M$.
    \label{step:bfs-add-to-queue}
\end{enumerate}
The ``that are not in $M$'' clause of step \ref{step:bfs-add-to-queue} prevents nodes from being added to $Q$ more than once.
Note that step \ref{step:bfs-add-to-queue} could be replaced with ``Add the neighbors of the current node that are not in $V \cup Q$ to $Q$.''
However, lookup in $M$ (a set) is much faster than lookup in $V$ and $Q$ (arrays or linked lists), so including $M$ greatly speeds up the algorithm.

\begin{info}
The first-in, first-out (FIFO) structure of $Q$ enforces the ``breadth-first'' nature of the BFS: nodes that are marked first are visited first.
Using a a last-in, first-out (LIFO) stack for $Q$ changes the search to a DFS: the next node to visit is the one that was marked last.
\end{info}

\begin{figure}[H] % Example of a breadth-first search.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.6\textwidth}
    \centering
    \begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
    % Nodes
    \node[normalcircle] (A) [fill=red!20] {A};
    \node[normalcircle] (B) [above of=A] {B};
    \node[normalcircle] (C) [right of=B] {C};
    \node[normalcircle] (D) [below of=C] {D};
    % Edges
    \foreach \a/\b in {A/B,A/D,B/D,C/D} \draw[thick,-,>=stealth'] (\a) edge (\b);
    \end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.39\textwidth}
    \Large\begin{tabular}{r|l}
    $V$ & \textcolor{white}{A B C D} \\ \hline
    $Q$ & \textcolor{red}{A} \\ \hline
    $M$ & A \\
    \end{tabular}
\end{subfigure}
\\\vspace{20px}
\begin{subfigure}{.6\textwidth}
    \centering
    \begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
    % Nodes
    \node[normalcircle] (A) [fill=blue!20] {A};
    \node[normalcircle] (B) [fill=red!20, above of=A] {B};
    \node[normalcircle] (C) [right of=B] {C};
    \node[normalcircle] (D) [fill=red!20, below of=C] {D};
    % Edges
    \foreach \a/\b in {B/D,C/D} \draw[thick,-,>=stealth'] (\a) edge (\b);
    \foreach \a/\b in {A/B,A/D} \draw[red!80,thick,->,>=stealth',line width=1.5pt] (\a) edge (\b);
    \end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.39\textwidth}
    \Large\begin{tabular}{r|l}
    $V$ & \textcolor{blue}{A} \textcolor{white}{B C D} \\ \hline
    $Q$ & \textcolor{red}{B D} \\ \hline
    $M$ & A B D \\
    \end{tabular}
\end{subfigure}
\\\vspace{20px}
\begin{subfigure}{.6\textwidth}
    \centering
    \begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
    % Nodes
    \node[normalcircle] (A) [fill=blue!20] {A};
    \node[normalcircle] (B) [fill=blue!20, above of=A] {B};
    \node[normalcircle] (C) [right of=B] {C};
    \node[normalcircle] (D) [fill=red!20, below of=C] {D};
    % Edges
    \foreach \a/\b in {A/B,A/D,B/D,C/D} \draw[thick,-,>=stealth'] (\a) edge (\b);
    \end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.39\textwidth}
    \Large\begin{tabular}{r|l}
    $V$ & \textcolor{blue}{A B} \textcolor{white}{C D}\\ \hline
    $Q$ & \textcolor{red}{D} \\ \hline
    $M$ & A B D \\
    \end{tabular}
\end{subfigure}
\\\vspace{20px}
\begin{subfigure}{.6\textwidth}
    \centering
    \begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
    % Nodes
    \node[normalcircle] (A) [fill=blue!20] {A};
    \node[normalcircle] (B) [fill=blue!20, above of=A] {B};
    \node[normalcircle] (C) [fill=red!20, right of=B] {C};
    \node[normalcircle] (D) [fill=blue!20, below of=C] {D};
    % Edges
    \foreach \a/\b in {A/B,A/D,B/D} \draw[thick,-,>=stealth'] (\a) edge (\b);
    \draw[red!80,thick,->,>=stealth',line width=1.5pt] (D) edge (C);
    \end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.39\textwidth}
    \Large\begin{tabular}{r|l}
    $V$ & \textcolor{blue}{A B D} \\ \hline
    $Q$ & \textcolor{red}{C} \\ \hline
    $M$ & A B D C \\
    \end{tabular}
\end{subfigure}
\caption{To start a BFS from node A to node C, put A in the visit queue $Q$ and mark it by adding it to the set $M$.
Pop A off the queue and ``visit'' it by adding A to the visited list $V$ and the neighboring nodes B and D to $Q$.
Then visit B, but do not add anything to $Q$ because all of the neighbors of B are already marked.
Finally, visit D, at which point the target node C is located because it is adjacent to D.
}
\label{fig:bfs-example}
\end{figure}

\begin{problem} % BFS graph traversal.
\label{prob:bfs-traversal}
Write a method for the \li{Graph} class that accepts a source node.
Traverse the graph with a breadth-first search until all nodes have been visited.
Return the list of nodes in the order that they were visited.
If the source node is not in the graph, raise a \li{KeyError}.
\\(Hint: for $Q$, use a \li{deque} from the \li{collections} module, and make sure that nodes are added to one end but popped off of the other.)
\end{problem}

\subsection*{Shortest Paths via BFS} % ----------------------------------------

Consider the problem of locating a path between two nodes with a BFS.
The nodes that are directly connected to the source node are all visited before any other nodes; more generally, the nodes that are $n$ nodes away from the source node are all visited before nodes that are $n+1$ or more nodes from the source point.
Therefore, the search path taken to discover to the target with a BFS must be the shortest path from the source node to the target node.

Examine again the graph in Figures \ref{fig:bfs-simple-graph} and \ref{fig:bfs-example}.
The shortest path from A to C starts at A, goes to D, and ends at C.
During a BFS originating at A, D is placed on the visit queue because it is one of A's neighbors, and C is placed on the queue because it is one of D's neighbors.
Given that A was the node that visited D, and that D was the node that visited C, the shortest path from A to C can be constructed by stepping backward along the search path.

To implement this idea, initialize a dictionary before starting the BFS.
When a node is marked and added to the visit queue, add a key-value pair mapping the \textbf{visited} node to the \textbf{visiting} node (for example, B $\mapsto$ A means B was marked while visiting A).
When the target node is found, step through the dictionary until arriving at the source node, recording each step.

\begin{figure}[H] % Example of a breadth-first search.
\centering
\begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=1.5cm}]
% Nodes
\node[normalcircle] (A) [fill=blue!20] {A};
\node[normalcircle] (B) [fill=blue!20, above of=A] {B};
\node[normalcircle] (C) [fill=blue!20, right of=B] {C};
\node[normalcircle] (D) [fill=blue!20, below of=C] {D};
% Edges
\draw[thick,-,>=stealth'] (B) edge (D);
\foreach \a/\b in {C/D,D/A,B/A} \draw[green!80,thick,->,>=stealth',line width=1.5pt] (\a) edge (\b);
\end{tikzpicture}
\caption{In the BFS from Figure \ref{fig:bfs-example}, nodes B and D were marked while visiting node A, and node C was marked while visiting node D (this is same as reversing the red arrows in Figure \ref{fig:bfs-example}).
Thus the ``visit path'' from C to A is $\text{C}\rightarrow\text{D}\rightarrow\text{A}$, so the shortest path from A to C is $[$A, D, C$]$.}
\label{fig:bfs-shortest-path}
\end{figure}

\begin{problem}
Add a method to the \li{Graph} class that accepts source and target nodes.
Begin a BFS at the source node and proceed until the target is found.
Return a list containing the node values in the shortest path from the source to the target (including the endpoints).
If either of the input nodes are not in the graph, raise a \li{KeyError}.
\label{prob:bfs-short-path1}
\end{problem}

\section*{Shortest Paths via NetworkX} % ======================================

\emph{NetworkX} is a Python package for creating, manipulating, and exploring graphs.
Its \li{Graph} object represents a graph with an adjacency dictionary, similar to the class from Problems \ref{prob:bfs-graph-warmup}--\ref{prob:bfs-short-path1}, and has many methods for interpreting information about the graph and its structure.
As before, the nodes must be hashable (a number, string, or another immutable object).

\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Method & Description\\
    \hline
    \li{add_node()} & Add a single node to the graph.\\
    \li{add_nodes_from()} & Add a list of nodes to the graph.\\
    \li{add_edge()} & Add an edge between two nodes.\\
    \li{add_edges_from()} & Add a list of edges to the graph.
\end{tabular}
\caption{Methods of the \li{nx.Graph} class for adding nodes and edges.}
\end{table}

\begin{lstlisting}
>>> import networkx as nx

# Initialize a NetworkX graph from an adjacency dictionary.
>>> G = nx.Graph({'A': {'B', 'D'},
                  'B': {'A', 'D'},
                  'C': {'D'},
                  'D': {'A', 'B', 'C'}})

>>> print(G.nodes())            # Print the nodes.
<<['A', 'B', 'C', 'D']>>
>>> print(G.edges())            # Print the edges as tuples.
<<[('A', 'D'), ('A', 'B'), ('B', 'D'), ('C', 'D')]>>

>>> G.add_node('E')             # Add a new node.
>>> G.add_edge('A', 'F')        # Add an edge, which also adds a new node 'F'.
>>> G.add_edges_from([('A', 'C'), ('F', 'G')])  # Add several edges at once.

>>> set(G['A'])                 # Get the set of nodes neighboring node 'A'.
<<{'B', 'C', 'D', 'F'}>>
\end{lstlisting}

\subsection*{The Kevin Bacon Problem} % ---------------------------------------

The vintage parlor game \href{http://oracleofbacon.org/help.php}{\emph{Six Degrees of Kevin Bacon}} is played by naming an actor, then trying to find the shortest chain of actors that have worked with each other leading to Kevin Bacon.
For example, Samuel L. Jackson was in the film \emph{Pulp Fiction (1994)} with Frank Whaley, who was in \emph{JFK (1991)} with Kevin Bacon.
In other words, the goal of the game is to solve a shortest path problem on a graph that connects actors to the movies that they have been in.

\begin{problem} % MovieGraph.__init__()
The file \texttt{movie\_data.txt} contains IMDb data for about 137,000 movies.
Each line of the file represents one movie: the title is listed first, then the cast members, with entries separated by a \texttt{/} character.
For example, the line for \emph{The Dark Knight (2008)} starts with
\begin{center}
\texttt{The Dark Knight (2008)/Christian Bale/Heath Ledger/Aaron Eckhart/...}
\end{center}
Any \li{/} characters in movie titles have been replaced with the vertical pipe character \texttt{|} (for example, \texttt{Frost|Nixon (2008)}).

Write a class whose constructor accepts the name of a file to read.
Initialize a set for movie titles, a set for actor names, and an empty NetworkX \li{Graph}, and store them as attributes.
Read the file line by line, adding the title to the set of movies and the cast members to the set of actors.
Add an edge to the graph between the movie and each cast member.
\\(Hint: Use the \li{split()} method for strings to parse each line.)

It should take no more than 20 seconds to construct the entire graph.
Check that there are 137,018 movies and 930,717 actors.
Compare parts of your graph to Figure \ref{fig:bfs-network-subset}.
\label{prob:bfs-movie-network-init}
\end{problem}

\begin{figure}[H]
\centering
\begin{tikzpicture}
% Set styles for Actor and Movie nodes
\tikzstyle{Actor}=[thick,circle,draw=purple,fill=purple!20!,font=\sffamily\footnotesize,align=center,minimum size=1.4cm]
\tikzstyle{Movie}=[thick,rectangle,draw=green!75!black,fill=green!20!,font=\sffamily\footnotesize,align=center,minimum height=1.35cm,minimum width=1.35cm]
% Nodes
\foreach [count=\i] \x/\y/\t/\n in {
    0/1.25/Kevin\\Bacon/Actor,
    5.9/-.75/Jim\\Cummings/Actor,
    2/-3.25/Toby\\Jones/Actor,
    -3.5/-2.5/Jennifer\\Lawrence/Actor,
    -5.5/-.2/James\\McAvoy/Actor,
    3.25/1/{Balto\\(1995)}/Movie,
    4.75/-3/{Christopher\\Robin (2018)}/Movie,
    1.25/-1/{Frost/Nixon\\(2008)}/Movie,
    .-.75/-3/{The Hunger\\Games (2012)}/Movie,
    -2.25/-.4/{X-Men: First\\Class (2011)}/Movie,
    -5.9/-2.5/{X-Men:\\Apocalypse\\(2016)}/Movie,
    -3.5/1.75/{Footloose\\(1984)}/Movie}
  \node[\n] at (\x,\y) (v\i) {\t};
% Edges
\foreach \i/\j in {1/6, 2/6, 2/7, 3/7, 1/8, 3/8, 3/9,
                   4/9, 1/10, 4/10, 5/10,4/11,5/11,1/12}
  \draw[thick] (v\i) edge (v\j);
\end{tikzpicture}
\caption{A subset of the graph in \texttt{movie\_data.txt}.
Each of these actors have a Bacon number of $1$ because they have all been in a movie with Kevin Bacon.
Every actor in \emph{The Hunger Games} has a Bacon number of at most $2$ because of the paths through Jennifer Lawrence or Toby Jones.}
\label{fig:bfs-network-subset}
\end{figure}

\begin{info} % Note that the movie-actor graph is bipartite.
The movie/actor graph of Problem \ref{prob:bfs-movie-network-init} and Figure \ref{fig:bfs-network-subset} has an interesting property: actors are only directly connected to movies, and movies are only directly connected to actors.
This kind of graph is called \emph{bipartite} because there are two types of nodes, and no node has an edge connecting it to another node of its type.
\end{info}

\begin{warn} % nx.draw() only works on small graphs.
NetworkX \li{Graph} objects can be visualized with \li{nx.draw()} (followed by \li{plt.show()}).
However, this visualization tool is only effective on relatively small graphs.
In fact, graph visualization in general remains a challenging and ongoing area of research.
Because of the size of the dataset, \textbf{do not} attempt to visualize the graph in Problem \ref{prob:bfs-movie-network-init} with \li{nx.draw()}.
\end{warn}

The Six Degrees of Kevin Bacon game poses an interesting question: can any actor be linked to Kevin Bacon, and if so, in how many steps?
The game hypothesizes, ``Yes, within $6$ steps'' (hence the title).
More precisely, let the \emph{Bacon number} of an actor be the number of steps from that actor to Kevin Bacon, only counting actors.
For example, since Samuel L. Jackson was in a film with Frank Whaley, who was in a film with Kevin Bacon, Samuel L. Jackson has a Bacon number of $2$.
Actors who have been in a movie with Kevin Bacon have a Bacon number of $1$, and actors with no path to Kevin Bacon have a Bacon number of $\infty$.
The game asserts that the largest Bacon number is $6$.

NetworkX is equipped with a variety of graph analysis tools, including a few for computing paths between nodes (and, therefore, Bacon numbers).
To compute a shortest path between nodes $u$ and $v$, \li{nx.shortest_path()} starts one BFS from $u$ and another from $v$, switching off between the two searches until they both discover a common node.
This approach is called a \emph{bidirectional BFS} and is typically faster than a regular, one-sided BFS.

\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Function & Description\\
    \hline
    \li{has_path()} & Return \li{True} if there is a path between two specified nodes.\\
    \li{shortest_path()} & Return \textbf{one} shortest path between nodes.\\
    \li{shortest_path_length()} & Return the length of the shortest path between nodes.\\
    \li{all_shortest_paths()} & Yield \textbf{all} shortest paths between nodes. \\
    % \li{average_shortest_path_length()} & Compute the average length of shortest paths from every node to every other node in the graph.
\end{tabular}
\caption{NetworkX functions for path problems. Each accepts a \li{Graph}, then a pair of nodes.}
\end{table}

\begin{lstlisting}
>>> G = nx.Graph({'A': {'B', 'D'},
                  'B': {'A', 'D'},
                  'C': {'D'},
                  'D': {'A', 'B', 'C'}})

# Compute the shortest path between 'A' and 'D'.
>>> nx.has_path(G, 'A', 'C')
<<True>>
>>> nx.shortest_path(G, 'A', 'C')
<<['A', 'D', 'C']>>
>>> nx.shortest_path_length(G, 'A', 'C')
2

# Compute all possible shortest paths between two nodes.
>>> G.add_edge('B', 'C')
>>> list(nx.all_shortest_paths(G, 'A', 'C'))
<<[['A', 'D', 'C'], ['A', 'B', 'C']]>>

# When the second node is omitted from these functions, the shortest paths
# from the given node to EVERY node are computed and returned as a dictionary.
>>> nx.shortest_path(G, 'A')
<<{'A': ['A'], 'D': ['A', 'D'], 'B': ['A', 'B'], 'C': ['A', 'D', 'C']}>>
>>> nx.shortest_path_length(G, 'A')     # Path lengths are defined by the
<<{'A': 0, 'D': 1, 'B': 1, 'C': 2}>>        #  number of edges, not nodes.
\end{lstlisting}

\begin{problem} % Individual shortest paths / Bacon numbers.
Write a method for your class from Problem \ref{prob:bfs-movie-network-init} that accepts two actors' names.
Use NetworkX to compute the shortest path between the actors and the degrees of separation between the two actors (if one of the actors is \li{"Kevin Bacon"}, this is the Bacon number of the other actor).
Note that this number is different than the number of entries in the actual shortest path list, since the movies are just intermediate steps between actors and are not counted when calculating the degress of separation.
\label{prob:bfs-actor-path}
\end{problem}

The idea of a Bacon number provides a few ways to analyze the connectivity of the Hollywood network.
For example, the distribution of all Bacon numbers describes how close Kevin Bacon is to actually knowing all of the actors in Hollywood
Someone with a lower average number---for instance, the average \emph{Jackson number}, for Samuel L. Jackson---is, on average, ``more connected with Hollywood'' than Kevin Bacon.
The actor with the lowest average number is sometimes called \emph{the center of the Hollywood universe}.

\begin{problem} % Average Bacon numbers.
\label{prob:bfs-average-bacon-number}
Write a method for your class from Problem \ref{prob:bfs-movie-network-init} that accepts one actor's name.
Calculate the shortest path lengths of every actor in the collection to the specified actor (not including movies).
Use \li{plt.hist()} to plot the distribution of path lengths and return the average path length.
\\(Hint: Use a NetworkX function to compute all path lengths simultaneously; this is significantly faster than calling your method from Problem \ref{prob:bfs-actor-path} repeatedly.
Also, use the keyword argument \li{bins=[i-.5 for i in range(8)]} in \li{plt.hist()} to get the histogram bins to correspond to integers nicely.)
\end{problem}

As an aside, the prolific \href{https://en.wikipedia.org/wiki/Erd%C5%91s_number}{Paul Erd\H{o}s} is the Kevin Bacon equivalent in the mathematical community.
Someone with an \emph{Erd\H{o}s number} of $2$ co-authored a paper with someone who co-authored a paper with Paul Erd\H{o}s.
Having an Erd\H{o}s number of $1$ or $2$ is considered quite an achievement (see \url{https://xkcd.com/599/}).

\newpage

\section*{Additional Material} % ==============================================

\subsection*{Other Hash-based Structures} % -----------------------------------

The standard library has a few specialized alternatives to regular sets and dictionaries.
\begin{itemize}
\item \li{frozenset}: an immutable version of the usual set class.
Frozen sets cannot be altered after creation and therefore lack methods like \li{add()}, \li{pop()}, and \li{remove()}, but they can be placed in other sets and used as dictionary keys.

\item \li{collections.defaultdict}: a dictionary with default values.
For instance, \li{defaultdict(set)} creates a dictionary that automatically uses an empty set as the value whenever a non-present key is used for indexing.
See \href{https://docs.python.org/3/library/collections.html\#defaultdict-examples}{\texttt{https://docs.python.org/3/library/collections.html}} for examples.

\item \li{collections.OrderedDict}: a dictionary that remembers insertion order.
For example, the \li{popitem()} method returns the most recently added key-value pair.
\end{itemize}

\subsection*{Depth-first Search} % --------------------------------------------

A \emph{depth-first search} (DFS) takes the opposite approach of a BFS.
Instead of checking all neighbors of a single node before moving on, it checks the first neighbor, then their first neighbor, then their first neighbor, and so on until reaching a leaf node.
The algorithm then backtracks to the previous node and checks its second neighbor.
While a DFS is rarely useful for finding shortest paths, it is a common strategy for solving recursively structured problems, such as mazes or Sudoku puzzles.

Consider adding a keyword argument to your method from Problem \ref{prob:bfs-traversal} that specifies whether to use a BFS (the default) or a DFS.
To change from a BFS to a DFS, change the visit queue $Q$ to a stack.
You may be able to implement the change in a single line of code.

\subsection*{The Center of the Hollywood Universe} % --------------------------

Computing the center of the universe in a graph amounts to solving Problem \ref{prob:bfs-average-bacon-number} for every node in the graph.
This is computationally expensive, but since each average number is independent of the others, the problem is a good candidate for \emph{parallel programming}, which divides the computational workload between multiple processes.
Even with parallelism, however, computing the center of the Hollywood universe may require significant computational time and resources.

\subsection*{Shortest Paths on Weighted Graphs} % -----------------------------

The graphs presented in this lab are \emph{unweighted}, meaning all edges have the same importance.
A \emph{weighted graph} assigns a weight to each edge, which can usually be thought of as the distance between the two adjacent nodes.
The shortest path problem becomes much more complicated on weighted graphs, and requires additions to the plain BFS.
The standard approach is \emph{Dijkstra's algorithm}, which is implemented as \li{nx.dijkstra_path()}.
Another approach, the \emph{Bellman-Ford algorithm}, is implemented as \li{nx.bellman_ford_path()}.


\documentclass[11pt]{article}

\usepackage{mathtools}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{listings}
%for dotex
\usepackage[pdftex]{graphicx}
\usepackage[pdf]{graphviz}
\usepackage[boxed]{algorithm2e} %end for dote
\usepackage{color}

\lstset{ %
    language=c++,
    identifierstyle=\textbf
}

\title{Everything is Search}
\author{Maxim Noah Khailo}
\begin{document}
\maketitle
\section{What is Dynamic Website Display Really?}

Whenever you display something on a web page with dynamic content, it requires search.
The typical case is searching by id, or within some time range. These are what are called
precise queries and the results are typically exactly accurate. Or perfect matches.

\begin{itemize}
    \item But why should the queries be precise?
    \item Why can't the system figure out which appropriate image or which description to show at any moment?
    \item And why does the result have to be one item and not a set?
\end{itemize}

This article attempts to answer these questions and create a novel model for storing
and retrieving content such as product descriptions, image references, recommendations, etc.
Automatically choosing the most appropriate item to display based on user feedback.

\section{Search and Selection}

There are two fundamental ideas that I will attempt to generalize and combine
in an interesting way.

\subsection{Search}

Any dynamic website display requires search. Generally this is achieved by a precise
search represented as a predicate. A predicate on a set of objects creates a subset.

\newpage
Example predicates might be...
\begin{itemize}
    \item Object with id X.
    \item Objects between time $T_1$ and $T_2$.
\end{itemize}

The first insight is that search does not have to be precise and can take a different
form. One such form is is a spatial N-Nearest Neighbors search. This type of search
answers a different sort of query.

\begin{itemize}
    \item N Items that are similar to X.
\end{itemize}

And instead of using a predicate, we use the concept of `close' which is defined
by a distance function.

\subsection{Selection}

Generally a search is done on a set of objects such as products, customers, images, etc.
The second generalization is that, instead of searching on a set of objects, we can search on a
set of sets instead.

\begin{itemize}
    \item Customer Groups instead of Customers.
    \item Product Representations instead of Products.
\end{itemize}

This derivative approach requires a second algorithm called "Selection".
Selection is a function that takes a set and chooses and object from that set
based on some criteria.

\begin{enumerate}
    \item Given subset G of sets after a search.
    \item Select object O from each set in G for display.
\end{enumerate}

This is powerful because it means we can provide multiple representations of a product
(multiple images, descriptions, and layouts) and can have some function to choose which
one is most appropriate to display. I will provide one such selection algorithm later here.

\section{Spatial Search}
\subsection{Representing Information as Multi-Dimensional Vectors}

Most information can be summarized using a multi-dimensional vector called a feature vector.
Feature vectors are multi-dimensional numerical representations of some kind interesting information.

\begin{equation}
    < 1, 5, 23, ..., n >
\end{equation}

The vector above stores each component as a number and each component belongs to a dimension.
For example you can store a 2D point as a vector

\begin{equation}
    < x, y >
\end{equation}

Where the first component is the x dimension, and the second is the y dimension.

Any piece of information can be mapped to a vector with N dimensions. Mappings
can be exact or lossy. We can attempt to map a product to a vector like so

\begin{equation}
    < id >
\end{equation}

Above is a vector of one dimension where the product id is used as the value.
This is what most databases do when you search for ID. They store the ID in some
spatial data structure and retrieve a pointer to the actual data.

We can also store another mapping of a product like this.

\begin{equation}
    < language, region, modality, category, id>
\end{equation}

Where we assign a numerical value to each item. This can also be stored in a spatial
data structure like a KD-Tree.

\subsection{Defining Distance}

Lets go back to our previous example of the 2D point.

\begin{equation}
    < x, y >
\end{equation}

We can compute how far apart two 2D points are by subtracting the vectors and
and computing the distance via Pythagorean Theorem.

\begin{equation}
    distance(<x_1, y_1>, <x_2, y_2>) = \sqrt{(x_1-x_2)^2 + (y_1-y_2)^2}
\end{equation}

The beauty of the Pythagorean Theorem is that it works with vectors of arbitrary
dimensions.

This means we can take any feature vector and compute how close two of them are.
So if we take our previous product representation minus the id...

\begin{equation}
    < language, region, modality, category>
\end{equation}

We can compute the distance between two products

\begin{equation}
    distance = \sqrt{(language_1-language_2)^2 + ... + (category_1 - category_2)^2}
\end{equation}

There are many data structures which can compute N-Nearest Neighbors like KD-Tree
or cover tree.

\subsection{Other Distance Functions}

Pythagorean theorem is one approach to computing distance.
Distance can also be computed using other functions...

\begin{itemize}
    \item Projected vector to the surface of a Hyper-Sphere and use Cosine Distance.
    \item Compute an approximation of distance using Hamming Distance.
    \item If the vector represents text, you can use an edit distance algorithm like
          Wagner-Fischer.
\end{itemize}

\subsection{Clustering}
The advantage of creating feature vectors is that they can be stored in a spatial
data structure and queried. Since the feature vectors can store a lossy representation
of the information, you can perform fuzzy searches and cluster similar objects together.

For example, you can cluster information via K-Means. We can store the vectors
in something like a KD-Tree or Cover Tree to speedup N-Nearest Neighbor search.

\section{Dynamic Selection}

Instead of an object, we can attach a set of objects instead to our feature vectors.
This means we need a selection algorithm after our search to choose what to display.
Why not just point to the object we want to display directly? Because we don't
actually know what we want to display!

For example, what if you have multiple images or descriptions for a product.
Which one is best to display? Even harder, which one is better to display on the
storefront vs mobile vs a 3rd party like Amazon or Ebay?

We need to answer this kind of question with data and a selection algorithm.

\subsection{The Multi-Armed Bandit Problem}

We can formalize our selection problem as the multi-armed bandit problem.
That is the expected "payout" from each object in the set has yet to be determined
and we want a strategy for choosing one with the highest payout as we accumulate more data.

For example, we don't know which image, or product description is most appropriate
to display. The multi-armed bandit model is an attempt to address this by having an
adaptive algorithm that accumulates data and chooses the most appropriate object
with the most payout. Where payout here can be clicks over impressions.

There are usually two phases in the approach called the exploratory phase and the
exploitation phase. One of the most simplest strategies to tackling these phases
is called the Epsilon-Greedy strategy.

This is where for some percentage, you choose the object with the highest payout,
and for the rest, you pick at random.

\subsection{Computing Payout}

Determining payout requires counting. For a website that normally means counting
impressions and clicks, where clicks are considered a payout. The object with the
highest payout is computed by taking clicks over impressions.

\begin{equation}
    payout = clicks / impressions
\end{equation}

Given our feature vector pointing to a set of objects. Each object needs to have
statistics attached to it. We can store simple counts but that doesn't provide
valuable information for insights. What we need to do is store these values in a
time series database. It is also preferable that we store the integrated value,
"the total", in this time series database because we can compute changes over time
using simple subtraction between times.

\begin{align*}
    clicks &= clicks[t_1] - clicks[t_2] \\
    impresions &= impressions[t_1] - impressions[t_2] \\
    payout &= clicks / impressions
\end{align*}

Having a time series database will also allow us to provide graphs for insights
and demonstrate the system's effectiveness at improving payout.

For example, if we store the clicks and impressions on the set that the feature
vector points to, and not just the objects of the set, then we can graph the improvements
in payout when our system makes decisions on what to display. We can graph
the points when our algorithm chooses to switch display and then we should see
an improvement in payout over time.

\subsection{Contextualized Bandit}

There is a version of Multi-Armed Bandit that uses a context feature vector to
help drive deciding what to choose. Given my idea of search and selection, using
feature vectors pointing to sets of objects, we can easily implement fancier algorithms
in the future since we will essentially have a context vector.

This includes training linear classifiers, neural nets, etc.

\section{What does MVP look like?}

This system sounds like a lot of work to build, and it is. However we can build it
in a lean way, just-in-time, when customers want it by having the right architecture.

MVP to me looks like a normal content system with the following generalizations

\subsection{Have a place to Switch Index Based on Feature Vector}

In an MVP, each object has a feature vector with one value, which has the id of the object.
We then have a place in our system to change which index we search with the feature vector.
In the beginning, this function would just point to ES or Postgresql and search
for id as a normal content system would.

\subsection{Have a Set of One}

Each index has a node object that looks like this.

\begin{lstlisting}
    class index_node
    {
        std::vector<int> feature_vector;
        std::set<object_ptr> objects;
    };
\end{lstlisting}

In MVP, the objects attribute would have only \emph{one} object. This is a generalization of the form

\begin{lstlisting}
    class traditional_index_node
    {
        int id;
        object_ptr object;
    };
\end{lstlisting}

Which is what you find in typical content systems.

\subsection{Have a Simple Selection Function}

Given our index\_node object described above, we can have a selection function
that looks like this.

\begin{lstlisting}
    object_ptr select(index_node& n)
    {
        return n.objects[0];
    }
\end{lstlisting}

This would obviously be a equivalent to this if we had the traditional\_index\_node

\begin{lstlisting}
    object_ptr select(traditional_index_node& n)
    {
        return n.object;
    }
\end{lstlisting}

\subsection{Store Statistics to /dev/null}

We have a place in the system to count stats like clicks and impressions.

\begin{lstlisting}
    void store_stat(time_t, string, int);
\end{lstlisting}

Where the implementation in the first go looks like this.

\begin{lstlisting}
    void store_stat(time_t timestamp, string key, int value)
    {
    //do nothing
    }
\end{lstlisting}

In MVP we would not even write a function to retrieve stats.

\section{Summary}

We have an opportunity to innovate how content is managed and displayed.
I proposed here a generalization of how most content systems store
and retrieve content.

By having a place in our architecture to select indexes based on feature vectors,
where the index nodes point to a set of objects, and we store stats in a time series
database, we can create new ways to manage content and have a system that adapts
to changes in customers and demand.

The best part, this system can be built just-in-time using a small set of
architectural decisions early on.

\end{document}


\chapter{Hypothesis Testing for Chapter \ref{rnns-causal}} \label{eval}

\citet{abadie2010synthetic} propose a randomization inference approach for calculating the exact distribution of placebo effects under the sharp null hypothesis of no effect. \citet{cavallo2013catastrophic} extends the placebo-based testing approach to the case of multiple (placebo) treated units by constructing a distribution of \emph{average} placebo effects under the null hypothesis. \citet{firpo2018synthetic} derive the conditions under which the randomization inference approach is valid from a finite sample perspective and \citet{hahn2017synthetic} analyze the approach from a repeated sampling perspective.

Randomization $p$-values are obtained following these steps:

\begin{enumerate}
	\item Estimate the observed test static $\boldsymbol{\hat{\upphi}}$ from (\ref{eq:pointwise}). Averaging over the time dimension results in a $\text{T}_\star$-length array of observed average treatment effects.
	\item Calculate every possible average placebo treated effect $\upmu$ by randomly sampling without replacement which $\text{J}-1$ control units are assumed to be treated. There are $\mathcal{Q} = \sum\limits_{\text{g}=1}^{\text{J}-1} {\text{J} \choose \text{g}}$ possible average placebo effects.\footnote{Since calculating $\mathcal{Q}$ can be computationally burdensome for relatively high values of $J$, I artificially set $\mathcal{Q} = 10,000$ in cases when $\text{J} > 16$.} The result is a matrix of dimension $\mathcal{Q} \times \text{T}_\star$
	\item Sum over the time dimension the number of $\upmu$ that are greater than or equal to $\boldsymbol{\hat{\upphi}}$.  \label{counts}
\end{enumerate}

Each element of the vector obtained from Step \ref{counts} is divided by $\mathcal{Q}$ to estimate a $\text{T}_\star$-length vector of exact two-sided $p$ values, $\hat{p}$.

\subsection{Randomization confidence intervals}

Under the assumption that treatment has a constant additive effect $\Delta$, I construct an interval estimate for $\Delta$ by inverting the randomization test. Let $\updelta_\Delta$ be the test statistic calculated by subtracting all possible $\upmu$ by $\Delta$. I derive a two-sided randomization confidence interval by collecting all values of $\updelta_\Delta$ that yield $\hat{p}$ values greater than or equal to significance level $\upalpha=0.05$. I find the endpoints of the confidence interval by randomly sampling 500 values of $\Delta$.


\section{Working with the console}

The console is a tool to work with graphs by entering commands rather
than by clicking the mouse buttons. This is especially convenient if
you want to create large subgraphs with a regular pattern.

By default, the console is the frame below the main frame with the
graph. Here, in the bottom line, you can enter commands just like in a
terminal.

\subsection{Lists}

The objects you work with are \emph{lists:} lists of vertices and
lists of edges. We concentrate on vertex lists in this manual, edge
lists behave similarly. Where appropriate, we point out the
differences.

The lists are used to connect them later.

\begin{example}[Running example]
  For example, if one wants to create a perfect matching with $50$
  edges, one way to do that in Gralog is to create two disjoint lists
  of vertices and then connect them by drawing an edge from vertex $i$
  in the first list to vertex $i$ in the second list. Well, for a
  matching we would use a generator (see
  Section~\ref{sec:generators}), but what if we want to add edges such
  that already exiting $100$ vertices build a matching?
  \label{ex:running}
\end{example}

\subsection{Creating lists, (de)selecting elements}

All lists can be created out of the default list of all
vertices and the internal list of all currently selected vertices. The
latter can be made with the mouse in the obvious way or you can write
in the command line:
\\\begin{tcolorbox}
  select all vertices
\end{tcolorbox}
\noindent
to select all vertices. By the way, in a similar way, all vertices are
deselected:
\\\begin{tcolorbox}
deselect all vertices
\end{tcolorbox}

Now use the selection to create a new list. The corresponding command
is \texttt{filter}: one filters the elements from an existing list
according to certain criteria and saves them into another list. If the
other list already exists, the new elements are appended to it (even
if they are already contained in the target list).
\\\begin{tcolorbox}
  filter all selected where no condition to VL1
\end{tcolorbox}

When creating list ids as \texttt{VL1}, keep in mind that the names
must be unique, in particular, it is impossible that a vertex list and
an edge list have the same name.

\subsection{Filter}

Now we created a new list \texttt{VL1} containing all vertices of the
graph. Let us now create a new list that contains only vertices with a
certain property, say those whose colour is blue. We can now use
\texttt{VL1} as a source of vertices.
\\\begin{tcolorbox}
  filter VL1 where fill color blue to VLblue
\end{tcolorbox}

Now the list \texttt{VLblue} contains all vertices with fill color
\texttt{blue}. Ne create a new list containing all vertices whose fill
color is red. Note in the following example that instead of the
keyword \texttt{where} one can write \texttt{such that} or
\texttt{st}. Note also that instead of \texttt{fill color} it is
possible to use just \texttt{fill}:
\\\begin{tcolorbox}
  filter VL1 st fill red to VLred
\end{tcolorbox}

The full specification of the filter command is as follows. Note that
Gralog does not distinguish between the upper and the lower cases.
\\\begin{tcolorbox}[colback=lightpink]
  FILTER <what> WHERE|ST|(SUCH THAT) <parameters> TO <list identifier>
  [ignored trash]
\end{tcolorbox}

\noindent where
\\\begin{tcolorbox}[colback=lightpink]
  \begin{tabular}[H]{rl}
    <what> := &ALL VERTICES | ALL EDGES\\
              &| [ALL ]? SELECTED VERTICES | [ALL ]? SELECTED EDGES\\
              & | <list id> \\[0.3cm]
    <parameters> := &<parameters> <parameters> | <boolean parameter>\\
              & | <fixed range parameter> <value>\\
              &| <numerical parameter> <cmp> <value> \\[0.3cm]
%                    & | FORMULA <integer expression(i)>\\
    <fixed range parameter> := & SHAPE | TYPE | EDGE TYPE | EDGETYPE \\[0.3cm]
    <numerical parameter> := & <integer parameter> | <float
                               parameter> | <string parameter>\\[0.3cm]
    <integer parameter> := & ID | DEGREE | INDEGREE |
                             OUTDEGREE\\[0.3cm]
    <float parameter> := & FILL | FILL COLOR | STROKE | STROKE
                       COLOR\\
                     &| THICKNESS | WIDTH | HEIGHT | SIZE |
                       WEIGHT\\[0.3cm]
    <string parameter> := &LABEL CONTAINS\\
    <boolean parameter> := &NO CONDITION | HAS SELFLOOP | DIRECTED | HAS
                             LABEL\\
              &| LABEL EMPTY | NO LABEL \\
                     &| BUTTERFLY // not implemented yet
  \end{tabular}
\end{tcolorbox}

In other words, we can write something like
\\\begin{tcolorbox}
  FILTER sourceList ST FILL RED STROKE BLUE SHAPE ELLIPSE DEGREE > 3 TO targetList
\end{tcolorbox}

Let us look at the grammar closer. In \texttt{<what>} there is no
difference between \texttt{ALL SELECTED VERTICES} and \texttt{SELECTED
VERTICES}, the result will be the same. The \texttt{<list id>} is the
name of a list we defined previously, it can be a list of vertices or
a list of edges.

The order of parameters in the parameter list is arbitrary. The list
of parameters cannot be empty. If you do not want any specifications,
choose \texttt{NO CONDITION}. In that case even if other parameters
are given, they are not taken into account and the whole source list
is given. This can be in particular used to duplicate every element in
a list:
\\\begin{tcolorbox}
  FILTER sourceList ST NO CONDITION TO newList

  FILTER sourceList ST NO CONDITION TO newList
\end{tcolorbox}

In this case \texttt{newList} will contain every element of
\texttt{sourceList} twice. By the way, being in the command line, one
can press $\uparrow$ (the arrow up key) to call previous commands.

Table~\ref{tab:parsAndVals} explains which values the parameters can have.

\begin{table}
  \centering
  \begin{tabular}{p{3cm}|p{5cm}|p{1.8cm}|p{5cm}}
    \textbf{parameter} &  \textbf{possible values} & \textbf{applicable to}  & \textbf{meaning}\\
    \hline
    \texttt{SHAPE}     &  ELLIPSE, RECTANGLE, DIAMOND & vertices& ellipse,
                                                                  rectangle, diamond\\
                       &  SQUARE, CYCLE & vertices & not implemented yet\\
    \hline
    \texttt{STROKE} or \texttt{STROKE COLOR} (synonyms)
                       &  WHITE, BLACK, BLUE, GREEN, RED, GRAY, \mbox{YELLOW},
                         CYAN, MAGENTA, SILVER, MAROON, OLIVE,
                         DARK\_GREEN, PURPLE, TEAL, NAVY, ORANGE
                                                   & both & the colour of the
                                                            border; other
                                                            colours are
                                                            possible as
                                                            properties of
                                                            vertices, but not
                                                            supported by the
                                                            filter
                                                            command\\
    \hline
    \texttt{EDGE TYPE} & SHARP, ROUND, BEZIER & edges & sharp or rounded
                                                        corners or a
                                                        B\'{e}zier curve\\
    \hline
    \texttt{FILL} or \texttt{FILL COLOR} (synonyms)
                       & as for \texttt{STROKE} & vertices & the fill color,
                                                             otherwise as for
                                                             \texttt{STROKE}\\
    \hline
    \texttt{WIDTH}     & float                 & vertices & \tcr{???}\\
    \hline
    \texttt{THICKNESS} & float                 & both\tcr{?} & \textcolor{red}{???}\\
    \hline
    \texttt{HEIGHT}     & float                & vertices  & \textcolor{red}{???}\\
    \hline
    \texttt{SIZE} & float                      & vertices \tcr{?}  & \textcolor{red}{???}\\
    \hline
    \texttt{WEIGHT} & float                      & edges  &
                                                            \textcolor{red}{???}\\
    \hline
    \texttt{ID}      & non-negative integer   & both & the internal unique id of
                                                       the vertex or of the edge\\
    \hline
    \texttt{DEGREE}    & non-negative integer & vertices & the degree of
                                                           the vertex;
                                                           only
                                                           undirected
                                                           edges count\\
    \hline
    \texttt{INDEGREE}    & non-negative integer & vertices & the in-degree of
                                                             the vertex;
                                                             only
                                                             directed
                                                             edges count\\
    \hline
    \texttt{OUTDEGREE}    & non-negative integer & vertices & the out-degree of
                                                              the vertex;
                                                              only
                                                              directed
                                                              edges count\\
    \hline
    \texttt{HAS SELFLOOP}  & no value & vertices & true if the vertex
                                                   has a self-loop\\
    \hline
    \texttt{NO SELFLOOP}  & no value & vertices & true if the vertex
                                                  has no self-loop\\
    \hline
    \texttt{LABEL EMPTY} or \texttt{NO LABEL} (synonyms)
                       & no value & vertices & true if the label is
                                               empty\\
    \hline
    \texttt{LABEL CONTAINS} & string & vertices & true if the label
                                                  contains the given string\\
    \hline
  \end{tabular}
  \caption{Parameters and their values}
  \label{tab:parsAndVals}
\end{table}

\subsection{Sorting the lists}

Before connecting lists of vertices (recall Example~\ref{ex:running})
we probably want to sort them, so that we know what vertex has
number~$i$. The lists can be sorted by
\\\begin{tcolorbox}[colback=lightpink]
  SORT <list id> <parameter>
\end{tcolorbox}%
where \texttt{parameter} is one of \texttt{LEFTRIGHT},
\texttt{RIGHTLEFT}, \texttt{TOPDOWN}, \texttt{BOTTOMUP}, \texttt{ID
  ASC}, \texttt{ID DECS}, \texttt{LABEL ASC}, \texttt{LABEL DESC}. The
former four parameters imply a sorting according to the corresponding
coordinate of vertices on the screen, \texttt{ID ASC} sorts by the id
in  the ascending order, \texttt{ID DESC} sorts by the id
in  the descending order and \texttt{LABEL} sorts alphabetically
(ascending or descending) by the label. If the labels of two vertices
are equal, the vertices keep their relative order.

\subsection{Operations on lists (before connecting)}

The following operations are currently supported:
\\\begin{tcolorbox}[colback=lightpink]
  \begin{tabular}[H]{p{7cm}|p{8cm}}
    \textbf{operation}    & \textbf{meaning}\\
    DELETE <list id> & deletes the list, but not the elements of the list from the graph\\

    UNION <source1> <source2> TO <target> & creates the union of \texttt{source1} and \texttt{source2} and stores the result in \texttt{target}\\

    INTERSECTION <list1 id> <list2 id> TO <list3 id> &creates the intersection of \texttt{source1} and \texttt{source2} and stores the result in \texttt{target}\\

    DIFFERENCE <source1> <source2> TO <target> & creates the difference of \texttt{source1} and \texttt{source2} and stores the result in \texttt{target}\\

    SYMMETRIC DIFFERENCE <source1> <source2> TO <target>  & creates the symmetric difference of \texttt{source1} and \texttt{source2} and stores the result in \texttt{target}\\

    COMPLEMENT <list id> TO <target>  & creates the complement of \texttt{list id} and stores the result in \texttt{target}.\\

    CONTRACT <vertex list id> | <edge list id> | SELECTED & builds a minor of the graph by contracting the subgraph induced by the elements of the list or by the selected elements (if \texttt{SELECTED} is specified and some elements are selected) to a single vertex. Works for all kinds of graphs. Not implemented yet.\\
    BUTTERFLY CONTRACT <edge list id> & builds a butterfly minor of the graph by butterfly contracting all butterfly contractable edges. On undirected edges the operation has no effect. Not implemented yet.\\

    SUBDIVIDE <edge list id> <$n$> & subdivides every edge from the list $n$ times where $n$ must be a natural number. Directed edges are replaced by directed paths of length $n+1$. Not implemented yet.
  \end{tabular}
\end{tcolorbox}

\subsection{Connecting lists of vertices}

One can either connect one list of vertices to another, which, however, can be the same list, or connect vertices of one list in a certain way. The first is done by the command
\\\begin{tcolorbox}[colback=lightpink]
  CONNECT <list1> <list2> =<formula> | BICLIQUE | MATCHING
\end{tcolorbox}

The easier case is to use a standard way of connection, for example,
\\\begin{tcolorbox}[colback=palegreen]
  CONNECT upper lower MATCHING
\end{tcolorbox}
which produces a matching connecting the $i$th vertex of
\texttt{list1} to the $i$th vertex of \texttt{list2}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gralog"
%%% End:


\documentclass[twoside]{MATH77}
\usepackage{multicol}
\usepackage[fleqn,reqno,centertags]{amsmath}
\DeclareRobustCommand{\us}{\rule{.2pt}{0pt}\rule[-.8pt]{.4em}{.5pt}\rule{.7pt}{0pt}}
\begin{document}
\begmath 19.6  Running Problems in Matrix Market Format With Codes in Chapter 4.7

\silentfootnote{$^\copyright$ \thisyear \ Math \`a la Carte, Inc.}

\subsection{Purpose}

These programs written in C will output either a Fortran code or a C
code which will solve sparse matrix problems entered in Matrix Market
Format, see \url{http://math.nist.gov/MatrixMarket/}.

\subsection{Usage}
Edit the two define's at the start of the code for your desired use,
and compile the code.  Make up a file named mmjob which contains a
list of names for the matrix market files that you may have an
interest in running and that are stored on your machine.
\begin{center}
\fbox{\begin{tabular}{@{\bf }c}
mmgen [--Options] Path [name\us 1] [name\us 2] ...\\
\end{tabular}}
\end{center}

Options are a string of letters and numbers interpreted as follows.
\begin{description}
\item[[a] Process all lines in mmjob after processing the last
  name\us k.  If no names are given, start with the first name in mmjob.
\item[t] Save the transpose of the matrix, and solve $A^T \mathbf{x} =
  \mathbf{b}$.
\item[b0--b9] Specify the number of right hand sides in $\mathbf{b}$.
  The defauls is b1.  In the case of 0, the matrix is factored, and
  another call is made to solve the problem with a single right hand
  side.
\item[c] Compute the reciprocal of the condition number.
\item[d] Compute the determinant.
\end{description}

\subsection{Examples and Remarks}

The file mmjob listed at the end of this document gives the output
shown.

\subsection{Functional Description}

Not applicable.

\subsection{Error Procedures and Restrictions}
\label{sec:errors}
In the case of input errors, an error message is printed.

\subsection{Supporting Information}

The source language is C.

Design and programming by Fred T. Krogh, Math \`a la Carte, Inc.
March 2006.

The random number generator from Chapter 3.1 is called by the drivers
generated.
\begcode
\vspace {10pt}
~\\
\normalsize
The File mmjob\\
1138\us bus\\
CRY10000\\
CURTIS54\\
add32\\
arc130\\
cry2500\\
e20r5000\\
small1\\

\begin{verbatim}
./mmgen -acd ./mmarket

 Problem      N  Seconds   RESERR     XERR      Unused     Used    RCOND     DET   x 10^?
1138_bus   1138    0.016  1.87E-16  4.44E-16     36816     16895  3.98E-08  6.78450  2151
CRY10000  10000    1.620  1.17E-15  6.31E-03   1675872   1554563  2.52E-28  6.30195 15523
CURTIS54     54    0.000  1.46E-15  3.20E-14      2513      1930  1.15E-03 -1.78000    -8
   add32   4960    0.292  6.21E-16  1.34E-14    738755    211828  2.23E-03  1.13981 -9892
  arc130    130    0.004  4.27E-16  1.43E-09      7736     12327  8.83E-08  1.10261     3
 cry2500   2500    0.100  7.27E-16  1.19E-04     98883    240714  3.09E-24  8.65650  2445
e20r5000   4241    1.828  8.14E-14  6.79E-10   2677775   2085209  2.95E-10 -1.24088  -671
  small1     54    0.000  1.46E-15  3.20E-14      2513      1930  1.15E-03 -1.78000    -8
\end{verbatim}

\end{document}