%% LyX 2.3.3 created this file.  For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[12pt,letterpaper,reqno,english]{amsart}
\usepackage[T1]{fontenc}
\synctex=-1
\usepackage{babel}
\usepackage{amstext}
\usepackage{amsthm}
\usepackage[unicode=true,pdfusetitle,
 bookmarks=true,bookmarksnumbered=false,bookmarksopen=false,
 breaklinks=false,pdfborder={0 0 1},backref=false,colorlinks=false]
 {hyperref}

\makeatletter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\pdfpageheight\paperheight
\pdfpagewidth\paperwidth

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
\theoremstyle{definition}
 \newtheorem{example}{\protect\examplename}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
\usepackage{tikz}
\usepackage{textgreek, enumitem}
\usepackage[T1]{fontenc}
\usetikzlibrary{decorations.pathreplacing, calc,fit,shapes, positioning,arrows, patterns}

%
\@ifundefined{definecolor}
 {\usepackage{color}}{}
\usepackage{amsfonts}\setcounter{MaxMatrixCols}{30}
\usepackage{ifpdf} % part of the hyperref bundle
\ifpdf % if pdflatex is used
 % set fonts for nicer pdf view
 \IfFileExists{lmodern.sty}
  {\usepackage{lmodern}}{}
\fi % end if pdflatex is used

\providecommand{\U}[1]{\protect \rule{.1in}{.1in}}

