Now we've pinned down the mechanics of how we will incorporate our signal functions into real working code, we can write our first example. Save a copy of \hask{YampaUtils.hs} in your working directory, for your use in these examples. Our first example, Listing \ref{lst:helloYampa}, is the Hello, World of Yampa.

\lstinputlisting[caption={HelloYampa.hs}, label=lst:helloYampa]{./src/HelloYampa.hs}

Our discussion in the introduction about \hask{reactimate}, and our tidied version \yampaMain, should give you a rough idea of what is going on here. \yampaMain first calls \hask{initialise}, which prints some text to the screen, but provides no input (or, more precisely, provides as input \hask{()}). The input function passed to \yampaMain is just \hask{return Nothing}, which again provides no input to the system.

\hask{waitTwo} is a signal function, and is the new code in this listing. For the moment, lets just observe that it converts a signal of values of type \hask{()} into a signal of values of type \hask{Bool}, which is what its type signature \hask{SF () Bool} is meant to indicate (`` a signal function from signals of type \hask{()} to signals of type \hask{Bool}'').

The output function, \hask{output}, takes this boolean value, and if its false, just instructs \yampaMain to continue by passing out a \hask{False} value in the \hask{IO} monad. However, if the boolean value is true, the output function first prints a message to the screen, and then returns an \hask{IO} value of \hask{True}, which instructs \yampaMain to stop executing, and the program finishes.

Precisely when the value \hask{True} emerges from \yampaMain is determined in the signal function \hask{waitTwo}. So lets take a look at this object.

\begin{lstlisting}
waitTwo :: SF () Bool
waitTwo = time >>> arr (>=2)
\end{lstlisting}

The specification for \hask{waitTwo} is that it should take the input signal (which here is constantly taking value \hask{()}), and if \hask{waitTwo} has been transforming input values for less than 2 seconds, it should transform the input into a value \hask{False}, and otherwise, it should transform the input signal into a value \hask{True}. This boils down to saying, \yampaMain should receive a value \hask{True} to give to \hask{output}, precisely when \yampaMain has been running for 2 seconds. Compiling and running this code seems to confirm this.

So how has \hask{waitTwo} been defined? It consists of two parts combined together with the operator \hask{>>>}. First lets take a look at \hask{time}.

\begin{lstlisting}
time :: SF a Time
\end{lstlisting}

\noindent \hask{time} takes a signal of any value, and replaces it with a value of type \hask{Time}, a synonym for \hask{Double}. The value is the time the particular instantiation of \hask{time} has been in use, starting from $0$. So in our case, it takes the value \hask{()}, and replaces it with the time that \yampaMain has been using \hask{waitTwo}, which is the length of time \yampaMain has been running.

Secondly, we have \hask{arr (>=2)}. Now inspecting the type of this in ghci reveals \hask{arr} is a function which makes use of the \hask{Arrow} type class. \hask{SF} is an instance of this type class, and specialising its type signature to \hask{SF}, we have:

\begin{lstlisting}
arr :: (a -> b) -> SF a b
\end{lstlisting}

\noindent \hask{arr} is a way of lifting pure functions into \hask{SF}, analogous to how \hask{return} lifts values in a monad, and \hask{pure} lifts values for applicative functors. More precisely, if \hask{f :: a -> b}, then \hask{arr f} takes a signal of values of type \hask{a}, and transforms it into a signal of values of type \hask{b}, by applying \hask{f} to each value of type \hask{a}. In some sense, it is the continuous signal analogue of \hask{fmap} for the functor typeclass.

In our example, we have the signal function \hask{arr (>=2)}, which by specialising to types \hask{SF} again has type:

\begin{lstlisting}
arr (>=2) :: (Num a, Ord a) => SF a Bool
\end{lstlisting}

\noindent \hask{arr (>=2)} takes a signal with numerical and orderable values, and applies \hask{(>=2)} to these values. So our transformed signal will output \hask{True} precisely when the input signal takes on values greater than or equal to 2.

So we have two signal functions, with an operator which combines them (a \emph{combinator}). Lets inspect the type of \hask{>>>}, specialised to \hask{SF} again.

\begin{lstlisting}
(>>>) :: SF a b -> SF b c -> SF a c
\end{lstlisting}

\noindent The type signature (and the fact that the more general version is for objects from the typeclass \hask{Category}), is a giveaway for what \hask{(>>>)} does. \hask{(>>>)} is the \hask{SF} analogue of composition. Given a way of transforming signals of value type \hask{a} into signals of value type \hask{b}, and a way of transforming signals of value type \hask{b} into signals of value type \hask{c}, by performing each transformation in order, I can transform signals of value type \hask{a} into signals of value type \hask{c}. This is the function of the \hask{(>>>)} combinator. More precisely, \hask{f >>> g} first transforms with \hask{f}, and then with \hask{g} (recall \hask{f.g} first applies g \emph{then} applies \hask{f}).

So now we can analyse what \hask{waitTwo} actually does. \hask{waitTwo} takes an input signal of values \hask{()}, and replaces these values with the time which \yampaMain has been running. It then takes this time, and if it is less than 2 seconds, replaces this time value with a \hask{False}. Otherwise, it replaces this time value with \hask{True}. In total, \hask{waitTwo} transforms \hask{()} into \hask{False} if \yampaMain has been running less than 2 seconds, and \hask{True} once its been running at least two seconds.

\begin{observation}
Observe that \hask{arr (f.g) = arr g >>> arr f}. Observe that \hask{time} is not the \hask{arr} of a pure function.
\end{observation}

\section{Building signal functions}

Our first example is intentionally not the most intricate or complicated of examples. We build a very simple signal function, with the intention of showing how a Yampa program fits together.

The bulk of the Yampa library is concerned with building signal functions. Rather than building signal functions explicitly, Yampa supplies a basic set of signal functions (we saw for instance, \hask{time}, above), and a set of \emph{combinators} for combining various signal functions (for instance, signal function composition \hask{>>>}).

\section{Some basic signal functions and combinators}

Lets begin with some of the basic signal functions which Yampa provides. As one might expect from a library based around transformations, one has analogues for the identity map, and constant maps.

\begin{lstlisting}
identity :: SF a a
constant :: b -> SF a b
\end{lstlisting}

\noindent Of course, \hask{identity} preserves the value of a signal, and \hask{constant v} takes a signal, and replaces its value by the value \hask{v}.

\begin{exercise}
Write definitions for \hask{identity} and \hask{constant} in terms of \hask{arr}.
\end{exercise}

In our first example, we saw the signal function \hask{time}. \hask{time} takes a signals value, and replaces it with the \emph{local} time, that is the time a signal function has been processing a signal. For the moment, this would appear to be the same time as \yampaMain has been running, and with what has been covered so far, it is, but later we will see that signal functions can be switched in and out in response to events, at which point the time counter starts over from zero. For the sake of completeness (recall \hask{Time} is a synonym for Double):

\begin{lstlisting}
time :: SF a Time
\end{lstlisting}

An interesting built in function is \hask{integral}. This performs numerical integratation of a signal over time. Of course this is useful for describing dynamical systems!

\begin{lstlisting}
integral :: SF Double Double
\end{lstlisting}

\hask{integral} actually has a more general type than the above, but this suffices for now. Yampa provides an similar signal function for derivatives also.

\begin{observation}
\hask{time = constant 1.0 >>> integral}.
\end{observation}

We also have, as we have seen already, a way of lifting pure functions \hask{a -> b} to values of type \hask{SF a b}:

\begin{lstlisting}
arr :: (a -> b) -> SF a b
\end{lstlisting}

\noindent \hask{arr f} will take a signal of type \hask{a}, and process its value with \hask{f}, to create a signal of type \hask{b}.

Now that we have a basic collection of arrows, we woud like some ways to combine them, to form more interesting arrows. The type constructor \hask{SF} is an instance of the \hask{Arrow} typeclass, a generalisation of the \hask{Monad} type class, so we have all the combinators from \hask{Arrow} available for use. We have already seen \hask{arr} above, which is part of the \hask{Arrow} interface, and earlier we saw \hask{(>>>)}.

\hask{(>>>)} is the composition operator for signal functions. \hask{(f >>> g)} applies \hask{f} to a signal, then \hask{g} (note the order is reverse of \hask{.}). Similarly, \hask{(<<<)} is the composition operator the other way around, so \hask{(f <<< g)} performs \hask{g} then \hask{f}.

\begin{lstlisting}
(>>>) :: SF a b -> SF b c -> SF a c
(<<<) :: SF b c -> SF a b -> SF a c
\end{lstlisting}

Sometimes we want to process a signal in two different ways. The combinator \hask{(\&\&\&)} is designed to allow us to do exactly that.

\begin{lstlisting}
(&&&) :: SF a b -> SF a c -> SF a (b,c)
\end{lstlisting}

\noindent Here \hask{(f \&\&\& g)} is intended to mean take the value of a signal, and apply \hask{f} to it, placing the output in the first component of a tuple. Also apply \hask{g} to the value of the signal, and place the output in the second component of the tuple.

Since we can produce a signal which takes a tuple for values, (which we can think of as being two signals captured in one), we have combinators for processing them.

First we have \hask{(***)}, which allows us to take two signal functions and make each act on a particular element of a tuple.

\begin{lstlisting}
(***) :: SF a1 b1 -> SF a2 b2 -> SF (a1, a2) (b1, b2)
\end{lstlisting}

\noindent \hask{(f *** g)} acts on a signal which takes a tuple for values, by applying \hask{f} to the first component, and \hask{g} to the second component.

Sometimes, we only want to transform one of the elements of a signal of tuple type. While something of the form \hask{(f *** identity)} would do, Yampa defines such combinators for us:

\begin{lstlisting}
first :: SF a b -> SF (a, c) (b, c)
second :: SF b c -> SF (a, b) (a, c)
\end{lstlisting}

\noindent \hask{first f} transforms only the first component of a signal of tuple values with \hask{f}, and \hask{second g} transforms only the second component of a signal with tuple values with \hask{g}.

\begin{exercise}
Write \hask{second} in terms of \hask{first} and \hask{arr}.
\end{exercise}

\begin{observation}
\hask{ (f *** g) = (first f) >>> (second g) }.
\end{observation}

Our last combinator is \hask{loop}. \hask{loop} allows us to build recursive signal functions. It has type

\begin{lstlisting}
loop :: SF (a, c) (b, c) -> SF a b
\end{lstlisting}

\noindent \hask{(loop f)} is obtained from \hask{f} by looping its values' second component back in to \hask{f} for the next sample.

\section{Arrow notation}

The above primitives and combinators allow us to form more complex signal functions. In fact, any combination of basic signal functions can be formed. However, using the combinators directly can often lead to code which is difficult to read. For this reason, the arrow syntax was developed. This is the arrow analogue of monadic do notation. It allows us to express more clearly how we wish to process the values which signals take. A preprocessor transforms this notation into a description using the combinators we described above. When using arrow notation in ghci, load ghci with the -XArrows option, e.g. \hask{ghci -XArrows}. Similarly, when compiling with ghc, use the -XArrows option, e.g. \hask{ghc -XArrows main.hs}.

Let us first inspect the general form of a block in arrow syntax. Also, take a look at the example that follows the discussion, since this will make it clearer. The basic form of arrow syntax is given in the following.

\begin{lstlisting}
sigFun :: SF a b
sigFun = proc input -> do
  processedSample1 <- sigFun1 -< sample1
  processedSample2 <- sigFun2 -< sample2
  ...
  returnA -< finalSample
\end{lstlisting}

\hask{proc} is a keyword to indicate that the following is a block written in arrow syntax. \hask{input} represents a sample of type \hask{a}, and can be pattern matched against. A line of the form

\begin{lstlisting}
processedSample <- sigFun -< sample
\end{lstlisting}

\noindent takes the sample (from a signal) named \hask{sample}, processes it with \hask{sigFun}, and binds the resulting value to \hask{processedSample}. We can pattern match in the position of \hask{processedSample}. The line

\begin{lstlisting}
returnA -< finalSample
\end{lstlisting}

\noindent yields \hask{finalSample} as the final transformed sample. Note there is no binding, just like (and for the same reason as) a monadic \hask{do} block. As with \hask{do} blocks, \hask{let} bindings are also allowed in arrow syntax. As a word of warning, recursive definitions in arrow syntax must be preceeded by the keyword \hask{rec}. We will investigate this fully later.

By way of example, lets describe a signal function which receives a signal of type \hask{Double}, which is intended to represent the acceleration of an object, and is intended to output a signal describing its position (assuming it starts at $0$, lets say). Using the normal combinators we could write the following:

\begin{lstlisting}
accToPos :: SF Double Double
accToPos = integral >>> integral
\end{lstlisting}

\noindent which to be fair, is clear enough. In arrow syntax however, we can write this as

