% !TEX root = hott_intro.tex

\section{Equivalences}
\index{equivalence|(}

We introduce equivalences in this section as functions that have a left inverse and a separate right inverse. This choice of definition might seem a little strange: why would we not say that an equivalence map is a map $f:A\to B$ for which there is a map $g:B\to A$ that is at the same time a left and a right inverse? We will be able to show, after all, that if a map has separate left and right inverses, then it has an inverse. For a precise answer to this question we will have to wait until \cref{chap:univalent-mathematics}, but we can say already that it turns out to be important that the condition of being an equivalence is a property, not structure. We have chose the definition of equivalences with a separate left and right inverses so that being an equivalence will indeed be a property.

\subsection{Homotopies}
\index{homotopy|(}
In homotopy type theory, a homotopy is just a pointwise equality between two functions $f$ and $g$. We view the type of homotopies as the observational equality for $\Pi$-types.\index{observational equality!of Pi-types@{of $\Pi$-types}}

\begin{defn}
Let $f,g:\prd{x:A}P(x)$ be two dependent functions. The type of \define{homotopies}\index{homotopy} from $f$ to $g$ is defined as the type of pointwise identifications, i.e., we define\index{f htpy g@{$f\htpy g$}|see {homotopy}}
\begin{equation*}
f\htpy g \defeq \prd{x:A} f(x)=g(x).
\end{equation*}
\end{defn}

Note that the type of homotopies $f\htpy g$ is a special case of a dependent function type. Therefore the definition of homotopies is set up in such a way that we may also consider homotopies \emph{between}\index{homotopy!iterated}\index{iterated homotopies} homotopies, and even further homotopies between those higher homotopies. More concretely, if $H,K:f\htpy g$ are two homotopies, then the type of homotopies $H\htpy K$ between them is just the type
\begin{equation*}
\prd{x:A} H(x)=K(x).
\end{equation*}

\index{groupoid laws!of homotopies|(}
\index{homotopy!groupoid laws|(}
In the following definition we define the groupoidal structure of homotopies. Note that we implement the groupoid laws as \emph{homotopies} rather than as identifications.

\begin{defn}\label{defn:htpy_groupoid}\index{groupoid laws!of homotopies}
For any type family $B$ over $A$ there are operations\index{homotopy!refl-htpy@{$\reflhtpy$}}\index{refl-htpy@{$\reflhtpy$}}\index{homotopy!inv-htpy@{$\invhtpy$}}\index{inv-htpy@{$\invhtpy$}}\index{homotopy!concathtpy@{$\concathtpy$}}\index{concathtpy@{$\concathtpy$}}
\begin{align*}
\reflhtpy & : \prd{f:\prd{x:A}B(x)}f\htpy f \\
\invhtpy & : \prd{f,g:\prd{x:A}B(x)} (f\htpy g)\to(g\htpy f) \\
\concathtpy & : \prd{f,g,h:\prd{x:A}B(x)} (f\htpy g)\to ((g\htpy h)\to (f\htpy h)).
\end{align*}
We will write $H^{-1}$ for $\invhtpy(H)$, and $\ct{H}{K}$ for $\concathtpy(H,K)$.

Furthermore, we define
\begin{align*}
\assochtpy(H,K,L) & : \ct{(\ct{H}{K})}{L}\htpy\ct{H}{(\ct{K}{L})} \\
\leftunithtpy(H) & : \ct{\reflhtpy_f}{H}\htpy H \\
\rightunithtpy(H) & : \ct{H}{\reflhtpy_g}\htpy H \\
\leftinvhtpy(H) & : \ct{H^{-1}}{H} \htpy \reflhtpy_g \\
\rightinvhtpy(H) & : \ct{H}{H^{-1}} \htpy \reflhtpy_f
\end{align*}
for any $H:f\htpy g$, $K:g\htpy h$ and $L:h\htpy i$, where $f,g,h,i:\prd{x:A}B(x)$.
\end{defn}

\begin{constr}
We define
\begin{align*}
\reflhtpy(f) & \defeq \lam{x} \refl{f(x)} \\
\invhtpy(H) & \defeq \lam{x} H(x)^{-1} \\
\concathtpy(H,K) & \defeq \lam{x}\ct{H(x)}{K(x)},
\end{align*}
where $H:f\htpy g$ and $K:g\htpy h$ are homotopies. Furthermore, we define
\begin{align*}
\assochtpy(H,K,L) & \defeq \lam{x}\assoc(H(x),K(x),L(x)) \\
\leftunithtpy(H) & \defeq \lam{x}\leftunit(H(x)) \\
\rightunithtpy(H) & \defeq \lam{x}\rightunit(H(x)) \\
\leftinvhtpy(H) & \defeq \lam{x}\leftinv(H(x)) \\
\rightinvhtpy(h) & \defeq \lam{x}\rightinv(H(x)).\qedhere
\end{align*}
\end{constr}
\index{groupoid laws!of homotopies|)}
\index{homotopy!groupoid laws|)}

Apart from the groupoid operations and their laws, we will occasionally need \emph{whiskering} operations.

\begin{defn}
We define the following \define{whiskering}\index{homotopy!whiskering operations}\index{whiskering operations!of homotopies} operations on homotopies:
\begin{enumerate}
\item Suppose $H:f\htpy g$ for two functions $f,g:A\to B$, and let $h:B\to C$. We define\index{h . H@{$h\cdot H$}|see {homotopy, whiskering operations}}
\begin{equation*}
h\cdot H\defeq \lam{x}\ap{h}{H(x)}:h\circ f\htpy h\circ g.
\end{equation*}
\item Suppose $f:A\to B$ and $H:g\htpy h$ for two functions $g,h:B\to C$. We define\index{H . f@{$H\cdot f$}|see {homotopy, whiskering operations}}
\begin{equation*}
H\cdot f\defeq\lam{x}H(f(x)):h\circ f\htpy g\circ f.
\end{equation*}
\end{enumerate}
\end{defn}

We also use homotopies to express the commutativity of diagrams. For example, we say that a triangle\index{homotopy!commutative diagram}
\begin{equation*}
  \begin{tikzcd}[column sep=tiny]
    A \arrow[rr,"h"] \arrow[dr,swap,"f"] & & B \arrow[dl,"g"] \\
    & X
  \end{tikzcd}
\end{equation*}
commutes if it comes equipped with a homotopy $H:f\htpy g\circ h$, and we say that a square
\begin{equation*}
  \begin{tikzcd}
    A \arrow[r,"g"] \arrow[d,swap,"f"] & A' \arrow[d,"{f'}"] \\
    B \arrow[r,swap,"h"] & B'
  \end{tikzcd}
\end{equation*}
if it comes equipped with a homotopy $h \circ f\htpy g\circ f'$.
\index{homotopy|)}

\subsection{Bi-invertible maps}

\begin{defn}
Let $f:A\to B$ be a function. We say that $f$ has a \define{section}\index{section!of a map}\index{function!has a section} if there is a term of type\index{sec(f)@{$\sections(f)$}}
\begin{equation*}
\sections(f) \defeq \sm{g:B\to A} f\circ g\htpy \idfunc[B].
\end{equation*}
Dually, we say that $f$ has a \define{retraction}\index{retraction}\index{function!has a retraction} if there is a term of type\index{retr(f)@{$\retractions(f)$}}
\begin{equation*}
\retractions(f) \defeq \sm{h:B\to A} h\circ f\htpy \idfunc[A].
\end{equation*}
If a map $f:A \to B$ has a retraction, we also say that $A$ is a \define{retract}\index{retract!of a type} of $B$.
We say that a function $f:A\to B$ is an \define{equivalence}\index{is an equivalence}\index{function!is an equivalence} if it has both a section and a retraction, i.e., if it comes equipped with a term of type\index{is-equiv(f)@{$\isequiv(f)$}}
\begin{equation*}
\isequiv(f)\defeq\sections(f)\times\retractions(f).
\end{equation*}
We will write $\eqv{A}{B}$\index{A simeq B@{$\eqv{A}{B}$}|see {equivalence}} for the type $\sm{f:A\to B}\isequiv(f)$.
\end{defn}

\begin{rmk}
An equivalence, as we defined it here, can be thought of as a \emph{bi-invertible map}\index{bi-invertible map|see {equivalence}}, since it comes equipped with a separate left and right inverse. Explicitly, if $f$ is an equivalence, then there are
\begin{align*}
g & : B\to A & h & : B\to A \\
G & : f\circ g \htpy \idfunc[B] & H & : h\circ f \htpy \idfunc[A].
\end{align*}
Clearly, if $f$ has an inverse\index{has an inverse}\index{function!has an inverse} in the sense that it comes equipped with a function $g:B\to A$ such that $f\circ g\htpy\idfunc[B]$ and $g\circ f\htpy\idfunc[A]$, then $f$ is an equivalence. We write\index{has-inverse(f)@{$\hasinverse(f)$}}
\begin{equation*}
\hasinverse(f)\defeq\sm{g:B\to A} (f\circ g\htpy \idfunc[B])\times (g\circ f\htpy\idfunc[A]).
\end{equation*}
\end{rmk}

\begin{lem}\label{lem:inv_equiv}
Any equivalence $e:A\simeq B$ can be given the structure of an invertible map.\index{equivalence!has an inverse} We define $e^{-1}$ to be the section $g:B\to A$ of $e$.\index{equivalence!inverse}\index{inverse!of an equivalence}
\end{lem}

\begin{proof}
First we construct for any equivalence $f$ with right inverse $g$ and left inverse $h$ a homotopy $K:g\htpy h$. For any $y:B$, we have
\begin{equation*}
\begin{tikzcd}[column sep=huge]
g(y) \arrow[r,equals,"H(g(y))^{-1}"] & hfg(y) \arrow[r,equals,"\ap{h}{G(y)}"] & h(y).
\end{tikzcd}
\end{equation*}
Therefore we define a homotopy $K:g\htpy h$ by $K\defeq \ct{(H\cdot g)^{-1}}{h\cdot G}$.
Using the homotopy $K$ we are able to show that $g$ is also a left inverse of $f$. For $x:A$ we have the identification
\begin{equation*}
\begin{tikzcd}[column sep=large]
gf(x) \arrow[r,equals,"K(f(x))"] & hf(x) \arrow[r,equals,"H(x)"] & x.
\end{tikzcd}\qedhere
\end{equation*}
\end{proof}

\begin{cor}
The inverse of an equivalence is again an equivalence.\index{inverse!of an equivalence!is an equivalence}\index{is an equivalence!inverse of an equivalence}
\end{cor}

\begin{proof}
Let $f:A\to B$ be an equivalence. By \cref{lem:inv_equiv} it follows that the section of $f$ is also a retraction. Therefore it follows that the section is itself an invertible map, with inverse $f$. Hence it is an equivalence.
\end{proof}

\begin{rmk}\label{thm:id_equiv}
For any type $A$, the identity function $\idfunc[A]$ is an equivalence, since it is its own section and its own retraction\index{identity function!is an equivalence}\index{is an equivalence!identity function}
\end{rmk}

\begin{eg}
  For any type $C(x,y)$ indexed by $x:A$ and $y:B$, the swap function\index{function!swap!is an equivalence}\index{is an equivalence!swap function}
\begin{equation*}
\sigma:\Big(\prd{x:A}\prd{y:B}C(x,y)\Big)\to\Big(\prd{y:B}\prd{x:A}C(x,y)\Big)
\end{equation*}
that swaps the order of the arguments $x$ and $y$ is an equivalence by \cref{ex:swap}.\index{swap function!is an equivalence}
\end{eg}

\subsection{The identity type of a \texorpdfstring{$\Sigma$-}{dependent pair }type}