\providecommand{\possessivecite}[1]{\citeauthor{#1}'s\nolinebreak[2]
(\citeyear{#1})}

\renewcommand{\baselinestretch}{1.35}
\setlength{\topmargin}{0.0in}
\setlength{\textheight}{8.0in}
\setlength{\evensidemargin}{0.20in}
\setlength{\oddsidemargin}{0.20in}
\setlength{\textwidth}{6.1in}

\usepackage{bbold}
\DeclareMathOperator{\EX}{\mathbb{E}}
\DeclareMathOperator{\E}{\mathbb{E}}
\DeclareMathOperator{\Prob}{\mathbb{P}}
\DeclareMathOperator{\R}{\mathbb{R}}
\DeclareMathOperator{\N}{\mathbb{N}}
\DeclareMathOperator{\1}{\mathbb{1}}
\DeclareMathOperator{\0}{\mathbb{0}}

\DeclareMathOperator{\CU}{\mathcal{U}}
\DeclareMathOperator{\CG}{\mathcal{G}}
\DeclareMathOperator{\CQ}{\mathcal{Q}}

\DeclareMathOperator{\val}{val}
\DeclareMathOperator{\marg}{marg}
\DeclareMathOperator{\supp}{supp}

\newcommand{\euler}{\mathrm{e}}

\usepackage{setspace}
%\onehalfspacing

\makeatother

\providecommand{\examplename}{Example}

\begin{document}
\title{TA Assignment Problem}
\author{Marcin Pęski}
\begin{abstract}
The goal is to formulate a TA assignment problem and discuss some
problems with tryig to solve it using stability-like notions.
\end{abstract}

\date{\today}
\maketitle

\section{Model}

Let $S$ be the set of students (i.e., candidate TAs). Let $C$ be
the set of courses. A (TA) assignment is a mapping $\phi:C\rightarrow\R_{+}^{S}$
We refer to $\phi\left(c\right)$ as the assignment to course $c$.
If $\phi$ is an assignment, then for each $s$, define $\phi\left(s\right)\in\R_{+}^{C}$
by $\phi\left(s,c\right)=\phi\left(c,s\right)$. We refer to $\phi\left(s\right)$
as the assignment of student $s$. Let $\Phi$ be the space of the
assignments.

Let $A_{S}=\R_{+}^{S}$ be the space of possible assignments to courses.
Analogously, let $A_{C}=\R_{+}^{C}$ be the space of possible assignments
for students.

Each course $c$ has a subset of assignments $F_{c}\subseteq A_{S}$
that are feasible for it. Examples of feasibility constraints include:
\begin{itemize}
\item budget: Each course has a budget of $h_{c}$ TA hours that need to
be allocated and assignment $\phi\left(c\right)\in A_{S}$ is feasible
for $c$ if and only if
\[
\sum_{s}\phi\left(c,s\right)=h_{c},
\]
\item minimum assignment hours: there is a constraint $\tau_{c}$ such that
an assignment is feasible only if for each $s$, either $\phi\left(c,s\right)=0$
or $\phi\left(c,s\right)\geq\tau_{c}$.
\end{itemize}
Similarly, each student $s$ has a subset $A_{s}\subseteq A_{C}$
of assignments that are feasible for them. Examples of student feasibility
constraints:
\begin{itemize}
\item maximum assignment: each student $s$ cannot work for more than $\kappa_{s}$
hours:
\[
\sum_{c}\phi\left(c,s\right)\leq\kappa_{s},
\]
\item minimum assignment: student $s$ must work for at least $l_{s}$ hours,
\item balance across semesters: There is a set $M$ of ``semesters'' and
each course $c$ is associated with a subset $M_{c}\subseteq M$ of
``semesters'' in which this course is taught. The student $s$ assigned
hours in semester $m$ are equal to
\[
h_{s}\left(m;\phi\right)=\sum_{c:m\in M_{c}}\frac{1}{\left|M_{c}\right|}\phi\left(c,s\right).
\]
It is required that the student assignment across semesters is balanced:
for some constant $\rho>1$, for each $m,m^{\prime}$,
\[
\frac{h_{s}\left(m,\phi\right)}{h_{s}\left(m^{\prime},\phi\right)}\leq\rho.
\]
\end{itemize}
An assignment $\phi$ is \emph{feasible} if $\phi\left(i\right)\in A_{i}$
for each $i\in S\cup C$.

Each student $s$ has preferences over possible assignments represented
by utility function $u_{s}:A_{C}\rightarrow\R$. Similarly, each course
$c$ has preferences over assignments represented by $u_{c}:A_{S}\rightarrow\R$.

An assignment is individually rational (for students) if none of the
students is better off by dropping some courses from its assignment
(the logic is that students cannot be made to work for a course, and
a typical TA contract is written separately for each course. If TAs
sign up for a bundle, i.e., for each of their assignment, the individual
rationality would require that each student prefers their assignment
to \textbf{0} assignment). Formally, for each $s$, each $D\subseteq C$,
$u\left(\phi\left(s\right)\right)\geq u\left(\phi_{D}\left(s\right)\right)$,
where $\phi_{D}$ is an assignment obtained from $\phi$ by zeroing
all courses not in $D$ $\phi_{D}\left(c,s\right)=\begin{cases}
\phi\left(c,s\right) & c\in D\\
0 & \text{otherwise}
\end{cases}$.

Let $\Phi^{*}$ be the set of feasible and individually rational assignments.

A social planner has preferences over $\Phi^{*}$.

\section{Core and stability}

Suppose that the social planner would like its assignment to be stable,
in some sense. It is not clear what exactly stable assignment means
- as there are many options available. Perhaps the most straightforward
would be t consider individually rational assignments that are not
blocked by 2-agent (student and course) coalitions. But, with many-to-many
assignments, 2-agent coalitions may not be sufficient and one may
want to think about some sort of core-type concept.

Instead of focusing on a stability notion, I want to illustrate the
problem with few examples why the any stability-like notion can be
problematic.

\subsection{No externalities\label{subsec:No-externalities}}

Suppose that student preferences are additive: for each $s$, there
exist constants $\nu_{s}\left(c\right)$ such that for each $a\in A_{C}$,
\[
u_{s}\left(a\right)=\sum_{c}a_{c}\nu_{s}\left(c\right).
\]
Additionally, suppose that all assignments of student $s$ are subject
to maximum constraint $\kappa_{s}$.

Similarly, suppose that course preferences are additive: for each
$c$, there exist constants $\nu_{c}\left(s\right)$ such that for
each $a\in A_{S}$,
\[
u_{c}\left(a\right)=\sum_{s}a_{s}\nu_{c}\left(s\right).
\]
Additionally, suppose that all assignments of course $c$ are subject
to maximum constraint $h_{s}$.

In this environment, one can show that the core is non-empty. Moreover,
core allocations can be found by a version of Gale-Shapley algorithm.
(Should I add this?)

\subsection{Courses that span across semesters}

It is well-known that any type of externality (or, more precisely,
complementarities) in many-to-many matching problems leads to problems
with the existence of a stable outcome (or core).

One source of externality that reduces the use of stability as a satisfactory
solution concept is given by courses that span across multiple semesters.
\begin{example}
\label{exa:There-are-three}There are three students $x,y,z$, and
four courses $aF,aS,bY,cY$. Courses $bY$ and $cY$ are offered across
two semesters, the other two courses are offered only in one semester.
Each course needs exactly 1 TA, and each student wants at most 1 course
per semester. All allocations must be either 1 or 0. (In this example,
partial allocations would not help anyway.) Student preferences over
bundles of courses are
\begin{align*}
x: & \left\{ aF,aS\right\} >bY>aF>\emptyset,\\
y: & aF>cY>\emptyset,\\
z: & cY>aS>\emptyset,
\end{align*}
Essentially, student $x$ really likes course $aF$, but also needs
money and would rather TA for $aF$ and $aS$ than for the whole-year
course $Y$, but is willing to TA for $aF$ only if that's the only
option. Course preferences are
\begin{align*}
aF: & x>y>\emptyset\\
aS: & z>x>\emptyset,\\
bY: & x>\emptyset,\\
cY: & y>z>\emptyset.
\end{align*}
So, $x$ and $aF$ are top matches for e\textbackslash each other,
but otherwise, there are no obvious matches.

We show that there is no core. If $y$ is assigned to $aF$, then
$z$ must be assigned to $cY$ (as that is the top assignment for
$z$ and the second best assignment for $cY$ after $y$ is taken).
But then, given that the best remaining for $aS$ is $x$, $x$ and
pair $\left\{ aF,aS\right\} $ are a blocking coalition (as the student
and all courses prefer to rematch with each other).

If $y$ is assigned to $cY$, then $z$ must be assigned with $aS$
(as $z$ is the top choice for $aS$ and $aS$ is the top choice for
$z$ aparat from $cY$ which prefers $y$. But then, since $aS$ prefers
$z$, $bY$ is the best option for $x$. As a consequence $aF$ is
available for $y$ who prefers it to $cY$.

If $y$ is not assigned to anybody, then $z$ gets $cY$, but then
$y$ and and $cY$ is a blocking pair.
\end{example}

\subsection{Preferences over the number of assignments}

Another source of problematic externality is when either students
(or, resp., courses) have preferences over the total number of assigned
courses (resp. students). In fact, a reinterpretation of Example \ref{exa:There-are-three}
illustrates a difficulty:
\begin{example}
There are three students $x,y,z$, and four courses $a,a^{\prime},b,c$.
Each student has up to 2h of work available. Courses $b$ and $c$
require 2h of work and they only want to hire the same TA. Courses
$a,a^{\prime}$ require 1h of work each. Otherwise, the preferences
are similar to Example \ref{exa:There-are-three}: for students
\begin{align*}
x: & \left\{ a,a^{\prime}\right\} >b>a>\emptyset,\\
y: & a>c>\emptyset,\\
z: & c>a^{\prime}>\emptyset,
\end{align*}
and for courses:
\begin{align*}
a: & x>y>\emptyset\\
a^{\prime}: & z>x>\emptyset,\\
b: & x>\emptyset,\\
c: & y>z>\emptyset.
\end{align*}
There is no stable matching.
\end{example}

\subsection{Minimum assignment}

There are $n\geq1$ students and $n+1$ courses. Each student has
$n+1$ hours and each course needs $n$ hours. The student $s$ utility
from assignment is linear in assignments (like in Section \ref{subsec:No-externalities}),
with coefficients equal to
\[
v_{s}\left(c\right)=\begin{cases}
1+\varepsilon & c=s\\
1 & c\neq s.
\end{cases}.
\]
Course $c$ utility from the assignment $a\in A_{S}$ depends on the
number of non-zero assignments and it equal to
\[
u_{c}\left(a\right)=\varepsilon1_{s=c}+\begin{cases}
1 & \left|\left\{ s:a_{s}>0\right\} \right|=1\\
1-\varepsilon & \left|\left\{ s:a_{s}>0\right\} \right|=2\\
1-10\left|\left\{ s:a_{s}>0\right\} \right| & \left|\left\{ s:a_{s}>0\right\} \right|>2.
\end{cases}
\]
The first term is a small boost of the utility when the student has
the same index as he course.

Then, the unique core allocation (or stable matching under any reasonable
deifnition) is when each student is matched for $n$ hours with the
course with the same index and for remaining $1$ hours is assigned
to course $n+1$.

Of course, the above assignment is Pareto-optimal, but wildly inefficient.
\end{document}


\section{Introduction} \label{sec:introduction}
Worst-case optimal join (WCOJ) algorithms, e.g. Leapfrog Triejoin, in the last few years turned conventional thinking about join processing
on its head because these multi-join algorithms have provable lower complexity than classical binary joins,
i.e. join algorithms that join just two tables at-a-time.
In the areas of data warehousing and OLAP, this finding does not have much impact, though,
since the join patterns most commonly encountered there are primary-foreign-key joins, short (PK-FK joins),
where the join shapes a tree or snowflake and contains no cycles.
The computational complexity of PK-FK joins is by definition linear in size of the inputs.
In these \textit{conventional} cases, binary joins are worst-case optimal already, e.g. hash joins.

However, analytical graph queries often use FK-FK joins which can grow over linearly in the size of their inputs,
and often contain cycles.
For these use-cases, binary joins often exhibit highly suboptimal run-times because they generate a rapidly increasing set of
intermediary results, e.g. when navigating a social graph with an out-degree in the hundreds.
Many of these intermediary results are eliminated in later joins, e.g. a join that closes a cycle.
Hence, an algorithm which avoids generating these results in the first place is to perform much better and
closer to the optimal possible performance given by the output size.
\textsc{WCOJ} avoid many of the intermediary results and are guaranteed to reach the best possible run time in terms of
the output size~\cite{agm}.

Because of the frequent presence of cyclic join-patterns in graph-pattern matching, we believe that worst-case optimal join algorithms
could be a useful addition to (analytical) graph database systems.
Therefore, we aim to integrate a scalable, \textsc{WCOJ} algorithm in Spark which is used by some modern graph engines~\cite{caps,gcore,
graphframe}.

The rest of our introduction is structures as follows.
\Cref{subsec:graph-pattern-matching} defines the term graph pattern matching, its translation into datalog and
relational queries and two examples of cyclic graph pattern used in practice.
We aim to give the reader an intuitive understanding of why \textsc{WCOJ}s are superior to binary joins for graph pattern matching
in~\cref{subsec:intuitive-example}.
\Cref{subsec:graphs-on-spark} motivates our choice to use Spark as the base for our thesis.
Next, we state our research questions and contributions in~\cref{subsec:research-questions-and-contributions}.
Finally in~\cref{subsec:thesis-idea}, we outline the main ideas behind the thesis and their connections.

\subsection{Graph pattern matching}\label{subsec:graph-pattern-matching}
Graph pattern matching is the problem of finding all instances of a specific subgraph in a graph.
The subgraph to find is described as a pattern or query.
In this thesis, we use datalog queries to define subgraph queries.

For example, \cref{eqn:triangle} shows the datalog query describing a triangle.

\begin{equation}
    \textit{triangle(a, b, c) $\leftarrow$ R(a, b), S(b, c), T(c, a)} \label{eqn:triangle}
\end{equation}

Here we join three atoms $S, R$ and $T$ with two attributes each $(a, b)$, $(b, c)$ and $(a, c)$ respectively.
The task of enumerating all triangles within the three atoms can be also be described as finding all possible
bindings for the join variables $a, b$ and $c$ within them.

The translation from datalog queries to graph patterns is straightforward.
An attribute or a variable refers to a vertice in a graph and an atom to an edge.
A depiction of the subgraph pattern described by~\cref{eqn:triangle} is shown in~\cref{fig:pattern-triangle}.

\begin{figure}
    \centering
    \includesvg[width=0.2\textwidth]{svg/triangle}
    \caption{Depiction of the triangle subgraph query.}
    \label{fig:pattern-triangle}
\end{figure}

In relational terms, a graph pattern matching query is an n-ary, conjunctive, self-equijoin on the edge relationship of the graph.
In this thesis, all join queries discussed belong to this subcategory of possible join queries.
Other join queries can be useful to describe more complex graph patterns, e.g. disjunction for two edges of which only one needs to
exist or negation to exclude instances that have too many connections.
Some techniques used in this work can be extended to cover these cases, we mention related literature but do not focus
our efforts on these extensions.

Graph pattern matching is fundamental to analytical graph analysis workloads~\cite{fraud-detection,flake2002,
bodaghi2018automobile,newman2004detecting}.
We show two graph patterns which are used in practice below and explain the use-cases.

\Cref{fig:pattern-diamond} shows the diamond query which is used by Twitter to recommend their users new people to follow.
The idea is that if user $a$ is following multiple accounts $c_1, \dots, c_k$ who all follow a person $b$ then it is likely that
$b$ would be interesting to follow for $a$ as well.
In the figure, we see the diamond query for $k = 2$.
This is the diamond query as discussed in most papers in academia~\cite{olddog,myria-detailed,mhedhbi2019}, although,
Twitter uses $k = 3$ in production~\cite{twitter-diamond}.

\begin{figure}
    \centering
    \includesvg[width=0.2\textwidth]{svg/diamond}
    \caption{The dimaond query is used by Twitter. The vertices are users and the edges follower relationships.
    In the example, they could recommend $A$ to follow $D$ because $A$ follows $B_1$ and $B_2$ which both follow $C$.
    }
    \label{fig:pattern-diamond}
\end{figure}

Our second concrete use-case example is the n-cycle.
As explained in~\cite{fraud-detection}, cycles can be used to detect bank fraud.
A typical bank-fraud often involves so-called \textit{fraud-rings}.
These are two or more people who combine their legitimate contact information in new ways to craft multiple false identities.
For example, two people share real phone numbers and addresses to craft four fake identities; all combinations possible with two pieces
of information.
They open accounts under wrong names with real contact information, use these accounts normally to build trust with the bank and
build up bigger credit lines.
At a certain date, they max out all credit lines and disappear.
The phone numbers are dropped and the actual people living at the addresses deny ever knowing the identities that opened the accounts.

This scheme can be detected using graph pattern matching.
Let us assume, we have a graph database in which customer of the bank, their addresses and phone numbers are all vertices and the
relationship of an address or phone number belonging to a customer are edges.
Then, the case described above forms an 8-cycle of 4 persons (fake identities) connected by the shared use of phone numbers and
addresses.
The imagined cycle is shown in~\cref{fig:graph-pattern-example-bank-fraud}.

\begin{figure}
    \centering
    \includesvg[width=0.2\textwidth]{svg/bank-fraud}
    \caption{Schematics of a bank fraud ring.
    2 fraudsters share their phone numbers and addresses (labelled $P$ and $A$) to create four
    fake customers ($C$ vertices).
    }
    \label{fig:graph-pattern-example-bank-fraud}
\end{figure}

\subsection{Binary joins vs \textsc{WCOJ}s: an intuitive example} \label{subsec:intuitive-example}
We introduce the triangle query and possible binary join plans.
Then we point out the general problem of binary join plans on this query and the idea of how \textsc{WCOJ}s can improve the situation.
Next, we give a concrete example of a database instance to illustrate the aforementioned problem.
We conclude our motivation to use worst-case optimal joins by reporting multiple papers that show that these joins are highly beneficial
to graph pattern matching queries in practice.

The simplest example of a cyclical join query enumerates all triangles in a graph.
It is shown in~\cref{eqn:triangle} and \cref{fig:pattern-triangle}.

Traditionally, this would be processed by using multiple binary joins:
\begin{equation}
    R \bowtie S \bowtie T
\end{equation}
The join above can be solved in 3 different orders: $ (R \bowtie S) \bowtie T$, $ (R \bowtie T) \bowtie S$ and
$ R \bowtie (T \bowtie S)$.
Independent of the chosen order, database instances exist where the intermediary result size is in $\mathcal{O}(N^2)$ with
\textit{N}= |\textit{R}| = |\textit{S}| = |\textit{T}|.
However, it is provable that the output of this query is guaranteed to be in $\mathcal{O}(n^{3/2})$~\cite{agm,skew-strikes-back}
for any database instance.
Hence, binary joins materialize huge intermediary results after processing parts of the query,
which are much bigger than the final result.

The described problem is a fundamental issue with traditional binary join plans~\cite{agm,skew-strikes-back}.
We call these plans also \textit{join-at-a-time} approach because they process whole joins at the time.

Fortunately, worst-case optimal join algorithms can materialize cyclic joins with memory usage linear to their output size
by solving the join \textit{variable-at-a-time} which avoids materializing big intermediary results~\cite{lftj,nprr}.

In variable-at-a-time the algorithm finds a binding for the first variable $a$, then one for $b$ and
finally one for $c$.
After this, it emits the tuple as part of the output.
Then it finds further bindings via backtracking until they enumerated the whole join when all bindings for $a$ have been explored.

% Example concrete
A simple example graph database instance gives an idea of why a variable-at-a-time approach is beneficial for cyclic queries.
In \cref{fig:edge-rel-example}, we see an edge relationship.
It is repeated three times labelled with different attributes to ease the understanding of the following explanation;
however, in a system's implementation, only one table exists and is used by all joins as input.

\begin{figure}
    \centering
    \subfloat{
      $R$
    \begin{tabular}{rr}
        \toprule
        a &  b \\\midrule
        1 &  2 \\
        2 &  7 \\
        2 &  8 \\
        2 &  9 \\
        2 & 10 \\
        3 &  2 \\
        4 &  2 \\
        5 &  2 \\
        6 & 11 \\
        11 & 12 \\
        12 &  6 \\\bottomrule
    \end{tabular}
    }
    \hspace{0.2\textwidth}
    \subfloat{
     $S$
    \begin{tabular}{rr}
        \toprule
        b &  c \\\midrule
        1 &  2 \\
        2 &  7 \\
        2 &  8 \\
        2 &  9 \\
        2 & 10 \\
        3 &  2 \\
        4 &  2 \\
        5 &  2 \\
        6 & 11 \\
        11 & 12 \\
        12 &  6 \\\bottomrule
    \end{tabular}
    }
    \hspace{0.2\textwidth}
    \subfloat{
    $T$
    \begin{tabular}{rr}
        \toprule
        c &  a \\\midrule
        1 &  2 \\
        2 &  7 \\
        2 &  8 \\
        2 &  9 \\
        2 & 10 \\
        3 &  2 \\
        4 &  2 \\
        5 &  2 \\
        6 & 11 \\
        11 & 12 \\
        12 &  6 \\\bottomrule
    \end{tabular}
    }
    \caption{
    Three aliases to an edge relationship which contains three triangles, the permutations of \{6, 11, 12\},
    and one skewed value.
    }
    \label{fig:edge-rel-example}
\end{figure}

A binary join plan which joins $R$ and $S$ via $b$ first produces $16 + 3$ intermediary results;
4 times 4 results for $b = 2$ and one for 6, 11, 12 each.
The next join reduces these 16 results to the three triangle instances; all permutations of the set \{6, 11, 12\}.

A variable-at-a-time approach finds 4 bindings for $a$, namely  $2, 6, 11, 12$;
the intersections of both columns labelled $a$.

Intersecting both columns of $b$ values we notice $2, 6, 11, 12$ could be possible bindings for $b$.
When we fix an $a$ value these four possibilities are reduced to the $b$ values which exist for this
$a$ value in the leftmost table.
So once we fixed a binding for $a$, we find one possible binding for $b$ each;
except the binding $a = 2$ for which we cannot find a matching $b$ value.

Finally, we find all three instances of the triangle by completing the three $a, b$ bindings with
the matching $c$ binding;
only one exists for each $a, b$ binding.

We can drastically reduce the workload by formulating the join as a problem of
finding variable bindings using information from all parts of the join, instead of, using only one constraint at the time
and building it join-by-join.

We do not claim that the example above illustrates the generality of why binary join plans are provable worse than
\textsc{WCOJ}s.
Clearly, the example does not show an intermediary result of $N^2$ as $N = 11$ and the intermediary result has the size of 16.
However, we note that even in such a simple example all possible binary join orders produce an intermediary result of size 16.
While all possible variable orderings for a variable-at-a-time approach eliminate the skewed value (2) after finding no binding
for the second variable.
A more general but less concrete example is explained in~\cite{skew-strikes-back}.

% WCOJ's in practice
In practice, these worst-case optimal join algorithms are highly beneficial for cyclic queries in analytical graph
workloads in an optimized, single machine system~\cite{lftj,olddog}.
\cite{olddog} compares a system using \textsc{WCOJ}s against multiple general-purpose database
systems using binary joins and some graph pattern matching engines on 15 datasets and 7 queries and
finds that worst-case optimal joins can beat all other systems in the vast majority of queries
and datasets, often by the order of magnitudes or even being the only system to finish within 30 minutes.

Later worst-case optimal joins have been applied successfully to a distributed shared-nothing settings~\cite{myria-detailed,
ammar2018distributed};
we describe these systems in more detail in~\cref{subsec:myria} and~\ref{subsec:wcoj-timely-data-flow}.

\subsection{Graphs on Spark}\label{subsec:graphs-on-spark}
Spark is an attractive target for big graph processing, due to its generality, widespread acceptance in the industry, the ability to use
cloud hardware and its fault tolerance by design.
For example, GraphFrames~\cite{graphframe}, GraphX~\cite{graphx} (a Pregel~\cite{pregel} implementation) or graph query languages
as \mbox{G-CORE}~\cite{gcore} and \mbox{openCypher} with `Cyper for Apache Spark' or \textsc{CAPS}~\cite{caps} all aim to ease graph
processing on Spark.
The last two technologies translate their graph specific operations to the relational interface of Spark (SparkSQL)
to profit from Spark's relational query optimizer Catalyst~\cite{spark-sql}.
Moreover, they allow the user to formulate graph pattern matching queries naturally.

Hence, we believe that the \textsc{WCOJ}s, with their efficiency for analytical graph queries, are a valuable addition to Spark's
built-in join algorithms in general and these graph-on-spark systems in particular.
Ideally, they are integrated such that they can be naturally used in the ecosystem of Catalyst.
This would allow easier use in SQL like graph languages as \textsc{G-CORE} or Cypher for graph pattern matching.

\subsection{Research questions and contributions}\label{subsec:research-questions-and-contributions}
We identify two challenging, novel directions for our research.
First, all papers about \textsc{WCOJ} focus on queries widely used in graph pattern matching, e.g. clique finding or path queries.
As explained above, graph pattern matching uses only self-joins on a single relationship with two attributes
namely the edge relationship of the graph.
However, all systems use worst-case optimal joins developed for general n-ary joins.
This raises the question if and how \textsc{WCOJ}s can be specialized for graph pattern matching.

Second, while the communication costs for worst-case optimal joins in MapReduce like systems\footnote{
An excellent definition of the term MapReduce like systems is given in~\cite{shares}}
is well-understood~\cite{shares,shares-skew,shares-proof,shares-skew-proof},
their scalability has not been studied in depth.
Given that the only integration in a MapReduce like system exhibits a speedup of 8 on 64 nodes over two workers (an efficiency of 0.125)
~\cite{myria-detailed},
we find that designing a scalable, distributed \textsc{WCOJ} for a MapReduce like system is an unsolved challenge.

It is time to investigate how these algorithms scale in the provable most widely used, general-purpose big data processing engine: Spark.
To the best of our knowledge, this is also the first time a worst-case optimal join is integrated with an industrial-strength cluster
computing model.
We detail our research questions below.

\begin{enumerate}
    \item Can we gain performance in \textsc{WCOJ}s by specializing them to graph pattern matching?
    \begin{enumerate}
        \item How much performance can we gain by using compressed sparse row representations as backing data structure to \textsc{WCOJ}s?
        \item Can we find a more suitable algorithm to build intersections for graph-pattern matching than the complex n-ary approach
         proposed originally?
    \end{enumerate}
    \item How well do \textsc{WCOJ}s scale in Spark when used for graph pattern matching?
    \begin{enumerate}
        \item How well does a previously proposed, optimal partitioning scheme, named Shares, scale?
          We explain Shares in detail in~\cref{subsubsec:shares}.
        \item How to integrate scalable work-stealing into Spark to counter tuple replication and skew?
    \end{enumerate}
\end{enumerate}

Towards answering our research questions, we make the following contributions.
\begin{enumerate}
    \item We integrate a sequential, general worst-case optimal join into Spark.
    This implementation serves as a baseline for our \textsc{WCOJ} optimized to graph pattern matching.
    \item We design and implement GraphWCOJ which is a worst-case optimal join specialized to graph pattern matching.
    It is backed by a compressed sparse row representation of the graph which reduces its memory footprint and speeds up execution by up
    to 11 times over a normal \textsc{LFTJ} because it acts as an index. % NUMBER
    Furthermore, we exploit the typical low out-degree of most graphs to by specializing the \textsc{LFTJ} for small intersections.
    \item We analyse how many tuples Shares replicates for typical graph pattern matching queries.
    From this analysis and the fact that Shares is an optimal partitioning scheme, we conclude that replication is inevitable for complex
    graph-pattern matching queries.
    Therefore, we cache the graph in the memory of all workers.
    \item Based on a replicated edge relationship, we design \textit{logical} Shares.
    This is an approach where the graph is fully replicated but we use Shares partitioning to divide work between executors.
    We measure a speedup of 13 on 64 workers for some queries and beat an existing implementation of (physical) Shares which reaches
    a speedup of 8 for the same number of machines.
    The results show that Shares is good in dealing with skew but requires too much replicated work to scale well.
    \item Therefore, we abandon static partitioning and design a \textsc{WCOJ} that applies work-stealing.
    We show that work-stealing can scale linearly on some input queries and beats \textit{logical} Shares for all levels of parallelism
    \item for 3-cliques and 5-cliques on three different datasets.
    \item We run experiments on 5 datasets, 6 queries, for up to 382 workers using Spark's build-in hash join,
    a general Leapfrog Triejoin and our specialized GraphWCOJ.
\end{enumerate}

\subsection{Thesis overview} \label{subsec:thesis-idea}
In this section, we outline the main ideas, motivation and decisions taken in this thesis.
We summarize the whole thesis as a graph in~\cref{fig:thesis-overview}.
We see the background that motivates our decision in the corners and our system in the centre.
The edges show connections between different ideas and components.
We give an overview of the thesis in the next paragraphs.

\begin{figure}
    \centering
    \includesvg[width=\textwidth]{svg/thesis-overview}
    \caption{
    Main ideas and components of the thesis.
    Background and related work shown in the corners.
    The center shows the main component of our parallized worst-case optimal join
    }
    \label{fig:thesis-overview}
\end{figure}

As mentioned in~\cref{subsec:graphs-on-spark}, Spark is a good platform for our work because many graph pattern matching systems use
it, like neo4j's Cypher on Apache Spark (CAPS) and LDBC's G-CORE~\cite{caps,gcore}.
In particular, they build on top of Spark's structured query execution offered by Catalyst.
Catalyst is designed to be easily extendable and allows to introduce new operators, such as a worst-case optimal join,
without modifying the core of Spark.
This is even possible in a way such that these new operators can be used with a native, unchanged installation of Spark.
We describe Catalyst query compilation process in~\cref{subsubsec:catalyst}.
Our integration is detailed in~\cref{sec:spark-integration}.

Normally, Spark achieves parallelism and distributed algorithms by partitioning data over all workers.
When data from different tables needs to be joined, Spark repartitions the data such that each worker can process parts of the join locally.
However, shuffling is an expensive operation in Spark, involving disk writes and reads, which should be avoided if possible.
Moreover, we can show that a communication-optimal partitioning scheme degenerates into a full broadcast for bigger graph pattern queries;
we explain this in detail in~\cref{subsubsec:shares}.

Given this finding, we design our system to build on a replicated and cached edge relationship on each worker.
As a short study of us reveals, most large graph problems described in literature, have edge structures that would fit in
main-memory (see~\cref{subsec:graph-analysis});
and our compressed storage format further helps to keep memory usage under control.
This has a few distinct advantages.

First, the broadcast can be done once at system startup.
Then, we can reuse it for any graph pattern matching query;
all of them need to join over the edge relationship many times.
Therefore, we can answer many graph pattern matching queries without shuffling data.
We explain the integration of replicated edge relationships into Spark in~\cref{subsec:spark-integration-graphWCOJ} and introduce
the necessary background in~\cref{subsubsec:broadcast-variables}.

Furthermore, such reuse helps to amortize the non-trivial setup costs for worst-case optimal joins;
they require their input data to be sorted.

Finally, a replicated data structure allows us to use dynamic work-sharing schemes as work-stealing cheaply without relocating
data.
Normally, partitioning is done completely statically in Spark.
However, this is problematic given that many real-world graphs are highly skewed, e.g. power-law graphs such as many follower graphs
(Facebook, Twitter) or web graphs.
We find that this skew can easily lead to bad load-balancing with the static partitioning of Spark.
We explain how to integrate work-stealing with Spark in~\cref{subsec:work-stealing}.

Using a fully replicated edge relationship and potentially work-stealing leads to the necessity to build data-partitioning into
the worst-case optimal join operators.
This is because Spark would normally have an operator work on all local data and archive parallelism via physically partitioning the
data over multiple workers.
We call partitioning built into our operators \textit{logical} partitioning.
The concept and its implementation are described in~\cref{sec:worst-case-optimal-join-parallelization}.

We choose to use the Leapfrog Triejoin~\cite{lftj} as a basis for our system;
this choice is motivated in~\cref{subsec:worst-case-optimal-join-algorithm}.
This join requires its input relationships to be presented in a sorted data structure which is searchable for upper bounds in
$\mathcal{O} (\log N)$.
Furthermore, it mainly uses intersections to compute the join.
The algorithm is explained in detail in~\cref{subsubsec:leapfrog-triejoin}.

We specialize the Leapfrog Triejoin to graph pattern matching by introducing a compressed sparse row representation~(\textsc{CSR}, see
\cref{subsec:csr-background}) as backing data structure for the input relationships.
\textsc{CSR} can compress the graph edge relationship by a compression factor of nearly 2.
Additionally, we show that it speeds up the \textsc{WCOJ} execution to be backed by a \textsc{CSR} because this representation
acts like an index.

Another graph specific optimization we apply to \textsc{LFTJ} is that we change the intersection building algorithm for one
that is specialized in small intersections.
This is motivated by the fact that real-world graphs have normally small average out degrees.
Hence, the intersection of multiple adjacency lists is predictably small.
We discuss both specializations to the Leapfrog Triejoin algorithm in~\cref{sec:graphwcoj}.

% Also introduce cached edge table, ref related work for why communication does not work
% and goals for explanation of why we think caching is helpful
% use mcsherry, other guy here?  --> read them

% These academic systems are not very usable nor used, nor is LogicBlox on the market as a database system.
% For all practical senses and purposes, there are no %systems available that implement WCOJs. Apache Spark is currently the most popular
% analytical data processing system. It does not implement WCOJs yet and has %multiple popular graph processing APIs or subsystems, among
% which GraphFrames, CAPS (neo4j's Cypher on Apache Spark) and the recent LDBC effort to implement the G-%CORE query language on Apache
% Spark. All of these APIs could potentially benefit greatly from a WCOJ algorithm.

%Spark offers a well optimized Relational interface [SparkSQL] [Catalsyst]
%Relational interfaces rely on JOINS which have different characteristics different for graphs than for traditional star or snowflake schemes.
% - they are cyclic for important graph algorithms (cluster, ?subgraphing?)
%  - large intermediary results which make the queries really expensive for the CPU as well as the in memory
%   - work is done for nothing because most of the intermediary results are filtered out later
% - they are highly selective (paths starting from a specific node)
%  - allowing to safe work when all "filters" are applied simultaneously
%  - allowing for big jumps on sorted keys with a seek operation, naturally, applied by LFTJ
% - therefore, they are a prime area of application for a new class of join algorithms with worst-case guarantees, which guarantee that no big intermediary results build up
%because the evaluate multiple joins as once only materializing results that fulfil all join filters.
% - Furthermore, they are naturally suited for highly selective queries because of using an O(log(N)) seek a method to jump over "uninteresting" parts of a sorted result.


%$Id: Oral.tex 82 2007-06-08 14:32:56Z jlconlin $
%$Author: jlconlin $
%$Date: 2007-06-08 08:32:56 -0600 (Fri, 08 Jun 2007) $
%$Revision: 82 $

\documentclass[11pt]{article}
\usepackage{geometry}
\usepackage[algo2e, ruled, linesnumbered]{algorithm2e}
\usepackage{amsmath}
\usepackage{amsfonts}

\SetKwComment{Comment}{$\triangleright$ }{}
\dontprintsemicolon

%\renewcommand{\span}{\mathrm{span}}

\author{Jeremy Conlin}
\title{Oral Thesis Prospectus}
\date{June 6, 2007}

\begin{document}
\maketitle
\abstract{
    The power method, or source iteration, has been the staple of Monte Carlo particle transport eigenvalue calculations for more than fifty years.  This method is easy to implement and provides the dominant eigenvalue and eigenfunction, however, this method is slow.  The rate of convergence is proportional to the dominance ratio, the ratio of the second largest eigenvalue to the largest eigenvalue.

    For this thesis, I propose using an alternative to the power method, Arnoldi's Method of Minimized Iterations.  Arnoldi's method is an improvement over the power method; it uses information from all previous iterations---instead of only the last iteration---to calculate the eigenfunction.

    Preliminary results indicate that Arnoldi's method is less noisy than the Power method and the eigenvalue and the eigenfunction are converged more quickly.  However, the RMS error of the eigenfunction---compared to a deterministic SN calculation---calculated with Arnoldi's method is larger than the RMS error from a power method calculation for the same number of Monte Carlo histories.  Other results show that Arnoldi's method can calculate higher eigenmodes which the power method is unable to do without additional calculations.

    Several questions must be explored before the use Arnoldi's method in Monte Carlo particle transport can be accepted.  Most importantly, how can the uncertainty be calculated?  Without a measure of the statistical uncertainty, the answer is meaningless.  A simple solution is to restart the method after a few iterations and find the mean and variance of the eigenvalues after each restart.  I believe there is a better and more efficient way; this is one aspect of my thesis research.

    Arnoldi's method requires the calculation of an inner product between two functions.  In Monte Carlo particle transport, these functions are fission sources.  In initial studies, these fission sources were spatially binned; the height of these bins are the elements of a vector.  Discretizing a fission source in this manner introduces bias to the calculation.  The inner product of two vectors is a simple dot product.  Is there a way to calculate the inner product of two fission sources without resorting to binning the sources?  Can we use basis functions other than histogram step functions to expand the fission source?  These are additional questions I plan on addressing in my thesis.

    All calculations so far have been performed in 1-D homogeneous slab geometries.  What will happen in heterogeneous and multi-dimensional geometries?  Is Arnoldi's method still valid and does it still offer the same benefits?  Although unknown for certain at this time, I propose the answer is yes.  The reduced noise when using Arnoldi's method may lead to dramatic improvements in calculating eigenfunctions of geometries where highly absorbing materials are separated by highly scattering materials (e.g. the eigenvalue of the world type problems).  No mathematical obstacles---other than lack of experience of the author---immediately present themselves as problems to using Arnoldi's method in higher dimensions.
}

%\end{document}
\section{Power Method---Source Iteration}
The particle transport equation
\begin{equation}
    \mathbf{\Omega}\cdot\mathbf{\nabla}\psi(\mathbf{r},\mathbf{\Omega})+\Sigma_t\psi(\mathbf{r},\mathbf{\Omega}) = \Sigma_s\psi(\mathbf{r},\mathbf{\Omega}) + \frac{1}{k}\nu\Sigma_f\psi(\mathbf{r},\mathbf{\Omega}),
\end{equation}
can be written in operator form
\begin{subequations}\begin{align}
    (\mathbf{L} + \mathbf{C} - \mathbf{S})\psi &= \frac{1}{k}\mathbf{F}\psi \\
    \mathbf{T}\psi &= \frac{1}{k}\mathbf{F}\psi. \label{eq:Opr}
\end{align}\end{subequations}
where $\mathbf{L}, \mathbf{C},$ and $\mathbf{S}$ are the leakage, collision, and scattering operators respectively; and $\mathbf{F}$ is the fission operator.  The operator $\mathbf{T}$ is the transport-collision operator.  The left-hand side represents the neutron loss mechanisms and the right-hand side represents the neutron gain mechanism.

Let us define
\begin{align}
    q &\equiv \mathbf{F}\psi, \\
    \mathbf{A} &\equiv \mathbf{F}\,\mathbf{T}^{-1}
\end{align}
and manipulate Eq. \ref{eq:Opr} to find
\begin{equation}
    q = \frac{1}{k}\mathbf{A}q. \label{eq:evalue}
\end{equation}
This is a standard eigenvalue problem with eigenvalue $k$ and eigenvector $q$.  The linear operator $\mathbf{A}$ first transports source particles and then computes a fission source from the resulting particle population.

We can use Eq. \ref{eq:evalue} in an iterative manner
\begin{equation}
    q^{(n+1)} = \frac{1}{k^{(n)}}\mathbf{A}q^{(n)}.
\end{equation}
given an initial eigenvector $q$ and eigenvalue $k$ (usually $k=1$.)  Each iteration consists of calculating a new estimate of the eigenvector and eigenvalue,
\begin{equation}
    k^{(n+1)} = \frac{Aq^{(n)}}{q^{(n)}} = \frac{q^{(n+1)}}{q^{(n)}}.
\end{equation}

\section{Krylov Subspaces}
A careful reader will notice Power Method generates a series of vectors
\begin{equation}
    \{v, Av, A^2v, \ldots, A^{m-1}v\} = \{q_0, q_1, q_2, \ldots, q_{m-1}\}.
\end{equation}
The vectors $\{q\}$ form a basis of the Krylov subspace denoted
\begin{equation}
    \mathcal{K}_m(A,v) = \mathrm{span} \{q_0, q_1, \ldots, q_{m-1}\}.
\end{equation}
Any Monte Carlo based particle transport code will create a Krylov subspace.  One starts with the initial source distribution, $q_0$, and transports it defined by the operator, $A$.  This generates a new source distribution, $q_1$ which is then transported.

Power Method has been used for greater than 50 years, but isn't there a better way?  Deterministic numerical methods researchers have found eigenvalue methods that are faster than Power Method.  Can these be applied in a Monte Carlo code?  The answer is a resounding ``We think so.''

\section{Minimized Iteration---Arnoldi's Method}
In contrast to the Power Method, Arnoldi's Method uses all the vectors previously calculated; after $k$ steps, we have $k+1$ vectors $\{q, Aq, A^2,\ldots, A^kq\}$.  In practice, these vectors usually are an ill-conditioned basis for the space they span.  The vector $A^jq$ points more and more in the direction of a dominant eigenveactor for $A$ as $j$ is increased.  \marginpar{Why is this a problem?  Is it because we get little information about the other vectors?}

Arnoldi's method creates an orthonormal set of basis vectors $\{q_1, \ldots, q_{k+1}\}$ that spans the same Krylov subspace, $\mathcal{K}(A, q)$.  This orthonormal basis can be built up one vector at a time.  At the $k+1$st step we could simply multiply $A^{k-1}q$ by $A$ to get $A$.  It is inefficient to raise the matrix to a high poer, but we dont' have to.  To get $q_{k+1}$ we operate on $q_k$ by $A$ and orthogonalize against the previous vectors.

The details of the Arnoldi process follow.  We begin with the normalization of the original vector
\begin{equation}
    q_1 = q/\|q\|_2.    \label{eq:begin}
\end{equation}
At all subsequent steps we take
\begin{equation}
    \tilde{q}_{k+1} = Aq_k - \sum_{j=1}^k q_j h_{jk}.   \label{eq:mvOrtho}
\end{equation}
where
\begin{equation}
    h_{jk} = \langle Aq_k, q_j \rangle.
\end{equation}
Lastly, the vector is normalized
\begin{equation}
    q_{k+1} = \frac{\tilde{q}_{k+1}}{h_{k+1,k}},
\end{equation}
where
\begin{equation}
    h_{k+1,k} = \|\tilde{q}_{k+1}\|_2. \label{eq:end}
\end{equation}

Eqs. \ref{eq:begin}-\ref{eq:end} are summarized in Algorithm \ref{alg:Arnoldi}.  The matrix/operator $A$ itself is never used, only the matrix-vector product (see line \ref{algln:MonteCarlo}).  This is what allows us to use this method in a Monte Carlo code.  The Monte Carlo particle transport solves $\tilde{q}_{k+1} = Aq_k$.

\begin{algorithm2e}
    \label{alg:Arnoldi}
    \SetVline
    \caption{Arnoldi Process (freely borrowed from Watkins(2002))}
    $q_1 = q/\left\|q\right\|_2$ \;
    \For{$k=1,\ldots,m-1$}{
        $\tilde{q}_{k+1} \gets Aq_k$\;  \nllabel{algln:MonteCarlo}
        \For(\Comment*[f]{Orthogonalize}){$j=1, \ldots, k$}{
            $h_{jk} \gets \left<q_j,q_{k+1}\right>$\;
            $q_{k+1} \gets q_{k+1} - q_jh_{jk}$}
        $h_{k+1,k} \gets \left\|q_{k+1}\right\|_2$\;
        \If(\Comment*[f]{Span \{$q_1, \ldots, q_k$\} is invariant under $A$}){$h_{k+1,k} = 0$}{
            quit.}
        $q_{k+1} \gets q_{k+1}/h_{k+1,k}$\;
    }
\end{algorithm2e}

\subsection{Finding Eigenvalues with Arnoldi's Method}
The orthonormal vectors can be combined into a single matrix
\begin{equation}
    Q_m = \left[q_1 \cdots q_m\right] \in \mathbb{C}^{n\times m}.
\end{equation}
The inner products
\begin{equation}
    h_{jk} = \langle Aq_k, q_j\rangle
\end{equation}
form an upper Hessenberg matrix,
\begin{equation}
    H =
    \begin{bmatrix}
        h_{11} & h_{12} & \cdots & h_{1,m-1} & h_{1m} \\
        h_{21} & h_{22} & \cdots & h_{2,m-1} & h_{2m} \\
        0 & h_{32} & \cdots & h_{3,m-1} & h_{3m} \\
        \vdots & \ddots & \ddots & & \vdots \\
        0 & \cdots & 0 & h_{m,m-1} & h_{mm} \\
        0 & 0 & \cdots & 0 & h_{m+1,m}
    \end{bmatrix}
    \in \mathbb{C}^{m+1 \times m}.
\end{equation}

We can rewrite Eq. \ref{eq:mvOrtho} in terms of $A$, $Q$, and $H$,
\begin{equation}
    AQ_m = Q_{m+1}H_{m+1,m},    \label{eq:MatrixRep}
\end{equation}
or by separating the last column of $Q_{m+1}$ and the bottom row of $H_{m+1,m}$
\begin{equation}
    AQ_m = Q_{m}H_{m} + q_{m+1}h_{m+1,m}e_m^T   \label{eq:MRepmthIter}
\end{equation}
where $e_m$ is the $m$th standard basis vector in $\mathbb{R}^m$.  Writing the equation in this way shows how the result of Arnoldi's process proceeds at each step.

If the vectors $q_j, \;j = 1, \ldots, k$ are linearly independent then $h_{m+1,m} \neq 0$.  If they are dependent, $h_{m+1,m} = 0$ and Eq. \ref{eq:MatrixRep} becomes
\begin{subequations}\begin{gather}
    AQ_m = Q_mH_m \\
    H_m = Q_m^{-1}AQ_m
\end{gather}\end{subequations}
and the Krylov space spanned by the columns of $Q$, $\mathcal{K}_m(q,A)$, is invariant under $A$; that is for any vector $x \in \mathcal{K}_m$, $Ax$ is also in $\mathcal{K}_m$.  It can be shown that the eigenvalues of $H_m$ are the eigenvalues of $A$ and the eigenvectors of $A$ are related to the eigenvectors of $H$ as
\begin{equation}
    x = Q_mv
\end{equation}
where $x$ is an eigenvector of $A$ and $v$ is the associated eigenvector of $H_m$.

If carried out to completion, Arnoldi's method computes a similarity transform of the matrix $A$ to an upper Hessenberg matrix, $H$.  However, unless a very clever choice of the initial vector $q_1$ is used, one rarely finds an invariant subspace and must estimate the eigenvalues and eigenvectors of A from just a few steps of the Arnoldi process.

We can show that the eigenvalues of $H$ are estimates of the eigenvalues of $A$ with some residual error at any step of the Arnoldi process.  We begin by finding an eigenpair of $H$, $(\mu,v)$.  If we multiply Eq. \ref{eq:MRepmthIter} by $v$ we obtain
\begin{subequations}\begin{gather}
    AQ_mv = Q_{m}H_{m}v + q_{m+1}h_{m+1,m}e_m^Tv   \\
    AQ_mv = \mu Q_mv + q_{m+1}h_{m+1,m}e_m^Tv      \\[4mm]  \label{eq:FullResidual}
    Ax = \mu x + r.
\end{gather}\end{subequations}
Here $x = Q_mv$ and $r = q_{m+1}h_{m+1,m}e_m^Tv$, the residual vector.

We can quantify how close the eigenpair $(\mu,x)$ is to a true eigenpair of $A$ by taking the 2-norm of the difference $Ax-\mu x$
\begin{equation}
    \|Ax - \mu x\|_2 = |h_{m+1,m}||e_m^Tv|
\end{equation}
where we have implicitly remembered $\|q_{m+1}\|_2 = 1$.  This difference is called the residual.  A small residual guarantees that $(\mu, x)$ is an exact eigenpair of a matrix that is close to $A$ thus one can monitor the residual to determine convergence of the calculation.

\subsection{Restarted Arnoldi}
Previously I mentioned that unless a careful choice of the initial vector $q_1$ is made, one rarely finds an invariant subspace.  One can make a careful choice by taking a few Arnoldi iterations and use the estimated eigenvector as the initial vector for a new calculation.  This is how Arnoldi's method is restarted.  Arnoldi's method can be restarted many times, each time with a better estimate of the eigenvector.

Restarting Arnoldi's method has several benefits including memory management and processing time of which I will not focus on at this time.  Performing restarts is a naive and simple way of duplicating the cycle in the power method.  The calculation of the eigenvalue and eigenvector after each restart can be compared to the eigenvalues and eigenvectors of the power method.  These eigenpairs can be evaluated to find their mean and variance, just like with the power method.

\section{Questions to Answer}
\begin{enumerate}
    \item \emph{What is the uncertainty?  Is the answer biased?}  This is the question of greatest import.  A Monte Carlo calculation is useless without some measure of its statistical uncertainty.  The easiest way to get this is to do restarted Arnoldi and find the mean and variance of of the eigenvalues and eigenvectors after each restart.  I think there is a better way.  There must also be some analysis of the bias (if one exists) in the answer.
    \item \emph{Is there a better way to evaluate the inner product $\langle q_k, q_j \rangle$?}  We know the definition of the inner product
    \begin{equation}
        \langle q_k, q_j \rangle \equiv \int q_j(x)q_k(x) dx.   \label{eq:InnerProduct}
    \end{equation}
    For vectors, this is a simple dot-product.  While this is simple, it requires biasing our results by spatial binning the fission source.  It should be possible to sample from a (semi-)continuous source distribution $q_j$ and finding the corresponding value from $q_k$
    \begin{equation}
        \langle q_k, q_j \rangle  = \frac{1}{N}\sum_{i=1}^N q_k(x_i).
    \end{equation}
    This is more of a Monte Carlo way of doing things and should reduce the bias in the calculation.
    \item \emph{Beyond Histograms---Other Functional Expansions}  Our fission source vectors are histogram sources
    \begin{equation}
        q(x) = \sum_{i=1}^B a_if_i(x)
    \end{equation}
    where $B$ is the number of spatial bins and
    \begin{equation}
        f_i(x) = \left \{
            \begin{array}{ccc}
                1 &,& x_{i} \leq x < x_{i+1} \\
                0 &,& \mathrm{otherwise}
            \end{array}\right. .
    \end{equation}
    We can, however choose a different set of basis vectors, $f_i(x)$, about which we can expand. One choice to pursue is a linear inspace across each spatial bin, but I'm not going to show how this is done.

\end{enumerate}

\section{Tasks to Complete}
\begin{itemize}
    \item Heterogeneity
    \item Multi-dimensional
\end{itemize}

\end{document}


\chapter{Synthesis in Example of a Magnetic Bearing on an Overhung Rotor}\label{MagExample}
Analysis and modeling techniques of the previous chapters will now be put to use in a practical example. The goal of which will be to reduce vibration on an overhung disk rotor system with the use of an Active Magnetic Bearing(AMB). An experimental test rig, not unlike the system used in the experimental example of \S\ref{ExperimentalPlots}, will be used to calibrate a  finite element theoretical model. Then, the theoretical model will be extended to include an AMB near the overhung disk. The model will be evaluated for stability, and parameters of the control algorithm for the AMB will be varied to attempt to eliminate modes and stabilize the system.
\section{Physical System Description}
The rotor system of interest is depicted in Figure \ref{fig:OverhungDiagram}. Geometric parameters are listed in Table \ref{tab:GeometricParametersofOverhung}. The springs at nodes 1 \& 4 are intended to represent bushings, portion at node 6 is the rotating disk, and nodal numbers are indications of how the rotor will be discretized for the finite element model.
\begin{figure}
	\centering
	\def\svgwidth{250pt}
	\import{figures/}{OverhungDiagram.pdf_tex}
	\caption{Overhung rotor system diagram.}
	\label{fig:OverhungDiagram}
\end{figure}
\begin{table}
	\centering
	\caption{Geometric parameters of the overhung rotor system.}
	\label{tab:GeometricParametersofOverhung}
	\begin{tabular}{cccccc}
		$ L[m] $&$ a[m] $&$ b[m] $&$ l_d[m] $&$ d_d[m] $&$ d_s[m] $\\\hline
		$ 0.5 $&$ 0.23 $&$ 0.13 $&$ 0.025 $&$ 0.075 $&$ 0.01 $
		\end{tabular}
\end{table}
\section{Experimental Results}
The rotor system was tested in a start-up from slow roll to $ 3000[RPM] $. Data shown here is taken from $ 1000[RPM] $ to $ 2000[RPM] $. A set of orthogonal eddy current position sensors placed near the disk on the outboard side were used to measure the position of the shaft throughout the start-up. Position data was recorded at a sampling rate of $ 128000[Hz] $ with no processing applied, this sampling rate is much higher than the required rate to avoid aliasing. The resulting 3D orbit of the start-up is shown in Figure \ref{fig:MagExampleOrbit3D}. Of note is the necking in the 3D orbit during the natural frequency that is indicative of high anisotropy inducing a negative whirl during the first natural frequency. Also resulting from the experiment is the full spectrum cascade plot of Figure \ref{fig:MagExampleCascade}, in which it is evident that synchronous vibration dominates the spectra. Though, for the production of the bode diagram (Figure \ref{fig:MagExampleBode}) there was a benefit in clarity from filtering the data to synchronous speed.
\begin{figure}
	\centering
	\includegraphics[width=.5\linewidth]{./figures/MagExpExampleOrbit3D.png}
	\caption{3D Orbit of the experimental overhung rotor system.}
	\label{fig:MagExampleOrbit3D}
\end{figure}
\begin{figure}
	\centering
	\includegraphics[width=.8\linewidth]{./figures/MagExampleCascade.png}
	\caption{Cascade of the experimental overhung rotor system.}
	\label{fig:MagExampleCascade}
\end{figure}
\begin{figure}[!htb]
	\def\width{.7\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={ylabel style={xshift=0},xlabel style={yshift=0}}}%, every axis/.style={hide axis}}%
	\centering
	\import{}{./figures/MagExampleBode.tex}
	\caption{Bode diagram of the experimental overhung rotor filtered to 1X.}
	\label{fig:MagExampleBode}
\end{figure}
\section{Theoretical Model}
To create a finite element model for this rotor system the shaft will be discretized into 7 elements a disk at node 6 and bearings at nodes 1 and 4, as depicted in Figure \ref{fig:OverhungDiagram}. In the experiment, a small length of shaft continued after the overhung disk and has been included in this model. The AMB will be included as a nodal point element with with stiffness and damping to be derived in \S\ref{Active Magnetic Bearing}. Parameter values for the finite element model are provided in Table \ref{tab:OverhungParameters}. Discovered values such as $ \eta_v $ and the stiffnesses of bearing are listed here, but the process for their determination is discussed.
\begin{table}
	\caption{Properties of disks, shaft elements, and bearings of the theoretical model.} \label{tab:MagTheoryRotorTable}
	\centering
	\label{tab:OverhungParameters}
	\begin{tabular}{rcccccc}
							&$\rho\left[\frac{kg}{m^3}\right]$	&$r[m]$					&$\nu$				&$E[Pa]$			&$ \eta_v[s] $	&$ \eta_h $	\\\hline
		\textbf{Shaft}		&$7850$					&$0.005$				&$0.3$				&$\num{210E9}$		&$ 0.0002 $		&$ 0 $		\\[-.2em]
							&$\rho\left[\frac{kg}{m^3}\right]$	&$r[m]$					&$l[m]$				&					&				&			\\\hline
		\textbf{Disks}		&$7850$					&$0.0375$				&$0.025$			&					&				&			\\[-.2em]
							&$k_y\left[\frac{N}{m}\right]$		&$k_z\left[\frac{N}{m}\right]$		&$c_y\left[\frac{Ns}{m}\right]$&$c_z\left[\frac{Ns}{m}\right]$&				&			\\\hline
		\textbf{Bearing A}	&$1.7\e{5}$				&$2.2\e{5}$				&$68$				&$88$				&				&			\\[-.5em]
		\textbf{Bearing B}	&$2.04\e{5}$			&$2.64\e{5}$			&$81.6$				&$105.6$			&				&			\\
	\end{tabular}
\end{table}
First the model is formed to match the experimental results. Known parameters, such as beam lengths, beam diameters, density of the material, and geometry of the disk and rotor are used to begin construction of the model. Then, guesses are made for the stiffnesses in the rotor bearings. The first natural frequency is calculated with the resulting model and its value compared to the experimentally found natural frequency from the bode diagram (fig.\ref{fig:MagExampleBode}). Stiffness are then adjusted to better match the natural frequency, and this is repeated until the natural frequency of the model matches the experiment. After this process, the stiffness was determined to be around $ 2\e{5} \left[\frac{N}{m}\right]$.\par
It is evident by inspection of the Bode diagram for the experimental system (fig.\ref{fig:MagExampleBode}), and the 3D orbit, that there is anisotropy in the system, leading to the dip in amplitude of one plane of vibration. It is also known from inspection of the frequency spectrum in the cascade of figure \ref{fig:MagExampleCascade} that in this speed range the orbit is in the opposite direction of the rotation--a phenomena only possible with anisotropy of the stiffness. Figures \ref{fig:HorVertStiffAniCompare} \& \ref{fig:PosNegStiffAniCompare} demonstrate this affect anisotropy has on both the real coordinates, as well as positive and negative whirl amplitudes. In the real coordinates, cross coupling of from gyroscopic moments causes an interaction of the two peaks in amplitude. As the stiffness anisotropy approaches a value of 1, the vibration of the more flexible plane will split into two peaks. One peak coinciding with that planes natural frequency and one plane coinciding with the orthogonal natural frequency. During this change in anisotropy of stiffness, the peaks of both positive and negative amplitude spectrums split to coincide with either plane's natural frequency. When the two orthogonal planes have widely separated natural frequencies, the negative amplitude spectrum is greater than the positive amplitude spectrum for the range of speed between the two natural frequencies. \par
\begin{figure}
\begin{subfigure}{\textwidth/2}
	\centering
	\includegraphics[width=\linewidth]{./figures/MagExampleHorVertStiffAniCompare.png}
	\caption{Comparison of v \& w as stiffness anisotropy is changed.}
	\label{fig:HorVertStiffAniCompare}
\end{subfigure}
\begin{subfigure}{\textwidth/2}
	\centering
	\includegraphics[width=\linewidth]{./figures/MagExamplePosNegStiffAniCompare.png}
	\caption{Comparison of positive and negative orbit amplitudes as stiffness anisotropy is changed.}
	\label{fig:PosNegStiffAniCompare}
\end{subfigure}
\end{figure}
Using the bode diagram, the stiffness anisotropy is adjusted until the shapes of the amplitudes and phases match the experimental results of figure \ref{fig:ExpExampleBode}. Then damping is added to the system to appropriately match the experimental results. The resulting bode diagram is Figure \ref{fig:MagTheoryBode}. Stiffnesses were determined to be $ k_y=1.7\e{5}[N/m]\ \&\ k_z=2.2\e{5}[N/m] $.
\begin{figure}[!htb]
	\def\width{.6\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={ylabel style={yshift=.5em},xlabel style={yshift=0}},
	every axis plot/.style={line width=1.4pt}}%, every axis/.style={hide axis}}%
	\centering
	\import{figures/}{MagTheoryBode.tex}
	\caption{Bode Diagram of overhung system without AMB.}
	\label{fig:MagTheoryBode}
\end{figure}
And now the resulting system is further described with an expanded speed range of $ 20000[RPM] $. This resulting model is described with the new Campbell diagram of Figure \ref{fig:MagTheoryCampbell}, the roots locus of Figure \ref{fig:MagTheoryRootLocus}, and the first three mode shapes (Figures \ref{fig:MagTheoryShape1}, \ref{fig:MagTheoryShape2}, \& \ref{fig:MagTheoryShape3}). Note that the first mode is conical in shape, but the disk is far from an antinode at node 6 so it does not experience significant gyroscopic moments. This idea is supported by the campbell diagram, fig. \ref{fig:MagTheoryCampbell}, as the first mode natural frequency does not change significantly over the speed range. On the other hand, the second mode has its antinode atode 6 so the disk experience maximum gyroscopic moments and the second mode critical speed is much more dependent on speed.
\begin{figure}[!htb]
	\def\width{.6\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={ylabel style={yshift=.5em},xlabel style={yshift=0}},
	every axis plot/.style={line width=1.4pt}}%, every axis/.style={hide axis}}%
	\centering
	\import{figures/}{MagTheoryCampbell.tex}
	\caption{Campbell Diagram of the overhung system without AMB.}
	\label{fig:MagTheoryCampbell}
\end{figure}
\begin{figure}[!htb]
	\def\width{.6\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={ylabel style={yshift=.0},xlabel style={yshift=0}},
	every axis plot/.style={line width=1.4pt}}%, every axis/.style={hide axis}}%
	\centering
	\import{}{./figures/MagExampleRootsLocus.tex}
	\caption{Roots Locus of overhung system without AMB.}
	\label{fig:MagTheoryRootLocus}
\end{figure}
\begin{figure}
	\def\cs{.29}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={yticklabel style={xshift=0,yshift=0},minor tick num=2}, grid style={line width=.1pt, draw=gray!20},major grid style={line width=.2pt,draw=gray!50},ticks=none,minor tick style={draw=none},	every axis plot/.style={line width=.9pt},}%, every axis/.style={hide axis}}%
	\begin{subfigure}{\cs\textwidth}
		\centering
		\def\width{\linewidth}
		\def\height{\linewidth}
		\import{}{./figures/MagTheoryShape1.tex}
		\caption{Mode Shape 1.}
		\label{fig:MagTheoryShape1}
	\end{subfigure}
	\begin{subfigure}{\cs\textwidth}
		\centering
		\def\width{\linewidth}
		\def\height{\linewidth}
		\import{figures/}{MagTheoryShape2.tex}
		\caption{Mode Shape 2.}
		\label{fig:MagTheoryShape2}
	\end{subfigure}
	\begin{subfigure}{\cs\textwidth}
		\centering
		\def\width{\linewidth}
		\def\height{\linewidth}
		\import{}{./figures/MagTheoryShape3.tex}
		\caption{Mode Shape 3.}
		\label{fig:MagTheoryShape3}
	\end{subfigure}
\end{figure}
\subsection{Active Magnetic Bearing}\label{Active Magnetic Bearing}
Magnetic pole-rotor relationship will be derived based on the detailed derivation in \cite{das2008vibration}, with influence from \cite{childs1993turbomachinery}. Assumptions made in this model are as follows:
\begin{itemize}
	\item Air gap between the magnet pole face and the rotor is vanishingly small compared to the diameter of the shaft.\
	\item Flux leakage from the magnetic pole is negligible.
	\item Curvature of rotor surface under the pole face is ignored.
	\item A linear relationship of flux density and magnetic field is assumed.
	\item Hysteresis of the magnetic field is negligible.
\end{itemize}
These assumptions lead to a magnetic force due to coil current in the relationship of
\begin{equation}\label{key}
F_m=\frac{-k_mi^2}{l_g^2}
\end{equation}
where, $ k_m=\frac{\mu_0A_pN^2}{4} $, and $ \mu_0=4\pi\e{-7} $ is the absolute permeability in free air, $ N $ is the number of coil turns, $ A_p $ is the pole face area, $ i $ is the supplied electrical current, and $ l_g $ is the air gap.\par
Consider a set of magnetic pole pairs in each the $ y\ \&\ z $ directions (i.e. One on the left and one on the right; one on top and one on bottom), where each pole pair has its own electrical circuit. There are four total magnets in this model, two in each direction, and eight total poles where two form a magnet. All poles in the neutral position of the system will have a nominal air gap of $ g_0 $ and will be supplied by a bias current of $ i_0 $. Deviations of the current from this bias will be considered as $ i_y $ and $ i_z $. Deviations of the position from this neutral position are the displacements of the rotor at this beam axis location, $ v,\ \&\ w $. Therefore, total current will be $ (i_0\pm i_y)\ \&\ (i_0\pm i_z) $ for opposing poles in the $ y\ \&\ z $ directions respectively. Similarly, total gaps are given by $ (g_0\pm v)\ \&\ (g_0\pm w) $. Using these new definitions for the gap and current, and summing forces in the $ y\ \&\ z $ directions leads to the total forces
\begin{equation}\label{eq:MagneticForceNL}
F_y=K_m\left\{\left(\frac{i_0+i_y}{g_0+v}\right)^2-\left(\frac{i_0-i_y}{g_0-v}\right)^2\right\}\ \&\ F_z=K_m\left\{\left(\frac{i_0+i_z}{g_0+w}\right)^2-\left(\frac{i_0-i_z}{g_0-w}\right)^2\right\}
\end{equation}
where, $ K_m=k_m\cos(\alpha) $, and $ \alpha $ is half of the angle between the poles of a magnet. Linearizing the magnetic force equations \eqref{eq:MagneticForceNL}, while assuming the operating point for the system is where all positions and control currents are zero, results in
\begin{equation}\label{eq:MagneticForce}
F_y=k_ii_y+k_yv,\ \&\ F_z=k_ii_z+k_zw
\end{equation}
where, $ k_i=4K_m\frac{i_0}{g_0^2} $ is the current stiffness developed by the bias current, and $ k_y=k_z=k_s=-4K_m\frac{i_0^2}{g_0^3} $.
\subsubsection{Proportional Derivative Control}
A control algorithm is used to control the current sent to each pair of poles based on the position (proportional) and velocity (derivative) of the rotor. It is assumed that each set of pole pairs will receive opposite currents to act as a unit. Current control is given by
\begin{equation}\label{eq:ControlCurrent}
i_y=-k_g(k_pv+k_v\dot{v}),\ \&\ i_z=-k_g(k_pw+k_v\dot{w})
\end{equation}
where, $ k_g $ is the power amplifier gain, $ k_p $ is the proportional gain, and $ k_v $ is the derivative gain. The total linearized force becomes
\begin{equation}\label{key}
F_y=-(k_gk_ik_p-k_s)v-k_gk_ik_v\dot{v},\ \&\ F_z=-(k_gk_ik_p-k_s)w-k_gk_ik_v\dot{w}
\end{equation}
so then the stiffness of the AMB is $ k_{mag}=(k_gk_ik_p-k_s) $ and the damping is $ d_{mag}=k_gk_ik_v $. As an equation of nodal stiffness and damping in the finite element system it can be represented by
\begin{equation}\label{eq:DiskNodeEquationofMotion}
\bunderline{\mathbf{D}}^m\dot{\vec{\mathbf{q}}}_k+\bunderline{\mathbf{K}}^m\vec{\mathbf{q}}_k=0
\end{equation}
where,
\begin{equation*}
\def\cs{2em}
\begin{array}{cc}
\bunderline{\mathbf{K}}^m=\left[\def\arraystretch{.8}\arraycolsep=0pt\begin{array}{cccccc}
\makebox[\cs]{$k_{mag}$}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}\\
0&k_{mag}&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0
\end{array}\right] & \bunderline{\mathbf{D}}^m=\left[\def\arraystretch{.8}\arraycolsep=0pt\begin{array}{cccccc}
\makebox[\cs]{$d_{mag}$}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}&\makebox[\cs]{0}\\
0&d_{mag}&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0\\
0&0&0&0&0&0
\end{array}\right]
\end{array}
\end{equation*}

\section{Addition of Magnetic Bearing to the Rotor Model}
In order to measure the effectiveness of the AMB, the Stability of the theoretical model before the addition is shown in Figure \ref{fig:MagTheoryStability}. The magnetic bearing added is modeled after a magnetic bearing that is currently in the lab at California Polytechnic State University. This theoretical exercise is intended to be followed by experimental verification not included in this work. The parameters used are listed in \ref{tab:MagBearingParameters} as well as the control values whose determinations will be evaluated.\par
First the axial position of the AMB must be determined. By inspection of the mode shapes, it is evident that in the first mode (the mode we are most concerned about suppressing) a shape exists with increasing amplitude toward the end of the beam after the second bearing. It is also known that the source of vibration, the rotating disk, is located at nodal index six. With both these pieces of information, node seven is chosen as a starting point for the AMB for two reasons: having the AMB closer to the source of vibration reduces the phase lag between the source and the bearing, increasing the effectiveness of control; amplitude of vibration, according to the mode shape, is higher on the outboard side of the disk and placing the AMB on this side will minimize more vibration. Additionally, this location should significantly suppress the second mode of vibration as node seven is near the maximum amplitude of that mode as well.\par
In order to choose a value for bias current, $ i_b $, and provide upper range estimates of the controller outputs, $ k_v,\ \&\ k_p $, the maximum expected current output of the control loop must be determined. $ i_b $ will be set so that under peak power output, in the expected speed range, the control current will push the total current output beyond the system limits.\par
Knowing that the amplitude of vibration, $ A $, in the experimental system peaks at about 10 mils, or $ 2.54\e{-4}[m] $, the greatest possible velocity for synchronous vibration is determined using the simple equation $ vel=(A/2)\omega $, where $ \omega $ is the whirl speed in rad/s. Under the assumption of synchronous vibration, $ \omega $ during the natural frequency is then $ 167.6[Rad/s] $. Leading to a velocity, $ vel $, of $ 0.02[m/s] $. Also, another possible peak velocity occurs in the upper speed range. Knowing that the amplitude of vibration after the first natural frequency is equal to the eccentricity of the unbalance, with an eccentricity of $ 1\e{-5} $, and an upper speed of $ 15000[RPM] $, the velocity is calulated to be $ 0.008[m/s] $. Since the estimated velocity during the natural frequency is higher, it will be used to limit the output of the AMB controller. Total voltage supply of most digital to analog converters is limited to $ 10[V] $. So the control voltage is calculated to be within this range for the given velocity and positions that will be seen under synchronous vibration. This results in a limitation of the term $ k_v $, which is proportional to the voltage control signal that is sent to the amplifier for conversion to control current. A value of $ 480[Vs/m] $ would max the converter, so the value to be determined must be less than this. With a similar, but separate, evaluation of the displacement leads to a maximum allowable value of $ 500000[V/m] $ for $ k_p $--a value not anticipated to be necessary. The maximum force due to unbalance is $ \epsilon m_d\Omega^2 $, where $ \epsilon $ is the eccentricity, and $ m_d $ is the mass of the disk. At the maximum speed expected of $ 15000[RPM] $, the force will be $ 24[N] $. To counteract this force with a single coil would require $ 1.25[A] $, or $ 0.625[A] $ per coil in a opposing pair. The amplifier gain is assumed to be programmable to $ k_g=1[A/V] $, this leads to a reasonable choice of bias current at $ 0.5[A] $ to maintain a good resolution on the voltage output of the controller. Under the operating conditions described, the control voltage should not exceed $ 1.25[V] $, and will rest at an output of $ 0.5[V] $. Now in the next section, control parameters $ k_v\ \&\ k_p $ will be determined to maximize stability of the system while also minimizing vibration.\par
 To determine best derivative control constant ($ k_v $), the proportional control constant ($ k_p $) was set to zero. $ k_v $ is increased until the first mode on the Roots locus(fig. \ref{fig:MagTheoryRootLocus}) moves away from the imaginary axis, becoming more damped. The resulting movement of the Roots on the Roots Locus is given in Figure \ref{fig:MagTheoryRootLocusControllerTune}. Note that because of bias current flowing through the bearing, a baseline stiffness of $ k_S $ is present in the system even withou $ k_p $. None of the modes that appear on the roots locus of the system with $ k_p=0,\ \&\ k_v=10[\frac{Vm}{s}] $ control algorithm cross the real plane--this demonstrates the stability of the new system. Stability of the system with the AMB addition is confirmed in the stability plot of Figure \ref{fig:MagTheoryStabilityWith}. In fact from the roots locus with $ k_v=1 $ to the roots locus with $ k_v=10 $ the first mode of vibration is completely relegated to the imaginary axis and not reaching break-away for this entire speed range--this indicates that the first mode has been over-damped. With additional damping through the increase of $ k_v $ it would be possible to over-damp the second mode as well, but in the speed range given, it would not improve the performance.\par
 Proportional control, $ k_p $, was added after the ideal derivative control was determined, but it did not improve the performance of the controller. It is the case that the stiffness of the bearing inherent to the bias current is sufficient. In any case, proportional control in this scenario is only adding stiffness to the system, and with the objective being to minimize vibration, $ k_p $ is not effective. So the optimal control is determined to be with $ k_p=0,\ \&\ k_v=10[Vs/m] $. The remaining parameters for this resulting controller are listed in table \ref{tab:MagBearingParameters}. It is worthwhile to note that this optimal control is standing on the basis that the feedback is of synchronous vibration only. In a scenario where there is significant sub or super-synchronous vibrations, this controller may exceed its voltage limit. It is recommended that the feedback signal be filtered to match rotor speed to ensure this scenario does not take place. Furthermore, without at least low-pass filtering of the feedback signal the control would certainly provide out of range signals due to the volatile nature of derivatives of discrete signals.\par
 The frequency spectrum is provided showing the result of the AMB application in the bode diagram of Figure \ref{fig:MagTheoryBodeCompare}. Certainly it can be concluded that the AMB is successfully performing the desired task of reducing the vibration while also inproving the stability of the system.\par
The result from this synthesis exercise can be implemented on the actual experimental test rig with the AMB set to the control parameters suggested. The power of the finite element method in this application is the ability to move components around with ease. For instance, with the changing of just two parmeters in the input file for this model, a new simulation is created for complete levitation of the overhung rotor. The AMB is put in place of bearing b and the resulting frequency spectrum is plotted in Figure \ref{fig:MagLevTheoryBodeCompare}
\begin{table}
	\centering
	\caption{Active Magnetic Bearing Parameters.}
	\begin{tabular}{cccccccc}
		$\alpha[rad]$&$g_0[m]$&$i_0[A]$&$k_p[\frac{V}{m}]$&$k_v[\frac{Vs}{m}]$&$k_g[\frac{A}{V}]$&$ N[\#]$&$A_p[m^2]$\\\hline
		$\frac{\pi}{8}$&$2.5\e{-3}$&$0.5$&$0$&$10$&$1$&$800$&$\frac{5}{100*100}$
	\end{tabular}
	\label{tab:MagBearingParameters}
\end{table}
\begin{figure}
	\begin{subfigure}{\textwidth/2}
		\def\width{.8\linewidth}
		\def\height{.4\linewidth}
		\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={ylabel style={yshift=-20},xlabel style={yshift=35}},every x tick scale label/.style={at={(xticklabel* cs:1,.3cm)},anchor=near xticklabel},every axis plot/.style={line width=1.4pt}}%, every axis/.style={hide axis}}%
		\centering
		\import{figures/}{MagTheoryStability.tex}
		\caption{Stability plot of rotor without AMB, threshold of stability:$ \ 4646[RPM] $.}
		\label{fig:MagTheoryStability}
	\end{subfigure}
	\begin{subfigure}{\textwidth/2}
		\def\width{.8\linewidth}
		\def\height{.35\linewidth}
		\pgfplotsset{every picture/.style={trim axis left, trim axis right}, every axis/.style={xlabel style={yshift=-2em},xlabel style={yshift=25,at={(axis description cs:0.5,1.05)},anchor=north}},every x tick scale label/.style={at={(xticklabel* cs:1,.3cm)},anchor=near xticklabel},every axis plot/.style={line width=1.4pt}}%, every axis/.style={hide axis}}%
		\centering
		\import{figures/}{MagTheoryStabilityWith.tex}
		\caption{Stability plot of rotor with AMB, indicates complete stability through speed range.}
		\label{fig:MagTheoryStabilityWith}
	\end{subfigure}
\end{figure}
\begin{figure}[!htb]
	\def\width{.7\linewidth}
	\def\height{.5\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right},every axis plot/.style={line width=1.4pt}}%, every axis/.style={ylabel style={yshift=0em},xlabel style={yshift=0}}}%, every axis/.style={hide axis}}%
	\centering
	\import{figures/}{MagTheoryRootLocusControllerTune.tex}
	\caption{Roots locus of Overhung rotor system with varying $ k_v $.}
	\label{fig:MagTheoryRootLocusControllerTune}
\end{figure}
\begin{figure}[!htb]
	\def\width{.6\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right},every axis plot/.style={line width=1.3pt}}%, every axis/.style={ylabel style={yshift=0em},xlabel style={yshift=0}}}%, every axis/.style={hide axis}}%
	\centering
	\import{figures/}{MagTheoryBodeCompare.tex}
	\caption{Bode diagram at node 6 comparing the rotor without AMB(solid) and with AMB(dashed).}
	\label{fig:MagTheoryBodeCompare}
\end{figure}
\begin{figure}[!htb]
	\def\width{.6\linewidth}
	\def\height{.4\linewidth}
	\def\sep{3em}
	\pgfplotsset{every picture/.style={trim axis left, trim axis right},every axis plot/.style={line width=1.3pt}}%, every axis/.style={ylabel style={yshift=0em},xlabel style={yshift=0}}}%, every axis/.style={hide axis}}%
	\centering
	\import{figures/}{MagLevTheoryBodeCompare.tex}
	\caption{Bode diagram at node 6 comparing the rotor without AMB(solid) and with AMB(dashed) for complete levitation at node 4.}
	\label{fig:MagLevTheoryBodeCompare}
\end{figure}


% !TEX root = ../zeth-protocol-specification.tex

\section{Processing $\zethTx$}\label{zeth-protocol:process-tx}

When a $\zethTx$ is mined (hence assuming that $\ethVerifyTx(\zethTx)$ returns $\true$), the state transition specified by the $\mix$ function of $\mixer$ is executed.

To preserve the soundness of \zeth, and make sure that no $\zparty{U}$ is able to create value by double spending $\zethnotes$, various checks need to be satisfied. The function $\zethVerifyTx$ is defined as the function that returns $\true$ if all the checks are satisfied, and $\false$ otherwise.

If $\zethVerifyTx(\zethTx)$ returns $\true$, then $\mix$ modifies the ``World state'' $\wstate$ to account for the spent $\zethnotes$ and the newly generated ones. However, if $\zethVerifyTx(\zethTx)$ returns $\false$, then the state transition ends.

\begin{notebox}
    Even if $\zethVerifyTx(\zethTx)$ returns $\false$, $\wstate$ is modified since the \ethereum~balances of the transaction originator is decremented by the sum of $\txDefaultGas$ and the gas consumed by the $\zethVerifyTx$ function, and the balance of the \ethereum~account of the miner gets incremented by the same amount.
\end{notebox}

Thus, $\mix$ proceeds as follows:
\begin{enumerate}
    \item Check that all the values of the primary inputs' ($\inp{\mix}.\primInp$) entries are elements of the scalar field over which the zk-proof is generated:
        \[
            \inp{\mix}.\primInp \in \FFx{\rCURVE}^*
        \]
    \item Unpack the nullifiers, signature hash and public values (see~\cref{instantiation:statement:pack} for the definitions of the $\unpack{}{}$ functions):
        \begin{align*}
            \nf{i} &= \unpack{\inp{\mix}.\primInp.\nfs{i}, \inp{\mix}.\primInp.\resbits}{\nf{}}\ \forall i \in [\jsin] \\
            \vin &= \decode{\unpack{(), \inp{\mix}.\primInp.\resbits}{\vin}}{\NN} \\
            \vout &= \decode{\unpack{(), \inp{\mix}.\primInp.\resbits}{\vout}}{\NN} \\
            \hsig &= \unpack{\inp{\mix}.\primInp.\hsig, \inp{\mix}.\primInp.\resbits}{\hsig}
        \end{align*}
    \item Check the validity of the $\zethTx$ object ($\zethVerifyTx$):
        \begin{enumerate}
            \item Check that $\inp{\mix}.\primInp.\hsig$ is correctly computed, i.e.~check that the following equation holds (to prevent transaction malleability, see~\cref{appendix:trnm}):
                \[
                    \hsig = \crhhsig{\inp{\mix}.\primInp.\nfs{}, \inp{\mix}.\otsvk}
                \]
            \item\label{zeth-protocol:process-tx:verify-zkp} Check that $\zkp$ is a valid zk-SNARK proof for $\inp{\mix}.\primInp$, i.e.~check that:
                \[
                    \zksnark.\verifier(\pparams_{\zksnark}, \zkp, \inp{\mix}.\primInp) = \true
                \]
            \item Check that none of the nullifiers in $\inp{\mix}.\primInp.\nfs{}$ have already been used, i.e.~check that:
                \[
                    \nf{i} \not\in \nullifierset, \forall i \in [\jsin]
                \]
                where $\nullifierset$ is the set of all nullifiers that are ``declared'' on $\mixer$.
            \item\label{zeth-protocol:process-tx:check-otsig} Check that $\inp{\mix}.\otssig$ is a valid signature of the $\ethereum{}$ sender's address $\addr$ (see~\cref{zeth-protocol:create-tx}) and the attributes of $\inp{\mix}$, to prevent transaction malleability (see~\cref{appendix:trnm}), i.e.~check that:
                \begin{align*}
                    & \otsigscheme.\verify(\inp{\mix}.\otsvk, \msg, \inp{\mix}.\otssig) = \true \\
                    & \text{where} \ \datatobesigned = \addr \concat \inp{\mix}.\primInp \concat \inp{\mix}.\zkp \concat \inp{\mix}.\ciphers, \\
                    & \text{and} \ \msg = \crhots{\datatobesigned}
                \end{align*}
            \item Check that $\inp{\mix}.\primInp.\mkroot$ corresponds to a valid state of the Merkle tree held on $\mixer$, i.e.~check that:
                \[
                    \inp{\mix}.\primInp.\mkroot \in \rootset'
                \]
                where $\rootset'$ is the set of all Merkle roots corresponding to one of the states of the Merkle tree.
            \item Check that $\vin$ corresponds to the value $\val$ of the transaction object, i.e.~check that:
                \[
                    \vin = \zethTx.\val
                \]
        \end{enumerate}
    \item If all checks above pass, i.e.~if $\zethVerifyTx(\zethTx)$ returns $\true$, then the following additional modifications are made in $\wstate$:
        \begin{enumerate}
            \item Add the commitments $\inp{\mix}.\primInp.\cms{}$ to the Merkle tree held on $\mixer$.
            \item $\rootset' \gets \rootset' \cup \smallset{\mkroot'}$, where $\mkroot'$ is the Merkle root of the Merkle tree after insertion of the commitments $\inp{\mix}.\primInp.\cms{}$ in the Merkle tree.
            \item $\nullifierset \gets \nullifierset \cup \indexedset{\nf{i}}{i \in [\jsin]}$, i.e.~the nullifiers $\nfs{}$ become ``declared''.
            \item Modify the \ethereum~balances according to the public values:
                \begin{itemize}
                    \item $\wstate[\eparty{S}.\addr].\balance = \wstate[\eparty{S}.\addr].\balance - \vin$
                    \item $\wstate[\eparty{S}.\addr].\balance = \wstate[\eparty{S}.\addr].\balance + \vout$
                    \item $\mixer.\balance = \mixer.\balance + \vin$
                    \item $\mixer.\balance = \mixer.\balance - \vout$
                \end{itemize}
            \item Emit an event (\cref{sssec:ethereum-events}) $\evMixOut$ of type \mixEventDType, containing the new root $\mkroot'$ of the Merkle tree of commitments, the nullifiers $\indexedset{\nf{i}}{i \in [\jsin]}$, commitments to the newly created \zethnotes $\inp{\mix}.\primInp.\cms{}$, and the corresponding ciphertexts $\inp{\mix}.\primInp.\ciphers$.
        \end{enumerate}
\end{enumerate}

\begin{remark}\label{zeth-protocol:process-tx:dispatch-call}
  In some deployments, verification of the zk-SNARK proof $\zkp$ may be delegated to an external mechanism (in such a way that integrity of the system can still be guaranteed), and $\zkp$ may not appear as public data on-chain. For example, where multiple \zeth~transactions are aggregated by a system such as that described in \cite{rondelet2020zecale}, the original zk-SNARK proofs become auxiliary inputs to a ``wrapping'' SNARK, which checks their validity via a single proof verification. A modified version of the \mix~function receives \mix~parameters from a specific contract (known to behave correctly with respect to the delegation protocol) without $\inp{\mix}.\zkp$.

  In this case, the value of $\datatobesigned$ in \cref{zeth-protocol:process-tx:check-otsig} may be replaced by:
  \[
  \datatobesigned = \addr \concat \inp{\mix}.\primInp \concat \inp{\mix}.\ciphers, \\
  \]
  and the equivalent change must be made when generating the \mix~parameters, as described in \cref{zeth-protocol:mix-inp:otsig-for-dispatch-call}. The transaction, as presented to an aggregator, is malleable since the $\groth$ proofs can be modified in a way that preserves the validity. However, once aggregated, the transaction proof data for the transaction does not appear on chain (it is an auxiliary input to some externally generated ``wrapping'' poof). Hence, the transaction can only be identified by the remaining public data, which is protected by the one-time signature $\otsSigma$, and hence non-malleable.

  The external scheme used to verify the zk-SNARK proof must specify the exact requirements of the contact and how it should be modified, including any further checks that must be carried out. Thus, this modification is not part of the core \zeth~protocol described in this document, but an augmentation forming part of an external protocol. However, for completeness, we briefly describe a \emph{dispatch} entry point in the proof-of-concept \mixer~implementation which supports delegation of proof verification, as described above. The \emph{dispatch} entry point performs the following checks:
  \begin{itemize}
  \item Check that the \mixer~has been deployed with the (immutable) address of a trusted contract, permitted to call this entry point. Otherwise, abort.
  \item Check that the caller $msg.sender$ matches the permitted caller set at deployment time, otherwise abort.
  \item Perform all checks related to the \mix~parameters, except \cref{zeth-protocol:process-tx:verify-zkp}, with the modification to \cref{zeth-protocol:process-tx:check-otsig} described in this remark.
  \end{itemize}
  After these checks, the state-transition continues as normal.

  The \zeth~client implementation is also augmented to include a flag to enable the corresponding change described in \cref{zeth-protocol:mix-inp:otsig-for-dispatch-call} (to generate a signature on the modified $\datatobesigned$). Naturally, the \emph{dispatch} entry point can only be used with parameters generated using this flag (otherwise the signature check will fail).

  Such modifications \MUSTNOT{} be implemented except as described by the secure external scheme for delegating proof verification.
\end{remark}