\begin{lstlisting}
accToPos :: SF Double Double
accToPos = proc acc -> do
  vel <- integral -< acc
  pos <- integral -< vel
  returnA -< pos
\end{lstlisting}

\noindent So we obtain \hask{vel} (velocity) by integrating the input \hask{acc} (acceleration), and we obtain \hask{pos} (position) by integrating the velocity \hask{vel}. \hask{pos} is the value we want, so we return that. It is not too hard to imagine signal functions where using the arrow syntax can greatly aid clarity. Observe that the wiring of samples through signal functions is represented in an intuitive manner.

The above example would potentially be used in an animation program, or a simulation of some kind. We will build these kinds of programs later, but for the moment it would be nice to have some working code. We will develop our ``Hello, Yampa!'' program a little further. Here, we start by asking the user to specify a time to delay finishing the greeting, and feed this value in to \yampaMain via the initialisation value.

\lstinputlisting[caption={askAndPause.hs}, label=lst:askingAndPausing]{./src/askAndPause.hs}


\chapter{Algorithm for Herbrand Analysis}
\label{chap:chapter4}

This chapter presents an algorithm for Herbrand analysis. The pseudocode
mentioned here is an updated version of the algorithm mentioned in \cite{Babu}
for Herbrand equivalence analysis. The corresponding implementation done for
LLVM compiler framework and a toy language can be found on
\href{https://www.github.com/himanshu520/HerbrandEquivalence}{GitHub}.
Also, see \autoref{chap:chapter7} and \autoref{chap:chapter8} for more details.

One important distinction must be clear between the general Herbrand analysis problem
and the one that the algorithm in this chapter addresses. The universe for the Herbrand
equivalence problem is the set of all expressions that can be formed using constants,
variables and operators used in the program. But as already mentioned, the algorithm
here is concerned with a restricted universe - set of expressions of length atmost two
formed using constants, variables and operators in the program.

\section{Notation}
\label{sec:NotationPseudocode}

Let $\mathcal C$ and $\mathcal X$ be the set of constants and variables used in the program;
$\mathcal W$ be our working set, which is the set of all expressions of length at most two
that can be formed using ($\mathcal C \cup \mathcal X$). Also, $V$ be the set of all program
points, with a special point \texttt{START} denoting the beginning of the program.
\bigbreak \noindent Three global variables are maintained -
\begin{itemize} \tightlist
    \item \texttt{Partitions} : It is two-dimensional integer array indexed by the
                                elements of sets $V$ and $\mathcal W$ respectively. It
                                helps to keep track of partitions at some $v \in V$ by
                                holding same integer at \texttt{Partitions[$v$][$e$]} and
                                \texttt{Partitions[$v$][$e'$]}, for $e, e' \in \mathcal W$
                                if they belongs to the same equivalence class at $v$.
                                Basically, the array maintains set identifiers which helps
                                to identify whether two expressions belong to the same sets
                                (equivalence classes).
    \item \texttt{SetCnt} : It helps to keep track of the next set identifier (an integer)
                            to be used. Whenever, a set identifier is needed the current
                            value of \texttt{SetCnt} is used and at the same time it is
                            incremented so that the same number is never used again.
    \item \texttt{Parent} : It is \texttt{map} indexed by a tuple of three elements - an
                            operator and two set identifiers. Whenever an expression
                            ($x + y$) is assigned a set identifier $c$, $c$ is stored in
                            \texttt{Parent} with $\{+, a, b\}$ as key, where $a$ and $b$ are
                            the set identifiers of $x$ and $y$ respectively. Next time
                            when a set identifier for an expression ($x' + y'$) is needed,
                            where $x'$ and $y'$ have identifiers $a$ and $b$ respectively,
                            $c$ is used instead of using a new set identifier - the \texttt
                            {Parent} of $\{+, a, b\}$ that was earlier stored in the map.
\end{itemize}

\bigbreak \noindent There are a few functions whose definitions are not required explicitly -
\begin{itemize} \tightlist
    \item \texttt{OPERATOR($e$)} : Returns operator used in expression $e \in (\mathcal W \setminus (\mathcal C \cup \mathcal X))$
    \item \texttt{LEFT($e$)} : Returns left operand of expression $e \in (\mathcal W \setminus (\mathcal C \cup \mathcal X))$
    \item \texttt{RIGHT($e$)} : Returns right operand of expression $e \in (\mathcal W \setminus (\mathcal C \cup \mathcal X))$
    \item \texttt{PREDECESSORS($v$)} : Returns the set of predecessors of program point $v \in V$
\end{itemize}

\bigbreak \noindent \textbf{NOTE} - For implementation, the identifiers corresponding to
$\top$ partition should be such that they don't occur in normal partitions and are also
easily distinguishable from them. An easy choice for consistency is to use non-negative
integers as normal set identifiers and an array of -1 to refer $\top$ partition.

\section{Pseudocode}
\label{sec:Pseudocode}

\begin{algorithm}
    \caption{Main Herbrand Equivalence Analysis Function}
    \label{alg:HerbrandEquivalenceAnalysis}
    \begin{algorithmic}
        \Procedure{HerbrandAnalysis}{$ $}
            \State \Comment{\% Initialise \texttt{Partitions} for all program points \%}
            \For{$v \in V$}
                \State \texttt{Partitions[$v$]} $\gets \top$
            \EndFor
            \State \Comment{\% Update \texttt{Partitions} for \texttt{START} point \%}
            \State \Call{findInitialPartition}{$ $}
            \State \Comment{\% Process all program points till convergence \%}
            \State \textbf{converged} $\gets$ \texttt{false}
            \While{\texttt{converged} \textit{is False}}
                \State \texttt{converged $\gets$ true}
                \For{$v \in (V \setminus \{\texttt{START}\})$}
                    \State \textbf{oldPartition} $\gets$ \texttt{Partitions[$v$]}
                    \State \Comment{\% Update \texttt{Partitions} at $v$ \%}
                    \If{$v$ \textit{is a Transfer Point}}
                        \State \Call{TransferFunction}{$v$}
                    \Else
                        \State \Call{ConfluenceFunction}{$v$}
                    \EndIf
                    \State \Comment{\$ Update \texttt{convergence} flag \%}
                    \If{\textit{not} \Call{SamePartition}{\texttt{oldPartition, Partitions[$v$]}}}
                        \State \texttt{converged $\gets$ false}
                    \EndIf
                \EndFor
            \EndWhile
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Transfer Function}
    \label{alg:TransferFunction}
    \begin{algorithmic}
        \Procedure{TransferFunction}{$v : x \gets e$}
            \State \textbf{u} $\gets$ \Call{Predecessors}{$v$}
            \State \texttt{Partitions[$v$] $\gets$ Partitions[$u$]}
            \State \Comment{\% Update set identifier for $x$ \%}
            \If{$e$ \textit{is Deterministic}}
                \State \texttt{Partitions[$v$][$x$] $\gets$ Partitions[$v$][$e$]}
            \Else
                \State \texttt{Partitions[$v$][$x$] $\gets$ SetCtr++}
            \EndIf
            \State \Comment{\% Update set identifiers for expressions containing $x$ \%}
            \For{$\{e' \in (\mathcal W \setminus (\mathcal C \cup \mathcal X)) \mid x \in e'\}$}
                \State \texttt{Partitions[v][$e'$]} $\gets$ \Call{GetSetId}{$v$, $e'$}
            \EndFor
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Confluence Function}
    \label{alg:ConfluenceFunction}
    \begin{algorithmic}
        \Procedure{ConfluenceFunction}{$v$}
            \State \Comment{If all predecessor partitions are $\top$ then current partition will also be $\top$}
            \State \textbf{continueFlag} $\gets$ false
            \For{$u \in$ \Call{Predecessors}{$v$}}
                \If{\texttt{Partitions[$u$] $\neq \top$}}
                    \State \texttt{continueFlag $\gets$ true}
                \EndIf
            \EndFor
            \State
            \If{\texttt{continueFlag} \textit{is False}}
                \State \texttt{Partitions[$v$] $\gets \top$}
                \State \Return{}
            \EndIf
            \State \Comment{\texttt{accessFlag} keeps track of processed expressions}
            \For{$e \in \mathcal W$}
                \State \textbf{accessFlag}[$e$] $\gets$ \texttt{false}
            \EndFor
            \State \Comment{Process all expressions if they are still unprocessed}
            \For{$e \in \mathcal W$}
                \If{\texttt{accessFlag[$e$]} \textit{is False}}
                    \State \Comment{\texttt{PredIDs} is the set of set identifiers of $e$ at its predecessors}
                    \State \textbf{PredIDs} $\gets \phi$
                    \For{$u \in$ \Call{Predecessors}{$v$}}
                        \If{\texttt{Partitions[u] $\neq \top$}}
                            \State \texttt{PredIDs $\gets$ (PredIDs $\cup$ Partitions[$u$][$e$])}
                        \EndIf
                    \EndFor
                    \State
                    \If{\texttt{PredIDs} \textit{is Singleton}}
                        \State \texttt{Partitions[$v$][$e$] $\gets$ PredIDs}
                        \State \texttt{accessFlag[$e$] $\gets$ true}
                    \Else
                        \State \Comment{\texttt{expClass} holds $e' \in \mathcal W$ that are equivalent to $e$ at all predecessors of $v$}
                        \State \textbf{expClass} $\gets \mathcal W$
                        \For{$u \in$ \Call{Predecessors}{$v$}}
                            \If{\texttt{Partitions[u] $\neq \top$}}
                                \State \texttt{expClass $\gets$ (expClass} $\cap$ \Call{GetClass}{$u$, $e$})
                            \EndIf
                        \EndFor
                        \State \Comment{Update \texttt{Partitions} map}
                        \State \textbf{newSetID} $\gets$ \texttt{SetCnt++}
                        \For{\texttt{$e' \in$ expClass}}
                            \State \texttt{Partitions[$v$][$e'$] $\gets$ newSetID}
                            \State \texttt{acessFlag[$e'$] $\gets$ true}
                        \EndFor
                    \EndIf
                \EndIf
            \EndFor
            \State
            \State \Comment{Update \texttt{Parent} map}
            \For{$e \in (\mathcal W \setminus (\mathcal C \cup \mathcal X))$}
                \State \textbf{op} $\gets$ \Call{Operator}{$e$}
                \State \textbf{leftSetID} $\gets$ \texttt{Partitions}[\Call{Left}{$e$}]
                \State \textbf{rightSetID} $\gets$ \texttt{Partitions}[\Call{Right}{$e$}]
                \State \texttt{Parent[\{op, leftSetID, rightSetID\}] $\gets$ Partitions[v][$e$]}
            \EndFor
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Checks whether two partitions are same or not}
    \label{alg:SamePartition}
    \begin{algorithmic}
        \Procedure{SamePartition}{\texttt{first, second}}
            \For{$e \in \mathcal W$}
                \If{\Call{GetClass}{\texttt{first}, $e$} $\neq$ \Call{GetClass}{\texttt{second}, $e$}}
                    \State \Return{\texttt{false}}
                \EndIf
            \EndFor
            \State \Return{\texttt{true}}
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Finds equivalence class of an expression in a partition}
    \label{alg:GetClass}
    \begin{algorithmic}
        \Procedure{GetClass}{\texttt{partition}, $e$}
            \State \textbf{expClass} $\gets \phi$
            \For{$e' \in \mathcal W$}
                \If{\texttt{partition[$e'$] == partition[$e$]}}
                    \State \texttt{expClass $\gets$ (expClass $\cup$ $\{e'\}$)}
                \EndIf
            \EndFor
            \State \Return{\texttt{expClass}}
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Initialises partition for START point}
    \label{alg:FindInitialPartition}
    \begin{algorithmic}
        \Procedure{FindInitialPartition}{$ $}
            \For{$x \in (\mathcal C \cup \mathcal X)$}
                \State \texttt{Partitions[START][$x$] $\gets$ SetCtr++}
            \EndFor
            \For{$e \in (\mathcal W \setminus (\mathcal C \cup \mathcal X))$}
                \State \texttt{Partitions[START][$e$]} $\gets$ \Call{GetSetID}{\texttt{Partitions[START], $e$}}
            \EndFor
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\begin{algorithm}
    \caption{Finds and returns set identifier for a two length expression in a partition, by
             looking at its operands and operator}
    \label{alg:GetSetID}
    \begin{algorithmic}
        \Procedure{GetSetID}{\texttt{partition, $e$}}
            \State \textbf{op} $\gets$ \Call{Operator}{$e$}
            \State \textbf{leftSetID} $\gets$ \texttt{partition}[\Call{Left}{$e$}]
            \State \textbf{rightSetID} $\gets$ \texttt{partition}[\Call{Right}{$e$}]
            \State
            \If{\textit{not defined} \texttt{Parent[\{op, leftSetID, rightSetID\}]}}
                \State \texttt{Parent[\{op, leftSetID, rightSetID\}] $\gets$ SetCtr++}
            \EndIf
            \State
            \State \Return{\texttt{Parent[\{op, leftSetID, rightSetID\}]}}
        \EndProcedure
    \end{algorithmic}
\end{algorithm}

\section{Updates Over Original Algorithm}
\label{sec:UpdatesOverOriginalAlgorithm}
Following major improvements/corrections have been made to the original algorithm
mentioned in \cite{Babu}.
\begin{itemize} \tightlist
    \item \textbf{Representing Partitions}\\
    The original algorithm uses \texttt{ID structure} to maintain equivalence information. A two-dimensional array \texttt{Partitions} having an entry for each program point and each expression, stores a pointer to an \texttt{ID object}. At a program point, two expressions are equivalent if they contain pointers to the same object. Though this approach is correct, it adds a lot of overhead in the implementation both in terms of time and space - the \texttt{ID object}s have to be created and destroyed during runtime, their data fields have to be maintained properly etc.\\
    The updated algorithm solves this problem by using just integer set identifiers instead of pointers to some dynamically created objects and the \texttt{Parent map}. Again same as before, two expressions are equivalent at a program point if \texttt{Partitions} array stores same set identifiers for the expressions at that program point. \texttt{Parent} map captures the relation between the set identifiers. This modification makes the actual implementation to be more simpler, efficient and intuitive.
    \item \textbf{Confluence Function}\\
    The \texttt{Confluence} function in the original algorithm processes only the set $\mathcal C \cup \mathcal V$ in its main loop. This is wrong and instead the whole working set $\mathcal W$ should be considered.\\
    As an example, consider the test case in \autoref{sec:tc15}. At the confluence point, $y$ and $x + 2$ must be equivalent, but the original algorithm assigns them pointers to different \texttt{ID objects} indicating they are not equivalent.
    \item \textbf{Non-deterministic Assignment}\\
    Non-deterministic assignment need not be handled separately and a single transfer function is sufficent (see \autoref{alg:TransferFunction}).
\end{itemize}


%!TEX root = ../thesis.tex
%*******************************************************************************
%****************************** Second Chapter *********************************
%*******************************************************************************

\chapter{Lattice QCD}\label{chapter:LatticeQCD}

\ifpdf
    \graphicspath{{Chapter2/Figs/Raster/}{Chapter2/Figs/PDF/}{Chapter2/Figs/}}
\else
    \graphicspath{{Chapter2/Figs/Vector/}{Chapter2/Figs/}}
\fi
Currently, lattice QCD represents the only technique able to perform accurate low-energy QCD calculations from first principles. The lattice prescription allows for the explicit calculation of path integrals present in continuum QCD, at the cost of introducing finite-spacing errors that must be systematically accounted for. In this chapter we will discuss the behaviour of QCD in the continuum, and demonstrate how the transition can be made to a finite set of coordinates on a lattice. We will then briefly detail how this formulation can be used to generate simulations of the QCD vacuum. Finally, we use this framework to describe how our generated configurations can be fixed to Landau gauge, one of the two gauge choices used in this research.

\section{QCD in the Continuum}
\subsection{Quarks and Gauge Invariance}
QCD is the gauge field theory that describes the interactions of quarks and gluons. Like all gauge theories, it has an internal symmetry group under which the Lagrangian is invariant. In the case of QCD there are three quark colours, which leads to the symmetry group being $SU(3)$, the group of $3\times 3$ unitary matrices of determinant 1. Note that this description of $SU(3)$ is only true in the fundamental representation, however it is this representation that the quarks inhabit and is therefore a useful and intuitive way to initially consider the group. We can observe this $SU(3)$ symmetry by inspecting the free quark Lagrangian
%
\begin{equation}
\mathcal{L}_0 = \bar{\psi}(x)\,(i\slashed{\partial}-m)\,\psi(x)\,.
\label{eq:GlobalQuarkLagrangian}
\end{equation}
%
where $\psi(x)$ and $\bar{\psi}(x)$ contain the three quark and anti-quark fields respectively, $m$ is the quark mass and $\slashed{\partial}=\partial_\mu\,\gamma^\mu$. We make use of the Dirac representation for the gamma matrices, given in Appendix~\ref{app:GellMann}. If we apply an $SU(3)$ transformation $\Omega$ to the three colour indices of the quark and anti-quark fields such that
%
\begin{align}
\psi(x)&\rightarrow\Omega\,\psi(x)\\
\bar{\psi}(x)&\rightarrow \bar{\psi}(x)\,\Omega^\dagger\, ,
\end{align}
%
we see that
%
\begin{align}
\mathcal{L}_0\rightarrow\mathcal{L'}_0&=\bar{\psi}(x)\,\Omega^\dag\,(i\slashed{\partial}-m)\,\Omega\,\psi(x)\nonumber\\
&= \bar{\psi}(x)\,(i\slashed{\partial}-m)\,\Omega^\dag\,\Omega\,\psi(x)\nonumber\\
&= \bar{\psi}(x)\,(i\slashed{\partial}-m)\,\psi(x)\nonumber\\
&= \mathcal{L}_0\, ,
\end{align}
%
where we have made use of the unitarity property, $\Omega\,\Omega^\dag = I$. If this symmetry were all we required then $\mathcal{L}_0$ would be our Lagrangian and our theory would be pleasantly simple. However, we find that we need our gauge symmetry to be \textit{local}; that is, we demand that our gauge transformation itself be a function of $x$~\cite{peskin2018introduction}. In this case, we find that the derivative in Eq.~\eqref{eq:GlobalQuarkLagrangian} acting on the gauge transformation results in a loss of $SU(3)$ symmetry. We can write an arbitrary local $SU(3)$ gauge transformation as an exponential of the eight traceless, Hermitian group generators $\lambda_a$, known as the Gell-Mann matrices (see Appendix~\ref{app:GellMann} for their values), such that
%
\begin{equation}
\Omega(x)=\exp\left(i\omega^a(x)\,\frac{\lambda_a}{2}\right)\, .
\label{eq:LocalGaugeTransformation}
\end{equation}
%
Note that we make use of the summation convention to imply a sum over the repeated indices. In this form, the spatial dependence is encapsulated entirely in the eight parameters, $\omega^a(x)$.  Using this form for $\Omega(x)$, we find that under a gauge transformation the Lagrangian is now
%
\begin{align}
\mathcal{L}_0\rightarrow\mathcal{L^\prime}_0&=\bar{\psi}(x)\,\Omega^\dag(x)\,(i\slashed{\partial}-m)\,\Omega(x)\,\psi(x)\nonumber\\
&=\bar{\psi}(x)\,\Omega^\dag(x)\left[-\frac{\lambda_a}{2}\,(\slashed{\partial}\,\omega^a(x))\,\Omega(x)\,\psi(x)+ i\,\Omega(x)\,(\slashed{\partial}\,\psi(x))-m\,\Omega(x)\,\psi(x)\right]\nonumber\\
&= \mathcal{L}_0-\bar{\psi}(x)\,\Omega^\dag(x)\,\frac{\lambda_a}{2}\,(\slashed{\partial}\,\omega^a(x))\,\Omega(x)\,\psi(x)\, .
\label{eq:LocalTrans}
\end{align}
%
It is apparent then that gauge invariance is lost under a local gauge transformation. To restore gauge invariance, we introduce the notion of the gauge-covariant derivative
%
\begin{equation}
D_\mu = \partial_\mu + ig A_\mu(x)\, ,
\label{eq:CovariantDerivative}
\end{equation}
%
where $A_\mu(x)=A_\mu^a(x)\,\frac{\lambda_a}{2}$ encapsulates the eight new `gauge potentials' and $g$ is the strong coupling constant. As the gauge potentials are a linear combination of $\lambda_a$, they belong not to the group $SU(3)$, but to the Lie algebra $\mathfrak{su}(3)$. In the context of QCD, these gauge potentials are also known as the gluon field. For the sake of cleanliness, we will stop explicitly writing the dependence of our fields and gauge transformations on $x$ from here on, but it should be remembered that all gauge transformations are local unless explicitly stated otherwise.\\

Making the substitution $\partial_\mu\rightarrow D_\mu$, we obtain the new Lagrangian
%
\begin{equation}
\mathcal{L}_\text{quark} = \bar{\psi}\,(i\slashed{D}-m)\,\psi\,.
\end{equation}
%
This substitution introduces a new interaction term into the Lagrangian that gives rise to an interaction between our quark and gauge fields.
%
\begin{equation}
\mathcal{L}_\text{int} = -g\,\bar{\psi}\,A_\mu\,\psi
\label{eq:InteractingLagrangian}
\end{equation}
%
To preserve the gauge invariance of the Lagrangian, we need the gauge transformation property of Eq.~\eqref{eq:InteractingLagrangian} to counteract the last term of Eq.~\eqref{eq:LocalTrans}. Hence we require that
%
\begin{align}
-g\,\bar{\psi}\,A_\mu\,\psi \rightarrow -g\,\bar{\psi}\,A_\mu\,\psi + \bar{\psi}\,\Omega^\dag\,\frac{\lambda_a}{2}(\partial_\mu\,\omega^a)\,\Omega\,\psi\, .
\end{align}
%
Making use of the transformation properties of $\psi$ and $\bar{\psi}$, this implies that
%
\begin{equation}
A_\mu\rightarrow \Omega\,A_\mu\,\Omega^\dag + \frac{i}{g}\,(\partial_\mu\,\Omega)\,\Omega^\dag\, .
\label{eq:GaugePotentialTrans}
\end{equation}
%
This transformation property can also be expressed in terms of the covariant derivative. Doing so, we find that
%
\begin{align}
D_\mu\,\psi \rightarrow &\left(\partial_\mu +ig\,\Omega\,A_\mu\,\Omega^\dag - (\partial_\mu\,\Omega)\,\Omega^\dag\right)\,\Omega\,\psi\nonumber\\
&= (\partial_\mu\,\Omega)\,\psi + \Omega\,(\partial_\mu\,\psi) + ig\,\Omega\,A_\mu\,\psi - (\partial_\mu\,\Omega)\psi\nonumber\\
&=\Omega\,D_\mu\,\psi\, .\label{eq:CovariantTransformation}
\end{align}
%
And therefore
%
\begin{equation}
D_{\mu}\rightarrow\Omega\,D_\mu \Omega^\dag
\end{equation}
%
Eq.~\eqref{eq:CovariantTransformation} tells us that the covariant derivative of a quark field transforms in the same way as the quark field itself. This implies that the covariant derivative can be understood as a connection between two points that may have a different underlying gauge. For example, if we consider an infinitesimal translation in the quark field
%
\begin{equation}
d\psi(x) = \psi(x+dx)-\psi(x)\, ,
\end{equation}
%
we note that the gauge at the point $x$ and at $x+dx$ in general will differ. It therefore does not make sense to compare the field values through the usual understanding of the derivative, as this ignores the change in local gauge. Instead, the covariant derivative accounts for this underlying gauge structure, `transporting' the field from one position to another. This is entirely analogous to the covariant derivative present in general relativity, however in this case the transport occurs over an internal gauge manifold, rather than an external curved space-time.\\

\subsection{Field Strength Tensor}
Using local gauge invariance as a guide, we can now seek other gauge invariant terms to insert into the Lagrangian. We define the gluon field strength tensor to be

%If we consider the commutator of the covariant derivative, we have
%
%\begin{align*}
%[D_\mu,\, D_\nu]\rightarrow &[\Omega\,D_\mu\,\Omega^\dag,\,\Omega\,D_\nu\,\Omega^\dag]\\
%&= \Omega\,D_\mu\, D_\nu\,\Omega^\dag - \Omega\,D_\nu\, D_\mu\,\Omega^\dag\\
%&= \Omega\,[D_\mu,\,D_\nu]\,\Omega^\dag\, .
%\end{align*}
%

%
\begin{equation}
F_{\mu\nu}=\partial_\mu A_\nu - \partial_\nu A_\mu + ig[A_\mu,\,A_\nu]\, .
\label{eq:FieldStrengthTensor}
\end{equation}
%
Alternatively, $F_{\mu\nu}$ may also be written
%
\begin{align}
F_{\mu\nu} = -\frac{i}{g}\,[D_\mu,\, D_\nu]\, .
\end{align}
%
By making use of the gauge transformation property of $A_\mu$, given in Eq.~\eqref{eq:GaugePotentialTrans}, we find that the field strength tensor transforms as
%
\begin{equation}
F_{\mu\nu}\rightarrow \Omega\,F_{\mu\nu}\, \Omega^\dagger\, .
\end{equation}
%
The proof of this is given in Appendix~\ref{app:GTF}. To obtain a gauge invariant quantity, we take the trace of the contracted field strength tensor. This allows us to make use of the cyclic property of the trace to obtain
%
\begin{align}
\Tr(F_{\mu\nu}F^{\mu\nu})\rightarrow &\Tr\left(\Omega\,F_{\mu\nu}\, \Omega^\dagger\,\Omega\,F^{\mu\nu}\, \Omega^\dagger\right)\nonumber\\
&=\Tr\left(\Omega^\dagger \, \Omega\,F_{\mu\nu}\,F^{\mu\nu}\right)\nonumber\\
&=\Tr(F_{\mu\nu}F^{\mu\nu})
\end{align}
Thus we define the full gauge invariant QCD Lagrangian to be
%
\begin{equation}
\mathcal{L_{\text{QCD}}}=\bar{\psi}(x)\,(i\slashed{D}-m)\,\psi(x)-\frac{1}{2}\,\Tr(F_{\mu\nu}(x)\,F^{\mu\nu}(x))\, .
\label{eq:QCDLagrangian}
\end{equation}\\

This gluon term is not the only gauge invariant quantity we could construct; for example, $\bar{\psi}\,\psi\,\bar{\psi}\,\psi$ is clearly gauge invariant. However, it turns out that there is a further condition that must be satisfied by each term in the Lagrangian; each term must be \textit{renormalisable}~\cite{peskin2018introduction}. A complete discussion of renormalisation is unnecessary for this work, but renormalisability can be quickly summarised by looking at the dimensionality of each term in the Lagrangian. The Lagrangian must have units of $(\text{Energy})^4$, which in natural units is $(\text{mass})^4$,  hereafter referred to as just dimension $D=4$. We therefore require that each term and its accompanying coupling constant give the same dimensionality. The fermion field has dimension $\frac{3}{2}$, the gauge potential has dimension 1 and $\partial_\mu$ has dimension 1. Thus, the terms present in Eq.~\eqref{eq:QCDLagrangian} have dimension
%
\begin{align}
\text{D}[\bar{\psi}(x)\,\gamma^\mu\,\partial_\mu\,\psi(x)]&=\frac{3}{2}+1+\frac{3}{2}=4\\
\text{D}[\bar{\psi}(x)\,\gamma^\mu\,A_\mu\,\psi(x)]&=\frac{3}{2}+1+\frac{3}{2}=4\\
\text{D}[m\bar{\psi}(x)\,\psi(x)]&=1+\frac{3}{2}+\frac{3}{2}=4\\
\text{D}[F_{\mu\nu}\,F^{\mu\nu}] &= 2+2=4\, ,
\end{align}
%
as required. This also tells us that the coupling constant $g$ is dimensionless. If a new gauge invariant term $h\bar{\psi}\,\psi\,\bar{\psi}\,\psi$ with coupling constant $h$ is introduced then by the above rules we would require that $h$ have dimension $-2$. It turns out that if the dimensionality of the coupling constant is less than 0 then the term in non-renormalisable. This means that integrals involving this new term will diverge in such a way that they cannot be systematically be made finite through the use of a renormalisation scheme, and hence they cannot form part of any physical theory. By applying the requirements of gauge invariance and renormalisability, it is apparent that Eq.~\eqref{eq:QCDLagrangian} is the full QCD Lagrangian.

\subsection{Pure Gauge Action}
For the purpose of this research, we are interested in the behaviour of gluons in the absence of any quarks, and as such we need to develop a description of pure gauge fields. In the continuum, a pure gauge field has the Lagrangian~\cite{ryder1996quantum}
%
\begin{equation}
\mathcal{L}_{\text{gluon}}=\frac{1}{2}\Tr(F_{\mu\nu}\,F^{\mu\nu})\, ,
\label{eq:GaugeLagrangian}
\end{equation}
%
which we observe to be the last term in Eq.~\eqref{eq:QCDLagrangian}. This Lagrangian has the corresponding action
%
\begin{equation}
\mathcal{S}=\int~d^4x~\mathcal{L_\text{gluon}}\, .
\label{eq:QCDAction}
\end{equation}
%
When considering the path integral formulation of a gauge field theory, integrals such as the generating functional,
%
\begin{equation}
\mathcal{Z} =\int \mathcal{D} A_\mu \exp\left(i\,\mathcal{S}\,[A_\mu]\right),
\label{eq:GeneratingFunctional}
\end{equation}
%
and others of a similar form appear frequently. This integral closely resembles the partition function found in statistical mechanics, $\mathcal{Z}_{\text{classical}}=\int d^3x\,d^3p\,\exp\left(-\beta\,H(x,p)\right)$, with the notable exception of the factor of $i$ in the exponential. From the statistical mechanics perspective, the exponential in Eq.~\eqref{eq:GeneratingFunctional} is a probability weighting for a given gauge potential. However, unlike the classical case, the factor of $i$ in Eq.~\eqref{eq:GeneratingFunctional} results in an oscillatory weighting, rendering numerical simulations untenable. To ensure that the weight factor is purely real, it is necessary to perform a Wick rotation to Euclidean space~\cite{Schafer:1996wv,Wilson:1974sk} such that
\begin{equation}
t \rightarrow -it \qquad A^0 \rightarrow iA^0\, .
\end{equation}
%
This has the result of changing the action such that
%
\begin{equation}
i\mathcal{S}_\text{Minkowski} \rightarrow -\mathcal{S}_\text{Euclidean}\, ,
\end{equation}
so that the generating functional now becomes
%
\begin{equation}
\mathcal{Z}=\int \mathcal{D} A_\mu \exp\left(-\mathcal{S}_E\,[A_\mu]\right).
\end{equation}
%
This enables us to now truly consider the generating functional to be a probability weighting for a given configuration.\\

In Euclidean space, we can make use of the generating functional to write the expectation value of an arbitrary operator $Q[A_\mu]$ as~\cite{Luscher:1984xn}
%
\begin{equation}
\langle Q \rangle = \frac{1}{\mathcal{Z}}\int \mathcal{D} A_\mu\, Q[A_\mu]\, \exp\left(-\mathcal{S}_E\,[A_\mu]\right)\, .
\end{equation}
%
This definition of the expectation value, whilst potentially difficult or even impossible to calculate analytically, has an intuitive interpretation. To calculate the expectation value of some operator, we integrate over every possible configuration of $A_\mu(x)$, weighted by the action of that configuration. In the case where the coupling constant $g$ of the theory is sufficiently small, as is the case for QED or high-energy QCD, it is possible to expand $\exp\left(-\mathcal{S}_E\,[A_\mu]\right)$ in terms of the coupling constant, leading to a perturbative expansion. Alternatively, if the only relevant configurations in the theory are those near the classical action satisfying $\frac{\delta S[A_\mu]}{\delta A_\mu}=0$, then the action can be expanded around the classical solution. However, in the case of low-energy QCD, both of these approximations are invalid, and as such it becomes essential to sample possible configurations of $A_\mu(x)$ and generate a representative finite subset that can be used to approximate the continuum expectation value. Obtaining this subset on which we can perform calculations is one of the key aims of lattice QCD.

\section{Lattice Discretisation}\label{sec:LatticeDiscretisation}
Using the continuum understanding developed in the previous section, we can now consider discretising space-time into a finite lattice. The lattice is a hypercube with $N_s$ lattice sites in the spacial directions and $N_t$ sites in the time direction. Each lattice site is separated by a spacing $a$, resulting in a total lattice volume $V=(N_s\,a)^3\times N_t\,a$. A two dimensional example of a discrete lattice with spacing $a$ is shown in Fig.~\ref{fig:LatticeExample}. The lattice notation $\hat{\mu}$ is used to denote the unit vector in the $\mu$ direction; for example, $\hat{y} = (0,0,1,0)$. We also must impose boundary conditions for the lattice; in this work we utilise periodic boundary conditions such that $x+N_\mu a\hat{\mu}=x$.\\
%
\begin{figure}[ht]
\centering
\input{Chapter2/Figs/LatticeExample.tex}
\caption[An example of a 2D lattice with lattice spacing $a$.]{\label{fig:LatticeExample} An example of a 2D lattice with lattice spacing $a$. From site $x$ we define $x+a\hat{\mu}$ to refer to the next lattice site in the $\hat{\mu}$ direction. The gauge links $U_\mu(x)$ (see Eq.~\eqref{eq:GaugeLink}) are defined on the links between sites. The plaquette $P_{\mu\nu}(x)$ (see Eq.~\eqref{eq:Plaquette}) is the product of the four gauge links around a $1\times 1$ loop.}
\end{figure}
%

When space-time is discretised, it becomes necessary to consider derivatives as finite differences and integrals as finite sums, such that.
\begin{align}
\partial_\mu\,f(x)&\rightarrow \frac{f(x+a\hat{\mu})-f(x-a\hat{\mu})}{2a}\\
\int d^4x~f(x) &\rightarrow a^4\sum_x \,f(x)\, .
\end{align}
For example, we can construct the lattice form of Eq.~\eqref{eq:FieldStrengthTensor} as
%
\begin{align}
F_{\text{Lat}}^{\mu\nu}(x) = &\frac{A_\nu(x+a\hat{\mu})-A_\nu(x-a\hat{\mu})}{2a}-\frac{A_\mu(x+a\hat{\nu})-A_\mu(x-a\hat{\nu})}{2a}\nonumber\\
&+ig[A_\mu(x),\,A_\nu(x)]\, .
\label{eq:DiscreteFST}
\end{align}
%
The notation $A_\nu(x+a\hat{\mu})$ denotes the field $A_\nu$ located at the site one lattice spacing in the $\hat{\mu}$ direction from $x$. We could continue to reformulate our lattice theory by imposing this method of discretisation, and indeed this is historically how the lattice framework was constructed~\cite{Wilson:1974sk}. However, it is useful to instead formulate our lattice theory in terms of gauge {\it links}. Analogous to how we introduced the covariant derivative to compensate for the fact that the quark field at infinitesimally different points in space has a different underlying gauge, we now want to have a mechanism for comparing gluon fields at some finite separation. This requires us to solve the parallel transport equation of our gauge field~\cite{peskin2018introduction}
%
\begin{equation}
\frac{dx^\mu(t)}{dt}\,D_\mu \,U(x(t),y)=0\, ,
\label{eq:ParallelTransport}
\end{equation}
%
where $U(x(t),y)$ is an $SU(3)$ element and $x(t)$ is some path parametrised by $t\,\in\,[0,1]$ satisfying $x(0)=y$. We further require that $U(x(0),y)=I$, as the parallel transport for a fixed point is trivial. We can now make use of the explicit parametrisation of the path between two adjacent lattice sites, $x^\mu(t;\nu) = y^\mu+a\,t\,\delta_\nu^\mu$, where $y^\mu$ is a fixed position and $\nu$ is the direction we are transporting the field. Substituting this parametrisation into Eq.~\eqref{eq:ParallelTransport} we have
\begin{align}
&a\, \delta_\nu^\mu\, (\partial_\mu + igA_\mu)\,U(x(t;\nu),y)=0\nonumber\\
&a\, \partial_\nu\, U(x(t;\nu),y) = -iag\, A_\nu\,U(x(t;\nu),y)\nonumber\\
&\frac{\partial}{\partial t}\, U(x(t;\nu),y) = -iag\,A_\nu\, U(x(t;\nu),y)\, .
\label{eq:PathOrderedDE}
\end{align}
For a non-Abelian field, Eq.~\eqref{eq:PathOrderedDE} is precisely the differential equation solved by the path-ordered exponential, known as the Wilson line
%
\begin{equation}
U(x(t;\nu),y) = \mathcal{P}\exp\left(-iag\int_0^t \,dt^\prime \,A_\nu(x(t^\prime;\nu))\right)
\end{equation}
%
Hence, for each direction $\hat{\mu}$, we define the gauge links between adjacent lattice sites to be
%
\begin{equation}
U_\mu(x) = \mathcal{P}\exp\left(-iag\int_0^1 \,dt \,A_\mu(x + at\hat{\mu})\right)\, .
\label{eq:GaugeLink}
\end{equation}
%
From this definition we also see that we can write the gauge link in the opposite direction, i.e. from $x+a\hat{\mu}$ to $x$, as
%
\begin{align}
\mathcal{P}\exp\left(-iag\int^0_1 \,dt\,A_\mu(x + at\hat{\mu})\right) &= \mathcal{P}\exp\left(+iag\int_0^1 \,dt\,A_\mu(x + at\hat{\mu})\right)\nonumber\\
&=U^\dag_\mu(x)\, .
\end{align}
%
These gauge links have the simple gauge transformation property~\cite{Lepage:1998dt} (see Appendix~\ref{app:WilsonLineGT})
%
\begin{equation}
U_\mu(x)\rightarrow \Omega(x)\,U_\mu(x)\,\Omega^\dag(x+a\hat{\mu})\, .
\label{eq:LinkTransformation}
\end{equation}
%
Making use of this gauge transformation property, we can construct gauge invariant Wilson loops by taking the trace of the product of the $U_\mu$'s around a closed loop. These Wilson loops form an essential building block of the lattice action, and  appear in later chapters as quantity of interest in their own right. The simplest such loop, the $1\times 1$ square, is called the \textit{plaquette}, and is defined as
\begin{equation}
P_{\mu\nu}(x) = U_\mu(x)\,U_\nu(x+a\hat{\mu})\, U_\mu^\dag(x+a\hat{\nu})\, U_\nu^\dag(x)\, .
\label{eq:Plaquette}
\end{equation}
Calculating the Wilson loop by taking the trace of the plaquette we see that, by the cyclic property of the trace, the Wilson loop is gauge invariant
\begin{align}
\Tr\left(P_{\mu\nu}(x)\right)\rightarrow& \Tr \left(\Omega(x)\,U_\mu(x)\Omega^\dag(x+a\hat{\mu})\,\Omega(x+a\hat{\mu})\,U_\nu(x+a\hat{\mu})\,\Omega^\dag(x+a\hat{\mu}+a\hat{\nu})\right.\nonumber\\
&~~~~~\left.\Omega(x+a\hat{\mu}+a\hat{\nu})\,U_\mu^\dag(x+a\hat{\nu})\,\Omega^\dag(x+a\hat{\nu})\,\Omega(x+a\hat{\mu})\, U_\nu^\dag(x)\,\Omega^\dag(x)\right)\nonumber\\
=&\Tr\left(P_{\mu\nu}(x)\right)\, .
\end{align}
Both the gauge links and the plaquette are also visualised in Fig.~\ref{fig:LatticeExample}.\\

We now return to the lattice formulation of QCD, making use of the gauge links to define our quantities of interest. Firstly, we approximate our gauge links on the lattice by using a midpoint definition, such that
\begin{equation}
U_\mu^\text{lat}(x) = \exp\left(-iag\, A_\mu\left(x+\frac{a}{2}\hat{\mu}\right)\right)\, .
\label{eq:GaugeLinkLat}
\end{equation}
From this definition, we can also recover the midpoint gauge potential~\cite{Leinweber:1998im,Alles:1996ka}
\begin{equation}
A_\mu\left(x+\frac{a}{2}\hat{\mu}\right) = \frac{i}{2ag}\left(U_\mu(x) - U_\mu^\dag(x)\right) - \frac{i}{6ag}\Tr\left(U_\mu(x) - U_\mu^\dag(x)\right)I + \mathcal{O}(a^2)\, .
\label{eq:GaugePotentialLat}
\end{equation}
We then note that we can write $F_{\mu\nu}$ in terms of the plaquette by Taylor expanding Eq.~\eqref{eq:Plaquette} (see Appendix \ref{app:TEPlaquette}) to obtain~\cite{Gupta:1997nd}
%
\begin{equation}
P_{\mu\nu} = I-ia^2g\, F_{\mu\nu} - \frac{a^4 g^2}{2}F^2_{\mu\nu} +\mathcal{O}(a^6)\, ,
\label{eq:PlaquetteExpansion}
\end{equation}
%
and hence to $\mathcal{O}(a^2)$
%
\begin{align}
\frac{a^4}{2}\Tr\left(F_{\mu\nu}F^{\mu\nu}\right) = \sum_{\mu,\,\nu}\frac{1}{g^2}\Tr\left(I-\frac{1}{2}\left(P_{\mu\nu}+P_{\mu\nu}^\dag\right)\right)\, .
\label{eq:FieldStrengthPlaquette}
\end{align}
%
We have now arrived at a definition of the contracted field strength tensor that can be used to define our lattice action. We can make a further simplification by noting that because $P_{\mu\nu}=P_{\nu\mu}^\dagger$, $\Re(P_{\mu\nu}) = \Re(P_{\nu\mu})$ and therefore we only need to sum over the 6 plaquettes for which $\mu<\nu$, so long as we introduce a factor of $2$. This gives us the definition of the Wilson action,
%
\begin{equation}
\mathcal{S}_\text{W} = \beta\sum_x\,\sum_{\mu<\nu} \frac{1}{3}\Tr\left(I-\frac{1}{2}\left(P_{\mu\nu}+P_{\mu\nu}^\dag\right)\right)\, ,
\label{eq:WilsonAction}
\end{equation}
%
where $\beta = \frac{6}{g^2}$ is the lattice coupling constant. To remove higher order errors from the lattice action, it is possible to take into account terms containing larger Wilson loops, following procedure similar to the one outlined above~\cite{Alford:1995hw,Symanzik:1983dc,Symanzik:1983gh}.\\

For the purpose of this work, the gauge fields were generated using the $\mathcal{O}(a^2)$-improved L\"uscher-Weisz action~\cite{Luscher:1984xn},
%
\begin{align}
\mathcal{S} _ { LW } = &\sum_x \left[ \frac { 5 \beta } { 9 } \sum _ { \mu < \nu } \operatorname { Tr } \left\{ 1 - \frac { 1 } { 2 } \left( P _ { \mu \nu } + P _ { \mu \nu } ^ { \dagger } \right) \right\}\right. \nonumber\\
& \left.- \frac { \beta } { 36 u _ { 0 } ^ { 2 } } \sum _ { \text { rect } } \operatorname { Tr } \left\{ 1 - \frac { 1 } { 2 } \left( R _ { \mu \nu } + R _ { \mu \nu } ^ { \dagger } \right) \right\}\right]\, ,
\end{align}
%
where
\begin{equation}
u_0 = \left(\frac{1}{3}\operatorname{ Re } \Tr\langle P_{\mu\nu} \rangle\right)^{\frac{1}{4}}\, ,
\end{equation}
and $R_{\mu\nu}$ is the $2\times 1 + 1\times 2$ rectangular Wilson loop, defined similarly to the plaquette
\begin{align}
 R _ { \mu \nu } ( x ) = \, &  U_\mu( x )\, U_\nu( x + \hat { \mu } )\, U_\nu( x + \hat { \nu } + \hat { \mu } )\, U_\mu^\dagger ( x + 2 \hat { \nu } )\, U _\nu^\dagger( x + \hat { \nu } )\, U_\nu^\dagger( x )\nonumber\\
&+ U_\mu ( x )\, U_\mu ( x + \hat{\mu} )\, U_\nu( x + 2 \hat { \mu } )\, U_\mu^\dagger ( x + \hat { \mu } + \hat { \nu } )\, U_\mu^\dagger ( x + \hat { \nu } )\, U_\nu^\dagger( x ) \, .
\end{align}
The presence of the `tadpole' improvement factor $u_0$ is necessary to ensure the perturbatively defined coefficient is accurate~\cite{Lepage:1992xa}. This choice of action provides reduced errors in comparison to the Wilson action.\\

This lattice framework provides the tools necessary to explicitly calculate quantities of interest from a first-principles standpoint. Firstly, the gauge links are generated by Markov-chain Monte Carlo methods, using $\exp\left(-\mathcal{S}\right)$ as a probability weighting in the Metropolis accept/reject for a given configuration. Once these configurations are generated, gauge fixing can be performed (Sec.~\ref{sec:LandauGauge}, \ref{sec:MCG}), and quantities of interest such as the gluon propagator (Chapter~\ref{chapter:GluonPropagator}) can be obtained.

\section{Gauge Fixing}
The choice of gauge is crucial when performing calculations of quantities which are gauge dependent. There are two choices of gauge relevant to this study: Landau gauge and maximal centre gauge. Maximal centre gauge is best explored in the context of centre vortices, and will therefore be detailed in Chapter~\ref{sec:MCG}, however the Landau gauge fixing condition provides a good introduction to the gauge-fixing procedure, and as such will be described here.

\subsection{Landau Gauge}\label{sec:LandauGauge}

In the continuum, Landau gauge corresponds to imposing the condition
\begin{equation}
\partial_\mu A^\mu = 0\, .
\label{eq:LandauGaugeCont}
\end{equation}
%
On the lattice, we can approximate this condition by imposing
\begin{equation}
\Delta(x) = \sum _ { \mu } A _ { \mu } \left( x + \frac{a}{2}\hat { \mu } \right) - A _ { \mu } \left( x-\frac{a}{2}\hat { \mu } \right) = 0\, .
\label{eq:LandauGaugeLat}
\end{equation}
Here the fact that we have defined the lattice gauge potential to be at the midpoint of the link produces an improved continuum limit when we consider Eq.~\eqref{eq:LandauGaugeLat} in momentum space~\cite{Alles:1996ka}. The Landau gauge condition is imposed on the lattice by finding extrema of the $\mathcal{O}(a^2)$-improved functional~\cite{Bonnet:1999mj}
%
\begin{equation}
\mathcal{F} =  \frac{4}{3}\mathcal{F}_1 - \frac{1}{12u_0}\mathcal{F}_2\, ,
\label{eq:LGFunctional}
\end{equation}
%
where
%
\begin{align}
\mathcal{F}_1 &= \sum _ { \mu , x } \frac { 1 } { 2 } \operatorname { Tr } \left\{ U _ { \mu } ^ { \Omega } ( x ) + U _ { \mu } ^ { \Omega } ( x ) ^ { \dagger } \right\}\\
\mathcal{F}_2 &= \sum _ { \mu , x } \frac { 1 } { 2 } \operatorname { Tr } \left\{ U _ { \mu } ^ { \Omega } ( x ) \,U _ { \mu } ^ { \Omega } ( x + a\hat { \mu } ) + U _ { \mu } ^ { \Omega } ( x + a\hat { \mu } )^\dagger\, U _ { \mu } ^ { \Omega } ( x )^\dagger  \right\}\, .
\end{align}
%
We explicitly write $U^\Omega_\mu$ to emphasise that we are considering gauge links under an as yet unknown gauge transformation $\Omega$. It becomes apparent why we seek the extrema of this particular functional when we take the functional derivative with respect to the free parameters of the gauge transformation , $\omega^a(x)$ (see Eq.~\eqref{eq:LocalGaugeTransformation}).
%
\begin{equation}
\frac { \delta \left\{ \frac { 4 } { 3 } \mathcal { F } _ { 1 } - \frac { 1 } { 12 u _ { 0 } } \mathcal { F } _ { 2 } \right\} } { \delta \omega ^ { a } ( x ) } = g a ^ { 2 } \sum _ { \mu } \operatorname { Tr } \left\{ \left[ \partial _ { \mu } A _ { \mu } ( x ) - \frac { 4 } { 360 } a ^ { 4 } \partial _ { \mu } ^ { 5 } A _ { \mu } ( x ) + \mathcal { O } \left( a ^ { 6 } \right) \right] \frac{\lambda^a}{2} \right\} + \mathcal { O } \left( g ^ { 3 } a ^ { 4 } \right)\, .
\label{eq:LGFunctionalDeriv}
\end{equation}
%
If Eq.~\eqref{eq:LGFunctionalDeriv} is at an extrema, then
%
\begin{equation}
\sum_\mu \partial_\mu A_\mu(x) = \sum_\mu \frac{4}{360}a^4 \partial_\mu^5\,A_\mu(x) + \mathcal{O}(a^6)+\mathcal{O}(g^3a^4)\, .
\end{equation}
%
Hence up to errors of order $\mathcal{O}(a^4)$, finding the extrema of Eq.~\eqref{eq:LGFunctionalDeriv} is equivalent to satisfying the continuum Landau gauge condition given in Eq.~\eqref{eq:LandauGaugeCont}. This Landau gauge fixing method gives an example of how a gauge choice can be implemented on a discrete lattice such that it approximates the continuum condition. This in turn enables us to use the continuum Landau gauge definition of the gluon propagator as described in Chapter~\ref{chapter:GluonPropagator}, which forms a vital component of this research.


\documentclass[main.tex]{subfiles}
\begin{document}

\section*{Fri Oct 11 2019}

\subsection{Bases}

In Euclidean 2D geometry we can choose,  for example, the basis \(e_1 = (1,0)^\top\) and \(e_2 = (0,1)^\top\). This basis is  orthonormal with respect to the scalar product \(g_{\mu \nu} = \delta_{\mu \nu}\): \(e_{(\alpha)} \cdot e_{(\beta)} = e_{(\alpha)}^{\mu} e_{(\beta)}^{\nu} g_{\mu \nu} =  g_{(\alpha) (\beta)}\).

I use parentheses around indices to denote the fact that they are not tensorial indices, but instead denote which basis vector we are considering.
We express our vectors in components with respect to this basis.

In SR, we can do the same: our coordinate basis can be given by \(e_{(\alpha)}^{\mu} = \delta_{(\alpha)}^{\mu}\).
Now, the orthonormality \(e_{(\alpha)} \cdot e_{(\beta)} = g_{(\alpha) (\beta)}\) holds with respect to \(g_{\mu \nu} = \eta_{\mu \nu}\).

% what's your name? my name is $e_1$...

\subsection{Observers \& observations}

Every observer will be characterized by their trajectory \(x^{\mu}(\tau)\).
We can associate a coordinate system with the observer: the one in which the observer's own  4-velocity \(u^{\mu}\) is the time-like unit vector (rescaled by a factor of \(c\): \(u^{\mu} = ce_{(0)}\)).

When the observer sees a particle with \(p^{\mu} = (E_p / c, p^i)\) they measure the energy of the particle to be \(p^{0}c\): in this frame this is \(E_{\text{measured}} = - e_{(0)}^\mu p_{\mu} c = - u^{\mu} p_{\mu} c\).
Do note that this is a covariant expression, while \(p^{0}\) is not: the energy of a particle with 4-momentum \(p^{\mu}\) measured by an observer with 4-velocity \(u^{\mu}\) is an invariant.

In the rest frame of the observer, their own 4-velocity is \((c, \vec{0}) = c (1, \vec{0})\).
In the rest frame of the particle, its own energy is measured to be \(mc^2\).
The measured energy by an observer such that the product of the 4-velocities of the particle and of the observer is \(-\gamma c^2\) is \(m \gamma c^2\).

The Earth moves with speed \(\num{e-4}  c\) around the Sun.

% wooooo

Now we can start using \(c=1\). We can put the \(c\) back whenever we want with dimensional analysis.

\section{Newtonian Gravity}

\subsection{The Equivalence Principle}

Just like Newton supposedly thought about universal gravity when, while looking at the sky, an apple fell on his head; Einstein supposedly thought up the equivalence principle when he saw a man falling from a rooftop.

\begin{proposition}[Equivalence principle]
Experiments in a small free falling system over a short amount of time give the same result as experiments in an inertial frame in empty space.
\end{proposition}

Why ``small''? The gravitational field is not really homogeneous.
The idea is that gravity can only be removed \emph{locally}, if we consider an extended system there are \emph{tidal effects}.

If we were to see that objects fall differently even in the same neighbouhood then we would lose the EP.

\begin{definition}
The \emph{inertial} mass is an object's resistance to motion: \(m _{\text{inertial}} = F^{i}/ a^{i}\).
\end{definition}

\begin{definition}
The \emph{gravitational} mass is the one which defines the gravitational force on an object: \(m _{\text{gravitational}} = \abs{F} r^2 / (G M)\).
\end{definition}

These are \emph{a priori} different, but experimentally equal: in general the gravitational acceleration is given by
\begin{equation}
a^{i} = \frac{GM r^{i} }{r^3} \frac{m _{\text{gravitational}}}{m _{\text{inertial}}}
\end{equation}

If the ratio of masses depended on the material, this could vary.

We can do a torsion pendulum experiment: the torsion applied by the Coriolis effect on a pendulum depends on the inertial mass, while its restoring force depends on the gravitational mass.
Experimentally we have measured them to be equal with an accuracy of \(\num{e-12} \).

A person on a rocket accelarating at \(g\) experiences the same acceleration as a person standing on Earth.

\subsection{Gravitational redshift}

We treat it now in a weak field approximation.

% now with gender roles!

Alice sends radiation to Bob from a higher altitude on Earth. Alice sends it with frequency \(f\), Bob receives it with \(f'\). They are at rest with respect to one another: there is no kinematic Doppler effect here.

We do this by applying the equivalence principle! We imagine A and B to be standing in a rocket which is accelerating at \(g\):
there is no more gravity.

Bob will receive a greater frequency: \(f'>f\). This can be seen by imagining two consecutive wavefronts as two particles. Alice sends them \(\Delta t_A = 1/f\) apart, Bob receives them as \(\Delta t_B=1/f'\) apart.

If the rocket is at rest, the time for the radiation to reach B is \(h/c\); if the rocket is moving then the time is \(<h/c\).

When the second wavefront starts moving the rocket is already going: the second wave starts later but it has less distance to travel. Therefore \(\Delta t_A > \Delta t_B\), which implies \(f'>f\).

\begin{claim}
    The first terms in the expansion are:
    \begin{equation}
        f' = f \qty(1+ \frac{gh}{c^2} + O \qty(\qty(\frac{gh}{c^2})^2))\,.
    \end{equation}
\end{claim}

\subsection{Potentials}

In electromagnetism, the potential energy between a charge \(Q\) and a test charge \(q\) is \(U = k Qq/r\): then we define the electromagnetic potential \(V = U/q\) which has the advantage of being test-charge independent.

Similarly, we define the gravitational potential \(\Phi = U/m \approx gh\) in the regime in which we are far enough from the object that the gravitational field can be well approximated as a constant vector field.

Then, the second order term in the formula for the redshift becomes \(\Delta \Phi c^{-2}\): now we can properly say that this \emph{weak field} means \(\Delta \Phi c^{-2} \ll 1\).

This is surely the case for the cases we can treat concretely.
If two people are separated by \SI{1}{km} of difference in altitude, they have \(\Delta \Phi c^{-2} \approx \num{e-13} \): the difference they will experience is one second in a million years.

Our expression from \(\Phi \) in the newtonian approximation is \(\Phi = GM /r\).

We can say even now by dimensional analysis that \(GM / (rc^2)\) is the parameter which tells us how relevant the gravitational effects are: if it is similar to 1 we must consider GR, if it is much smaller than 1 the GR effects will be negligible.

This is very close to the expression for the Schwarzschild radius: it is \(r=GM\) in units \(c=1\), while the correct expression is \(r= 2GM\): that one can actually be recovered exactly if we calculate the radius at which the escape velocity is equal to \(c\).

\end{document}


\documentclass[12pt]{article}
\usepackage[arabmaths]{luabidi}
\begin{document}
\setRTLmain
\section{ghesmate 1}

in yek ghesmat ast ke an ra dar inja minevisam

\begin{equation}
1+2=3
\end{equation}
in ham dobare masalei ast ke man minevisam va shoma an ra mibinid.
\end{document}


Recurrent neural networks (RNNs) are Turing-Complete models that can perform
complex transformations on the data over an extended period of time
\cite{siegelmann1995computational}. Since RNNs are Turing-Complete, it is
evident that these models in theory can be used to solve any problems a
Turing machine can solve. However, a given problem may require a very specific
and complex setup of an RNN. Therefore we do not take the time to set up
RNNs manually in a way that it solves a specific problem. Rather, we design
rich architectures with the means of learning how to solve a problem in
an efficient manner. RNNs and models alike are trained using gradient descent
so that it solves a given problem with greater accuracy than before.

\section{Neural Turing Machines}
The Neural Turing Machine (NTM) is an RNN with a rich design that enables it to
learn how to solve problems better than basic RNNs. The NTM is an RNN with the
means of addressing a differentiable memory unit external to that of the model
itself \cite{DBLP:journals/corr/GravesWD14}.
Because of this differentiable memory unit, the model can learn what is most
important to store in memory. An efficient model would learn what information
is most useful and store that in memory to be read at a later timestep with the
assumption that the read results in a better solution to the task.
This creates a model that can more strongly refer to important imformation
that was present much earlier than a given timestep.

The NTM can be described as four main components: controller, read heads,
write heads, memory. The data flow of these four components is described
in Figure ~\ref{fig:NTMArchitecture}. Even though these components work in a
non-traditional manner, the model as a whole can be interacted with and
trained the same way you would any other RNN. The model simply receives
some external input at each timestep and will produce an external output
at each timestep. The components of the NTM are comparable to that of a
Turing machine, such that it contains read and write heads that interact
with a memory unit \cite{DBLP:journals/corr/GravesWD14}. Unlike a Turing
machine however, the NTM is end to end differentiable
\cite{DBLP:journals/corr/GravesWD14}. This feature gives the model a lot of
power in the field of Deep Learning research.

\begin{figure}[!htb]
    \centering
    \includegraphics[width=0.9\linewidth]{resources/NTM.png}
    \caption{
        The components inside the dotted line represent everything the NTM
        is. The arrows represent the control flow of the data starting
        as \textit{External Input} fed into the \textit{Controller}. The
        \textit{Controller} can then activate either \textit{Read Heads} or
        \textit{Write Heads}. The \textit{Read Heads} do not receive any
        information about the \textit{External Input}, but is rather told what
        to read in \textit{Memory} by the \textit{Controller}. The
        \textit{Controller} can send information from the
        \textit{External Input} to the \textit{Write Heads} which then
        write that information into memory. The \textit{Controller} receives
        data back from the \textit{Read Heads} and then produces an
        \textit{External Output} \cite{DBLP:journals/corr/GravesWD14}.
    }
    \label{fig:NTMArchitecture}
\end{figure}

The memory unit is a matrix where the rows represent a memory location and the
number of columns correspond to how large each memory location is
\cite{DBLP:journals/corr/GravesWD14}. The read head emits a weighting vector
the length of the number of memory locations at each timestep
\cite{DBLP:journals/corr/GravesWD14}. A read operation on the memory matrix
is then a convex combination between this weighting and the contents of the
memory matrix \cite{DBLP:journals/corr/GravesWD14}. Using a weighting vector
here empowers the read head to narrowly focus on a single memory location's
information or to use a wider focus by using a little bit of information
from many different memory locations. The differentiability of the model allows
the read heads to learn the best weighting vectors to emit at a given state for
some timestep.

Writing to memory in the NTM is done with an erase operation followed by an
addition operation \cite{DBLP:journals/corr/GravesWD14}. The write head
emits three vectors at each timestep: \textit{weighting vector, erase vector,
add vector} \cite{DBLP:journals/corr/GravesWD14}. Assuming a weighting of $1$
for a memory location, a value of $1$ in the \textit{erase vector} at location
$j$ would mean to set the memory to $0$ in column $j$ within that memory
location \cite{DBLP:journals/corr/GravesWD14}. However, an
\textit{erase vector} with a value of $1$ can possibly not erase any
information in a memory location if the weighting for that memory location is
$0$ \cite{DBLP:journals/corr/GravesWD14}. So the \textit{erase vector}
represents the degree to which information in columns for weighted memory
locations shall be erased. As one would suspect, the \textit{add vector} works
quite oppositely from that of the \textit{erase vector}. Again assuming a
weighting of $1$ for a memory location, a value of $1$ in the
\textit{add vector} at location $j$ would mean to add $1$ to whatever value
is already stored in that memory location in column $j$
\cite{DBLP:journals/corr/GravesWD14}. Similarly to that of the
\textit{erase vector}, the weighting can overrule the \textit{add vector} by
having a value of $0$ for some location \cite{DBLP:journals/corr/GravesWD14}.
In other words, a value of $0$ in the \textit{weighting vector} means it does
not matter what the \textit{add vector} is because nothing will be added to
that memory location.

The weighting vectors emitted by both read and write heads are done so
through two different addressing mechanisms: \textit{content-based addressing},
\textit{location-based addressing} \cite{DBLP:journals/corr/GravesWD14}.
Content-based addressing compares a key vector with all of the memory locations
\cite{DBLP:journals/corr/GravesWD14}. This produces a weighting that has
greater values in locations that are most similar to that key vector and
lesser values in locations that are least similar to that key vector
\cite{DBLP:journals/corr/GravesWD14}. This addressing mechanism is useful for
easily identifying data in the memory matrix simply by producing an
approximation of that data. The location-based addressing mechanism is better
suited for iterating through sequence data or even jumping to a specific
memory location that may have a range of unknown data stored there. If the
previous weighting for a head was focused on location $j$, the location-based
addressing mechanism can easily produce a new weighting that focuses on
location $j-1$, $j$, or $j+1$. The choice between using these two addressing
mechanisms is controlled through a gating parameter emitted by the controller.
If this gating parameter is equal to $0$, then it will only use location-based
addressing. If the gating parameter is equal to $1$, then it will only use
content-based addressing. If the gating parameter is somewhere between
$0$ and $1$, it will use a mixture of both addressing mechanisms.

\section{Differentiable Neural Computers}
The Differentiable Neural Computer (DNC) is similar to that of the NTM, but
enhanced in it's ability to address the augmented external memory. These
enhancements make the DNC more capable than the NTM at solving complex,
structured tasks. Similarly to the NTM, the DNC is differentiable end-to-end
except one operation in which the researchers claim do not make a significant
impact on the model as a whole \cite{graves2016hybrid}.

A NTM is allowed any number of read and write heads, but the DNC limits
the number of write heads to be only one \cite{graves2016hybrid}. The NTM
was only able to iterate through consecutive written locations until a
content-based addressing write occured \cite{graves2016hybrid}. The DNC,
however, can continue iterating through consecutive written locations because
it has, what the researchers call, a temporal linkage matrix
\cite{graves2016hybrid}. The temporal linkage matrix, $L$, is $N \times N$ with
weighted values between zero and one \cite{graves2016hybrid}. A value closer
to one at position $(i, j)$ means memory location $i$ was written to directly
after memory location $j$ was written to \cite{graves2016hybrid}. Otherwise,
the value should be near zero \cite{graves2016hybrid}. So given a weighting
vector, $\bf{w}$, the vector produced by $L\bf{w}$ augments the weighting to
focus on memory locations written to directly \textit{after} those
locations focused on by weighting $\bf{w}$ \cite{graves2016hybrid}.
Conveniently, the vector produced by $L^\top \bf{w}$ augments the weighting to
focus on memory locations written to directly \textit{before} those
locations focused on by weighting $\bf{w}$ \cite{graves2016hybrid}. This
interaction between the temporal linkage matrix and the external memory is one
of the three differentiable attention mechanisms in the DNC
\cite{graves2016hybrid}. This attention mechanism replaces the location-based
addressing method from the NTM. The temporal linkage matrix allows the DNC to
better handle sequential data that is not necessarily written to in sequential
memory locations. This is a more powerful concept than that of the NTM's
location-based addressing mechanism which was limited to sequential
memory locations.

Like the NTM, the DNC uses a content-based addressing mechanism that produces
a weighting vector focusing on memory locations most similar to some
emitted key vector \cite{graves2016hybrid}. Similarity in both cases are
defined as cosine similarity
\cite{DBLP:journals/corr/GravesWD14,graves2016hybrid}. If the DNC controller
emits a key vector with only part of the information it needs, this
content-based addressing mechanism can be used to read the complete
information related to it. In theory this allows the DNC to iterate
through data structures in which memory locations reference other memory
locations through a key-value address mechanism.

Unlike the NTM, the DNC uses a \textit{usage vector} to find the best memory
locations to write to and to identify any important memory locations not to
write to \cite{graves2016hybrid}. The vector's values range between zero and
one, where values closer to one means the memory locations have greater usages
\cite{graves2016hybrid}. The weighting vector given to a write head focuses on
unused locations, where the usage vector has low values
\cite{graves2016hybrid}. When the write head writes to a memory location, the
usage vector is updated at that memory location by increasing the value
\cite{graves2016hybrid}. The usage vector is also capable of decreasing values
in a memory location after it is read \cite{graves2016hybrid}. For example,
consider a task which provides a sequence of numbers and then asks what that
sequence was. After asking for what a sequence was, it will provide a new
sequence of numbers and repeat itself. The DNC can learn to write that
sequence of numbers in the external memory using the write heads. At that
point, the usage vector will have greater values in those locations written
to and lower values in the locations not needed. When the task asks for the
sequence of numbers, the DNC would use the read heads to read those locations
written to. After the reads, the usage vector will update the memory locations
to have low usage. This effectively reallocates the memory locations for
later usage.

The DNC is very comparable to how a human interacts with what we think of as
a modern day computer. Much of the human interaction with computers are done
automatically with a trained DNC. For instance, a human controls more or less
exactly what to read and write in memory. The DNC however, learns what
information is most useful to read and write in memory without being controled
by an external force. When a human deletes data on a computer, they are
essentially reallocating space in their memory for future data to be stored.
In this same manner, the DNC automatically learns when to reallocate memory
based on the task given. So as the name suggests, the DNC can be thought of
as a differentiable computer. This does not mean that a DNC will ever take the
place of a modern day computer because the applications are different. When
we interact with a computer, we expect the memory to always be there regardless
of how often we may use it. Having the computer automatically erase data
because it thinks you do not need it would be very unfavorable for many users.
However, a DNC is a model that learns how to represent complex data
structures to solve difficult tasks that cannot otherwise be solved.

The DNC has been found to be useful in a variety of experimental applications.
The researchers show that the DNC outperforms the previous best models in
a synthetic question answering task using the bAbI dataset
\cite{graves2016hybrid}. The following example shows that the DNC is able to
combine supporting facts together to come up with a solution
\cite{graves2016hybrid}:
\begin{align*}
\textnormal{\bf{Input: }}  & \quad \textnormal{John is in the playground. John
                                               picked up the football.} \\
\textnormal{\bf{Input: }}  & \quad \textnormal{Where is the football?} \\
\textnormal{\bf{Output: }} & \quad \textnormal{playground.}
\end{align*}
An even more complex task is to still be able to combine supporting facts
but also have resilience to distractors in the input \cite{graves2016hybrid}:
\begin{align*}
\textnormal{\bf{Input: }}  & \quad \textnormal{Sheep are afraid of wolves.
                             Gertrude is a sheep.} \\
                           & \quad \textnormal{Mice are afraid of cats.} \\
\textnormal{\bf{Input: }}  & \quad \textnormal{What is Gertrude afraid of?} \\
\textnormal{\bf{Output: }} & \quad \textnormal{wolves.}
\end{align*}
This example requires the DNC to have textual reasoning and be able to ignore
the last sentence that is unecessary to answer the question. This shows that
the differentiable attention mechanisms in the DNC are working and capable
of handling complex tasks such as this.

To test how the DNC handles data structures, the researchers explored
performance on graph problems: \textit{traversal}, \textit{shortest path},
\textit{inference} \cite{graves2016hybrid}. Before the model was asked to solve
one of these problems, it would first receive a graph as input. The model would
learn how to represent this graph in external memory. When the model is asked
to complete a traversal task, it receives a starting node and a path in the
graph \cite{graves2016hybrid}. The model must then output the ending node of
the path, requiring a traversal through the graph \cite{graves2016hybrid}.
The shortest path problem was given by a start and end node
\cite{graves2016hybrid}. The model must output the in-order path from start to
end. The inference task is given by an incomplete triple
(\quotes{from node}, \quotes{to node}, \quotes{relation}), where one of the
three were missing \cite{graves2016hybrid}. For example, if \quotes{to node} is
missing from the input, the model must infer what node has the given
relationship with \quotes{from node}. In the example of a family tree, one
might ask (\quotes{Jen}, \quotes{\_}, \quotes{MaternalGreatUncle}). For which,
if Joe is Jen's Maternal-Great-Uncle, then the model is expected to output
the triple (\quotes{Jen}, \quotes{Joe}, \quotes{MaternalGreatUncle}). This task
requires the model to not only learn how to traverse the graphs, but to learn
the meaning of relationships.

When the three graph problems were tested on the DNC and a baseline LSTM, the
DNC produced much better results while the LSTM failed to even learn the
easiest task of traversal \cite{graves2016hybrid}. When tested on randomly
generated paths of length seven, the DNC performed with an accuracy of 98.8\%
and the LSTM performed with an accuracy of 37\% \cite{graves2016hybrid}. This
shows how the DNC can solve problems otherwise unsolvable because the DNC has
an external memory with read and write access. The DNC performed at an accuracy
of 55.3\% when tested on shortest paths of length four \cite{graves2016hybrid}.
On the last task, inference, the DNC performed with accuracy 81.8\% when tested
on relationships that connect nodes with distance four \cite{graves2016hybrid}.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This work is licensed under the Creative Commons Attribution 4.0 International %
% License. To view a copy of this license, visit                                 %
% http://creativecommons.org/licenses/by/4.0/.                                   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass[11pt]{article}
\usepackage[cm]{fullpage}
%%AVC PACKAGES
\usepackage{avcgreek}
\usepackage{avcfonts}
\usepackage{avcmath}
\usepackage[numberby=section]{avcthm}
\usepackage{qcmacros}
\usepackage{goldstone}
%%MACROS FOR THIS DOCUMENT
\numberwithin{equation}{section}
\usepackage[
  margin=1.5cm,
  includefoot,
  footskip=30pt,
  headsep=0.2cm,headheight=1.3cm
]{geometry}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[LE,RO]{Quiz 2, Handout 1: Roothaan-Hall/Pople-Nesbet}
\fancyfoot[CE,CO]{\thepage}
\usepackage{url}

\begin{document}

\setlength{\abovedisplayskip}{3pt}
\setlength{\belowdisplayskip}{3pt}

\setcounter{section}{1}
\section{The Roothaan-Hall and Pople-Nesbet equations}

\subsection{Spin and spin-orbitals}

A spin-orbital $\y$ can be expressed as $\y(\bo{r},s)=\f(\bo{r})\w(s)$, where $\f(\bo{r})$ is a spatial orbital and $\w(s)$ is a spin function.
Spin functions live in a two-dimensional space spanned by $\{\a(s),\b(s)\}$, which are orthonormal eigenfunctions of one component of $\op{\bo{S}}$, the spin angular momentum operator.
\begin{align}
  \op{S}_z\a
=
  +\fr{1}{2}\a
&&
  \op{S}_z\b
=
  -\fr{1}{2}\b
&&
  \ip{\a|\a}=\ip{\b|\b}=1
&&
  \ip{\a|\b}=\ip{\b|\a}=0
\end{align}
The ``spin-coordinate'' $s$ is either $+$ or $-$, identifying the component of $\w(s)$ along $\a(s)$ and $\b(s)$.
You can think of it as the index of a coordinate vector in spin space
\begin{align*}
  \ma{\w(+)\\\w(-)}
=
  \ma{\ip{\a|\w}\\\ip{\b|\w}}
\end{align*}
so that $\a(+)=\b(-)=1$ and $\a(-)=\b(+)=0$.
Using this spin coordinate, the inner product in spin space can be defined explicitly as $\ip{\w|\w'}=\sum_s\w^*(s)\w'(s)$.
This is commonly referred to as a ``spin integration'', even though it looks more like a dot product.

A complete set of one-electron functions (spin-orbitals) comes in $\a,\b$-pairs.
\begin{align}\label{eq:spin-orb-general}
	\y_{2p-1}(\bo{r},s)
=
  \f_{p_\a}(\bo{r})\a(s)
&&
  \y_{2p}(\bo{r},s)
=
  \f_{p_\b}(\bo{r})\b(s)
\end{align}
The spatial components of these functions can be expanded in terms of a set of AO basis functions $\{\x_\nu\}$ as
\begin{align}\label{eq:space-orb}
  \f_{p_\a}
=
  \sum_\mu \x_\mu C_{\mu p_\a}
&&
  \f_{p_\b}
=
  \sum_\mu \x_\mu C_{\mu p_\b}
\end{align}
where the AOs basis set consists of atom-centered Gaussian functions (cc-pVTZ, 6-31G, etc.).

\subsection{Spin-integration of the canonical Hartree-Fock equations}

For a system with $n_\a$ spin-up and $n_\b$ spin-down electrons, the spin-orbital canonical Hartree-Fock equation takes the following form.
\begin{align}\label{eq:canonical-hf}
&
  \op{f}\y_p
=
  \ev_p\y_p
&&
  \op{f}
=
  \op{h}
+
  \sum_{i_\a}^{n_\a}
  (\op{J}_{i_\a}-\op{K}_{i_\a})
+
  \sum_{i_\b}^{n_\b}
  (\op{J}_{i_\b}-\op{K}_{i_\b})
\end{align}
This equation can be expanded in the spin basis as
\begin{align*}
  \ma{
    \ip{\a|\op{f}|\a}&\ip{\a|\op{f}|\b}\\
    \ip{\b|\op{f}|\a}&\ip{\b|\op{f}|\b}}
  \ma{
    \ip{\a|\y_p}\\
    \ip{\b|\y_p}}
=
  \ev_p
  \ma{
    \ip{\a|\y_p}\\
    \ip{\b|\y_p}}
\end{align*}
where we are integrating over the spin coordinate.
The operators in $\op{f}$ then become
\begin{align*}
&
  \op{h}
\mapsto
  \ma{
    \ip{\a|\op{h}|\a}&0\\
    0&\ip{\b|\op{h}|\b}}
&&
\begin{array}{r@{\ }l@{\hspace{1cm}}r@{\ }l}
  \op{J}_{i_\a}
&\mapsto
  \ma{
    \ip{\a|\op{J}_{i_\a}|\a}&0\\
    0&\ip{\b|\op{J}_{i_\a}|\b}}
&
  \op{K}_{i_\a}
&\mapsto
  \ma{
    \ip{\a|\op{K}_{i_\a}|\a}&0\\
    0&\makebox[\widthof{\ip{\b|\op{K}_{i_\b}|\b}}]{0}}
\\[10pt]
  \op{J}_{i_\b}
&\mapsto
  \ma{
    \ip{\a|\op{J}_{i_\b}|\a}&0\\
    0&\ip{\b|\op{J}_{i_\b}|\b}}
&
  \op{K}_{i_\b}
&\mapsto
  \ma{
    \makebox[\widthof{\ip{\a|\op{K}_{i_\a}|\a}}]{0}&0\\
    0&\ip{\b|\op{K}_{i_\b}|\b}}
\end{array}
\end{align*}
where the core and Coulomb operators can be evaluated as $\ip{\w|\op{h}|\w'}=\op{h}\ip{\w|\w'}$, since they don't act on spin coordinates.
The exchange operator, however, does act on spin coordinates by its coordinate-swapping operation.
\begin{align*}
  \op{K}_{i_\a}(\bo{r})\a(s)
=&\
  \sum_{s'}
  \ip{\f_{i_\a}(\bo{r}')\a(s')|\op{g}(\bo{r},\bo{r}')|\cdot(\bo{r}')\a(s')}\,
  \f_{i_\a}(\bo{r})\a(s)
=
  \ip{\f_{i_\a}(\bo{r}')|\op{g}(\bo{r},\bo{r}')|\cdot(\bo{r}')}\,
  \f_{i_\a}(\bo{r})\a(s)
\\
  \op{K}_{i_\b}(\bo{r})\a(s)
=&\
  \sum_{s'}
  \ip{\f_{i_\b}(\bo{r}')\b(s')|\op{g}(\bo{r},\bo{r}')|\cdot(\bo{r}')\a(s')}\,
  \f_{i_\b}(\bo{r})\b(s)
=
  0
\end{align*}
Here, the $\cdot$ means ``fill in spatial function here'' and the matrix elements are integrated over $\bo{r}'$.
This shows why $\ip{\a|\op{K}_{i_\b}|\a}=\ip{\b|\op{K}_{i_\b}|\a}=\ip{\b|\op{K}_{i_\a}|\a}=0$ and $\ip{\a|\op{K}_{i_\a}|\a}\neq0$.
The remaining components can be derived in the same way.

Since all of the off-diagonal elements in the spin basis vanish, we can separate \cref{eq:canonical-hf} into two equations.
\begin{align}\label{eq:canonical-uhf-equation-alpha}
&
  \op{f}_\a \f_{p_\a}
=
  \ev_{p_\a} \f_{p_\a}
&&
  \op{f}_\a
=
  \op{h}
+
  \sum_{i_\a}^{n_\a}
  (\op{J}_{i_\a} - \op{K}_{i_\a})
+
  \sum_{i_\b}^{n_\b}
  \op{J}_{i_\b}
\\\label{eq:canonical-uhf-equation-beta}
&
  \op{f}_\b \f_{p_\b}
=
  \ev_{p_\b} \f_{p_\b}
&&
  \op{f}_\b
=
  \op{h}
+
  \sum_{i_\a}^{n_\a}
  \op{J}_{i_\a}
+
  \sum_{i_\b}^{n_\b}
  (\op{J}_{i_\b} - \op{K}_{i_\b})
\end{align}

\subsection{RHF: The Roothaan-Hall Equations}

Assuming a closed-shell system with $n_\a=n_\b=n/2$, we can impose the restriction that $\f_{i_\a}=\f_{i_\b}$ for each pair of electrons.
Then equations~\ref{eq:canonical-uhf-equation-alpha} and~\ref{eq:canonical-uhf-equation-beta} collapse into a single expression.
\begin{align*}
  \op{f}_\textsc{r}\f_p
=
  \ev_p\f_p
&&
  \op{f}_\textsc{r}
=
  \op{h}
+
  \sum_i^{n/2}
  (2\op{J}_i - \op{K}_i)
\end{align*}
where the R stands for ``restricted''.
Expanding $\f_p$ in the AO basis and projecting by $\x_\mu$, we get
\begin{align*}
  \sum_\nu
  \ip{\x_\mu|\op{f}_\textsc{r}|\x_\nu}
  C_{\nu p}
=
  \sum_\nu
  \ip{\x_\mu|\x_\nu}C_{\mu p}\ev_p
\end{align*}
which are the \textit{Roothaan-Hall equations}.
In matrix notation, these can be written as follows.
\begin{align}\label{eq:roothaan-hall}
&
  \bo{F}\bo{C}
=
  \bo{S}\bo{C}\bm{\ev}
&&
  F_{\mu\nu}
=
  \ip{\x_\mu|\op{f}_\textsc{r}|\x_\nu}
&&
  S_{\mu\nu}
=
  \ip{\x_\mu|\x_\nu}
&&
  (\bm{\ev})_{pq}
=
  \ev_p\d_{pq}
\end{align}
Note that if the AO basis contains $m$ functions, then $\bo{C}=[C_{\mu p}]$ is an $m\times m$ matrix with each column vector containing the expansion coefficients for an orbital $\f_p$.
Also, note that only the $n/2$ MOs of lowest energy ($\ev_p$) will be ``occupied'' -- the remaining virtual orbitals will not enter into the Coulomb and exchange parts of $\op{f}_\textsc{R}$.
Expanding $\op{f}_\textsc{R}$ in its core, Coulomb, and exchange parts, we find
\begin{align*}
  F_{\mu\nu}
=&\
  \ip{\x_\mu|\op{h}|\x_\nu}
+
  \sum_i^{n/2}
  (2\ip{\x_\mu\f_i|\x_\nu\f_i}-\ip{\x_\mu\f_i|\f_i\x_\nu})
\\
=&\
  \ip{\x_\mu|\op{h}|\x_\nu}
+
  \sum_i^{n/2}
  \sum_{\rho\si}^m
  C_{\rho i}^*C_{\si i}
  (2\ip{\x_\mu\x_\rho|\x_\nu\x_\si}-\ip{\x_\mu\x_\rho|\x_\si\x_\nu})
\end{align*}
which is conveniently given in terms of a ``density matrix'' $D_{\mu\nu}$.
\begin{align}\label{eq:rhf-ao-basis-fock}
  F_{\mu\nu}
=&\
  \ip{\x_\mu|\op{h}|\x_\nu}
+
  \sum_{\rho\si}^m
  D_{\rho\si}
  (2\ip{\x_\mu\x_\rho|\x_\nu\x_\si}-\ip{\x_\mu\x_\rho|\x_\si\x_\nu})
&&
  D_{\mu\nu}
=
  \sum_i^{n/2}
  C_{\mu i}^*C_{\nu i}
\end{align}

\subsubsection{Solving the Roothaan-Hall Equations}

Equation~\ref{eq:roothaan-hall} would look like an ordinary eigenvalue problem if $\bo{S}$ were an identity matrix.
This would be the case if the AO basis were orthogonal, but that generally isn't the case.
We can get around this problem using the following algebraic trick:
if we multiply both sides of equation~\ref{eq:roothaan-hall} by $\bo{S}^{-\frac{1}{2}}$ and insert $\bo{I}=\bo{S}^{-\frac{1}{2}}\bo{S}^{\frac{1}{2}}$ between $\bo{F}$ and $\bo{C}$, we can write
\begin{align}
\label{orthogonalized-roothaan-hall}
&
  \tl{\bo{F}}
  \tl{\bo{C}}
=
  \tl{\bo{C}}\bm\ev
&&
  \tl{\bo{F}}
=
  \bo{S}^{-\frac{1}{2}}\bo{F}\bo{S}^{-\frac{1}{2}}
&&
  \tl{\bo{C}}
=
  \bo{S}^{\frac{1}{2}}\bo{C}\ .
\end{align}
This is equivalent to a transformation to an orthogonalized AO basis $\tl\x_\mu=\sum_\nu\x_\nu (\bo{S}^{-\frac{1}{2}})_{\nu\mu}$ which satisfies $\ip{\tl\x_\mu|\tl\x_\nu}=\d_{\mu\nu}$.
After diagonalizing the transformed Fock matrix, $\tl{\bo{F}}$, the MO coefficients with respect to the original non-orthogonal AO basis can be recovered as $\bo{C}=\bo{S}^{-\frac{1}{2}}\tl{\bo{C}}$.

\begin{samepage}
Equation~\ref{orthogonalized-roothaan-hall} is still not exactly an ordinary eigenvalue problem because $\bo{F}$ depends on the MOs via the density matrix $\bo{D}$.
The standard procedure for solving the Roothaan-Hall equations repeatedly diagonalizes $\tl{\bo{F}}$ and feeds in the new density until the equation becomes self-consistent.
The algorithm looks as follows.
\begin{enumerate}
  \item Get integrals $\ip{\x_\mu|\x_\nu}, \ip{\x_\mu|\op{h}|\x_\nu}, \ip{\x_\mu\x_\nu|\x_\rho\x_\si}$ and form orthogonalizer $\bo{S}^{-\frac{1}{2}}$
  \item Guess $\bo{D}=\bo{0}$
  \item\label{loop} Build $\bo{F}$ (equation~\ref{eq:rhf-ao-basis-fock})
  \item Diagonalize $\tl{\bo{F}}=\bo{S}^{-\frac{1}{2}}\bo{F}\bo{S}^{-\frac{1}{2}}$ to get $\tl{\bo{C}}$ and $\bm\ev$
  \item Backtransform to original basis: $\bo{C}=\bo{S}^{-\frac{1}{2}}\tl{\bo{C}}$
  \item Form new density matrix: $D_{\mu\nu}=\sum_i^{n/2} C_{\mu i}^*C_{\nu i}$
  \item If the new $\bo{D}$ differs from the old $\bo{D}$ by more than some threshold, return to step~\ref{loop}
\end{enumerate}
\end{samepage}

\subsection{UHF: The Pople-Nesbet Equations}

For open-shell systems of arbitrary $n_\a, n_\b$, we can solve equations~\ref{eq:canonical-uhf-equation-alpha} and~\ref{eq:canonical-uhf-equation-beta} without requiring $\f_{i_\a}=\f_{i_\b}$.
By exactly the same procedure as was used for the Roothaan-Hall equations, this leads to \textit{Pople-Nesbet equations}
\begin{align*}
&
  \bo{F}^\a\bo{C}^\a
=
  \bo{S}\bo{C}^\a\bm\ev^\a
&&
  F_{\mu\nu}^\a
=
  \ip{\x_\mu|\op{f}_\a|\x_\nu}
&&
  S_{\mu\nu}
=
  \ip{\x_\mu|\x_\nu}
&&
  (\bm\ev^\a)_{p_\a q_\a}
=
  \ev_{p_\a}\d_{p_\a q_\a}
\\
&
  \bo{F}^\b\bo{C}^\b
=
  \bo{S}\bo{C}^\b\bm\ev^\b
&&
  F_{\mu\nu}^\b
=
  \ip{\x_\mu|\op{f}_\b|\x_\nu}
&&
  S_{\mu\nu}
=
  \ip{\x_\mu|\x_\nu}
&&
  (\bm\ev^\b)_{p_\b q_\b}
=
  \ev_{p_\b}\d_{p_\b q_\b}
\end{align*}
where $\bo{C}^\a=[C_{\mu p_\a}]$ is an $m\times m$ matrix of MO coefficients for $\{\f_{p_\a}\}$ and $\bo{C}^\b=[C_{\mu p_\b}]$ is an $m\times m$ matrix of MO coefficients for $\{\f_{p_\b}\}$.
Expanding the $\a$ and $\b$ Fock matrices as in equation~\ref{eq:rhf-ao-basis-fock}, we find
\begin{align*}
&
  F_{\mu\nu}^\a
=
  \ip{\x_\mu|\op{h}|\x_\nu}
+
  \sum_{\rho\si}
  D_{\rho\si}^\a
  \ip{\x_\mu\x_\rho||\x_\nu\x_\si}
+
  \sum_{\rho\si}
  D_{\rho\si}^\b
  \ip{\x_\mu\x_\rho|\x_\nu\x_\si}
&&
  D_{\mu\nu}^\a
=
  \sum_{i_\a}^{n_\a} C_{\mu i_\a}^*C_{\nu i_\a}
\\
&
  F_{\mu\nu}^\b
=
  \ip{\x_\mu|\op{h}|\x_\nu}
+
  \sum_{\rho\si}
  D_{\rho\si}^\a
  \ip{\x_\mu\x_\rho|\x_\nu\x_\si}
+
  \sum_{\rho\si}
  D_{\rho\si}^\b
  \ip{\x_\mu\x_\rho||\x_\nu\x_\si}
&&
  D_{\mu\nu}^\b
=
  \sum_{i_\b}^{n_\b} C_{\mu i_\b}^*C_{\nu i_\b}
\end{align*}
where $\bo{D}^\a$ and $\bo{D}^\b$ are the $\a$ and $\b$ density matrices.
The procedure for solving the Pople-Nesbet equations is identical to the one given for RHF\@.
However, note that one must solve the $\a$ and $\b$ equations simultaneously because each Fock operator depends on both $\bo{C}^\a$ and $\bo{C}^\b$ (via $\bo{D}^\a$ and $\bo{D}^\b$).

\end{document}