\index{identity type!of a Sigma-type@{of a $\Sigma$-type}|(}
\index{dependent pair type!identity type|(}
\index{characterization of identity type!Sigma-type@{$\Sigma$-type}|(}
In this section we characterize the identity type of a $\Sigma$-type as a $\Sigma$-type of identity types. In this course we will be characterizing the identity types of many types, so we will follow the general outline of how such a characterization goes:
\begin{enumerate}
\item First we define a binary relation $R:A\to A\to \UU$ on the type $A$ that we are interested in. This binary relation is intended to be equivalent to its identity type.
\item Then we will show that this binary relation is reflexive, by constructing a term of type
  \begin{equation*}
    \prd{x:A}R(x,x)
  \end{equation*}
\item Using the reflexivity we will show that there is a canonical map
  \begin{equation*}
    (x=y)\to R(x,y)
  \end{equation*}
  for every $x,y:A$. This map is just constructed by path induction, using the reflexivity of $R$.
\item Finally, it has to be shown that the map
  \begin{equation*}
    (x=y)\to R(x,y)
  \end{equation*}
  is an equivalence for each $x,y:A$.
\end{enumerate}
The last step is usually the most difficult, and we will refine our methods for this step in \cref{chap:fundamental}, where we establish the fundamental theorem of identity types.\index{fundamental theorem of identity types}

In this section we consider a type family $B$ over $A$. Given two pairs
\begin{equation*}
  (x,y),(x',y'):\sm{x:A}B(x),
\end{equation*}
if we have a path $\alpha:x=x'$ then we can compare $y:B(x)$ to $y':B(x')$ by first transporting $y$ along $\alpha$, i.e., we consider the identity type
\begin{equation*}
  \tr_B(\alpha,y)=y'.
\end{equation*}
Thus it makes sense to think of $(x,y)$ to be identical to $(x',y')$ if there is an identification $\alpha:x=x'$ and an identification $\beta:\tr_B(\alpha,y)=y'$. In the following definition we turn this idea into a binary relation on the $\Sigma$-type.

\begin{defn}
  We will define a relation\index{Eq Sigma@{$\EqSigma$}}\index{dependent pair type!Eq Sigma@{$\EqSigma$}}\index{observational equality!Eq Sigma@{$\EqSigma$}}
  \begin{equation*}
    \EqSigma : \Big(\sm{x:A}B(x)\Big)\to\Big(\sm{x:A}B(x)\Big)\to\UU
  \end{equation*}
  by defining
  \begin{equation*}
    \EqSigma(s,t)\defeq\sm{\alpha:\proj 1(s)=\proj 1(t)}\tr_B(\alpha,\proj 2(s))=\proj 2 (t).
  \end{equation*}
\end{defn}

\begin{lem}
  The relation $\EqSigma$ is reflexive, i.e., there is a term
  \begin{equation*}
    \reflexiveEqSigma:\prd{s:\sm{x:A}B(x)}\EqSigma(s,s).
  \end{equation*}
\end{lem}

\begin{constr}
  This term is constructed by $\Sigma$-induction on $s:\sm{x:A}B(x)$. Thus, it suffices to construct a term of type
  \begin{equation*}
    \prd{x:A}\prd{y:B(x)}\sm{\alpha:x=x}\tr_B(\alpha,y)=y.
  \end{equation*}
  Here we take $\lam{x}\lam{y}(\refl{x},\refl{y})$.
\end{constr}

\begin{defn}
  Consider a type family $B$ over $A$. Then for any $s,t:\sm{x:A}B(x)$ we define a map\index{pair-eq@{$\paireq$}}
  \begin{equation*}
    \paireq: (s=t)\to \EqSigma(s,t)
  \end{equation*}
  by path induction, taking $\paireq(\refl{s})\defeq\reflexiveEqSigma(s)$.
\end{defn}

\begin{thm}\label{thm:eq_sigma}
  Let $B$ be a type family over $A$. Then the map\index{pair-eq@{$\paireq$}!is an equivalence}\index{is an equivalence!pair-eq@{$\paireq$}}
  \begin{equation*}
    \paireq: (s=t)\to \EqSigma(s,t)
  \end{equation*}
  is an equivalence for every $s,t:\sm{x:A}B(x)$.
\end{thm}

\begin{proof}
The maps in the converse direction\index{eq-pair@{$\eqpair$}}
\begin{equation*}
\eqpair : \EqSigma(s,t)\to(\id{s}{t})
\end{equation*}
are defined by repeated $\Sigma$-induction. By $\Sigma$-induction on $s$ and $t$  we see that it suffices to define a map
\begin{equation*}
\eqpair : \Big(\sm{p:x=x'}\id{\tr_B(p,y)}{y'}\Big)\to(\id{(x,y)}{(x',y')}).
\end{equation*}
A map of this type is again defined by $\Sigma$-induction. Thus it suffices to define a dependent function of type
\begin{equation*}
\prd{p:x=x'} (\id{\tr_B(p,y)}{y'}) \to (\id{(x,y)}{(x',y')}).
\end{equation*}
Such a dependent function is defined by double path induction by sending $\pairr{\refl{x},\refl{y}}$ to $\refl{\pairr{x,y}}$. This completes the definition of the function $\eqpair$.

Next, we must show that $\eqpair$ is a section of $\paireq$. In other words, we must construct an identification
\begin{equation*}
\paireq(\eqpair(\alpha,\beta))=\pairr{\alpha,\beta}
\end{equation*}
for each $\pairr{\alpha,\beta}:\sm{\alpha:x=x'}\id{\tr_B(\alpha,y)}{y'}$. We proceed by path induction on $\alpha$, followed by path induction on $\beta$. Then our goal becomes to construct a term of type
\begin{equation*}
\paireq(\eqpair\pairr{\refl{x},\refl{y}})=\pairr{\refl{x},\refl{y}}
\end{equation*}
By the definition of $\eqpair$ we have $\eqpair\pairr{\refl{x},\refl{y}}\jdeq \refl{\pairr{x,y}}$, and by the definition of $\paireq$ we have $\paireq(\refl{\pairr{x,y}})\jdeq\pairr{\refl{x},\refl{y}}$. Thus we may take $\refl{\pairr{\refl{x},\refl{y}}}$ to complete the construction of the homotopy $\paireq\circ\eqpair\htpy\idfunc$.

To complete the proof, we must show that $\eqpair$ is a retraction of $\paireq$. In other words, we must construct an identification
\begin{equation*}
\eqpair(\paireq(p))=p
\end{equation*}
for each $p:s=t$. We proceed by path induction on $p:s=t$, so it suffices to construct an identification
\begin{equation*}
\eqpair\pairr{\refl{\proj 1(s)},\refl{\proj 2(s)}}=\refl{s}.
\end{equation*}
Now we proceed by $\Sigma$-induction on $s:\sm{x:A}B(x)$, so it suffices to construct an identification
\begin{equation*}
\eqpair\pairr{\refl{x},\refl{y}}=\refl{(x,y)}.
\end{equation*}
Since $\eqpair\pairr{\refl{x},\refl{y}}$ computes to $\refl{(x,y)}$, we may simply take $\refl{\refl{(x,y)}}$.
\end{proof}
\index{identity type!of a Sigma-type@{of a $\Sigma$-type}|)}
\index{dependent pair type!identity type|)}
\index{characterization of identity type!Sigma-type@{$\Sigma$-type}|)}

\begin{exercises}
  \exercise \label{ex:equiv_grpd_ops}Show that the functions\index{inv@{$\invfunc$}!is an equivalence}\index{is an equivalence!inv@{$\invfunc$}}\index{concat@{$\concat$}!is a family of equivalences}\index{is an equivalence!concat(p)@{$\concat(p)$}}\index{concat'@{$\concat'$}!is a family of equivalences}\index{is an equivalence!concat'@{$\concat'(q)$}}\index{tr B@{$\tr_B$}!is a family of equivalences}\index{is an equivalence!tr B(p)@{$\tr_B(p)$}}
  \begin{align*}
    \invfunc & :(\id{x}{y})\to(\id{y}{x}) \\
    \concat(p) & : (\id{y}{z})\to(\id{x}{z}) \\
    \concat'(q) & : (\id{x}{y}) \to (\id{x}{z}) \\
    \tr_B(p) & :B(x)\to B(y)
  \end{align*}
  are equivalences, where $\concat'(q,p)\defeq \ct{p}{q}$\index{concat'@{$\concat'$}}. Give their inverses explicitly.
  \exercise \label{ex:unit-laws-coprod}Show that the maps\index{unit laws!coproduct}\index{coproduct!unit laws}\index{annihilation laws!cartesian product}\index{cartesian product!annihilation laws}
  \begin{align*}
    \inl & : X \to X+\emptyt &     \proj 1 & : \emptyt \times X \to \emptyt \\
    \inr & : X \to \emptyt+X &    \proj 2 & : X \times \emptyt \to \emptyt
  \end{align*}
  are equivalences.
  \exercise
  \begin{subexenum}
  \item \label{ex:htpy_equiv}\index{equivalence!closed under homotopies} Consider two functions $f,g:A\to B$ and a homotopy $H:f\htpy g$. Then
    \begin{equation*}
      \isequiv(f)\leftrightarrow\isequiv(g).
    \end{equation*}
  \item Show that for any two homotopic equivalences $e,e':\eqv{A}{B}$, their inverses are also homotopic.
  \end{subexenum}
  \exercise \label{ex:3_for_2}
  Consider a commuting triangle
  \begin{equation*}
    \begin{tikzcd}[column sep=tiny]
      A \arrow[rr,"h"] \arrow[dr,swap,"f"] & & B \arrow[dl,"g"] \\
      & X.
    \end{tikzcd}
  \end{equation*}
  with $H:f\htpy g\circ h$.
  \begin{subexenum}
  \item Suppose that the map $h$ has a section $s:B \to A$. Show that the triangle
    \begin{equation*}
      \begin{tikzcd}[column sep=tiny]
        B \arrow[rr,"s"] \arrow[dr,swap,"g"] & & A \arrow[dl,"f"] \\
        & X.
      \end{tikzcd}
    \end{equation*}
    commutes, and that $f$ has a section if and only if $g$ has a section.
  \item Suppose that the map $g$ has a retraction $r:X\to B$. Show that the triangle
    \begin{equation*}
      \begin{tikzcd}[column sep=tiny]
        A \arrow[rr,"f"] \arrow[dr,swap,"h"] & & X \arrow[dl,"r"] \\
        & B.
      \end{tikzcd}
    \end{equation*}
    commutes, and that $f$ has a retraction if and only if $h$ has a retraction.
  \item (The \define{3-for-2 property} for equivalences.)\index{equivalence!3-for-2 property}\index{3-for-2 property!of equivalences}\index{composition!of equivalences}\index{equivalence!composition} Show that if any two of the functions
    \begin{equation*}
      f,\qquad g,\qquad h
    \end{equation*}
    are equivalences, then so is the third.
  \end{subexenum}
  \exercise \label{ex:neg_equiv}
  \begin{subexenum}
  \item Show that the negation function on the booleans $\negbool:\bool\to\bool$ defined in \cref{eg:boolean-ops} is an equivalence.\index{neg 2@{$\negbool$}!is an equivalence}\index{is an equivalence!neg bool@{$\negbool$}}
  \item Use the observational equality on the booleans\index{observational equality!on booleans!0 2 neq 1 2@{$\bfalse\neq\btrue$}}, defined in \cref{ex:obs_bool}, to show that $\bfalse\neq\btrue$.\index{0 2 neq 1 2@{$\bfalse\neq\btrue$}}
  \item Show that for any $b:\bool$, the constant function $\const_b$ is not an equivalence.\index{booleans!const b is not an equivalence@{$\const_b$ is not an equivalence}}
  \end{subexenum}
  \exercise \label{ex:succ_equiv}Show that the successor function on the integers is an equivalence.\index{successor function!on Z@{on $\Z$}!is an equivalence}\index{succ Z@{$\succZ$}!is an equivalence}\index{is an equivalence!succ Z@{$\succZ$}}
  \exercise \label{ex:comm_prod}Construct a equivalences\index{coproduct!is commutative}\index{commutativity!of coproducts}
  \begin{equation*}
    \eqv{A+B}{B+A}\qquad\text{and}\qquad \eqv{A\times B}{B\times A}.
  \end{equation*}
  \exercise \label{ex:retr_id} Consider a section-retraction pair
  \begin{equation*}
    \begin{tikzcd}
      A \arrow[r,"i"] & B \arrow[r,"r"] & A,
    \end{tikzcd}
  \end{equation*}
  with $H:r\circ i\htpy \idfunc$. Show that $\id{x}{y}$ is a retract of $\id{i(x)}{i(y)}$.\index{retract!identity type}\index{identity type!of retract is retract}
%  \exercise \label{ex:sigma_assoc}\index{Sigma-type@{$\Sigma$-type}!associativity of}Let $B$ be a family of types over $A$, and let $C$ be a family of types indexed by $x:A,y:B(x)$. Construct an equivalence\index{associativity!of Sigma-types@{of $\Sigma$-types}}
%  \begin{equation*}
%    \assocSigma:\eqv{\Big(\sm{p:\sm{x:A}B(x)}C(\proj 1(p),\proj 2(p))\Big)}{\Big(\sm{x:A}\sm{y:B(x)}C(x,y)\Big)}.
%  \end{equation*}
%  \exercise \label{ex:sigma_swap}Let $A$ and $B$ be types, and let $C$ be a family over $x:A,y:B$. Construct an equivalence
%  \begin{equation*}
%    \swapSigma:\eqv{\Big(\sm{x:A}\sm{y:B}C(x,y)\Big)}{\Big(\sm{y:B}\sm{x:A}C(x,y)\Big)}.
%  \end{equation*}
  % \item \label{ex:sigma_base_equiv}Consider an equivalence $e:A'\eqv A$ and a type family $B$ over $A$. Show that the map
  %   \begin{equation*}
  %     \lam{(x',y)}(e(x'),y) : \Big(\sm{x':A'}B(e(x'))\Big)\to\Big(\sm{x:A}B(x)\Big)
  %   \end{equation*}
  %   is an equivalence.
  \exercise \label{ex:int_group_laws}\index{integers!group laws} In this exercise we will show that the laws for abelian groups hold for addition on the integers. Note: these are obvious facts, but the proof terms that show \emph{how} the group laws hold are nevertheless fairly involved. This exercise is perfect for a formalization project.
  \begin{subexenum}
  \item Show that addition satisfies the left and right unit laws, i.e., show that\index{unit laws!for addition on Z@{for addition on $\Z$}}
    \begin{align*}
      0+x & = x \\
      x+0 & = x.
    \end{align*}
  \item Show that the following successor and predecessor laws hold for addition on $\Z$.
    \begin{align*}
      \predZ(x)+y & = \predZ(x+y) & \succZ(x)+y & = \succZ(x+y) \\
      x+\predZ(y) & = \predZ(x+y) & x+\succZ(y) & = \succZ(x+y).
    \end{align*}
    Hint: to avoid an excessive number of cases, use induction on $x$ but not on $y$. You may need to use the homotopies $\succZ\circ \predZ\htpy \idfunc$ and $\predZ\circ\succZ\htpy\idfunc$ constructed in exercise \cref{ex:succ_equiv}.
  \item Use part (b) to show that addition on the integers is associative and commutative, show that\index{associativity!of addition on Z@{of addition on $\Z$}}\index{commutativity!of addition on Z@{of addition on $\Z$}}
    \begin{align*}
      (x+y)+z & = x + (y+z) \\
      x+y & = y+x.
    \end{align*}
    Hint: Especially in the construction of the associator there is a risk of running into an unwieldy amount of cases if you use $\Z$-induction on all arguments. Avoid induction on $y$ and $z$.
  \item Show that addition satisfies the left and right inverse laws:\index{inverse laws!for addition on Z@{for addition on $\Z$}}
    \begin{align*}
      (-x)+x & =0 \\
      x+(-x) &=0.
    \end{align*}
    Conclude that the functions $y \mapsto x + y$ and $x\mapsto x + y$ are equivalences for any $x:\Z$ and $y:\Z$, respectively.
  \end{subexenum}
  \exercise \label{ex:ring-Z}In this exercise we will show that $\Z$ satisfies the axioms of a \define{ring}\index{ring!integers}\index{integers!is a ring}.
  \begin{subexenum}
  \item Show that multiplication on $\Z$ satisfies the following laws for $0$ and $1$\index{zero laws!for mulZ@{for $\mulZ$}}\index{unit laws!for mulZ@{for $\mulZ$}}\index{mulZ@{$\mulZ$}!unit laws}\index{mulZ@{$\mulZ$}!zero laws}:
    \begin{align*}
      0\cdot x & = 0 & 1\cdot x & = x \\
      x\cdot 0 & = 0 & x\cdot 1 & = x.
    \end{align*}
  \item Show that multiplication on $\Z$ satisfies the predecessor and successor laws\index{mulZ@{$\mulZ$}!predecessor laws}\index{mulZ@{$\mulZ$}!successor laws}:
    \begin{align*}
      \predZ(x)\cdot y & = x\cdot y-y & \succZ(x)\cdot y & = x\cdot y + y \\
      x\cdot \predZ(y) & = x\cdot y-x & y\cdot \succZ(y) & = x\cdot y + x.
    \end{align*}
  \item Show that multiplication on $\Z$ distributes over addition, both from the left and from the right\index{mulZ@{$\mulZ$}!distributive over addZ@{distributive over $\addZ$}}\index{distributivity!mulZ over addZ@{$\mulZ$ over $\addZ$}}:
    \begin{align*}
      x\cdot(y+z) & = x\cdot y+ x\cdot z \\
      (x+y)\cdot z & = x\cdot z + y\cdot z.
    \end{align*}
  \item Show that multiplication on $Z$ is associative and commutative\index{associativity!of mulZ@{of $\mulZ$}}\index{mulZ@{$\mulZ$}!associativity}\index{commutativity!of mulZ@{of $\mulZ$}}\index{mulZ@{$\mulZ$}!commutativity}:
    \begin{align*}
      (x\cdot y)\cdot z & = x\cdot (y\cdot z) \\
      x\cdot y & = y\cdot x.
    \end{align*}
  \end{subexenum}
  \exercise \label{ex:coproduct_functor}In this exercise we will construct the \define{functorial action}\index{functorial action!of coproducts}\index{coproduct!functorial action} of coproducts.
  \begin{subexenum}
  \item Construct for any two maps $f:A \to A'$ and $g:B \to B'$, a map\index{f + g@{$f+g$}|see {functorial action, of coproducts}}
    \begin{equation*}
      f+g:A+B \to A'+B'.
    \end{equation*}
  \item Show that if $H:f\htpy f'$ and $K:g\htpy g'$, then there is a homotopy
    \begin{equation*}
      H+K:(f+g)\htpy (f'+g').
    \end{equation*}
  \item Show that $\idfunc[A]+\idfunc[B]\htpy \idfunc[A+B]$.
  \item Show that for any
    \begin{equation*}
      \begin{tikzcd}[row sep=small]
        A \arrow[r,"f"] & {A'} \arrow[r,"{f'}"] & {A''} \\
        B \arrow[r,"g"] & {B'} \arrow[r,"{g'}"] & {B''}
      \end{tikzcd}
    \end{equation*}
    there is a homotopy
    \begin{equation*}
      (f'\circ f)+(g'\circ g) \htpy (f'+g')\circ (f\circ g).
    \end{equation*}
  \item \label{ex:coproduct_functor_equivalence}Show that if $f$ and $g$ are equivalences, then so is $f+g$. (The converse of this statement also holds, see \cref{ex:is-equiv-is-equiv-functor-coprod}.)
  \end{subexenum}
  \exercise Construct equivalences
  \begin{align*}
    \Fin(m+n) & \simeq \Fin(m)+\Fin(n) \\
    \Fin(mn) & \simeq \Fin(m)\times\Fin(n).
  \end{align*}
\end{exercises}
\index{equivalence|)}


\chapter{Search Algorithm}
\label{chap:sa}

In chapter \ref{chap:model} we defined the internal space of our models. We now look to optimize it. Differential Evolution, a multi-objective optimization algorithm is used to optimize the decision space as per the stakeholders requirements(objectives) and post which a bayesian selection algorithm is used to rank the design decisions of the model according to how well they satisfy the objectives.

\section{Differential Evolution}
\label{sec:sa:de}
\textit{Meta-heuristics} are higher-level procedures or heuristics designed to find, generate, or select a heuristic that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity. Meta-heuristics sample a set of solutions which is too large to be completely sampled. Meta-heuristics may make few assumptions about the optimization problem being solved, and so they may be usable for a variety of problems. Meta-heuristics are also based of Monte Carlo algorithms. A \textit{Monte Carlo} algorithm randomly samples the space of possible controllable model states. A \textit{Metropolis} Monte Carlo algorithm \cite{metropolis53} creates new states by small mutations to the current state. If a new state is ``better" (as assessed through the domination of the decisions with respect to the objectives of the model), it replaces the current state and us used for future mutations.

\textbf{D}ifferential \textbf{E}volution(DE) is a meta-heuristic evolutionary computation method that can find the Pareto Front of the multi-objective optimization problem without converting it into a single-objective optimization one. DE optimizes a problem by iteratively trying to improve a candidate solution with regard to a specific measure(s) of quality. DE does not make any assumptions on the nature of the optimization problem and does not require the problem to be continuous or differentiable.

\begin{algorithm}[!hbtp]
\caption{Differential Evolution}
\label{algo:DE}
\begin{algorithmic}[1]
\State Generate randomly an initial population($P$) of solutions where each solution $x \in R^n$.
\State Calculate the fitness of the initial population.
\Repeat
    \For{each point $p \in P$}
        \State Pick 3 other points $a$, $b$ \& $c$ from $P$ where $a,b,c \neq p$
        \State Pick a random index $R \in {1, \ldots, n}$
        \For{$i \in n$}
            \State $r_i \in U(0,1)$
            \If{$r_i \le CR$ or $i = R$}
                \State $y_i = a_i + F * x_i *  (b_i - c_i)$
            \Else
                \State $y_i = x_i$
            \EndIf
        \EndFor
        \If{$f(y) < f(x)$}
            \State replace $x$ with $y$ in $P$
        \EndIf
    \EndFor
\Until {Stop condition is satisfied}
\State $P$ now represents the Pareto Front
\end{algorithmic}
\end{algorithm}

Algorithm \ref{algo:DE} describes the generic approach for the Differential Evolution algorithm. The parameter $F \in [0,2]$ on line 10 represents \textit{differential weight} and $CR \in [0,1]$ on line 9 represents the crossover rate. Both these parameters are chosen based on the problem and requires engineering judgement or tuning to be correctly chosen.

For our models there are a few changes we incorporate that is different to the classical differential evolution method. We change the random generation by introducing the structure of the model while generation and we augment the mutation operation in line 10 to support binary variables.

\subsection{Generation}
\label{subsec:sa:de:gen}

The classical Differential Evolution algorithm uses random generation for the initial population i.e the decisions are randomly sampled across the entire model decision space. We propose a modified method that utilizes the structure of the model for sampling the initial population.

\begin{algorithm}[!hbtp]
\caption{Generation}
\label{algo:DE:gen}
\begin{algorithmic}[1]
    \Procedure{generate}{$tree$, $node$, $value$}
        \State $kids = \bm{GET\_KIDS}(tree, node)$
        \If{$kids == null$}
            \State \Return $\{\bm{ID}(node)\ :\ value\}$
        \EndIf
        \State $decisions = \{ \ \}$
        \State $e\_type = kids[0].edge$
        \State $kids = \bm{SHUFFLE}(kids)$
        \If {($e\_type == ``and" \ \&\&\ value==t) \quad||\quad (e\_type == ``or" \ \&\&\  value==f$)}
            \For{each $kid$ in $kids$}
                \State $\bm{UPDATE}(decisions,\ \bm{GENERATE}(tree,\ kid,\ value))$
            \EndFor
        \Else
            \State $first, rest$ = $\bm{LOO}(kids)$
            \State $\bm{UPDATE}(decisions,\ \bm{GENERATE}(tree,\ kid,\ value))$
            \For{each $kid$ in $rest$}
                \State $\bm{UPDATE}(decisions,\ \bm{GENERATE}(tree,\ kid,\ \bm{choice}(t, f)))$
            \EndFor
        \EndIf
    \EndProcedure
\end{algorithmic}
\end{algorithm}

The modified \textbf{generation} algorithm is defined in Algorithm \ref{algo:DE:gen}. The function is called by passing the model(represented as tree), the root node(represented as node) and the expected value($t$ represents satisfied and $f$ represents unsatisfied). On line 2 the incoming nodes(kids) of the node is retrieved and if there are no incoming nodes a map containing with the node id as the key and the expected value is returned. On lines 6 an empty dictionary is declared and on line 7 edge type of the incoming children are retrieved. The children are randomly shuffled in line 8. On lines 9-13, if the incoming edge is of type AND and the expected value is satisfied or if the incoming edge is of type OR and the expected values is unsatisfied, each incoming node is recursively called with the expected value. This is because for a node with AND edge to be satisfied, all the incoming nodes needs to be satisfied and similarly for a node with an OR edge to be unsatisfied all the incoming nodes needs to be unsatisfied. In the alternate case on lines 13 to 19 one of the incoming nodes($first$) is satisfied for an OR edge and one the incoming nodes is unsatisfied for an AND edge. For all the remaining nodes($rest$), each node is recursively called with a random expected value.

\subsection{Mutation \& Crossover}
\label{subsec:sa:de:mut}

Storn classically proposed using differential mutation and crossover strategy \cite{storn96} but this can only be applied only to continuous decision spaces(As shown on line 10 of Algorithm \ref{algo:DE}). Since the goal models we deal with are binary in nature, we take an alternate method of mutation as shown in \cite{falco07}. The method is defined in \eref{eq:DE:binary}.

\begin{equation}
    \begin{aligned}
        & X_{new} = X_1 \lor (FV \land (X_2 \oplus X_3))\\
        & FV = \{0, 1\}^n \quad where\ n = length(X_{1}) \\
        & FV_i = 1,\quad if\ Random() < F \\
        & \quad \ \ \ \, = 0,\quad otherwise
    \end{aligned}
    \label{eq:DE:binary}
\end{equation}

Three decision vectors are selected at random. In the vector 1 represents a satisfied and 0 represents an unsatisfied decision. FV is a random vector whose length is equal to the number of decisions. $\lor$ represents a logical OR operator, $\land$ represents a logical AND operator and $\oplus$ represents a logical XOR operator.

\bigskip

\noindent
In terms of the goal of this thesis, exploring the decision subset selection is an essential feature.

\begin{itemize}
    \item Prior to removing unimportant decisions, we rank them with respect to their effectiveness in contribution towards the objectives.
    \item After removal of the non-essential decisions we see the contribution of the reduced model towards the objectives and the savings in the cost.
\end{itemize}

\section{Support Based Bayesian Ranking}
\label{sec:sa:bayes}

Each decision in the model contributes towards the objectives. Some decisions contribute more than others and if such decisions are identified, the complexity of the model can be reduced. Menzies Et. Al. proposed a support based bayesian ranking algorithm \cite{menzies07} that ranks the decisions using a Simulated Annealer \cite{kirkpatrick83}. We adapt this approach but replace the simulated annealer with differential evolution and also introduce non-dominated sorting.

\begin{figure}
    \begin{mdframed}[backgroundcolor=white]
        \begin{center}
            {\bf Non Dominated Sorting}\\
        \end{center}
        Non Dominated Sorting was a fast objective sorting approach was developed by Srinivas and Deb \cite{srinivas94}. The algorithm is described as follows.
        \bigskip
        \begin{compactitem}
            \item \boldm{P} is a set of points to be sorted and \boldm{k} top points have to be retrieved.
            \item For each individual \boldm{p} in the set \boldm{P}.
            \begin{compactitem}
                \item Initialize \boldm{S_p} = []. This set would contain all the points dominated by p.
                \item Initialize \boldm{n_p} = 0. This would be the number of points that dominate p.
                \item For each point \boldm{q} in \boldm{P}
                \begin{compactitem}
                    \item If \boldm{p} dominates \boldm{q} then
                        \begin{compactitem}
                            \item Add q to set
                        \end{compactitem}
                    \item Else If \boldm{q} dominates \boldm{p} then
                        \begin{compactitem}
                            \item Increment \boldm{n_p} by 1.
                        \end{compactitem}
                \end{compactitem}
            \end{compactitem}
            \item If \boldm{n_p} = 0 then
                \begin{compactitem}
                    \item Set rank of \boldm{p} to 1.
                    \item Update the first front set by adding \boldm{p} to first front(\boldm{F_1}).
                \end{compactitem}
            \item Initialize front counter to 1; i.e \boldm{i} = 1.
            \item While \boldm{F_i} is not empty
                \begin{compactitem}
                    \item Initialize \boldm{Q} = []; i.e Set of all points in $(\bm{i} + 1)^{th}$ front.
                    \item For each individual \boldm{p} in \boldm{F_i}.
                    \begin{compactitem}
                        \item For each individual \boldm{q} in \boldm{S_p}
                        \begin{compactitem}
                            \item Decrement \boldm{n_q} by 1.
                            \item If \boldm{n_q} = 0 then
                            \begin{compactitem}
                                \item Set rank of \boldm{q} to (\boldm{i} + 1).
                                \item Update Q with \boldm{q}.
                            \end{compactitem}
                        \end{compactitem}
                    \end{compactitem}
                    \item Increment the front counter \boldm{i} by 1.
                    \item Set \boldm{Q} as the next front; i.e \boldm{F_i} = \boldm{Q}.
                \end{compactitem}
            \item Return the top \boldm{k} points from the top fronts.
        \end{compactitem}
        \bigskip
        In the algorithm the term \bit{dominate} refers to Pareto Dominance \cite{deb01} and is mathematically defined in section \ref{sec:bg:moo}.
    \end{mdframed}
    \caption{Non Dominated Sorting}
    \label{fig:non_dom}
\end{figure}

We first rank the decisions using \boldm{K} runs of the differential evolution algorithm. The \boldm{K} runs are divided based on Non Dominated Sorting as described in \fref{fig:non_dom} into:

\begin{itemize}
    \item \textit{Best} : Points associated with the top \boldm{BEST}\% points.
    \item \textit{Rest} : Points that are not included in best.
\end{itemize}

The algorithm then computes the probability that a decision is found in \textit{best} using Bayes' Theorem. Informally, the theorem says that $posterior = prior * likelihood$ ;i.e. what we'll believe next($posterior$) comes from how the $likelihood$ effects with our $prior$ beliefs. More formally:

\begin{equation}
    P(H|E) = P(E|H) * \dfrac{P(H)}{P(E)}
    \label{eq:bayes}
\end{equation}

i.e using evidence $E$ and a prior probability $P(H)$ for hypothesis $H \in \{best, rest\}$. The theorem calculates the posterior probability $P(H|E)$. Simple Bayes classifiers are often called ``naive" since they assume independence of each feature. While this assumption simplifies the implementation(frequency counts are required only for each decision), it is possible that correlated events are missed by this naive approach. Domingos and Pazzani show theoretically that the independence assumption is a problem in a vanishingly small percent of cases \cite{domingos97}. This explains the repeated empirical result that, on average, seemingly naive Bayes classifiers perform as well as other seemingly more sophisticated schemes.

When applying the theorem, \textit{likelihoods} are computed from observed frequencies, then normalized to create probabilities (this normalization cancels out $P(E)$ in \eref{eq:bayes}, so it need not be computed). For example after K = 10,000 runs divide into 1,000 lowest 10\% \textit{best} solutions and 9,000 \textit{rest}, the decision $2Tier = satisfied$ from \fref{fig:ahp} might appear 10 times in the \textit{best} solutions, but only 5 times in the rest. This can be formulated as follows:

\begin{equation}
    \begin{aligned}
        E &\quad =\quad (2Tier == satisfied) \\
        P(best) &\quad =\quad 1000 / 10000 = 0.1 \\
        P(rest) &\quad =\quad 1000 / 10000 = 0.1 \\
        freq(E|best) &\quad =\quad 10/1000 = 0.01 \\
        freq(E|rest) &\quad =\quad 5/9000 = 0.00056 \\
        like(best|E) &\quad =\quad freq(E|best) * P(best) = 0.001\\
        like(rest|E) &\quad =\quad freq(E|rest) * P(rest) = 0.000504\\
        P(best|E) &\quad =\quad \dfrac{like(best|E)}{like(best|E) + like(rest|E)}
    \end{aligned}
    \label{eq:posterior}
\end{equation}

Clark found that \eref{eq:posterior} is a poor ranking heuristic since it is distracted by low frequency evidence \cite{clark05}. For example, note how the probability of $E$ belonging to the best class is moderately high even though its support is very low; i.e $P(best|E) = 0.66$ but $freq(E|best) = 0.01$.

To avoid such unreliable low frequency evidence, \eref{eq:posterior} is augmented with a support term. Support should \textit{increase} as the frequency of a range \textit{increases},i.e $like(best|x)$ is a valid support measure. STAR1 algorithm thus ranks the decisions using \eref{eq:star1}.

\begin{equation}
    \begin{aligned}
        P(best|E) * support(best|E) &\quad = \quad \dfrac{like(best|x)^2}{like(best|x) + like(rest|x)}
    \end{aligned}
    \label{eq:star1}
\end{equation}

\section{The STAR1 Algorithm}
\label{sec:sa:star1}

STAR1 was a framework proposed by Menzies Et. Al \cite{menzies07} that utilized an optimizer and a ranker to rank the decisions. We include Differential Evolution as an optimizer and the Bayesian ranker from Section \ref{sec:sa:bayes} as the ranker for the framework. The STAR1 runs in six phases. With respect to standard machine learning theory, step 1 generates a training set; sets 2 and 3 performs some generalization; step 4 tests the learned theory on the data; and step 5 reports our learning.

\begin{itemize}
    \item \bit{SAMPLE}: To sample the decisions form the models, STAR1 runs the Differential Evolution algorithm $\bm{K_1}$ times.
    \item \bit{CLASSIFY}: The outcomes of the runs are then ranked into those seen in $\bm{BEST}$\% as \textit{best} and the remaining into \textit{rest}.
    \item \bit{RANK}: The decisions along with their optimal values are then ranked using Non Dominated Sorting as depicted in \fref{fig:non_dom} in the decreasing order by their $probability\ *\ support$ \eref{eq:star1} of appearing in the \textit{best} outcomes.
    \item \bit{PRUNE}: The algorithm then runs $\bm{K_2}$ experiments with the models where the top ranked decisions 1 \ldots $\bm{X}$ are pre-set to their optimal value as computed on the previous step. The remaining decisions are randomly are assigned random values. This step is crucial as we identify the significance of each decision and its contribution towards the satisfaction of the model's objectives.
    \item \bit{REPORT}: The algorithm finally plots the median and Inter-Quartile Range(IQR) for each of the 1 \dots $\bm{X}$ decisions which the analyst can use to identify the significance of the decisions.
\end{itemize}

To run our experiments, we applied our engineering judgement and experimental verification for setting the parameters in the algorithm:

\begin{center}
    $\bm{K_1}$ = 1,000, $\bm{K_2}$ = 1,000, $\bm{BEST}$ = 10\%
\end{center}


\renewcommand{\labelenumi}{\arabic{enumi}.}
\chapter{Notations and Conventions}
\section{Logic}
\begin{enumerate}
\item{{\bf Halmos' iff}:  \iif is a short for "if and only if".}
\item{{\bf Definitions (of values) with $\Def$}: Given a variables %
$\varit{a}$ and $\varit{b}$, %
$a\Def b$ means that $\varit{a}$ is defined as equal to $\varit{b}$.}
\item{{\bf Definitions (formul\ae)}: Definitions come from \iif. %
In other words, both parts (the "if \dots" part and the "only if \dots" part) %
are explicitely stated. }
\item{{\bf Iverson notation}:  Given a boolean expression $\Phi$, %
$\boolean{\Phi}$ returns the truth value of $\Phi$, encoded as follows, %
%
  \begin{align} \nonumber
    \boolean{\Phi}\Def
    \begin{cases}
      0 & \quad\quad \text{if } \Phi \text{ is false;} \\
      1 & \quad\quad \text{if } \Phi \text{ is true.}
    \end{cases}
  \end{align}

For example, $\boolean{1 > 0} = 1$ but $\boolean{ \sqrt{2} \in \Q} = 0$.
}
\end{enumerate}
%\section{Vector spaces}
%\begin{enumerate}
%  \item{If $X$ is a vector space of base $B$ and $e$ is an element of B, }
%\end{enumerate}


%!TEX root = ceres.tex
\chapter{Tutorial}
\label{chapter:tutorial}

\section{Non-linear Least Squares}
\label{sec:tutorial:nonlinsq}
Let $x \in \reals^n$ be an $n$-dimensional vector of variables, and
$F(x) = \left[f_1(x); \hdots ; f_k(x)\right]$ be a vector of residuals $f_i(x)$.
The function $f_i(x)$ can be a scalar or a vector valued
function.   We are interested in finding the solution to the following optimization problem
\begin{equation}
	\arg \min_x \frac{1}{2} \sum_{i=1}^k \|f_i(x)\|^2.
\end{equation}
Here $\|\cdot\|$ denotes the Euclidean norm of a vector.

Such optimization problems arise in almost every area of science and engineering. Whenever there is data to be analyzed, curves to be fitted, there is usually a linear or a non-linear least squares problem lurking in there somewhere.

Perhaps the simplest example of such a problem is the problem of Ordinary Linear Regression, where given observations $(x_1,y_1),\hdots, (x_k,y_k)$, we wish to find the line $y = mx + c$, that best explains $y$ as a function of $x$. One way to solve this problem is to find the solution to the following optimization problem
\begin{equation}
		\arg\min_{m,c} \sum_{i=1}^k (y_i - m x_i - c)^2.
\end{equation}
With a little bit of calculus, this problem can be solved easily by hand. But what if, instead of a line we were interested in a more complicated relationship between $x$ and $y$, say for example $y = e^{mx + c}$. Then the optimization problem becomes
\begin{equation}
		\arg\min_{m,c} \sum_{i=1}^k \left(y_i - e^{m x_i + c}\right)^2.
\end{equation}
This is a  non-linear regression problem and solving it by hand is much more tedious.  Ceres is designed to help you model and solve problems like this easily and efficiently.

\section{Hello World!}
\label{sec:tutorial:helloworld}
Let us consider the problem of finding the minimum of the function
\begin{equation}
	g(x) = \frac{1}{2}(10 -x)^2.
\end{equation}

This is a trivial problem, whose minimum is easy to see is located at 10, but it is a good place to start to illustrate the basics of solving a problem with Ceres. Let us write this problem as a non-linear least squares problem by defining the scalar residual function $f_1(x) = 10 - x$. Then $F(x) = [f_1(x)]$ is a residual vector with exactly one component.

When solving a problem with Ceres, the first thing to do is to define a \texttt{CostFunction}
object\footnote{Full working code for this and other examples in this manual can be found in the \texttt{examples} directory. Code for this example can be found in \texttt{examples/quadratic.cc}}. It is responsible for computing the value of the residual function and its derivative (also known as the Jacobian) with respect to $x$. Listing~\ref{listing:simplecostfunction} has the code.
\begin{listing}[H]
\begin{minted}[frame=lines]{c++}
class SimpleCostFunction
  : public ceres::SizedCostFunction<1 /* number of residuals */,
                                    1 /* size of first parameter */> {
 public:
  virtual ~SimpleCostFunction() {}
  virtual bool Evaluate(double const* const* parameters,
                        double* residuals,
                        double** jacobians) const {
    double x = parameters[0][0];
    // f(x) = 10 - x.
    residuals[0] = 10 - x;
    if (jacobians != NULL) {
	  // If the jacobians are asked for,
	  // then compute the derivative.
      jacobians[0][0] = -1;
    }
    return true;
  }
};
\end{minted}
\caption{A \texttt{CostFunction} for $f = 10 - x $}
\label{listing:simplecostfunction}
\end{listing}
\texttt{SimpleCostFunction} is provided with an input array of parameters, an output array for residuals and an optimal output array for Jacobians. In our example, there is just one parameter and one residual and this is known at compile time, therefore we inherit from templated \texttt{SizedCostFunction} class. The \texttt{jacobians} array is optional, \texttt{Evaluate} is expected to check when it is non-null, and if it is the case then fill it with the values of the derivative of the residual function. In this case since the residual function is linear, the Jacobian is constant.

Let us now look at the construction and solution of the problem using this \texttt{CostFunction}.
\begin{listing}[H]
\begin{minted}[frame=lines]{c++}
int main(int argc, char** argv) {
  double x = 5.0;
  ceres::Problem problem;

  // The problem object takes ownership of the newly allocated
  // SimpleCostFunction and uses it to optimize the value of x.
  problem.AddResidualBlock(new SimpleCostFunction, NULL, &x);

  // Configure the solver.
  ceres::Solver::Options options;
  options.max_num_iterations = 2;
  // Small, simple problem so we will use the Dense QR
  // factorization based solver.
  options.linear_solver_type = ceres::DENSE_QR;
  options.minimizer_progress_to_stdout = true;

  ceres::Solver::Summary summary;
  ceres::Solve(options, &problem, &summary);
  std::cout << summary.BriefReport() << "\n";
  std::cout << "x : 5.0 -> " << x << "\n";
  return 0;
}
\end{minted}
\caption{Problem construction and solution for $F(x) = \frac{1}{2}(x-10)^2$}
\end{listing}

Compiling and running this program gives us
\begin{minted}{bash}
0: f: 1.250000e+01 d: 0.00e+00 g: 5.00e+00 h: 0.00e+00 rho: 0.00e+00 mu: 1.00e-04 li:  0
1: f: 1.249750e-07 d: 1.25e+01 g: 5.00e-04 h: 5.00e+00 rho: 1.00e+00 mu: 3.33e-05 li:  1
2: f: 1.388518e-16 d: 1.25e-07 g: 1.67e-08 h: 5.00e-04 rho: 1.00e+00 mu: 1.11e-05 li:  1
Ceres Solver Report: Iterations: 2, Initial cost: 1.250000e+01,  \
Final cost: 1.388518e-16, Termination: PARAMETER_TOLERANCE.
x : 5 -> 10
\end{minted}

Starting from a $x=5$, the solver in two iterations goes to 10. The careful reader will note that this is a linear problem and one linear solve should be enough to get the optimal value.  The default configuration of the solver is aimed at non-linear problems, and for reasons of simplicity we did not change it in this example. It is indeed possible to obtain the solution to this problem using Ceres in one iteration. Also note that the solver did get very close to the optimal function value of 0 in the very first iteration. We will discuss these issues in greater detail when we talk about convergence and initial parameter setting for Ceres.

\section{A Non-linear Example}
\label{sec:tutorial:powell}
Consider now a slightly more complicated example -- the minimization of Powell's function. Let $x = \left[x_1, x_2, x_3, x_4 \right]$ and
\begin{align}
   f_1(x) &= x_1 + 10*x_2 \\
   f_2(x) &= \sqrt{5} * (x_3 - x_4)\\
   f_3(x) &= (x_2 - 2*x_3)^2\\
   f_4(x) &= \sqrt{10} * (x_1 - x_4)^2\\
	F(x) & = \frac{1}{2}\left(f_1^2(x) + f_2^2(x) + f_3^2(x) + f_4^2(x) \right)
\end{align}
$F(x)$ is a function of four parameters, and has four residuals. Now,
one way to solve this problem would be to define four
\texttt{CostFunction}s that computes the residual and Jacobian. \eg Listing~\ref{listing:f4full} shows the implementation for $f_4(x)$.

\begin{listing}[H]
\begin{minted}[frame=lines,mathescape]{c++}
class F4 : public ceres::SizedCostFunction<1, 4> {
 public:
  virtual ~F4() {}
  virtual bool Evaluate(double const* const* parameters,
                        double* residuals,
                        double** jacobians) const {
    double x1 = parameters[0][0];
    double x4 = parameters[1][0];

    // $f_4 = \sqrt{10} * (x_1 - x_4)^2$
    residuals[0] = sqrt(10.0) * (x1 - x4) * (x1 - x4)
    if (jacobians != NULL) {
      // $\partial_{x_1}f_1(x)$
      jacobians[0][0] = 2.0 * sqrt(10.0) * (x1 - x4);
      // $\partial_{x_2}f_1(x)$
      jacobians[0][1] = 0.0;
      // $\partial_{x_3}f_1(x)$
      jacobians[0][2] = 0.0;
      // $\partial_{x_4}f_1(x)$
      jacobians[0][3] = -2.0 * sqrt(10.0) * (x1 - x4);
    }
    return true;
  }
};
\end{minted}
\caption{A full \texttt{CostFunction} implementation of $f_4(x) = \sqrt{10} * (x_1 - x_4)^2$.}
\label{listing:f4full}
\end{listing}

But this can get painful very quickly, especially for residuals involving complicated multivariate terms. Ceres provides two ways around this problem. Numeric and automatic symbolic differentiation.

\subsection{Automatic Differentiation}
\label{sec:tutorial:autodiff}
With its automatic differentiation support, Ceres allows you to define templated objects that will compute the residual and it takes care of computing the Jacobians as needed and filling the \texttt{jacobians} arrays with them.
For example, for $f_4(x)$ we define

\begin{listing}[H]
\begin{minted}[frame=lines,mathescape]{c++}
class F4 {
 public:
  template <typename T> bool operator()(const T* const x1,
                                        const T* const x4,
                                        T* residual) const {
    // $f_4 = \sqrt{10} * (x_1 - x_4)^2$
    residual[0] = T(sqrt(10.0)) * (x1[0] - x4[0]) * (x1[0] - x4[0]);
    return true;
  }
};
\end{minted}
\caption{Templated functor implementing $f_4(x) = \sqrt{10} * (x_1 - x_4)^2$ for use in automatic differentiation.}
\label{listing:f4functor}
\end{listing}

The important thing to note here is that the \texttt{operator()} is a
templated method, which assumes that all its inputs and outputs are of
some type \texttt{T}.  Note also that the parameters are not packed
into a single array, they are instead passed as separate arguments to
\texttt{operator()}. Similarly we can define classes \texttt{F1,F2}
and \texttt{F4}. Then let us consider the construction and solution of the problem. For brevity we only describe the relevant bits of code. The full source code for this example can be found in \texttt{examples/powell.cc}.

\begin{listing}[H]
\begin{minted}[frame=lines,mathescape]{c++}
double x1 =  3.0; double x2 = -1.0; double x3 =  0.0; double x4 =  1.0;

// Add residual terms to the problem using the using the autodiff
// wrapper to get the derivatives automatically. The parameters, x1 through
// x4, are modified in place.
problem.AddResidualBlock(
  new ceres::AutoDiffCostFunction<F1, 1, 1, 1>(new F1), NULL, &x1, &x2);
problem.AddResidualBlock(
  new ceres::AutoDiffCostFunction<F2, 1, 1, 1>(new F2), NULL, &x3, &x4);
problem.AddResidualBlock(
  new ceres::AutoDiffCostFunction<F3, 1, 1, 1>(new F3), NULL, &x2, &x3)
problem.AddResidualBlock(
  new ceres::AutoDiffCostFunction<F4, 1, 1, 1>(new F4), NULL, &x1, &x4);
\end{minted}
\caption{Problem construction using \texttt{AutoDiffCostFunction} for Powell's function.}
\label{listing:powell}
\end{listing}
A few things are worth noting in the code above. First, the object
being added to the \texttt{Problem} is an
\texttt{AutoDiffCostFunction} with \texttt{F1}, \texttt{F2}, \texttt{F3} and \texttt{F4} as template parameters. Second, each \texttt{ResidualBlock} only depends on the two parameters that the corresponding residual object depends on and not on all four parameters.

Compiling and running \texttt{powell.cc} gives us:
\begin{minted}{bash}
Initial x1 = 3, x2 = -1, x3 = 0, x4 = 1
   0: f: 1.075000e+02 d: 0.00e+00 g: 1.55e+02 h: 0.00e+00 rho: 0.00e+00 mu: 1.00e-04 li:  0
   1: f: 5.036190e+00 d: 1.02e+02 g: 2.00e+01 h: 2.16e+00 rho: 9.53e-01 mu: 3.33e-05 li:  1
   2: f: 3.148168e-01 d: 4.72e+00 g: 2.50e+00 h: 6.23e-01 rho: 9.37e-01 mu: 1.11e-05 li:  1
   3: f: 1.967760e-02 d: 2.95e-01 g: 3.13e-01 h: 3.08e-01 rho: 9.37e-01 mu: 3.70e-06 li:  1
   4: f: 1.229900e-03 d: 1.84e-02 g: 3.91e-02 h: 1.54e-01 rho: 9.37e-01 mu: 1.23e-06 li:  1
   5: f: 7.687123e-05 d: 1.15e-03 g: 4.89e-03 h: 7.69e-02 rho: 9.37e-01 mu: 4.12e-07 li:  1
   6: f: 4.804625e-06 d: 7.21e-05 g: 6.11e-04 h: 3.85e-02 rho: 9.37e-01 mu: 1.37e-07 li:  1
   7: f: 3.003028e-07 d: 4.50e-06 g: 7.64e-05 h: 1.92e-02 rho: 9.37e-01 mu: 4.57e-08 li:  1
   8: f: 1.877006e-08 d: 2.82e-07 g: 9.54e-06 h: 9.62e-03 rho: 9.37e-01 mu: 1.52e-08 li:  1
   9: f: 1.173223e-09 d: 1.76e-08 g: 1.19e-06 h: 4.81e-03 rho: 9.37e-01 mu: 5.08e-09 li:  1
  10: f: 7.333425e-11 d: 1.10e-09 g: 1.49e-07 h: 2.40e-03 rho: 9.37e-01 mu: 1.69e-09 li:  1
  11: f: 4.584044e-12 d: 6.88e-11 g: 1.86e-08 h: 1.20e-03 rho: 9.37e-01 mu: 5.65e-10 li:  1
Ceres Solver Report: Iterations: 12, Initial cost: 1.075000e+02, \
Final cost: 2.865573e-13, Termination: GRADIENT_TOLERANCE.
Final x1 = 0.000583994, x2 = -5.83994e-05, x3 = 9.55401e-05, x4 = 9.55401e-05
\end{minted}
It is easy to see that the  optimal solution to this problem is at $x_1=0, x_2=0, x_3=0, x_4=0$ with an objective function value of $0$. In 10 iterations, Ceres finds a solution with an objective function value of $4\times 10^{-12}$.

If a templated implementation is not possible then a \texttt{NumericDiffCostFunction} object can be used. \texttt{examples/quadratic\_numeric\_diff.cc} shows a numerically differentiated implementation of \texttt{examples/quadratic.cc}.

When possible, automatic differentiation should be used. The use of
C++ templates makes automatic differentiation extremely efficient,
whereas numeric differentiation can be quite expensive, prone to
numeric errors and leads to slower convergence.

\section{Data Fitting}
\label{sec:tutorial:datafitting}
The examples we have seen until now are simple optimization problems with no data. The original purpose of least squares and non-linear least squares analysis was fitting curves to data. It is only appropriate that we now consider an example of such a problem. Let us fit some data to the curve
\begin{equation}
	y = e^{mx + c}.
\end{equation}

The full code and data for this example can be found in
\texttt{examples/data\_fitting.cc}. It contains data generated by sampling the curve $y = e^{0.3x + 0.1}$ and adding Gaussian noise with standard deviation $\sigma = 0.2$.

We begin by defining a templated object to evaluate the residual. There will be a residual for each observation.

\begin{listing}[H]
\begin{minted}[frame=lines,mathescape]{c++}
class ExponentialResidual {
 public:
  ExponentialResidual(double x, double y)
      : x_(x), y_(y) {}

  template <typename T> bool operator()(const T* const m,
                                        const T* const c,
                                        T* residual) const {
    // $y - e^{mx + c}$
    residual[0] = T(y_) - exp(m[0] * T(x_) + c[0]);
    return true;
  }

 private:
  // Observations for a sample.
  const double x_;
  const double y_;
};
\end{minted}
\caption{Templated functor to compute the residual for the exponential model fitting problem. Note that one instance of the functor is responsible for computing the residual for one observation.}
\label{listing:exponentialresidual}
\end{listing}
Assuming the observations are in a $2n$ sized array called \text{data}, the problem construction is a simple matter of creating a \texttt{CostFunction} for every observation.
\begin{listing}[H]
\begin{minted}[frame=lines,mathescape]{c++}
double m = 0.0;
double c = 0.0;

Problem problem;
for (int i = 0; i < kNumObservations; ++i) {
  problem.AddResidualBlock(
      new AutoDiffCostFunction<ExponentialResidual, 1, 1, 1>(
          new ExponentialResidual(data[2 * i], data[2 * i + 1])),
      NULL,
      &m, &c);
}
\end{minted}
\caption{Problem construction for the exponential data fitting problem. A \texttt{ResidualBlock} is added for each observation.}
\label{listing:datafitting}
\end{listing}
Compiling and running \texttt{data\_fitting.cc} gives us
\begin{minted}{bash}
 0: f: 1.211734e+02 d: 0.00e+00 g: 3.61e+02 h: 0.00e+00 rho: 0.00e+00 mu: 1.00e-04 li:  0
 1: f: 1.211734e+02 d:-2.21e+03 g: 3.61e+02 h: 7.52e-01 rho:-1.87e+01 mu: 2.00e-04 li:  1
 2: f: 1.211734e+02 d:-2.21e+03 g: 3.61e+02 h: 7.51e-01 rho:-1.86e+01 mu: 8.00e-04 li:  1
 3: f: 1.211734e+02 d:-2.19e+03 g: 3.61e+02 h: 7.48e-01 rho:-1.85e+01 mu: 6.40e-03 li:  1
 4: f: 1.211734e+02 d:-2.02e+03 g: 3.61e+02 h: 7.22e-01 rho:-1.70e+01 mu: 1.02e-01 li:  1
 5: f: 1.211734e+02 d:-7.34e+02 g: 3.61e+02 h: 5.78e-01 rho:-6.32e+00 mu: 3.28e+00 li:  1
 6: f: 3.306595e+01 d: 8.81e+01 g: 4.10e+02 h: 3.18e-01 rho: 1.37e+00 mu: 1.09e+00 li:  1
 7: f: 6.426770e+00 d: 2.66e+01 g: 1.81e+02 h: 1.29e-01 rho: 1.10e+00 mu: 3.64e-01 li:  1
 8: f: 3.344546e+00 d: 3.08e+00 g: 5.51e+01 h: 3.05e-02 rho: 1.03e+00 mu: 1.21e-01 li:  1
 9: f: 1.987485e+00 d: 1.36e+00 g: 2.33e+01 h: 8.87e-02 rho: 9.94e-01 mu: 4.05e-02 li:  1
10: f: 1.211585e+00 d: 7.76e-01 g: 8.22e+00 h: 1.05e-01 rho: 9.89e-01 mu: 1.35e-02 li:  1
11: f: 1.063265e+00 d: 1.48e-01 g: 1.44e+00 h: 6.06e-02 rho: 9.97e-01 mu: 4.49e-03 li:  1
12: f: 1.056795e+00 d: 6.47e-03 g: 1.18e-01 h: 1.47e-02 rho: 1.00e+00 mu: 1.50e-03 li:  1
13: f: 1.056751e+00 d: 4.39e-05 g: 3.79e-03 h: 1.28e-03 rho: 1.00e+00 mu: 4.99e-04 li:  1
Ceres Solver Report: Iterations: 13, Initial cost: 1.211734e+02, \
Final cost: 1.056751e+00, Termination: FUNCTION_TOLERANCE.
Initial m: 0 c: 0
Final   m: 0.291861 c: 0.131439
\end{minted}

\begin{figure}[t]
	\begin{center}
	\includegraphics[width=\textwidth]{fit.pdf}
	\caption{Least squares data fitting to the curve $y = e^{0.3x + 0.1}$. Observations were generated by sampling this curve uniformly in the interval $x=(0,5)$ and adding Gaussian noise with $\sigma = 0.2$.\label{fig:exponential}}
\end{center}
\end{figure}

Starting from parameter values $m = 0, c=0$ with an initial objective function value of $121.173$ Ceres finds a solution $m= 0.291861, c = 0.131439$ with an objective function value of $1.05675$. These values are a a bit different than the parameters of the original model $m=0.3, c= 0.1$, but this is normal. When reconstructing a curve from noisy data, we expect to see such deviations. Indeed, if you were to evaluate the objective function for $m=0.3, c=0.1$, the fit is worse with an objective function value of 1.082425. Figure~\ref{fig:exponential} illustrates the fit.

\section{Bundle Adjustment}
\label{sec:tutorial:bundleadjustment}
\begin{listing}[ht]
\begin{minted}[frame=lines,mathescape]{c++}
struct SnavelyReprojectionError {
  SnavelyReprojectionError(double observed_x, double observed_y)
      : observed_x(observed_x), observed_y(observed_y) {}

  template <typename T>
  bool operator()(const T* const camera,
                  const T* const point,
                  T* residuals) const {
    // camera[0,1,2] are the angle-axis rotation.
    T p[3];
    ceres::AngleAxisRotatePoint(camera, point, p);
    // camera[3,4,5] are the translation.
    p[0] += camera[3]; p[1] += camera[4]; p[2] += camera[5];

    // Compute the center of distortion. The sign change comes from
    // the camera model that Noah Snavely's Bundler assumes, whereby
    // the camera coordinate system has a negative z axis.
    const T& focal = camera[6];
    T xp = - focal * p[0] / p[2];
    T yp = - focal * p[1] / p[2];

    // Apply second and fourth order radial distortion.
    const T& l1 = camera[7];
    const T& l2 = camera[8];
    T r2 = xp*xp + yp*yp;
    T distortion = T(1.0) + r2  * (l1 + l2  * r2);

    // Compute final projected point position.
    T predicted_x = distortion * xp;
    T predicted_y = distortion * yp;

    // The error is the difference between the predicted and observed position.
    residuals[0] = predicted_x - T(observed_x);
    residuals[1] = predicted_y - T(observed_y);
    return true;
  }

  double observed_x;
  double observed_y;
};
\end{minted}
\caption{Templated functor to compute the residual using the Bundler camera. Note that the structure of this functor is similar to the \texttt{ExponentialResidual}~\ref{listing:exponentialresidual}, in that there is an instance of this object responsible for each image observation. The camera has nine parameters. Three for rotation as a Rodriquez axis-angle vector, three for translation, one for focal length and two for radial distortion. \texttt{AngleAxisRotatePoint} can be found in \texttt{rotation.h}.}
\label{listing:bundlerresidual}
\end{listing}

One of the main reasons for writing Ceres was our desire to solve large scale bundle adjustment problems~\cite{hartley-zisserman-book-2004,triggs-etal-1999}.

Given a set of measured image feature locations and correspondences, the goal of bundle adjustment is to find 3D point positions and camera parameters that minimize the reprojection error. This optimization problem is usually formulated as a non-linear least squares problem, where the error is the squared $L_2$ norm of the difference between the observed feature location and the projection of the corresponding 3D point on the image plane of the camera.

Ceres has extensive support for solving bundle adjustment problems. Let us consider the solution of a problem from the BAL~\cite{Agarwal10bal} dataset. The code for this example can be found in \texttt{examples/simple\_bundle\_adjuster.cc}.

The first step is to define the CostFunction. Each residual in a BAL
problem depends on a three dimensional point and a nine parameter
camera. The details of this camera model can be found on Noah
Snavely's Bundler
homepage~\footnote{\url{http://phototour.cs.washington.edu/bundler/}}
and the BAL
homepage~\footnote{\url{http://grail.cs.washington.edu/projects/bal/}}. Listing~\ref{listing:bundlerresidual}
describes the templated functor for computing the residual. Unlike the
examples before this is a non-trivial function and computing its
analytic Jacobian is a bit of a pain. Automatic differentiation makes
our life very simple here. Given this functor, let us look at the problem construction.

\begin{minted}[frame=lines,mathescape]{c++}
// Create residuals for each observation in the bundle adjustment problem. The
// parameters for cameras and points are added automatically.
ceres::Problem problem;
for (int i = 0; i < bal_problem.num_observations(); ++i) {
  // Each Residual block takes a point and a camera as input and outputs a 2
  // dimensional residual. Internally, the cost function stores the observed
  // image location and compares the reprojection against the observation.
  ceres::CostFunction* cost_function =
      new ceres::AutoDiffCostFunction<SnavelyReprojectionError, 2, 9, 3>(
          new SnavelyReprojectionError(
              bal_problem.observations()[2 * i + 0],
              bal_problem.observations()[2 * i + 1]));

  problem.AddResidualBlock(cost_function,
                           NULL /* squared loss */,
                           bal_problem.mutable_camera_for_observation(i),
                           bal_problem.mutable_point_for_observation(i));
  }
}
\end{minted}

Note that the problem construction for bundle adjustment is not very
different from the data fitting example. One extra feature here is the
optional use of a robust loss function. If the user wants, instead of just using a squared reprojection error as the objective function we robustify it using Huber's loss. More details of the various loss functions available in Ceres and their characteristics can be found in \texttt{loss\_function.h}.

One way to solve this problem would be to set \texttt{Solver::Options::linear\_solver\_type} to \texttt{SPARSE\_NORMAL\_CHOLESKY} and call \texttt{Solve}. And while this is a reasonable thing to do, bundle adjustment problems have a special sparsity structure that can be exploited to solve them much more efficiently. Ceres provides three specialized solvers (collectively known as Schur based solvers) for this task. The example code uses the simplest of them \texttt{DENSE\_SCHUR}. For more details on the available solvers and how they work see Chapter~\ref{chapter:theory}.

For a more sophisticated example of bundle adjustment which demonstrates the use of the various linear solvers, robust loss functions and local parameterizations see \texttt{examples/bundle\_adjuster.cc}.


\subsection{Affine varieties}\label{subsec:affine_varieties}

As in \fullref{sec:commutative_algebra}, by \( R \) will denote a nontrivial commutative unital \hyperref[def:semiring/commutative_unital_ring]{ring}.

\begin{definition}\label{def:affine_variety}\mcite[69]{КоцевСидеров2016}
  For each ideal \( I \) of the polynomial \hyperref[def:multivariate_polynomial]{ring} \( \BbbK[X_1, \ldots, X_n] \) over a \hyperref[def:field]{field} \( \BbbK \), we define its \term{affine variety} as the locus
  \begin{equation*}
    \mscrV(I) \coloneqq \{ (x_1, \ldots, x_n) \in \BbbK^n \colon \forall p \in I, p(x_1, \ldots, x_n) = 0 \}
  \end{equation*}
  of the simultaneous roots of all polynomials in \( I \).

  \begin{thmenum}
    \thmitem{def:affine_variety/dimension} The \term{dimension} \( \dim(\mscrV(I)) \) of an affine variety is defined as the Krull \hyperref[def:krull_dimension]{dimension} of the quotient \( \BbbK[X_1, \ldots, X_k] / I \).

    \thmitem{def:affine_variety/algebraic_curve} An \term{algebraic curve} over \( \BbbK^n \) is an affine variety of dimension one.

    \thmitem{def:affine_variety/algebraic_surface} An \term{algebraic surface} over \( \BbbK^n \) is an affine variety of dimension two.
  \end{thmenum}
\end{definition}

\begin{proposition}\label{thm:dimension_of_variety_of_prime_ideal}
  If \( P \) is a prime ideal of \( \BbbK[X_1, \ldots, X_n] \), the dimension of \( \mscrV(P) \) is the number of prime ideals strictly containing \( P \).

  In particular, \( \dim \mscrV(P) \leq n - 1 \) and, if \( P \) is not maximal, \( \dim \mscrV(P) \geq 1 \).
\end{proposition}
\begin{proof}
  By \fullref{thm:prime_ideal_iff_prime_quotient_ideal}, \( \dim \mscrV(P) = \dim(\BbbK[X_1, \ldots, X_n] / P) \) is the number of prime ideals of \( \BbbK[X_1, \ldots, X_n] \) strictly containing \( P \).

  Since \( P \) itself is a prime ideal, the number of prime ideals strictly containing \( P \) is at least \( 1 \) less than the Krull dimension of \( \BbbK[X_1, \ldots, X_n] \). By \fullref{thm:def:krull_dimension/properties/polynomials_over_field}, \( \dim \mscrV(I) \leq n - 1 \).

  By \fullref{thm:field_maximal_ideal_representation}, \( \braket{X_1, \ldots, X_n} \) is a maximal ideal of \( \BbbK[X_1, \ldots, X_n] \) (which is also prime), therefore \( \dim \mscrV(I) \geq 1 \).
\end{proof}

\begin{example}\label{ex:affine_varieties}
  We will work in the ring \( \BbbR[X, Y] \) of real polynomials in two indeterminates. By \fullref{thm:dimension_of_variety_of_prime_ideal}, any variety generated by a nonconstant irreducible polynomial is an \hyperref[def:affine_variety/algebraic_curve]{algebraic curve}.

  \begin{itemize}
    \item The variety of the ideal \( I \coloneqq \braket{X^2 + Y^2 - 1} \) is the unit \hyperref[def:quadratic_plane_curve/ellipse]{circle}
          \begin{equation*}
            \mscrV(I) = \{ (x, y) \in \BbbR^2 \colon x^2 + y^2 = 1 \}.
          \end{equation*}

          Note that \( p(X, Y) \coloneqq X^2 + Y^2 - 1 \) is an \hyperref[def:irreducible_ring_element]{irreducible} polynomial. Indeed, if \( p(X, Y) = p_1(X, Y) p_1(X, Y) \), then by \fullref{thm:def:polynomial_degree/properties/product}, \( \deg(p_1) + \deg(p_2) = \deg(p) \). If \( \deg(p_1) = \deg(p_2) = 1 \), the variety of \( p \) would be a union of two lines, which cannot possibly be the unit circle \( \mscrV(I) \). Thus, at least one of \( p_1 \) or \( p_2 \) is invertible and hence \( p \) is irreducible.

          Therefore, \( \mscrV(I) \) is an algebraic curve.

    \item Another example is
          \begin{equation*}
            I \coloneqq \braket{X + Y, X - Y - 1},
          \end{equation*}
          whose variety is
          \begin{equation*}
            \mscrV(I) = \{ (x, y) \in \BbbR^2 \colon x = -y \text{ and } x = y + 1 \} = \{ (x, y) \in \BbbR^2 \colon 2y = -1 \}.
          \end{equation*}

          This can also be shown algebraically, since the ideal \( I \) is principal and generated by
          \begin{equation*}
            \gcd(X + Y, X - Y - 1) = 2Y + 1.
          \end{equation*}

          Since \( 2Y + 1 \) is irreducible, \( \mscrV(I) \) is an algebraic curve.

    \item The ideal
          \begin{equation*}
            I \coloneqq \{ p(X, Y) \in R[X, Y] \colon p(X) = 0 \text{ or } \deg p \neq 0 \}
          \end{equation*}
          contains all polynomials except for the units - the nonzero constants. It is not principal because the only common divisors for all of \( I \) are the units.

          The variety \( \mscrV(I) \) for \( I \) is the empty set since it contains polynomials with no common roots - for example, \( X - Y \) and \( X - Y - 1 \).
  \end{itemize}
\end{example}

\begin{definition}\label{def:ideal_of_affine_variety}\mcite[70]{КоцевСидеров2016}
  Dually to \fullref{def:affine_variety}, for each subset \( V \subseteq R^n \), we define its \term{ideal} as
  \begin{equation*}
    \mathcal{I}(V) \coloneqq \{ p \in R[X_1, \ldots, X_n] \colon \forall (x_1, \ldots, x_n) \in V, p(x_1, \ldots, x_n) = 0 \}.
  \end{equation*}
\end{definition}

\begin{remark}\label{rem:nullstelletsatz_etymology}
  The word \enquote{nullstellensatz} is German for \enquote{\hyperref[def:zero_locus]{zero locus} theorem}.
\end{remark}

\begin{theorem}[Algebraic nullstellensatz]\label{thm:algebraic_nullstellensatz}\mcite[64]{КоцевСидеров2016}
  Let \( \BbbK \) be a field, \( A \) be a finitely-generated \( \BbbK \)-\hyperref[def:algebra_over_ring]{algebra} and \( M \) be a maximal ideal of \( A \). Then the field \( A / M \) is a finite extension of \( \BbbK \).

  In the special case that \( \BbbK \) is algebraically \hyperref[def:algebraically_closed_field]{closed}, we have
  \begin{equation*}
    \BbbK = A / M.
  \end{equation*}
\end{theorem}

\begin{example}\label{ex:algebraic_nullstellensatz_real_over_complex}
  For \( \BbbK = \BbbR \) and \( A = \BbbR[X] \), by \fullref{def:set_of_complex_numbers/polynomials} \( \BbbC = \BbbR[X] / \braket{X^2 + 1} \) is a field, so the ideal \( \braket{X^2 + 1} \) is maximal.

  By \fullref{thm:algebraic_nullstellensatz}, \( \BbbC \) is a finite degree extension of \( \BbbR \).
\end{example}

\begin{corollary}\label{thm:closed_field_maximal_ideal_representation}\mcite[exer. 8.1]{КоцевСидеров2016}
  If \( \BbbK \) is algebraically closed, an ideal \( I \) of the polynomial ring \( \BbbK[X_1, \ldots, X_n] \) is maximal if and only if \( I = \braket{X_1 - r_1, \ldots, X_n - r_n} \) for some \( r_1, \ldots, r_n \in \BbbK \).
\end{corollary}

\begin{theorem}[Geometric nullstellensatz]\label{thm:geometric_nullstellensatz}\mcite[70]{КоцевСидеров2016}
  If \( \BbbK \) is an algebraically \hyperref[def:algebraically_closed_field]{closed} field, then for each ideal \( I \subseteq \BbbK[X_1, \ldots, X_n] \) we have the equality
  \begin{equation*}
    \mathcal{I}(\mscrV(I)) = \sqrt I,
  \end{equation*}
  where \( \sqrt I \) is the \hyperref[def:radical_ideal]{radical} of \( I \).
\end{theorem}

\begin{example}\label{ex:geometric_nullstellensatz_does_not_hold_for_reals}
  By \fullref{thm:reals_not_algebraically_closed}, the field \( \BbbR \) of \hyperref[def:set_of_real_numbers]{real numbers} is not algebraically closed since \( x^2 + 1 \) has no root. Denote \( I \coloneqq \braket{x^2 + 1} \)

  Then \( \mscrV(I) = \varnothing \), so \( \mathcal{I}(\mscrV)(I) = \BbbR[X] \).

  But \( \sqrt{I} = I \) since \( x^2 + 1 \) is irreducible and thus forms a a prime ideal by \fullref{thm:ufd_prime_iff_irreducible}.

  Thus, \( \mscrV(I) \neq \sqrt{I} \) and \fullref{thm:geometric_nullstellensatz} does not hold.
\end{example}

\begin{corollary}\label{thm:weak_nullstellensatz}\mcite{Tao:nullstellensatz}
  If \( \BbbK \) is an algebraically \hyperref[def:algebraically_closed_field]{closed} field, then for each finite collection
  \begin{equation*}
    p_i(X_1, \ldots, X_n), i = 1, \ldots, k
  \end{equation*}
  of polynomials over \( n \) variables either
  \begin{thmenum}
    \thmitem{thm:weak_nullstellensatz/roots} the system of equations
    \begin{equation}\label{thm:weak_nullstellensatz/system}
      \begin{cases}
        p_1(x_1, \ldots, x_n) = 0 \\
        p_2(x_1, \ldots, x_n) = 0 \\
        \vdots                    \\
        p_k(x_1, \ldots, x_n) = 0
      \end{cases}
    \end{equation}
    has a, solution.

    \thmitem{thm:weak_nullstellensatz/bezout} there exist polynomials
    \begin{equation*}
      q_1(X_1, \ldots, X_n), i = 1, \ldots, k
    \end{equation*}
    such that
    \begin{equation*}
      p_1 q_1 + \cdots + p_k q_k = 1.
    \end{equation*}
  \end{thmenum}
\end{corollary}
\begin{proof}
  Define the ideal
  \begin{equation*}
    I \coloneqq \braket{p_1, \ldots, p_k}.
  \end{equation*}

  The following are equivalent:
  \begin{itemize}
    \item The variety \( \mscrV(I) \) is not empty.
    \item The system \fullref{thm:weak_nullstellensatz/system} has a, solution.
    \item The ideal \( \mathcal{I}(\mscrV(I)) \) is not the whole space \( \BbbK[X_1, \ldots, X_n] \).
    \item By \fullref{thm:geometric_nullstellensatz}, the radical \( \sqrt I \) is not the whole space.
    \item The units of \( \BbbK[X_1, \ldots, X_n] \) are not contained in \( \sqrt I \), hence also not contained in \( I \).
    \item There exists a set of polynomials satisfying \fullref{thm:weak_nullstellensatz/bezout}.
  \end{itemize}
\end{proof}

\begin{corollary}\label{thm:polynomial_over_closed_field_is_either_invertible_or_has_root}
  A multivariate polynomial over an algebraically closed field either has a root or is invertible.
\end{corollary}
\begin{proof}
  \Fullref{thm:weak_nullstellensatz} with \( k = 1 \).
\end{proof}


\section{Convex Learning Problems}
\frame{\tableofcontents[currentsection, hideothersubsections]}

% In general, a convex learning problem is a problem whose hypothesis class is a
% convex set, and whose loss function is a convex function for each example.

\begin{frame}
\frametitle{Convex Learning Problems: Intro}

Recall, we have:
\begin{itemize}
    \item a set of examples $\mathcal{Z} = \mathcal{X} \times \mathcal{Y}$
    \item a hypothesis class $\mathcal{H}$, which can be an arbitrary set,\\
    for now consider: $ \mathcal{H} \subseteq \mathbb{R}^d$,
    thus, denote a hypothesis in $\mathcal{H}$ by $\mathbf{w}$
    \item a loss function $\ell: \mathcal{H} \times \mathcal{Z} \mapsto \mathbb{R_{+}}$
\end{itemize}

\begin{figure}
    \centering
    \includegraphics[scale=0.3]{def_12_10}
\end{figure}

\end{frame}

\begin{frame}
\frametitle{Convex Learning Problems: Intro}

Example 12.7: \\
Linear Regression with the Squared Loss
\begin{itemize}
    \item  to learn a linear function $h: \mathbb{R}^d \mapsto \mathbb{R}$ that best approximates
        the relationship between ``explanatory'' and outcome variables.
    \item Each linear function is parameterized by a vector $\mathbf{w} \in \mathbb{R}^d$,\\
        hence $\mathcal{H} = \mathbb{R}^d$
    \item set of examples:
    $\mathcal{Z} = \mathcal{X} \times \mathcal{Y} = \mathbb{R}^d \times \mathbb{R} = \mathbb{R}^{d+1}$
    \item loss function: $\ell(\mathbf{w}, (\mathbf{x}, y)) = (\langle \mathbf{w},\mathbf{x}  \rangle - y)^2$
    \item Clearly: $\mathcal{H}$ is a convex set and  $\ell$ is convex fn wrt $\mathbf{w}$
\end{itemize}

\begin{figure}
    \centering
    \includegraphics[scale=0.3]{lemma_12_11}
\end{figure}

\end{frame}

\begin{frame}
\frametitle{Convex Learning Problems: Learnability}
QUESTIONS:
\begin{itemize}
    \item is convexity a sufficient condition for the learnability of a problem?
    \item are all convex learning problems over $R^d$ learnable?
\end{itemize}
\vspace{5mm}

ANSWERS:\\
\begin{itemize}
    \item \textbf{not all} convex learning problems over $\mathbb{R}^d$ are learnable.
    \item Convex problems are \textbf{learnable under} some restricting conditions:\\
        the properties of convexity, boundedness, and Lipschitzness or smoothness
        of the loss function are sufficient for learnability.
\end{itemize}

\end{frame}

\begin{frame}
\frametitle{Convex Learning Problems: Learnability}
TWO families of learning problems are learnable.

\noindent\makebox[\linewidth]{\rule{\paperwidth}{0.4pt}}

\begin{figure}
    \centering
    \includegraphics[scale=0.3]{def_12_12}
\end{figure}

\noindent\makebox[\linewidth]{\rule{\paperwidth}{0.4pt}}

\begin{figure}
    \centering
    \includegraphics[scale=0.3]{def_12_13}
\end{figure}

\end{frame}


\documentclass[a4paper,11pt]{article}
\usepackage{a4wide}
\usepackage{amsmath}
\usepackage{amssymb}

\begin{document}
\begin{center}
  {\LARGE\bf Supplemental note for Week 3 Part 1}
  \end{center}
\begin{flushright}
  {\large\bf ver. 20170422-01}\\
 \ \\
{\large\bf Ryoichi Yamamoto}\\
\end{flushright}

\section{Vector products}

For $\mathbf{A}=(A_x, A_y,A_z)$ and  $\mathbf{B}=(B_x, B_y,B_z)$

\subsection{Dot product (=scalar)}

$$
\mathbf{A}\cdot\mathbf{B}=A_xB_x+A_yB_y+A_zB_z=S
$$

Equivalent Einstein convention: $S=A_\alpha B_\alpha$

\subsection{Cross product (=vector)}

$$
\mathbf{A}\times\mathbf{B}=(
      A_yB_z -  A_zB_y ,
      A_xB_z -  A_zB_x ,
      A_xB_y -  A_yB_x
)
=(V_x,V_y,V_z)
$$

Equivalent Einstein convention: $V_\alpha=\epsilon_{\alpha,\beta,\gamma}A_\beta B_\gamma$, where $\epsilon_{\alpha,\beta,\gamma}$ is the Levi-Civita Symbol
$$
\epsilon_{\alpha,\beta,\gamma}=
\begin{cases}
    +1\ \ \ \ \ {\rm if\ ({\it \alpha,\beta,\gamma})=(x,y,z),\ (y,z,x),\ or\ (z,x,y)}\\
    -1 \ \ \ \ \ {\rm if\ ({\it \alpha,\beta,\gamma})=(z,y,x),\ (y,x,z),\ or\ (x,z,y)}\\
    0\ \ \ \ \ \ \ \ {\rm if}\ \alpha=\beta,\ \alpha=\gamma,\ {\rm or}\ \beta=\gamma
\end{cases}
$$

\subsection{Dyadic product (=tensor)}

$$
\mathbf{A}\mathbf{B}=\left(
\begin{array}{ccc}
      A_xB_x & A_xB_y & A_xB_z \\
      A_yB_x & A_yB_y & A_yB_z \\
      A_zB_x & A_zB_y & A_zB_z
\end{array}\right)
=\left(
\begin{array}{ccc}
      M_{xx} & M_{xy} & M_{xz} \\
      M_{yx} & M_{yy} & M_{yz} \\
      M_{zx} & M_{zy} & M_{zz}
\end{array}\right)
$$

Equivalent Einstein convention: $M_{\alpha\beta}=A_\alpha B_\beta$

\end{document}

Let us start with the Langevin equation
\begin{equation}
m\frac{d\mathbf{V}(t)}{dt}={-\zeta\mathbf{V}(t)}+{\mathbf{F}(t)},
\tag{F2}
\end{equation}
where the random force $\mathbf{F}(t)$ satisfies the following conditions
\begin{equation}
\langle \mathbf{F}(t)\rangle=\mathbf{0}
\tag{F3}
\end{equation}
\begin{equation}
\langle \mathbf{F}(t)\mathbf{F}(0)\rangle = {2k_B T\zeta}\mathbf{I}\delta(t),\tag{F4}
\end{equation}
with
$\mathbf{0}\equiv(0,0,0)$ and $\mathbf{I}\equiv\begin{bmatrix}1&0&0\\0&1&0\\0&0&1\end{bmatrix}$.\\
We now discretize the time $t$ using an increment $\Delta t$, such that
$t_i\equiv i\Delta t$, and define the cumulative impulse during the
interval $t_i\le t\le t_{i+1} = t_i + \Delta t$, as
\begin{equation}
\Delta\mathbf{W}_i
\equiv\int_{t_i}^{t_{i+1}} dt\mathbf{F}(t).
\tag{F8}
\end{equation}
From Eq.(F3), it is straightforward to show
\begin{equation}
\langle\Delta\mathbf{W}_i\rangle
=\int_{t_i}^{t_{i+1}} dt\langle\mathbf{F}(t)\rangle=\mathbf{0}.
\tag{F10}
\end{equation}
Also from Eq.(F4), for $j\ne i$
\begin{eqnarray}
\langle\Delta\mathbf{W}_i\Delta\mathbf{W}_{j\ne i}\rangle
&=&\int_{t_i}^{t_{i+1}} dt\int_{t_j}^{t_{j+1}} dt'\langle\mathbf{F}(t)\mathbf{F}(t')\rangle\\
&=&2k_B T\zeta\mathbf{I} \int_{t_i}^{t_{i+1}} dt\int_{t_j}^{t_{j+1}} dt'
\delta(t-t')\\
&=&\mathbf{O},
\end{eqnarray}
where $\mathbf{O}\equiv\begin{bmatrix}0&0&0\\0&0&0\\0&0&0\end{bmatrix}$.\\
For $j=i$
\begin{eqnarray}
\langle\Delta\mathbf{W}_i\Delta\mathbf{W}_i\rangle
&=&\int_{t_i}^{t_{i+1}} dt\int_{t_i}^{t_{i+1}} dt'\langle\mathbf{F}(t)\mathbf{F}(t')\rangle\\
&=&2k_B T\zeta\mathbf{I} \int_{t_i}^{t_{i+1}} dt\int_{t_i}^{t_{i+1}} dt'
\delta(t-t')\\
&=&2k_B T\zeta\Delta t\mathbf{I}.
\end{eqnarray}
Combining Eqs.(3) and (6), we obtain
\begin{equation}
\langle \Delta \mathbf{W}_i\Delta \mathbf{W}_j\rangle = {2k_B T\zeta}\Delta t\mathbf{I}\delta_{ij} .
\tag{F11}
\end{equation}

%\newpage
\section{Distribution of $\Delta\mathbf{W}_i$}

Here we further divide $\Delta t$ into $n$ segments ($n\gg1$) of a
very small time span $\epsilon$, {\it i.e.}, $\Delta t \equiv n\epsilon$, and
define a new cumulative impulse over $\epsilon$
\begin{equation}
\mathbf{W}^m_i
\equiv\int_{t_i+(m-1)\epsilon}^{t_{i}+m\epsilon} dt\mathbf{F}(t),
\end{equation}
where $1\le m\le n$.\\
Repeating the same procedure performed in the previous section, the following conditions are derived.
\begin{eqnarray}
\langle\mathbf{W}^m_i\rangle&=&\mathbf{0}\\
\langle \mathbf{W}^m_i\mathbf{W}^l_j\rangle &=& {2k_B T\zeta}\epsilon\mathbf{I}\delta_{ij}\delta_{ml}
\end{eqnarray}
Eqs.(8) and (9) show that the mean and variance of the random numbers $W^m_{\alpha,i}$ $(\alpha\in x,y,z)$ are zero and $2k_B T\zeta\epsilon$, respectively. \\
From Eq.(F8) and (7), we should notice that
\begin{equation}
\Delta\mathbf{W}_i
=\mathbf{W}^1_i+\mathbf{W}^2_i+\cdots+\mathbf{W}^n_i.
\end{equation}
Therefore, from the central limit theorem Eqs.(D7)-(D9) introduced in
Part 3 of Week 2, one realizes that the $\Delta W_{\alpha,i}$ should be
drawn from a \textit{Gaussian} distribution, with average and variance
equal to zero and $2k_B T\zeta\Delta t$, respectively, regardless of the
distribution of the $W^m_{\alpha,i}$.
\end{document}


\section{Random: Random Numbers}
\subsection{Object Structure}
For most topics we have used simple Modules.
That is because they did not have statistice memory.  However, for
the random generators we need to remember data between invocations.  The
selection of which engine, the seed, the current engine settings, etc.
are needed.  Therefore, we wrap the generators in objects.

Many different generators can be used.  See the Random Number Generator
(RNGnn) modules.  Each of these is subtyped from Random.RandomGen, which
in turn allows the generators to be used to drive various
deviate generators.

\subsection{Deviate Generators}

\subsection*{uniform}
This just returns the engine's value, possibly with scaling to fit
min..max.  It checks to see if the parameters really are different
from Min and Max before bothering to do scaling.

\subsection*{exponential}
This one is trivial.  I don't know what NR92 had in
mind with the do-while loop.  I just return the log, since
I'm already checking for 0.0 in the generators.

\subsection*{gaussian}
We have implemented this twice, with Warren Smith's version being
provided as the default. See the code for his commentary.

The alternative implementation was based on NR92, pg 289.
The basic equation is:
\begin{equation}
  p(y)dy = \frac{1}{\sqrt{2\pi}}e^{-y^2/2}dy
\end{equation}

The trick is to use the Box-Muller method to transformed y's:
\begin{eqnarray}
     R^2 & = & v_1^2 + v_2^2\\
     y_1 & = & \sqrt{-2.0\ln(x_1)} v_1/\sqrt{R^2}\\
     y_2 & = & \sqrt{-2.0*ln(x_1)} v_2/\sqrt{R^2}
\end{eqnarray}

Since $R^2$ is made from squares, and is supposed to range 0..1, we don't
need to actually do the sqrt.  We just check to see if $R^2$ is
in the 0..1 range.

Obviously the sqrt and Rsq can be pulled out for a tmp
value:
\begin{verbatim}
     tmp:=sqrt(-2.0*ln(x1))/R^2
\end{verbatim}

Also, $R^2$ can be used for x1, so let's make a tmp for it:
\begin{verbatim}
     tmp:=sqrt(-2.0*ln(Rsq))/Rsq
\end{verbatim}

Now we get v's until we are inside the unit circle, then use
the radius squared (Rsq) to that point as x1.  We know x1
will be < 1 because we were already inside the circle.  Then
use the tmp factor to get the associated y's:
\begin{verbatim}
     y1:=v1*tmp
     y2:=v2*tmp
\end{verbatim}

The function is only supposed to return one of these at a
time, so we save one for use later, and set a boolean to the
effect that it is ready to use.  Since we already have
"start", we'll use that.  When self.start is true, we need to
generate two more y's.  When it is false, we use the saved
one and set for start again.

\subsection*{gamma}
See W. Smith's code for commentary.

\subsection*{dirichlet}
See W. Smith's code for commentary.

\subsection*{poisson}
Not implemented.

\subsection*{binomial}
Not implemented.


%======================================================================
\chapter{Future Work}
%======================================================================
In terms of future work, the chart generation pipeline will be utilized to generate the training data of another system. On top of that, the chart regeneration will be used for determining the correctness of the aforementioned network. However, aside from future use-cases, there are still a few tasks that were unable to be completed, largely due to time constraints.

\section{Data Modifiers \& Multipliers}
Virtually all of the data generation produces values that are within a set range. When generated in vast quantities, the values will lack variance and appear to be repetitive. This can result in poor performance for succeeding systems such as a Generative Adversarial Network. The way to combat this is quite simple in nature, but was unable to be implemented as the process of manually testing all graph-types combinations is quite time consuming. Furthermore, the possible maintenance required to initially fix all existing graph creation code should not be undermined.

\hfill

Following the data generation step, data modifiers and multipliers could be used to alter the data in one of two ways. The first is an offset which adds a constant value to all applicable data points. For example, this could involve adding a singular value to all \(X\) values in the dataset. The second method involves transforming the data points by a modifier. This would entail multiplying the data points by a constant value. Additionally, the values could be passed into exponent or logarithmic functions, however, many edge cases must be covered in order to preserve the underlying distribution of the generated data.

\hfill

The values for the offset and multiplication modifiers are intended to be random, as to provide greater variability in the graph generation. On a more technical level, this code would reside in the data generation step (\autoref{subsection:data_generation}) and could be as simple as adding a function to take in the data after generation is complete.

\section{Additional Theming}
Another aspect that was unable to be completed was the implementation of additional Bokeh themes. Both Altair and plotnine contain a sequence of 10 unique themes, while Bokeh only possesses 6. The main concern with having less stylization options is having reduced uniqueness and variability when this application is used on a larger scale. Provided with more time, this task could be easily completed by simply implementing additional themes.

\section{Mini-Batching}
The main premise of mini-batching is to separate the dataset into smaller batches for further calculation. The benefit of applying mini-batching in this project would be avoiding the hardware limitations of the system executing the pipeline. As loading in upwards of 30,000 images may result in out of memory errors, having smaller batches for the garbage collection system to dispose of images that have already been generated would be extremely beneficial. The reason this was not implemented is simply due to time constraints and is definitely something worth further examining.

\section{Multimodal Histograms}
The final aspect in terms of future work is to allow for the generation of multimodal histograms. This could be done by splicing together two or more separate distributions. A random number would be used to determine how many values should be discarded when connecting the tail of one distribution to the head of another. Similar to how area and line plots contain multiple layers, adding multimodal histograms would provide a higher degree of variability.